From a53dc3a8c19213c9f8b0ae6a195e8014b7176ee5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 10 Mar 2020 14:46:16 +0000 Subject: [PATCH 001/166] Remove usage of the responder as this is a json only controller --- app/controllers/admin/proxy_orders_controller.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/proxy_orders_controller.rb b/app/controllers/admin/proxy_orders_controller.rb index b6d0140845..296bf83e67 100644 --- a/app/controllers/admin/proxy_orders_controller.rb +++ b/app/controllers/admin/proxy_orders_controller.rb @@ -9,9 +9,7 @@ module Admin def cancel if @proxy_order.cancel - respond_with(@proxy_order) do |format| - format.json { render_as_json @proxy_order } - end + render_as_json @proxy_order else respond_with(@proxy_order) do |format| format.json { render json: { errors: [t('admin.proxy_orders.cancel.could_not_cancel_the_order')] }, status: :unprocessable_entity } @@ -21,13 +19,9 @@ module Admin def resume if @proxy_order.resume - respond_with(@proxy_order) do |format| - format.json { render_as_json @proxy_order } - end + render_as_json @proxy_order else - respond_with(@proxy_order) do |format| - format.json { render json: { errors: [t('admin.proxy_orders.resume.could_not_resume_the_order')] }, status: :unprocessable_entity } - end + render json: { errors: [t('admin.proxy_orders.resume.could_not_resume_the_order')] }, status: :unprocessable_entity end end end From bc0a1d9baee1dcec02da915d0a97eaa4dea2e6d4 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 10 Mar 2020 15:56:08 +0000 Subject: [PATCH 002/166] Remove one more responder and fix rubocop issues --- .rubocop_manual_todo.yml | 1 - app/controllers/admin/proxy_orders_controller.rb | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 77b598ad3c..08ed408d85 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -33,7 +33,6 @@ Layout/LineLength: - app/controllers/admin/inventory_items_controller.rb - app/controllers/admin/manager_invitations_controller.rb - app/controllers/admin/product_import_controller.rb - - app/controllers/admin/proxy_orders_controller.rb - app/controllers/admin/schedules_controller.rb - app/controllers/admin/subscriptions_controller.rb - app/controllers/admin/variant_overrides_controller.rb diff --git a/app/controllers/admin/proxy_orders_controller.rb b/app/controllers/admin/proxy_orders_controller.rb index 296bf83e67..8e92f307f4 100644 --- a/app/controllers/admin/proxy_orders_controller.rb +++ b/app/controllers/admin/proxy_orders_controller.rb @@ -11,9 +11,8 @@ module Admin if @proxy_order.cancel render_as_json @proxy_order else - respond_with(@proxy_order) do |format| - format.json { render json: { errors: [t('admin.proxy_orders.cancel.could_not_cancel_the_order')] }, status: :unprocessable_entity } - end + render json: { errors: [t('admin.proxy_orders.cancel.could_not_cancel_the_order')] }, + status: :unprocessable_entity end end @@ -21,7 +20,8 @@ module Admin if @proxy_order.resume render_as_json @proxy_order else - render json: { errors: [t('admin.proxy_orders.resume.could_not_resume_the_order')] }, status: :unprocessable_entity + render json: { errors: [t('admin.proxy_orders.resume.could_not_resume_the_order')] }, + status: :unprocessable_entity end end end From 523d819575c4408a0c2524a15576e931db9f4f73 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 11:09:16 +0000 Subject: [PATCH 003/166] Move and rename SubscriptionPaymentUpdater to Subscriptios::PaymentSetup to move to services/subscriptions and call it Setup instead to make explicit this is executed before the payment is processed --- app/jobs/subscription_confirm_job.rb | 7 +++-- .../services/subscriptions/payment_setup.rb | 6 ++--- .../subscriptions/payment_setup_spec.rb} | 27 +++++++++---------- 3 files changed, 19 insertions(+), 21 deletions(-) rename lib/open_food_network/subscription_payment_updater.rb => app/services/subscriptions/payment_setup.rb (94%) rename spec/{lib/open_food_network/subscription_payment_updater_spec.rb => services/subscriptions/payment_setup_spec.rb} (89%) diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index be7f589cfc..b7ed797be3 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -1,4 +1,3 @@ -require 'open_food_network/subscription_payment_updater' require 'open_food_network/subscription_summarizer' class SubscriptionConfirmJob @@ -35,7 +34,7 @@ class SubscriptionConfirmJob def process! record_order(@order) - update_payment! if @order.payment_required? + setup_payment! if @order.payment_required? return send_failed_payment_email if @order.errors.present? @order.process_payments! if @order.payment_required? @@ -44,8 +43,8 @@ class SubscriptionConfirmJob send_confirm_email end - def update_payment! - OpenFoodNetwork::SubscriptionPaymentUpdater.new(@order).update! + def setup_payment! + Subscriptions::PaymentSetup.new(@order).call! end def send_confirm_email diff --git a/lib/open_food_network/subscription_payment_updater.rb b/app/services/subscriptions/payment_setup.rb similarity index 94% rename from lib/open_food_network/subscription_payment_updater.rb rename to app/services/subscriptions/payment_setup.rb index 4a9c8fa144..92677d6917 100644 --- a/lib/open_food_network/subscription_payment_updater.rb +++ b/app/services/subscriptions/payment_setup.rb @@ -1,10 +1,10 @@ -module OpenFoodNetwork - class SubscriptionPaymentUpdater +module Subscriptions + class PaymentSetup def initialize(order) @order = order end - def update! + def call! create_payment ensure_payment_source return if order.errors.any? diff --git a/spec/lib/open_food_network/subscription_payment_updater_spec.rb b/spec/services/subscriptions/payment_setup_spec.rb similarity index 89% rename from spec/lib/open_food_network/subscription_payment_updater_spec.rb rename to spec/services/subscriptions/payment_setup_spec.rb index 77be81020e..d0133ac388 100644 --- a/spec/lib/open_food_network/subscription_payment_updater_spec.rb +++ b/spec/services/subscriptions/payment_setup_spec.rb @@ -1,10 +1,9 @@ require 'spec_helper' -require 'open_food_network/subscription_payment_updater' -module OpenFoodNetwork - describe SubscriptionPaymentUpdater do +module Subscriptions + describe PaymentSetup do let(:order) { create(:order) } - let(:updater) { OpenFoodNetwork::SubscriptionPaymentUpdater.new(order) } + let(:updater) { Subscriptions::PaymentSetup.new(order) } describe "#payment" do context "when only one payment exists on the order" do @@ -44,7 +43,7 @@ module OpenFoodNetwork end end - describe "#update!" do + describe "#call!" do let!(:payment){ create(:payment, amount: 10) } context "when no pending payments are present" do @@ -58,7 +57,7 @@ module OpenFoodNetwork end it "creates a new payment on the order" do - expect{ updater.update! }.to change(Spree::Payment, :count).by(1) + expect{ updater.call! }.to change(Spree::Payment, :count).by(1) expect(order.payments.first.amount).to eq 5 end end @@ -76,7 +75,7 @@ module OpenFoodNetwork context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } it "updates the payment total to reflect the outstanding balance" do - expect{ updater.update! }.to change(payment, :amount).from(10).to(5) + expect{ updater.call! }.to change(payment, :amount).from(10).to(5) end end @@ -84,7 +83,7 @@ module OpenFoodNetwork before { allow(order).to receive(:outstanding_balance) { 10 } } it "does nothing" do - expect{ updater.update! }.to_not change(payment, :amount).from(10) + expect{ updater.call! }.to_not change(payment, :amount).from(10) end end end @@ -104,7 +103,7 @@ module OpenFoodNetwork it "adds an error to the order and does not update the payment" do expect(payment).to_not receive(:update_attributes) - expect{ updater.update! }.to change(order.errors[:base], :count).from(0).to(1) + expect{ updater.call! }.to change(order.errors[:base], :count).from(0).to(1) end end @@ -116,7 +115,7 @@ module OpenFoodNetwork it "adds an error to the order and does not update the payment" do expect(payment).to_not receive(:update_attributes) - expect{ updater.update! }.to change(order.errors[:base], :count).from(0).to(1) + expect{ updater.call! }.to change(order.errors[:base], :count).from(0).to(1) end end @@ -129,7 +128,7 @@ module OpenFoodNetwork context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } it "updates the payment total to reflect the outstanding balance" do - expect{ updater.update! }.to change(payment, :amount).from(10).to(5) + expect{ updater.call! }.to change(payment, :amount).from(10).to(5) end end @@ -137,7 +136,7 @@ module OpenFoodNetwork before { allow(order).to receive(:outstanding_balance) { 10 } } it "does nothing" do - expect{ updater.update! }.to_not change(payment, :amount).from(10) + expect{ updater.call! }.to_not change(payment, :amount).from(10) end end end @@ -149,7 +148,7 @@ module OpenFoodNetwork context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } it "updates the payment total to reflect the outstanding balance" do - expect{ updater.update! }.to change(payment, :amount).from(10).to(5) + expect{ updater.call! }.to change(payment, :amount).from(10).to(5) end end @@ -157,7 +156,7 @@ module OpenFoodNetwork before { allow(order).to receive(:outstanding_balance) { 10 } } it "does nothing" do - expect{ updater.update! }.to_not change(payment, :amount).from(10) + expect{ updater.call! }.to_not change(payment, :amount).from(10) end end end From 25e3f729340bc98930d7bf211042acd117d986a5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 11:54:53 +0000 Subject: [PATCH 004/166] Fix rubocop issues in subs payment_setup --- .rubocop_manual_todo.yml | 3 +- app/services/subscriptions/payment_setup.rb | 2 + .../subscriptions/payment_setup_spec.rb | 68 +++++++++++-------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 77b598ad3c..c0ca52abbd 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -241,7 +241,6 @@ Layout/LineLength: - spec/lib/open_food_network/products_and_inventory_report_spec.rb - spec/lib/open_food_network/proxy_order_syncer_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - - spec/lib/open_food_network/subscription_payment_updater_spec.rb - spec/lib/open_food_network/subscription_summarizer_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb @@ -703,7 +702,6 @@ Metrics/ModuleLength: - spec/lib/open_food_network/products_and_inventory_report_spec.rb - spec/lib/open_food_network/proxy_order_syncer_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - - spec/lib/open_food_network/subscription_payment_updater_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb - spec/models/spree/ability_spec.rb @@ -713,6 +711,7 @@ Metrics/ModuleLength: - spec/models/spree/product_spec.rb - spec/models/spree/variant_spec.rb - spec/services/permissions/order_spec.rb + - spec/services/subscriptions/payment_setup_spec.rb - spec/support/request/web_helper.rb Metrics/ParameterLists: diff --git a/app/services/subscriptions/payment_setup.rb b/app/services/subscriptions/payment_setup.rb index 92677d6917..9448a0828c 100644 --- a/app/services/subscriptions/payment_setup.rb +++ b/app/services/subscriptions/payment_setup.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Subscriptions class PaymentSetup def initialize(order) diff --git a/spec/services/subscriptions/payment_setup_spec.rb b/spec/services/subscriptions/payment_setup_spec.rb index d0133ac388..01b9720895 100644 --- a/spec/services/subscriptions/payment_setup_spec.rb +++ b/spec/services/subscriptions/payment_setup_spec.rb @@ -1,21 +1,23 @@ +# frozen_string_literal: true + require 'spec_helper' module Subscriptions describe PaymentSetup do let(:order) { create(:order) } - let(:updater) { Subscriptions::PaymentSetup.new(order) } + let(:payment_setup) { Subscriptions::PaymentSetup.new(order) } describe "#payment" do context "when only one payment exists on the order" do let!(:payment) { create(:payment, order: order) } context "where the payment is pending" do - it { expect(updater.send(:payment)).to eq payment } + it { expect(payment_setup.__send__(:payment)).to eq payment } end context "where the payment is failed" do before { payment.update_attribute(:state, 'failed') } - it { expect(updater.send(:payment)).to be nil } + it { expect(payment_setup.__send__(:payment)).to be nil } end end @@ -24,12 +26,12 @@ module Subscriptions let!(:payment2) { create(:payment, order: order) } context "where more than one payment is pending" do - it { expect([payment1, payment2]).to include updater.send(:payment) } + it { expect([payment1, payment2]).to include payment_setup.__send__(:payment) } end context "where only one payment is pending" do before { payment1.update_attribute(:state, 'failed') } - it { expect(updater.send(:payment)).to eq payment2 } + it { expect(payment_setup.__send__(:payment)).to eq payment2 } end context "where no payments are pending" do @@ -38,7 +40,7 @@ module Subscriptions payment2.update_attribute(:state, 'failed') end - it { expect(updater.send(:payment)).to be nil } + it { expect(payment_setup.__send__(:payment)).to be nil } end end end @@ -57,7 +59,7 @@ module Subscriptions end it "creates a new payment on the order" do - expect{ updater.call! }.to change(Spree::Payment, :count).by(1) + expect{ payment_setup.call! }.to change(Spree::Payment, :count).by(1) expect(order.payments.first.amount).to eq 5 end end @@ -67,15 +69,15 @@ module Subscriptions context "when a credit card is not required" do before do - allow(updater).to receive(:card_required?) { false } - expect(updater).to_not receive(:card_available?) - expect(updater).to_not receive(:ensure_credit_card) + allow(payment_setup).to receive(:card_required?) { false } + expect(payment_setup).to_not receive(:card_available?) + expect(payment_setup).to_not receive(:ensure_credit_card) end context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } it "updates the payment total to reflect the outstanding balance" do - expect{ updater.call! }.to change(payment, :amount).from(10).to(5) + expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) end end @@ -83,18 +85,18 @@ module Subscriptions before { allow(order).to receive(:outstanding_balance) { 10 } } it "does nothing" do - expect{ updater.call! }.to_not change(payment, :amount).from(10) + expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) end end end context "when a credit card is required" do before do - expect(updater).to receive(:card_required?) { true } + expect(payment_setup).to receive(:card_required?) { true } end context "and the payment source is not a credit card" do - before { expect(updater).to receive(:card_set?) { false } } + before { expect(payment_setup).to receive(:card_set?) { false } } context "and no default credit card has been set by the customer" do before do @@ -103,32 +105,40 @@ module Subscriptions it "adds an error to the order and does not update the payment" do expect(payment).to_not receive(:update_attributes) - expect{ updater.call! }.to change(order.errors[:base], :count).from(0).to(1) + expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) end end context "and the customer has not authorised the shop to charge to credit cards" do before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: create(:credit_card)) } - allow(order).to receive(:customer) { instance_double(Customer, allow_charges?: false) } + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: create(:credit_card)) + } + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: false) + } end it "adds an error to the order and does not update the payment" do expect(payment).to_not receive(:update_attributes) - expect{ updater.call! }.to change(order.errors[:base], :count).from(0).to(1) + expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) end end context "and an authorised default credit card is available to charge" do before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: create(:credit_card)) } - allow(order).to receive(:customer) { instance_double(Customer, allow_charges?: true) } + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: create(:credit_card)) + } + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: true) + } end context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } it "updates the payment total to reflect the outstanding balance" do - expect{ updater.call! }.to change(payment, :amount).from(10).to(5) + expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) end end @@ -136,19 +146,19 @@ module Subscriptions before { allow(order).to receive(:outstanding_balance) { 10 } } it "does nothing" do - expect{ updater.call! }.to_not change(payment, :amount).from(10) + expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) end end end end context "and the payment source is already a credit card" do - before { expect(updater).to receive(:card_set?) { true } } + before { expect(payment_setup).to receive(:card_set?) { true } } context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } it "updates the payment total to reflect the outstanding balance" do - expect{ updater.call! }.to change(payment, :amount).from(10).to(5) + expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) end end @@ -156,7 +166,7 @@ module Subscriptions before { allow(order).to receive(:outstanding_balance) { 10 } } it "does nothing" do - expect{ updater.call! }.to_not change(payment, :amount).from(10) + expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) end end end @@ -166,7 +176,7 @@ module Subscriptions describe "#ensure_credit_card" do let!(:payment) { create(:payment, source: nil) } - before { allow(updater).to receive(:payment) { payment } } + before { allow(payment_setup).to receive(:payment) { payment } } context "when no default credit card is found" do before do @@ -175,7 +185,7 @@ module Subscriptions it "returns false and down not update the payment source" do expect do - expect(updater.send(:ensure_credit_card)).to be false + expect(payment_setup.__send__(:ensure_credit_card)).to be false end.to_not change(payment, :source).from(nil) end end @@ -193,7 +203,7 @@ module Subscriptions it "returns false and does not update the payment source" do expect do - expect(updater.send(:ensure_credit_card)).to be false + expect(payment_setup.__send__(:ensure_credit_card)).to be false end.to_not change(payment, :source).from(nil) end end @@ -205,7 +215,7 @@ module Subscriptions it "returns true and stores the credit card as the payment source" do expect do - expect(updater.send(:ensure_credit_card)).to be true + expect(payment_setup.__send__(:ensure_credit_card)).to be true end.to change(payment, :source_id).from(nil).to(credit_card.id) end end From 15231a9128c8ad4322b9eed271c3940b1da9b5a1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 12:23:05 +0000 Subject: [PATCH 005/166] Make SubsConfirmJob more readable --- app/jobs/subscription_confirm_job.rb | 65 +++++++++++++--------- spec/jobs/subscription_confirm_job_spec.rb | 46 +++++++-------- 2 files changed, 59 insertions(+), 52 deletions(-) diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index b7ed797be3..016f3bc21c 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -1,16 +1,9 @@ require 'open_food_network/subscription_summarizer' +# Confirms orders of unconfirmed proxy orders in recently closed Order Cycles class SubscriptionConfirmJob def perform - ids = proxy_orders.pluck(:id) - proxy_orders.update_all(confirmed_at: Time.zone.now) - ProxyOrder.where(id: ids).each do |proxy_order| - Rails.logger.info "Confirming Order for Proxy Order #{proxy_order.id}" - @order = proxy_order.order - process! - end - - send_confirmation_summary_emails + confirm_proxy_orders! end private @@ -22,7 +15,23 @@ class SubscriptionConfirmJob @summarizer ||= OpenFoodNetwork::SubscriptionSummarizer.new end - def proxy_orders + def confirm_proxy_orders! + # Fetch all unconfirmed proxy orders + unconfirmed_proxy_orders_ids = unconfirmed_proxy_orders.pluck(:id) + + # Mark these proxy orders as confirmed + unconfirmed_proxy_orders.update_all(confirmed_at: Time.zone.now) + + # Confirm these proxy orders + ProxyOrder.where(id: unconfirmed_proxy_orders_ids).each do |proxy_order| + Rails.logger.info "Confirming Order for Proxy Order #{proxy_order.id}" + confirm_order!(proxy_order.order) + end + + send_confirmation_summary_emails + end + + def unconfirmed_proxy_orders ProxyOrder.not_canceled.where('confirmed_at IS NULL AND placed_at IS NOT NULL') .joins(:order_cycle).merge(recently_closed_order_cycles) .joins(:order).merge(Spree::Order.complete.not_state('canceled')) @@ -32,30 +41,32 @@ class SubscriptionConfirmJob OrderCycle.closed.where('order_cycles.orders_close_at BETWEEN (?) AND (?) OR order_cycles.updated_at BETWEEN (?) AND (?)', 1.hour.ago, Time.zone.now, 1.hour.ago, Time.zone.now) end - def process! - record_order(@order) - setup_payment! if @order.payment_required? - return send_failed_payment_email if @order.errors.present? + # It sets up payments, processes payments and sends confirmation emails + def confirm_order!(order) + record_order(order) - @order.process_payments! if @order.payment_required? - return send_failed_payment_email if @order.errors.present? + setup_payment!(order) if order.payment_required? + return send_failed_payment_email(order) if order.errors.present? - send_confirm_email + order.process_payments! if order.payment_required? + return send_failed_payment_email(order) if order.errors.present? + + send_confirmation_email(order) end - def setup_payment! - Subscriptions::PaymentSetup.new(@order).call! + def setup_payment!(order) + Subscriptions::PaymentSetup.new(order).call! end - def send_confirm_email - @order.update! - record_success(@order) - SubscriptionMailer.confirmation_email(@order).deliver + def send_confirmation_email(order) + order.update! + record_success(order) + SubscriptionMailer.confirmation_email(order).deliver end - def send_failed_payment_email - @order.update! - record_and_log_error(:failed_payment, @order) - SubscriptionMailer.failed_payment_email(@order).deliver + def send_failed_payment_email(order) + order.update! + record_and_log_error(:failed_payment, order) + SubscriptionMailer.failed_payment_email(order).deliver end end diff --git a/spec/jobs/subscription_confirm_job_spec.rb b/spec/jobs/subscription_confirm_job_spec.rb index 3c433bf94d..a061d0fbd4 100644 --- a/spec/jobs/subscription_confirm_job_spec.rb +++ b/spec/jobs/subscription_confirm_job_spec.rb @@ -16,7 +16,7 @@ describe SubscriptionConfirmJob do placed_at: 5.minutes.ago) end let!(:order) { proxy_order.initialise_order! } - let(:proxy_orders) { job.send(:proxy_orders) } + let(:proxy_orders) { job.send(:unconfirmed_proxy_orders) } before do AdvanceOrderService.new(order).call! @@ -80,8 +80,8 @@ describe SubscriptionConfirmJob do before do proxy_order.initialise_order! - allow(job).to receive(:proxy_orders) { ProxyOrder.where(id: proxy_order.id) } - allow(job).to receive(:process!) + allow(job).to receive(:unconfirmed_proxy_orders) { ProxyOrder.where(id: proxy_order.id) } + allow(job).to receive(:confirm_order!) allow(job).to receive(:send_confirmation_summary_emails) end @@ -92,8 +92,7 @@ describe SubscriptionConfirmJob do it "processes confirmable proxy_orders" do job.perform - expect(job).to have_received(:process!) - expect(job.instance_variable_get(:@order)).to eq proxy_order.reload.order + expect(job).to have_received(:confirm_order!).with(proxy_order.reload.order) end it "sends a summary email" do @@ -117,7 +116,7 @@ describe SubscriptionConfirmJob do end end - describe "processing an order" do + describe "confirming an order" do let(:shop) { create(:distributor_enterprise) } let(:order_cycle1) { create(:simple_order_cycle, coordinator: shop) } let(:order_cycle2) { create(:simple_order_cycle, coordinator: shop) } @@ -128,35 +127,34 @@ describe SubscriptionConfirmJob do before do AdvanceOrderService.new(order).call! - allow(job).to receive(:send_confirm_email).and_call_original - job.instance_variable_set(:@order, order) + allow(job).to receive(:send_confirmation_email).and_call_original setup_email - expect(job).to receive(:record_order).with(order) + expect(job).to receive(:record_order) end context "when payments need to be processed" do let(:payment_method) { create(:payment_method) } - let(:payment) { double(:payment, amount: 10) } + let(:payment) { create(:payment, amount: 10) } before do - allow(order).to receive(:payment_total) { 0 } - allow(order).to receive(:total) { 10 } allow(order).to receive(:payment_required?) { true } allow(order).to receive(:pending_payments) { [payment] } end context "and an error is added to the order when updating payments" do - before { expect(job).to receive(:update_payment!) { order.errors.add(:base, "a payment error") } } + before do + expect(job).to receive(:setup_payment!) { |order| order.errors.add(:base, "a payment error") } + end it "sends a failed payment email" do expect(job).to receive(:send_failed_payment_email) - expect(job).to_not receive(:send_confirm_email) - job.send(:process!) + expect(job).to_not receive(:send_confirmation_email) + job.send(:confirm_order!, order) end end context "and no errors are added when updating payments" do - before { expect(job).to receive(:update_payment!) { true } } + before { expect(job).to receive(:setup_payment!) { true } } context "when an error occurs while processing the payment" do before do @@ -165,8 +163,8 @@ describe SubscriptionConfirmJob do it "sends a failed payment email" do expect(job).to receive(:send_failed_payment_email) - expect(job).to_not receive(:send_confirm_email) - job.send(:process!) + expect(job).to_not receive(:send_confirmation_email) + job.send(:confirm_order!, order) end end @@ -182,8 +180,8 @@ describe SubscriptionConfirmJob do it "sends only a subscription confirm email, no regular confirmation emails" do ActionMailer::Base.deliveries.clear - expect{ job.send(:process!) }.to_not enqueue_job ConfirmOrderJob - expect(job).to have_received(:send_confirm_email).once + expect{ job.send(:confirm_order!, order) }.to_not enqueue_job ConfirmOrderJob + expect(job).to have_received(:send_confirmation_email).once expect(ActionMailer::Base.deliveries.count).to be 1 end end @@ -191,19 +189,18 @@ describe SubscriptionConfirmJob do end end - describe "#send_confirm_email" do + describe "#send_confirmation_email" do let(:order) { instance_double(Spree::Order) } let(:mail_mock) { double(:mailer_mock, deliver: true) } before do - job.instance_variable_set(:@order, order) allow(SubscriptionMailer).to receive(:confirmation_email) { mail_mock } end it "records a success and sends the email" do expect(order).to receive(:update!) expect(job).to receive(:record_success).with(order).once - job.send(:send_confirm_email) + job.send(:send_confirmation_email, order) expect(SubscriptionMailer).to have_received(:confirmation_email).with(order) expect(mail_mock).to have_received(:deliver) end @@ -214,14 +211,13 @@ describe SubscriptionConfirmJob do let(:mail_mock) { double(:mailer_mock, deliver: true) } before do - job.instance_variable_set(:@order, order) allow(SubscriptionMailer).to receive(:failed_payment_email) { mail_mock } end it "records and logs an error and sends the email" do expect(order).to receive(:update!) expect(job).to receive(:record_and_log_error).with(:failed_payment, order).once - job.send(:send_failed_payment_email) + job.send(:send_failed_payment_email, order) expect(SubscriptionMailer).to have_received(:failed_payment_email).with(order) expect(mail_mock).to have_received(:deliver) end From 3aefea9f04f27694d749bff5fa91ce2cb27b1901 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 12:38:48 +0000 Subject: [PATCH 006/166] Prepare SubsConfirmJob to receive a bit more payment logic --- app/jobs/subscription_confirm_job.rb | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index 016f3bc21c..9db6cd6050 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -45,13 +45,24 @@ class SubscriptionConfirmJob def confirm_order!(order) record_order(order) - setup_payment!(order) if order.payment_required? - return send_failed_payment_email(order) if order.errors.present? + if process_payment!(order) + send_confirmation_email(order) + else + send_failed_payment_email(order) + end + end - order.process_payments! if order.payment_required? - return send_failed_payment_email(order) if order.errors.present? + def process_payment!(order) + return false if order.errors.present? + return true unless order.payment_required? - send_confirmation_email(order) + setup_payment!(order) + return false if order.errors.present? + + order.process_payments! + return false if order.errors.present? + + true end def setup_payment!(order) From 34fa2d7ad660f3c485dacc5f1cb5870297051ab1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 17:20:38 +0000 Subject: [PATCH 007/166] Move Subscriptions::PaymentSetup to OrderManagement engine where all subscription code will be at some point in the future --- .rubocop_manual_todo.yml | 2 +- app/jobs/subscription_confirm_job.rb | 2 +- .../services/order_management}/subscriptions/payment_setup.rb | 2 +- .../order_management}/subscriptions/payment_setup_spec.rb | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename {app/services => engines/order_management/app/services/order_management}/subscriptions/payment_setup.rb (97%) rename {spec/services => engines/order_management/spec/services/order_management}/subscriptions/payment_setup_spec.rb (98%) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index c0ca52abbd..f61d3a9148 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -685,6 +685,7 @@ Metrics/ModuleLength: - app/helpers/injection_helper.rb - app/helpers/spree/admin/navigation_helper.rb - app/helpers/spree/admin/base_helper.rb + - engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb - lib/open_food_network/column_preference_defaults.rb - spec/controllers/admin/enterprises_controller_spec.rb - spec/controllers/admin/order_cycles_controller_spec.rb @@ -711,7 +712,6 @@ Metrics/ModuleLength: - spec/models/spree/product_spec.rb - spec/models/spree/variant_spec.rb - spec/services/permissions/order_spec.rb - - spec/services/subscriptions/payment_setup_spec.rb - spec/support/request/web_helper.rb Metrics/ParameterLists: diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index 9db6cd6050..2d40b02539 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -66,7 +66,7 @@ class SubscriptionConfirmJob end def setup_payment!(order) - Subscriptions::PaymentSetup.new(order).call! + OrderManagement::Subscriptions::PaymentSetup.new(order).call! end def send_confirmation_email(order) diff --git a/app/services/subscriptions/payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb similarity index 97% rename from app/services/subscriptions/payment_setup.rb rename to engines/order_management/app/services/order_management/subscriptions/payment_setup.rb index 9448a0828c..77e398c512 100644 --- a/app/services/subscriptions/payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module Subscriptions +module OrderManagement::Subscriptions class PaymentSetup def initialize(order) @order = order diff --git a/spec/services/subscriptions/payment_setup_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb similarity index 98% rename from spec/services/subscriptions/payment_setup_spec.rb rename to engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb index 01b9720895..f80d10cb95 100644 --- a/spec/services/subscriptions/payment_setup_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' -module Subscriptions +module OrderManagement::Subscriptions describe PaymentSetup do let(:order) { create(:order) } - let(:payment_setup) { Subscriptions::PaymentSetup.new(order) } + let(:payment_setup) { OrderManagement::Subscriptions::PaymentSetup.new(order) } describe "#payment" do context "when only one payment exists on the order" do From e36b0249b9032c776368a571eee27985f7fd0d22 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 17:27:02 +0000 Subject: [PATCH 008/166] Use nested module names to fix rubocpo issue --- .../subscriptions/payment_setup.rb | 94 ++--- .../subscriptions/payment_setup_spec.rb | 324 +++++++++--------- 2 files changed, 213 insertions(+), 205 deletions(-) diff --git a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb index 77e398c512..86ce1f2c29 100644 --- a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb @@ -1,67 +1,69 @@ # frozen_string_literal: true -module OrderManagement::Subscriptions - class PaymentSetup - def initialize(order) - @order = order - end +module OrderManagement + module Subscriptions + class PaymentSetup + def initialize(order) + @order = order + end - def call! - create_payment - ensure_payment_source - return if order.errors.any? + def call! + create_payment + ensure_payment_source + return if order.errors.any? - payment.update_attributes(amount: order.outstanding_balance) - end + payment.update_attributes(amount: order.outstanding_balance) + end - private + private - attr_reader :order + attr_reader :order - def payment - @payment ||= order.pending_payments.last - end + def payment + @payment ||= order.pending_payments.last + end - def create_payment - return if payment.present? + def create_payment + return if payment.present? - @payment = order.payments.create( - payment_method_id: order.subscription.payment_method_id, - amount: order.outstanding_balance - ) - end + @payment = order.payments.create( + payment_method_id: order.subscription.payment_method_id, + amount: order.outstanding_balance + ) + end - def card_required? - [Spree::Gateway::StripeConnect, - Spree::Gateway::StripeSCA].include? payment.payment_method.class - end + def card_required? + [Spree::Gateway::StripeConnect, + Spree::Gateway::StripeSCA].include? payment.payment_method.class + end - def card_set? - payment.source is_a? Spree::CreditCard - end + def card_set? + payment.source is_a? Spree::CreditCard + end - def ensure_payment_source - return unless card_required? && !card_set? + def ensure_payment_source + return unless card_required? && !card_set? - ensure_credit_card || order.errors.add(:base, :no_card) - end + ensure_credit_card || order.errors.add(:base, :no_card) + end - def ensure_credit_card - return false if saved_credit_card.blank? || !allow_charges? + def ensure_credit_card + return false if saved_credit_card.blank? || !allow_charges? - payment.update_attributes(source: saved_credit_card) - end + payment.update_attributes(source: saved_credit_card) + end - def allow_charges? - order.customer.allow_charges? - end + def allow_charges? + order.customer.allow_charges? + end - def saved_credit_card - order.user.default_card - end + def saved_credit_card + order.user.default_card + end - def errors_present? - order.errors.any? + def errors_present? + order.errors.any? + end end end end diff --git a/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb index f80d10cb95..442fb64cb5 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb @@ -2,138 +2,159 @@ require 'spec_helper' -module OrderManagement::Subscriptions - describe PaymentSetup do - let(:order) { create(:order) } - let(:payment_setup) { OrderManagement::Subscriptions::PaymentSetup.new(order) } +module OrderManagement + module Subscriptions + describe PaymentSetup do + let(:order) { create(:order) } + let(:payment_setup) { OrderManagement::Subscriptions::PaymentSetup.new(order) } - describe "#payment" do - context "when only one payment exists on the order" do - let!(:payment) { create(:payment, order: order) } + describe "#payment" do + context "when only one payment exists on the order" do + let!(:payment) { create(:payment, order: order) } - context "where the payment is pending" do - it { expect(payment_setup.__send__(:payment)).to eq payment } + context "where the payment is pending" do + it { expect(payment_setup.__send__(:payment)).to eq payment } + end + + context "where the payment is failed" do + before { payment.update_attribute(:state, 'failed') } + it { expect(payment_setup.__send__(:payment)).to be nil } + end end - context "where the payment is failed" do - before { payment.update_attribute(:state, 'failed') } - it { expect(payment_setup.__send__(:payment)).to be nil } + context "when more that one payment exists on the order" do + let!(:payment1) { create(:payment, order: order) } + let!(:payment2) { create(:payment, order: order) } + + context "where more than one payment is pending" do + it { expect([payment1, payment2]).to include payment_setup.__send__(:payment) } + end + + context "where only one payment is pending" do + before { payment1.update_attribute(:state, 'failed') } + it { expect(payment_setup.__send__(:payment)).to eq payment2 } + end + + context "where no payments are pending" do + before do + payment1.update_attribute(:state, 'failed') + payment2.update_attribute(:state, 'failed') + end + + it { expect(payment_setup.__send__(:payment)).to be nil } + end end end - context "when more that one payment exists on the order" do - let!(:payment1) { create(:payment, order: order) } - let!(:payment2) { create(:payment, order: order) } + describe "#call!" do + let!(:payment){ create(:payment, amount: 10) } - context "where more than one payment is pending" do - it { expect([payment1, payment2]).to include payment_setup.__send__(:payment) } - end + context "when no pending payments are present" do + let(:payment_method) { create(:payment_method) } + let(:subscription) { double(:subscription, payment_method_id: payment_method.id) } - context "where only one payment is pending" do - before { payment1.update_attribute(:state, 'failed') } - it { expect(payment_setup.__send__(:payment)).to eq payment2 } - end - - context "where no payments are pending" do before do - payment1.update_attribute(:state, 'failed') - payment2.update_attribute(:state, 'failed') + allow(order).to receive(:pending_payments).once { [] } + allow(order).to receive(:outstanding_balance) { 5 } + allow(order).to receive(:subscription) { subscription } end - it { expect(payment_setup.__send__(:payment)).to be nil } - end - end - end - - describe "#call!" do - let!(:payment){ create(:payment, amount: 10) } - - context "when no pending payments are present" do - let(:payment_method) { create(:payment_method) } - let(:subscription) { double(:subscription, payment_method_id: payment_method.id) } - - before do - allow(order).to receive(:pending_payments).once { [] } - allow(order).to receive(:outstanding_balance) { 5 } - allow(order).to receive(:subscription) { subscription } - end - - it "creates a new payment on the order" do - expect{ payment_setup.call! }.to change(Spree::Payment, :count).by(1) - expect(order.payments.first.amount).to eq 5 - end - end - - context "when a payment is present" do - before { allow(order).to receive(:pending_payments).once { [payment] } } - - context "when a credit card is not required" do - before do - allow(payment_setup).to receive(:card_required?) { false } - expect(payment_setup).to_not receive(:card_available?) - expect(payment_setup).to_not receive(:ensure_credit_card) - end - - context "when the payment total doesn't match the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 5 } } - it "updates the payment total to reflect the outstanding balance" do - expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) - end - end - - context "when the payment total matches the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 10 } } - - it "does nothing" do - expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) - end + it "creates a new payment on the order" do + expect{ payment_setup.call! }.to change(Spree::Payment, :count).by(1) + expect(order.payments.first.amount).to eq 5 end end - context "when a credit card is required" do - before do - expect(payment_setup).to receive(:card_required?) { true } + context "when a payment is present" do + before { allow(order).to receive(:pending_payments).once { [payment] } } + + context "when a credit card is not required" do + before do + allow(payment_setup).to receive(:card_required?) { false } + expect(payment_setup).to_not receive(:card_available?) + expect(payment_setup).to_not receive(:ensure_credit_card) + end + + context "when the payment total doesn't match the outstanding balance on the order" do + before { allow(order).to receive(:outstanding_balance) { 5 } } + it "updates the payment total to reflect the outstanding balance" do + expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) + end + end + + context "when the payment total matches the outstanding balance on the order" do + before { allow(order).to receive(:outstanding_balance) { 10 } } + + it "does nothing" do + expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) + end + end end - context "and the payment source is not a credit card" do - before { expect(payment_setup).to receive(:card_set?) { false } } + context "when a credit card is required" do + before do + expect(payment_setup).to receive(:card_required?) { true } + end - context "and no default credit card has been set by the customer" do - before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } + context "and the payment source is not a credit card" do + before { expect(payment_setup).to receive(:card_set?) { false } } + + context "and no default credit card has been set by the customer" do + before do + allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } + end + + it "adds an error to the order and does not update the payment" do + expect(payment).to_not receive(:update_attributes) + expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) + end end - it "adds an error to the order and does not update the payment" do - expect(payment).to_not receive(:update_attributes) - expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) + context "and the customer has not authorised the shop to charge to credit cards" do + before do + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: create(:credit_card)) + } + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: false) + } + end + + it "adds an error to the order and does not update the payment" do + expect(payment).to_not receive(:update_attributes) + expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) + end + end + + context "and an authorised default credit card is available to charge" do + before do + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: create(:credit_card)) + } + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: true) + } + end + + context "when the payment total doesn't match the order's outstanding balance" do + before { allow(order).to receive(:outstanding_balance) { 5 } } + it "updates the payment total to reflect the outstanding balance" do + expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) + end + end + + context "when the payment total matches the outstanding balance on the order" do + before { allow(order).to receive(:outstanding_balance) { 10 } } + + it "does nothing" do + expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) + end + end end end - context "and the customer has not authorised the shop to charge to credit cards" do - before do - allow(order).to receive(:user) { - instance_double(Spree::User, default_card: create(:credit_card)) - } - allow(order).to receive(:customer) { - instance_double(Customer, allow_charges?: false) - } - end - - it "adds an error to the order and does not update the payment" do - expect(payment).to_not receive(:update_attributes) - expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) - end - end - - context "and an authorised default credit card is available to charge" do - before do - allow(order).to receive(:user) { - instance_double(Spree::User, default_card: create(:credit_card)) - } - allow(order).to receive(:customer) { - instance_double(Customer, allow_charges?: true) - } - end + context "and the payment source is already a credit card" do + before { expect(payment_setup).to receive(:card_set?) { true } } context "when the payment total doesn't match the outstanding balance on the order" do before { allow(order).to receive(:outstanding_balance) { 5 } } @@ -151,72 +172,57 @@ module OrderManagement::Subscriptions end end end - - context "and the payment source is already a credit card" do - before { expect(payment_setup).to receive(:card_set?) { true } } - - context "when the payment total doesn't match the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 5 } } - it "updates the payment total to reflect the outstanding balance" do - expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) - end - end - - context "when the payment total matches the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 10 } } - - it "does nothing" do - expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) - end - end - end - end - end - end - - describe "#ensure_credit_card" do - let!(:payment) { create(:payment, source: nil) } - before { allow(payment_setup).to receive(:payment) { payment } } - - context "when no default credit card is found" do - before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } - end - - it "returns false and down not update the payment source" do - expect do - expect(payment_setup.__send__(:ensure_credit_card)).to be false - end.to_not change(payment, :source).from(nil) end end - context "when a default credit card is found" do - let(:credit_card) { create(:credit_card) } - before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: credit_card) } - end + describe "#ensure_credit_card" do + let!(:payment) { create(:payment, source: nil) } + before { allow(payment_setup).to receive(:payment) { payment } } - context "and charge have not been authorised by the customer" do + context "when no default credit card is found" do before do - allow(order).to receive(:customer) { instance_double(Customer, allow_charges?: false) } + allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } end - it "returns false and does not update the payment source" do + it "returns false and down not update the payment source" do expect do expect(payment_setup.__send__(:ensure_credit_card)).to be false end.to_not change(payment, :source).from(nil) end end - context "and charges have been authorised by the customer" do + context "when a default credit card is found" do + let(:credit_card) { create(:credit_card) } before do - allow(order).to receive(:customer) { instance_double(Customer, allow_charges?: true) } + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: credit_card) + } end - it "returns true and stores the credit card as the payment source" do - expect do - expect(payment_setup.__send__(:ensure_credit_card)).to be true - end.to change(payment, :source_id).from(nil).to(credit_card.id) + context "and charge have not been authorised by the customer" do + before do + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: false) + } + end + + it "returns false and does not update the payment source" do + expect do + expect(payment_setup.__send__(:ensure_credit_card)).to be false + end.to_not change(payment, :source).from(nil) + end + end + + context "and charges have been authorised by the customer" do + before do + allow(order).to receive(:customer) { instance_double(Customer, allow_charges?: true) } + end + + it "returns true and stores the credit card as the payment source" do + expect do + expect(payment_setup.__send__(:ensure_credit_card)).to be true + end.to change(payment, :source_id).from(nil).to(credit_card.id) + end end end end From fb1c825fbccca76c95357be5e1da147b5ea5b6cc Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 17:47:38 +0000 Subject: [PATCH 009/166] Move both subscription summarizer and subscription summary to order management engine --- .rubocop_manual_todo.yml | 1 - .rubocop_todo.yml | 12 +- app/jobs/subscription_confirm_job.rb | 4 +- app/jobs/subscription_placement_job.rb | 4 +- .../subscriptions/subscription_summarizer.rb | 55 ++++++++ .../subscriptions/subscription_summary.rb | 53 +++++++ .../subscription_summarizer_spec.rb | 132 ++++++++++++++++++ .../subscription_summary_spec.rb | 127 +++++++++++++++++ .../subscription_summarizer.rb | 53 ------- lib/open_food_network/subscription_summary.rb | 49 ------- .../subscription_summarizer_spec.rb | 126 ----------------- .../subscription_summary_spec.rb | 125 ----------------- 12 files changed, 377 insertions(+), 364 deletions(-) create mode 100644 engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb delete mode 100644 lib/open_food_network/subscription_summarizer.rb delete mode 100644 lib/open_food_network/subscription_summary.rb delete mode 100644 spec/lib/open_food_network/subscription_summarizer_spec.rb delete mode 100644 spec/lib/open_food_network/subscription_summary_spec.rb diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index f61d3a9148..9b0fd3b537 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -241,7 +241,6 @@ Layout/LineLength: - spec/lib/open_food_network/products_and_inventory_report_spec.rb - spec/lib/open_food_network/proxy_order_syncer_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - - spec/lib/open_food_network/subscription_summarizer_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb - spec/lib/open_food_network/xero_invoices_report_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 33970eb805..323426fda9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -70,8 +70,8 @@ Lint/DuplicateHashKey: # Offense count: 4 Lint/DuplicateMethods: Exclude: + - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'lib/discourse/single_sign_on.rb' - - 'lib/open_food_network/subscription_summary.rb' # Offense count: 10 Lint/IneffectiveAccessModifier: @@ -882,6 +882,8 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/report_service.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb' + - 'engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb' + - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'engines/order_management/app/services/reports.rb' - 'engines/order_management/app/services/reports/authorizer.rb' - 'engines/order_management/app/services/reports/parameters/base.rb' @@ -900,6 +902,8 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summizer_spec.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb' - 'engines/order_management/spec/spec_helper.rb' - 'engines/web/app/controllers/web/angular_templates_controller.rb' - 'engines/web/app/controllers/web/api/cookies_consent_controller.rb' @@ -967,8 +971,6 @@ Style/FrozenStringLiteralComment: - 'lib/open_food_network/scope_variants_for_search.rb' - 'lib/open_food_network/spree_api_key_loader.rb' - 'lib/open_food_network/subscription_payment_updater.rb' - - 'lib/open_food_network/subscription_summarizer.rb' - - 'lib/open_food_network/subscription_summary.rb' - 'lib/open_food_network/tag_rule_applicator.rb' - 'lib/open_food_network/user_balance_calculator.rb' - 'lib/open_food_network/users_and_enterprises_report.rb' @@ -1219,8 +1221,6 @@ Style/FrozenStringLiteralComment: - 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb' - 'spec/lib/open_food_network/scope_variants_to_search_spec.rb' - 'spec/lib/open_food_network/subscription_payment_updater_spec.rb' - - 'spec/lib/open_food_network/subscription_summarizer_spec.rb' - - 'spec/lib/open_food_network/subscription_summary_spec.rb' - 'spec/lib/open_food_network/tag_rule_applicator_spec.rb' - 'spec/lib/open_food_network/user_balance_calculator_spec.rb' - 'spec/lib/open_food_network/users_and_enterprises_report_spec.rb' @@ -1542,6 +1542,7 @@ Style/Send: Exclude: - 'app/controllers/spree/checkout_controller.rb' - 'app/models/spree/shipping_method_decorator.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb' - 'spec/controllers/admin/subscriptions_controller_spec.rb' - 'spec/controllers/checkout_controller_spec.rb' - 'spec/controllers/spree/admin/base_controller_spec.rb' @@ -1559,7 +1560,6 @@ Style/Send: - 'spec/lib/open_food_network/products_and_inventory_report_spec.rb' - 'spec/lib/open_food_network/sales_tax_report_spec.rb' - 'spec/lib/open_food_network/subscription_payment_updater_spec.rb' - - 'spec/lib/open_food_network/subscription_summarizer_spec.rb' - 'spec/lib/open_food_network/tag_rule_applicator_spec.rb' - 'spec/lib/open_food_network/xero_invoices_report_spec.rb' - 'spec/lib/stripe/webhook_handler_spec.rb' diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index 2d40b02539..9b1ae7a79f 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -1,4 +1,4 @@ -require 'open_food_network/subscription_summarizer' +require 'order_management/subscriptions/subscription_summarizer' # Confirms orders of unconfirmed proxy orders in recently closed Order Cycles class SubscriptionConfirmJob @@ -12,7 +12,7 @@ class SubscriptionConfirmJob delegate :record_and_log_error, :send_confirmation_summary_emails, to: :summarizer def summarizer - @summarizer ||= OpenFoodNetwork::SubscriptionSummarizer.new + @summarizer ||= OrderManagement::Subscriptions::SubscriptionSummarizer.new end def confirm_proxy_orders! diff --git a/app/jobs/subscription_placement_job.rb b/app/jobs/subscription_placement_job.rb index ecaa9208ef..8a77367217 100644 --- a/app/jobs/subscription_placement_job.rb +++ b/app/jobs/subscription_placement_job.rb @@ -1,4 +1,4 @@ -require 'open_food_network/subscription_summarizer' +require 'order_management/subscriptions/subscription_summarizer' class SubscriptionPlacementJob def perform @@ -17,7 +17,7 @@ class SubscriptionPlacementJob delegate :record_and_log_error, :send_placement_summary_emails, to: :summarizer def summarizer - @summarizer ||= OpenFoodNetwork::SubscriptionSummarizer.new + @summarizer ||= OrderManagement::Subscriptions::SubscriptionSummarizer.new end def proxy_orders diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb b/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb new file mode 100644 index 0000000000..dbffcb96ab --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# Used by for SubscriptionPlacementJob and SubscriptionConfirmJob to summarize the +# result of automatic processing of subscriptions for the relevant shop owners. +module OrderManagement + module Subscriptions + class SubscriptionSummarizer + def initialize + @summaries = {} + end + + def record_order(order) + summary_for(order).record_order(order) + end + + def record_success(order) + summary_for(order).record_success(order) + end + + def record_issue(type, order, message = nil) + Rails.logger.info "Issue in Subscription Order #{order.id}: #{type}" + summary_for(order).record_issue(type, order, message) + end + + def record_and_log_error(type, order) + return record_issue(type, order) unless order.errors.any? + + error = "Subscription#{type.to_s.camelize}Error" + line1 = "#{error}: Cannot process order #{order.number} due to errors" + line2 = "Errors: #{order.errors.full_messages.join(', ')}" + Rails.logger.info("#{line1}\n#{line2}") + record_issue(type, order, line2) + end + + def send_placement_summary_emails + @summaries.values.each do |summary| + SubscriptionMailer.placement_summary_email(summary).deliver + end + end + + def send_confirmation_summary_emails + @summaries.values.each do |summary| + SubscriptionMailer.confirmation_summary_email(summary).deliver + end + end + + private + + def summary_for(order) + shop_id = order.distributor_id + @summaries[shop_id] ||= SubscriptionSummary.new(shop_id) + end + end + end +end diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb b/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb new file mode 100644 index 0000000000..aa9a61c469 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + class SubscriptionSummary + attr_reader :shop_id, :order_count, :success_count, :issues + + def initialize(shop_id) + @shop_id = shop_id + @order_ids = [] + @success_ids = [] + @issues = {} + end + + def record_order(order) + @order_ids << order.id + end + + def record_success(order) + @success_ids << order.id + end + + def record_issue(type, order, message) + issues[type] ||= {} + issues[type][order.id] = message + end + + def order_count + @order_ids.count + end + + def success_count + @success_ids.count + end + + def issue_count + (@order_ids - @success_ids).count + end + + def orders_affected_by(type) + case type + when :other then Spree::Order.where(id: unrecorded_ids) + else Spree::Order.where(id: issues[type].keys) + end + end + + def unrecorded_ids + recorded_ids = issues.values.map(&:keys).flatten + @order_ids - @success_ids - recorded_ids + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb new file mode 100644 index 0000000000..26a79af4d1 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module OrderManagement + module Subscriptions + describe SubscriptionSummarizer do + let(:order) { create(:order) } + let(:summarizer) { OrderManagement::Subscriptions::SubscriptionSummarizer.new } + + before { allow(Rails.logger).to receive(:info) } + + describe "#summary_for" do + let(:order) { double(:order, distributor_id: 123) } + + context "when a summary for the order's distributor doesn't already exist" do + it "initializes a new summary object, and returns it" do + expect(summarizer.instance_variable_get(:@summaries).count).to be 0 + summary = summarizer.send(:summary_for, order) + expect(summary.shop_id).to be 123 + expect(summarizer.instance_variable_get(:@summaries).count).to be 1 + end + end + + context "when a summary for the order's distributor already exists" do + let(:summary) { double(:summary) } + + before do + summarizer.instance_variable_set(:@summaries, 123 => summary) + end + + it "returns the existing summary object" do + expect(summarizer.instance_variable_get(:@summaries).count).to be 1 + expect(summarizer.send(:summary_for, order)).to eq summary + expect(summarizer.instance_variable_get(:@summaries).count).to be 1 + end + end + end + + describe "recording events" do + let(:order) { double(:order) } + let(:summary) { double(:summary) } + before { allow(summarizer).to receive(:summary_for).with(order) { summary } } + + describe "#record_order" do + it "requests a summary for the order and calls #record_order on it" do + expect(summary).to receive(:record_order).with(order).once + summarizer.record_order(order) + end + end + + describe "#record_success" do + it "requests a summary for the order and calls #record_success on it" do + expect(summary).to receive(:record_success).with(order).once + summarizer.record_success(order) + end + end + + describe "#record_issue" do + it "requests a summary for the order and calls #record_issue on it" do + expect(order).to receive(:id) + expect(summary).to receive(:record_issue).with(:type, order, "message").once + summarizer.record_issue(:type, order, "message") + end + end + + describe "#record_and_log_error" do + before do + allow(order).to receive(:number) { "123" } + end + + context "when errors exist on the order" do + before do + allow(order).to receive(:errors) { + double(:errors, any?: true, full_messages: ["Some error"]) + } + end + + it "sends error info to rails logger and calls #record_issue with an error message" do + expect(summarizer).to receive(:record_issue).with(:processing, + order, "Errors: Some error") + summarizer.record_and_log_error(:processing, order) + end + end + + context "when no errors exist on the order" do + before do + allow(order).to receive(:errors) { double(:errors, any?: false) } + end + + it "falls back to calling record_issue" do + expect(summarizer).to receive(:record_issue).with(:processing, order) + summarizer.record_and_log_error(:processing, order) + end + end + end + end + + describe "#send_placement_summary_emails" do + let(:summary1) { double(:summary) } + let(:summary2) { double(:summary) } + let(:summaries) { { 1 => summary1, 2 => summary2 } } + let(:mail_mock) { double(:mail, deliver: true) } + + before do + summarizer.instance_variable_set(:@summaries, summaries) + end + + it "sends a placement summary email for each summary" do + expect(SubscriptionMailer).to receive(:placement_summary_email).twice { mail_mock } + summarizer.send_placement_summary_emails + end + end + + describe "#send_confirmation_summary_emails" do + let(:summary1) { double(:summary) } + let(:summary2) { double(:summary) } + let(:summaries) { { 1 => summary1, 2 => summary2 } } + let(:mail_mock) { double(:mail, deliver: true) } + + before do + summarizer.instance_variable_set(:@summaries, summaries) + end + + it "sends a placement summary email for each summary" do + expect(SubscriptionMailer).to receive(:confirmation_summary_email).twice { mail_mock } + summarizer.send_confirmation_summary_emails + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb new file mode 100644 index 0000000000..e24aa6449b --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + describe SubscriptionSummary do + let(:summary) { OrderManagement::Subscriptions::SubscriptionSummary.new(123) } + + describe "#initialize" do + it "initializes instance variables: shop_id, order_count, success_count and issues" do + expect(summary.shop_id).to be 123 + expect(summary.order_count).to be 0 + expect(summary.success_count).to be 0 + expect(summary.issues).to be_a Hash + end + end + + describe "#record_order" do + let(:order) { double(:order, id: 37) } + it "adds the order id to the order_ids array" do + summary.record_order(order) + expect(summary.instance_variable_get(:@order_ids)).to eq [order.id] + end + end + + describe "#record_success" do + let(:order) { double(:order, id: 37) } + it "adds the order id to the success_ids array" do + summary.record_success(order) + expect(summary.instance_variable_get(:@success_ids)).to eq [order.id] + end + end + + describe "#record_issue" do + let(:order) { double(:order, id: 1) } + + context "when no issues of the same type have been recorded yet" do + it "adds a new type to the issues hash, and stores a new issue against it" do + summary.record_issue(:some_type, order, "message") + expect(summary.issues.keys).to include :some_type + expect(summary.issues[:some_type][order.id]).to eq "message" + end + end + + context "when an issue of the same type has already been recorded" do + let(:existing_issue) { double(:existing_issue) } + + before { summary.issues[:some_type] = [existing_issue] } + + it "stores a new issue against the existing type" do + summary.record_issue(:some_type, order, "message") + expect(summary.issues[:some_type]).to include existing_issue + expect(summary.issues[:some_type][order.id]).to eq "message" + end + end + end + + describe "#order_count" do + let(:order_ids) { [1, 2, 3, 4, 5, 6, 7] } + it "counts the number of items in the order_ids instance_variable" do + summary.instance_variable_set(:@order_ids, order_ids) + expect(summary.order_count).to be 7 + end + end + + describe "#success_count" do + let(:success_ids) { [1, 2, 3, 4, 5, 6, 7] } + it "counts the number of items in the success_ids instance_variable" do + summary.instance_variable_set(:@success_ids, success_ids) + expect(summary.success_count).to be 7 + end + end + + describe "#issue_count" do + let(:order_ids) { [1, 3, 5, 7, 9] } + let(:success_ids) { [1, 2, 3, 4, 5] } + + it "counts the number of items in order_ids that are not in success_ids" do + summary.instance_variable_set(:@order_ids, order_ids) + summary.instance_variable_set(:@success_ids, success_ids) + expect(summary.issue_count).to be 2 # 7 & 9 + end + end + + describe "#orders_affected_by" do + let(:order1) { create(:order) } + let(:order2) { create(:order) } + + before do + allow(summary).to receive(:unrecorded_ids) { [order1.id] } + allow(summary).to receive(:issues) { { failure: { order2.id => "A message" } } } + end + + context "when the issue type is :other" do + let(:orders) { summary.orders_affected_by(:other) } + + it "returns orders specified by unrecorded_ids" do + expect(orders).to include order1 + expect(orders).to_not include order2 + end + end + + context "when the issue type is :other" do + let(:orders) { summary.orders_affected_by(:failure) } + + it "returns orders specified by the relevant issue hash" do + expect(orders).to include order2 + expect(orders).to_not include order1 + end + end + end + + describe "#unrecorded_ids" do + let(:issues) { { type: { 7 => "message", 8 => "message" } } } + + before do + summary.instance_variable_set(:@order_ids, [1, 3, 5, 7, 9]) + summary.instance_variable_set(:@success_ids, [1, 2, 3, 4, 5]) + summary.instance_variable_set(:@issues, issues) + end + + it "returns order_ids that are not marked as an issue or a success" do + expect(summary.unrecorded_ids).to eq [9] + end + end + end + end +end diff --git a/lib/open_food_network/subscription_summarizer.rb b/lib/open_food_network/subscription_summarizer.rb deleted file mode 100644 index 6e4b95da8b..0000000000 --- a/lib/open_food_network/subscription_summarizer.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'open_food_network/subscription_summary' - -# Used by for SubscriptionPlacementJob and SubscriptionConfirmJob to summarize the -# result of automatic processing of subscriptions for the relevant shop owners. -module OpenFoodNetwork - class SubscriptionSummarizer - def initialize - @summaries = {} - end - - def record_order(order) - summary_for(order).record_order(order) - end - - def record_success(order) - summary_for(order).record_success(order) - end - - def record_issue(type, order, message = nil) - Rails.logger.info "Issue in Subscription Order #{order.id}: #{type}" - summary_for(order).record_issue(type, order, message) - end - - def record_and_log_error(type, order) - return record_issue(type, order) unless order.errors.any? - - error = "Subscription#{type.to_s.camelize}Error" - line1 = "#{error}: Cannot process order #{order.number} due to errors" - line2 = "Errors: #{order.errors.full_messages.join(', ')}" - Rails.logger.info("#{line1}\n#{line2}") - record_issue(type, order, line2) - end - - def send_placement_summary_emails - @summaries.values.each do |summary| - SubscriptionMailer.placement_summary_email(summary).deliver - end - end - - def send_confirmation_summary_emails - @summaries.values.each do |summary| - SubscriptionMailer.confirmation_summary_email(summary).deliver - end - end - - private - - def summary_for(order) - shop_id = order.distributor_id - @summaries[shop_id] ||= SubscriptionSummary.new(shop_id) - end - end -end diff --git a/lib/open_food_network/subscription_summary.rb b/lib/open_food_network/subscription_summary.rb deleted file mode 100644 index fb2a1dc066..0000000000 --- a/lib/open_food_network/subscription_summary.rb +++ /dev/null @@ -1,49 +0,0 @@ -module OpenFoodNetwork - class SubscriptionSummary - attr_reader :shop_id, :order_count, :success_count, :issues - - def initialize(shop_id) - @shop_id = shop_id - @order_ids = [] - @success_ids = [] - @issues = {} - end - - def record_order(order) - @order_ids << order.id - end - - def record_success(order) - @success_ids << order.id - end - - def record_issue(type, order, message) - issues[type] ||= {} - issues[type][order.id] = message - end - - def order_count - @order_ids.count - end - - def success_count - @success_ids.count - end - - def issue_count - (@order_ids - @success_ids).count - end - - def orders_affected_by(type) - case type - when :other then Spree::Order.where(id: unrecorded_ids) - else Spree::Order.where(id: issues[type].keys) - end - end - - def unrecorded_ids - recorded_ids = issues.values.map(&:keys).flatten - @order_ids - @success_ids - recorded_ids - end - end -end diff --git a/spec/lib/open_food_network/subscription_summarizer_spec.rb b/spec/lib/open_food_network/subscription_summarizer_spec.rb deleted file mode 100644 index a0d2b3f7bf..0000000000 --- a/spec/lib/open_food_network/subscription_summarizer_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'spec_helper' -require 'open_food_network/subscription_summarizer' - -module OpenFoodNetwork - describe SubscriptionSummarizer do - let(:order) { create(:order) } - let(:summarizer) { OpenFoodNetwork::SubscriptionSummarizer.new } - - before { allow(Rails.logger).to receive(:info) } - - describe "#summary_for" do - let(:order) { double(:order, distributor_id: 123) } - - context "when a summary for the order's distributor doesn't already exist" do - it "initializes a new summary object, and returns it" do - expect(summarizer.instance_variable_get(:@summaries).count).to be 0 - summary = summarizer.send(:summary_for, order) - expect(summary.shop_id).to be 123 - expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - end - end - - context "when a summary for the order's distributor already exists" do - let(:summary) { double(:summary) } - - before do - summarizer.instance_variable_set(:@summaries, 123 => summary) - end - - it "returns the existing summary object" do - expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - expect(summarizer.send(:summary_for, order)).to eq summary - expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - end - end - end - - describe "recording events" do - let(:order) { double(:order) } - let(:summary) { double(:summary) } - before { allow(summarizer).to receive(:summary_for).with(order) { summary } } - - describe "#record_order" do - it "requests a summary for the order and calls #record_order on it" do - expect(summary).to receive(:record_order).with(order).once - summarizer.record_order(order) - end - end - - describe "#record_success" do - it "requests a summary for the order and calls #record_success on it" do - expect(summary).to receive(:record_success).with(order).once - summarizer.record_success(order) - end - end - - describe "#record_issue" do - it "requests a summary for the order and calls #record_issue on it" do - expect(order).to receive(:id) - expect(summary).to receive(:record_issue).with(:type, order, "message").once - summarizer.record_issue(:type, order, "message") - end - end - - describe "#record_and_log_error" do - before do - allow(order).to receive(:number) { "123" } - end - - context "when errors exist on the order" do - before do - allow(order).to receive(:errors) { double(:errors, any?: true, full_messages: ["Some error"]) } - end - - it "sends error info to the rails logger and calls #record_issue on itself with an error message" do - expect(summarizer).to receive(:record_issue).with(:processing, order, "Errors: Some error") - summarizer.record_and_log_error(:processing, order) - end - end - - context "when no errors exist on the order" do - before do - allow(order).to receive(:errors) { double(:errors, any?: false) } - end - - it "falls back to calling record_issue" do - expect(summarizer).to receive(:record_issue).with(:processing, order) - summarizer.record_and_log_error(:processing, order) - end - end - end - end - - describe "#send_placement_summary_emails" do - let(:summary1) { double(:summary) } - let(:summary2) { double(:summary) } - let(:summaries) { { 1 => summary1, 2 => summary2 } } - let(:mail_mock) { double(:mail, deliver: true) } - - before do - summarizer.instance_variable_set(:@summaries, summaries) - end - - it "sends a placement summary email for each summary" do - expect(SubscriptionMailer).to receive(:placement_summary_email).twice { mail_mock } - summarizer.send_placement_summary_emails - end - end - - describe "#send_confirmation_summary_emails" do - let(:summary1) { double(:summary) } - let(:summary2) { double(:summary) } - let(:summaries) { { 1 => summary1, 2 => summary2 } } - let(:mail_mock) { double(:mail, deliver: true) } - - before do - summarizer.instance_variable_set(:@summaries, summaries) - end - - it "sends a placement summary email for each summary" do - expect(SubscriptionMailer).to receive(:confirmation_summary_email).twice { mail_mock } - summarizer.send_confirmation_summary_emails - end - end - end -end diff --git a/spec/lib/open_food_network/subscription_summary_spec.rb b/spec/lib/open_food_network/subscription_summary_spec.rb deleted file mode 100644 index f5b0cd8d71..0000000000 --- a/spec/lib/open_food_network/subscription_summary_spec.rb +++ /dev/null @@ -1,125 +0,0 @@ -require 'open_food_network/subscription_summary' - -module OpenFoodNetwork - describe SubscriptionSummary do - let(:summary) { OpenFoodNetwork::SubscriptionSummary.new(123) } - - describe "#initialize" do - it "initializes instance variables: shop_id, order_count, success_count and issues" do - expect(summary.shop_id).to be 123 - expect(summary.order_count).to be 0 - expect(summary.success_count).to be 0 - expect(summary.issues).to be_a Hash - end - end - - describe "#record_order" do - let(:order) { double(:order, id: 37) } - it "adds the order id to the order_ids array" do - summary.record_order(order) - expect(summary.instance_variable_get(:@order_ids)).to eq [order.id] - end - end - - describe "#record_success" do - let(:order) { double(:order, id: 37) } - it "adds the order id to the success_ids array" do - summary.record_success(order) - expect(summary.instance_variable_get(:@success_ids)).to eq [order.id] - end - end - - describe "#record_issue" do - let(:order) { double(:order, id: 1) } - - context "when no issues of the same type have been recorded yet" do - it "adds a new type to the issues hash, and stores a new issue against it" do - summary.record_issue(:some_type, order, "message") - expect(summary.issues.keys).to include :some_type - expect(summary.issues[:some_type][order.id]).to eq "message" - end - end - - context "when an issue of the same type has already been recorded" do - let(:existing_issue) { double(:existing_issue) } - - before { summary.issues[:some_type] = [existing_issue] } - - it "stores a new issue against the existing type" do - summary.record_issue(:some_type, order, "message") - expect(summary.issues[:some_type]).to include existing_issue - expect(summary.issues[:some_type][order.id]).to eq "message" - end - end - end - - describe "#order_count" do - let(:order_ids) { [1, 2, 3, 4, 5, 6, 7] } - it "counts the number of items in the order_ids instance_variable" do - summary.instance_variable_set(:@order_ids, order_ids) - expect(summary.order_count).to be 7 - end - end - - describe "#success_count" do - let(:success_ids) { [1, 2, 3, 4, 5, 6, 7] } - it "counts the number of items in the success_ids instance_variable" do - summary.instance_variable_set(:@success_ids, success_ids) - expect(summary.success_count).to be 7 - end - end - - describe "#issue_count" do - let(:order_ids) { [1, 3, 5, 7, 9] } - let(:success_ids) { [1, 2, 3, 4, 5] } - - it "counts the number of items in order_ids that are not in success_ids" do - summary.instance_variable_set(:@order_ids, order_ids) - summary.instance_variable_set(:@success_ids, success_ids) - expect(summary.issue_count).to be 2 # 7 & 9 - end - end - - describe "#orders_affected_by" do - let(:order1) { create(:order) } - let(:order2) { create(:order) } - - before do - allow(summary).to receive(:unrecorded_ids) { [order1.id] } - allow(summary).to receive(:issues) { { failure: { order2.id => "A message" } } } - end - - context "when the issue type is :other" do - let(:orders) { summary.orders_affected_by(:other) } - - it "returns orders specified by unrecorded_ids" do - expect(orders).to include order1 - expect(orders).to_not include order2 - end - end - - context "when the issue type is :other" do - let(:orders) { summary.orders_affected_by(:failure) } - - it "returns orders specified by the relevant issue hash" do - expect(orders).to include order2 - expect(orders).to_not include order1 - end - end - end - - describe "#unrecorded_ids" do - let(:issues) { { type: { 7 => "message", 8 => "message" } } } - - before do - summary.instance_variable_set(:@order_ids, [1, 3, 5, 7, 9]) - summary.instance_variable_set(:@success_ids, [1, 2, 3, 4, 5]) - summary.instance_variable_set(:@issues, issues) - end - - it "returns order_ids that are not marked as an issue or a success" do - expect(summary.unrecorded_ids).to eq [9] - end - end - end -end From ae0ceb61a169e531fe9b7f8d13e7c4c1f7273acb Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 18:22:36 +0000 Subject: [PATCH 010/166] Move ProxyOrderSyncer to OrderManagement engine --- .rubocop_manual_todo.yml | 4 +- .rubocop_todo.yml | 6 +- app/controllers/admin/schedules_controller.rb | 4 +- app/services/order_cycle_form.rb | 4 +- app/services/subscription_form.rb | 4 +- .../subscriptions/proxy_order_syncer.rb | 99 +++++ .../subscriptions/proxy_order_syncer_spec.rb | 69 +++ .../subscriptions/proxy_order_syncer_spec.rb | 402 ++++++++++++++++++ lib/open_food_network/proxy_order_syncer.rb | 95 ----- .../admin/schedules_controller_spec.rb | 4 +- .../proxy_order_syncer_spec.rb | 400 ----------------- spec/performance/proxy_order_syncer_spec.rb | 67 --- spec/services/order_cycle_form_spec.rb | 6 +- 13 files changed, 587 insertions(+), 577 deletions(-) create mode 100644 engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb create mode 100644 engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb delete mode 100644 lib/open_food_network/proxy_order_syncer.rb delete mode 100644 spec/lib/open_food_network/proxy_order_syncer_spec.rb delete mode 100644 spec/performance/proxy_order_syncer_spec.rb diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 9b0fd3b537..9494595048 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -101,6 +101,7 @@ Layout/LineLength: - app/services/subscriptions_count.rb - app/services/variants_stock_levels.rb - engines/web/app/helpers/web/cookies_policy_helper.rb + - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - lib/discourse/single_sign_on.rb - lib/open_food_network/available_payment_method_filter.rb - lib/open_food_network/bulk_coop_report.rb @@ -239,7 +240,6 @@ Layout/LineLength: - spec/lib/open_food_network/packing_report_spec.rb - spec/lib/open_food_network/permissions_spec.rb - spec/lib/open_food_network/products_and_inventory_report_spec.rb - - spec/lib/open_food_network/proxy_order_syncer_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb @@ -684,6 +684,7 @@ Metrics/ModuleLength: - app/helpers/injection_helper.rb - app/helpers/spree/admin/navigation_helper.rb - app/helpers/spree/admin/base_helper.rb + - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb - lib/open_food_network/column_preference_defaults.rb - spec/controllers/admin/enterprises_controller_spec.rb @@ -700,7 +701,6 @@ Metrics/ModuleLength: - spec/lib/open_food_network/order_grouper_spec.rb - spec/lib/open_food_network/permissions_spec.rb - spec/lib/open_food_network/products_and_inventory_report_spec.rb - - spec/lib/open_food_network/proxy_order_syncer_spec.rb - spec/lib/open_food_network/scope_variant_to_hub_spec.rb - spec/lib/open_food_network/tag_rule_applicator_spec.rb - spec/lib/open_food_network/users_and_enterprises_report_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 323426fda9..1c003c0504 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -882,6 +882,7 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/report_service.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb' + - 'engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb' - 'engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb' - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'engines/order_management/app/services/reports.rb' @@ -895,6 +896,7 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/lib/order_management/engine.rb' - 'engines/order_management/lib/order_management/version.rb' - 'engines/order_management/order_management.gemspec' + - 'engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/authorizer_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/parameters_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/permissions_spec.rb' @@ -902,6 +904,7 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb' + - 'engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb' - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summizer_spec.rb' - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb' - 'engines/order_management/spec/spec_helper.rb' @@ -954,7 +957,6 @@ Style/FrozenStringLiteralComment: - 'lib/open_food_network/products_and_inventory_report.rb' - 'lib/open_food_network/products_and_inventory_report_base.rb' - 'lib/open_food_network/property_merge.rb' - - 'lib/open_food_network/proxy_order_syncer.rb' - 'lib/open_food_network/rack_request_blocker.rb' - 'lib/open_food_network/referer_parser.rb' - 'lib/open_food_network/reports/bulk_coop_allocation_report.rb' @@ -1212,7 +1214,6 @@ Style/FrozenStringLiteralComment: - 'spec/lib/open_food_network/permissions_spec.rb' - 'spec/lib/open_food_network/products_and_inventory_report_spec.rb' - 'spec/lib/open_food_network/property_merge_spec.rb' - - 'spec/lib/open_food_network/proxy_order_syncer_spec.rb' - 'spec/lib/open_food_network/referer_parser_spec.rb' - 'spec/lib/open_food_network/reports/report_spec.rb' - 'spec/lib/open_food_network/reports/row_spec.rb' @@ -1306,7 +1307,6 @@ Style/FrozenStringLiteralComment: - 'spec/models/variant_override_spec.rb' - 'spec/performance/injection_helper_spec.rb' - 'spec/performance/orders_controller_spec.rb' - - 'spec/performance/proxy_order_syncer_spec.rb' - 'spec/performance/shop_controller_spec.rb' - 'spec/requests/checkout/failed_checkout_spec.rb' - 'spec/requests/checkout/paypal_spec.rb' diff --git a/app/controllers/admin/schedules_controller.rb b/app/controllers/admin/schedules_controller.rb index 580a6a9c72..c568bf0ad7 100644 --- a/app/controllers/admin/schedules_controller.rb +++ b/app/controllers/admin/schedules_controller.rb @@ -1,5 +1,5 @@ require 'open_food_network/permissions' -require 'open_food_network/proxy_order_syncer' +require 'order_management/subscriptions/proxy_order_syncer' module Admin class SchedulesController < ResourceController @@ -81,7 +81,7 @@ module Admin return unless removed_ids.any? || new_ids.any? subscriptions = Subscription.where(schedule_id: @schedule) - syncer = OpenFoodNetwork::ProxyOrderSyncer.new(subscriptions) + syncer = OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscriptions) syncer.sync! end end diff --git a/app/services/order_cycle_form.rb b/app/services/order_cycle_form.rb index 2ab5d109de..7026d5f5b6 100644 --- a/app/services/order_cycle_form.rb +++ b/app/services/order_cycle_form.rb @@ -1,6 +1,6 @@ require 'open_food_network/permissions' -require 'open_food_network/proxy_order_syncer' require 'open_food_network/order_cycle_form_applicator' +require 'order_management/subscriptions/proxy_order_syncer' class OrderCycleForm def initialize(order_cycle, params, user) @@ -58,7 +58,7 @@ class OrderCycleForm return unless schedule_ids? return unless schedule_sync_required? - OpenFoodNetwork::ProxyOrderSyncer.new(subscriptions_to_sync).sync! + OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscriptions_to_sync).sync! end def schedule_sync_required? diff --git a/app/services/subscription_form.rb b/app/services/subscription_form.rb index da82063b5c..fa33b216b2 100644 --- a/app/services/subscription_form.rb +++ b/app/services/subscription_form.rb @@ -1,4 +1,4 @@ -require 'open_food_network/proxy_order_syncer' +require 'order_management/subscriptions/proxy_order_syncer' class SubscriptionForm attr_accessor :subscription, :params, :order_update_issues, :validator, :order_syncer, :estimator @@ -29,6 +29,6 @@ class SubscriptionForm private def proxy_order_syncer - OpenFoodNetwork::ProxyOrderSyncer.new(subscription) + OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscription) end end diff --git a/engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb b/engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb new file mode 100644 index 0000000000..b53085f1c1 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: false + +module OrderManagement + module Subscriptions + class ProxyOrderSyncer + attr_reader :subscription + + delegate :order_cycles, :proxy_orders, :begins_at, :ends_at, to: :subscription + + def initialize(subscriptions) + case subscriptions + when Subscription + @subscription = subscriptions + when ActiveRecord::Relation + @subscriptions = subscriptions.not_ended.not_canceled + else + raise "ProxyOrderSyncer must be initialized with " \ + "an instance of Subscription or ActiveRecord::Relation" + end + end + + def sync! + return sync_subscriptions! if @subscriptions + + return initialise_proxy_orders! unless @subscription.id + + sync_subscription! + end + + private + + def sync_subscriptions! + @subscriptions.each do |subscription| + @subscription = subscription + sync_subscription! + end + end + + def initialise_proxy_orders! + uninitialised_order_cycle_ids.each do |order_cycle_id| + Rails.logger.info "Initializing Proxy Order " \ + "of subscription #{@subscription.id} in order cycle #{order_cycle_id}" + proxy_orders << ProxyOrder.new(subscription: subscription, order_cycle_id: order_cycle_id) + end + end + + def sync_subscription! + Rails.logger.info "Syncing Proxy Orders of subscription #{@subscription.id}" + create_proxy_orders! + remove_orphaned_proxy_orders! + end + + def create_proxy_orders! + return unless not_closed_in_range_order_cycles.any? + + query = "INSERT INTO proxy_orders (subscription_id, order_cycle_id, updated_at, created_at)" + query << " VALUES #{insert_values}" + query << " ON CONFLICT DO NOTHING" + + ActiveRecord::Base.connection.exec_query(query) + end + + def uninitialised_order_cycle_ids + not_closed_in_range_order_cycles.pluck(:id) - proxy_orders.map(&:order_cycle_id) + end + + def remove_orphaned_proxy_orders! + orphaned_proxy_orders.scoped.delete_all + end + + # Remove Proxy Orders that have not been placed yet + # and are in Order Cycles that are out of range + def orphaned_proxy_orders + orphaned = proxy_orders.where(placed_at: nil) + order_cycle_ids = in_range_order_cycles.pluck(:id) + return orphaned unless order_cycle_ids.any? + + orphaned.where('order_cycle_id NOT IN (?)', order_cycle_ids) + end + + def insert_values + now = Time.now.utc.iso8601 + not_closed_in_range_order_cycles + .map{ |oc| "(#{subscription.id},#{oc.id},'#{now}','#{now}')" } + .join(",") + end + + def not_closed_in_range_order_cycles + in_range_order_cycles.merge(OrderCycle.not_closed) + end + + def in_range_order_cycles + order_cycles.where("orders_close_at >= ? AND orders_close_at <= ?", + begins_at, + ends_at || 100.years.from_now) + end + end + end +end diff --git a/engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb new file mode 100644 index 0000000000..b62267b714 --- /dev/null +++ b/engines/order_management/spec/performance/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + describe ProxyOrderSyncer, performance: true do + let(:start) { Time.zone.now.beginning_of_day } + let!(:schedule) { create(:schedule, order_cycles: order_cycles) } + + let!(:order_cycles) do + Array.new(10) do |i| + create(:simple_order_cycle, orders_open_at: start + i.days, + orders_close_at: start + (i + 1).days ) + end + end + + let!(:subscriptions) do + Array.new(150) do |_i| + create(:subscription, schedule: schedule, begins_at: start, ends_at: start + 10.days) + end + Subscription.where(schedule_id: schedule) + end + + context "measuring performance for initialisation" do + it "reports the average run time for adding 10 OCs to 150 subscriptions" do + expect(ProxyOrder.count).to be 0 + times = [] + 10.times do + syncer = ProxyOrderSyncer.new(subscriptions.reload) + + t1 = Time.zone.now + syncer.sync! + t2 = Time.zone.now + diff = t2 - t1 + times << diff + puts diff.round(2) + + expect(ProxyOrder.count).to be 1500 + ProxyOrder.destroy_all + end + puts "AVG: #{(times.sum / times.count).round(2)}" + end + end + + context "measuring performance for removal" do + it "reports the average run time for removing 8 OCs from 150 subscriptions" do + times = [] + 10.times do + syncer = ProxyOrderSyncer.new(subscriptions.reload) + syncer.sync! + expect(ProxyOrder.count).to be 1500 + subscriptions.update_all(begins_at: start + 8.days + 1.minute) + syncer = ProxyOrderSyncer.new(subscriptions.reload) + + t1 = Time.zone.now + syncer.sync! + t2 = Time.zone.now + diff = t2 - t1 + times << diff + puts diff.round(2) + + expect(ProxyOrder.count).to be 300 + subscriptions.update_all(begins_at: start) + end + puts "AVG: #{(times.sum / times.count).round(2)}" + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb new file mode 100644 index 0000000000..ab01eddc4c --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -0,0 +1,402 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + describe ProxyOrderSyncer do + describe "initialization" do + let!(:subscription) { create(:subscription) } + + it "raises an error when initialized with an object that is not a Subscription or an ActiveRecord::Relation" do + expect{ ProxyOrderSyncer.new(subscription) }.to_not raise_error + expect{ ProxyOrderSyncer.new(Subscription.where(id: subscription.id)) }.to_not raise_error + expect{ ProxyOrderSyncer.new("something") }.to raise_error RuntimeError + end + end + + describe "#sync!" do + let(:now) { Time.zone.now } + let(:schedule) { create(:schedule) } + let(:closed_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now) } # Closed + let(:open_oc_closes_before_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now + 59.seconds) } # Open, but closes before begins at + let(:open_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now + 90.seconds) } # Open & closes between begins at and ends at + let(:upcoming_closes_before_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 59.seconds) } # Upcoming, but closes before begins at + let(:upcoming_closes_on_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 1.minute) } # Upcoming & closes on begins at + let(:upcoming_closes_on_ends_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 2.minutes) } # Upcoming & closes on ends at + let(:upcoming_closes_after_ends_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 121.seconds) } # Upcoming & closes after ends at + let(:subscription) { build(:subscription, schedule: schedule, begins_at: now + 1.minute, ends_at: now + 2.minutes) } + let(:proxy_orders) { subscription.reload.proxy_orders } + let(:order_cycles) { proxy_orders.map(&:order_cycle) } + let(:syncer) { ProxyOrderSyncer.new(subscription) } + + context "when the subscription is not persisted" do + before do + oc # Ensure oc is created before we attempt to sync + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) + end + + context "and the schedule includes a closed oc (ie. closed before opens_at)" do + let(:oc) { closed_oc } + it "does not create a new proxy order for that oc" do + expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + + context "and the schedule includes an open oc that closes before begins_at" do + let(:oc) { open_oc_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do + expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + + context "and the schedule includes an open oc that closes between begins_at and ends_at" do + let(:oc) { open_oc } + it "creates a new proxy order for that oc" do + expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) + expect(order_cycles).to include oc + end + end + + context "and the schedule includes upcoming oc that closes before begins_at" do + let(:oc) { upcoming_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do + expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + + context "and the schedule includes upcoming oc that closes on begins_at" do + let(:oc) { upcoming_closes_on_begins_at_oc } + it "creates a new proxy order for that oc" do + expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) + expect(order_cycles).to include oc + end + end + + context "and the schedule includes upcoming oc that closes after ends_at" do + let(:oc) { upcoming_closes_on_ends_at_oc } + it "creates a new proxy order for that oc" do + expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) + expect(order_cycles).to include oc + end + end + + context "and the schedule includes upcoming oc that closes after ends_at" do + let(:oc) { upcoming_closes_after_ends_at_oc } + it "does not create a new proxy order for that oc" do + expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + end + + context "when the subscription is persisted" do + before { expect(subscription.save!).to be true } + + context "when a proxy order exists" do + let!(:proxy_order) { create(:proxy_order, subscription: subscription, order_cycle: oc) } + + context "for an oc included in the relevant schedule" do + context "and the proxy order has already been placed" do + before { proxy_order.update_attributes(placed_at: 5.minutes.ago) } + + context "the oc is closed (ie. closed before opens_at)" do + let(:oc) { closed_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the schedule includes an open oc that closes before begins_at" do + let(:oc) { open_oc_closes_before_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is open and closes between begins_at and ends_at" do + let(:oc) { open_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes before begins_at" do + let(:oc) { upcoming_closes_before_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on begins_at" do + let(:oc) { upcoming_closes_on_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on ends_at" do + let(:oc) { upcoming_closes_on_ends_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes after ends_at" do + let(:oc) { upcoming_closes_after_ends_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + end + + context "and the proxy order has not already been placed" do + context "the oc is closed (ie. closed before opens_at)" do + let(:oc) { closed_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the schedule includes an open oc that closes before begins_at" do + let(:oc) { open_oc_closes_before_begins_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the oc is open and closes between begins_at and ends_at" do + let(:oc) { open_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes before begins_at" do + let(:oc) { upcoming_closes_before_begins_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the oc is upcoming and closes on begins_at" do + let(:oc) { upcoming_closes_on_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on ends_at" do + let(:oc) { upcoming_closes_on_ends_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes after ends_at" do + let(:oc) { upcoming_closes_after_ends_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + end + end + + context "for an oc not included in the relevant schedule" do + let!(:proxy_order) { create(:proxy_order, subscription: subscription, order_cycle: open_oc) } + before do + open_oc.schedule_ids = [] + expect(open_oc.save!).to be true + end + + context "and the proxy order has already been placed" do + before { proxy_order.update_attributes(placed_at: 5.minutes.ago) } + + context "the oc is closed (ie. closed before opens_at)" do + let(:oc) { closed_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the schedule includes an open oc that closes before begins_at" do + let(:oc) { open_oc_closes_before_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is open and closes between begins_at and ends_at" do + let(:oc) { open_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes before begins_at" do + let(:oc) { upcoming_closes_before_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on begins_at" do + let(:oc) { upcoming_closes_on_begins_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes on ends_at" do + let(:oc) { upcoming_closes_on_ends_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + + context "and the oc is upcoming and closes after ends_at" do + let(:oc) { upcoming_closes_after_ends_at_oc } + it "keeps the proxy order" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) + expect(proxy_orders).to include proxy_order + end + end + end + + context "and the proxy order has not already been placed" do + # This shouldn't really happen, but it is possible + context "the oc is closed (ie. closed before opens_at)" do + let(:oc) { closed_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + # This shouldn't really happen, but it is possible + context "and the oc is open and closes between begins_at and ends_at" do + let(:oc) { open_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the oc is upcoming and closes before begins_at" do + let(:oc) { upcoming_closes_before_begins_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the oc is upcoming and closes on begins_at" do + let(:oc) { upcoming_closes_on_begins_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the oc is upcoming and closes on ends_at" do + let(:oc) { upcoming_closes_on_ends_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + + context "and the oc is upcoming and closes after ends_at" do + let(:oc) { upcoming_closes_after_ends_at_oc } + it "removes the proxy order" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) + expect(proxy_orders).to_not include proxy_order + end + end + end + end + end + + context "when a proxy order does not exist" do + context "and the schedule includes a closed oc (ie. closed before opens_at)" do + let!(:oc) { closed_oc } + it "does not create a new proxy order for that oc" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + + context "and the schedule includes an open oc that closes before begins_at" do + let(:oc) { open_oc_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do + expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + + context "and the schedule includes an open oc that closes between begins_at and ends_at" do + let!(:oc) { open_oc } + it "creates a new proxy order for that oc" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) + expect(order_cycles).to include oc + end + end + + context "and the schedule includes upcoming oc that closes before begins_at" do + let!(:oc) { upcoming_closes_before_begins_at_oc } + it "does not create a new proxy order for that oc" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + + context "and the schedule includes upcoming oc that closes on begins_at" do + let!(:oc) { upcoming_closes_on_begins_at_oc } + it "creates a new proxy order for that oc" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) + expect(order_cycles).to include oc + end + end + + context "and the schedule includes upcoming oc that closes on ends_at" do + let!(:oc) { upcoming_closes_on_ends_at_oc } + it "creates a new proxy order for that oc" do + expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) + expect(order_cycles).to include oc + end + end + + context "and the schedule includes upcoming oc that closes after ends_at" do + let!(:oc) { upcoming_closes_after_ends_at_oc } + it "does not create a new proxy order for that oc" do + expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) + expect(order_cycles).to_not include oc + end + end + end + end + end + end + end +end diff --git a/lib/open_food_network/proxy_order_syncer.rb b/lib/open_food_network/proxy_order_syncer.rb deleted file mode 100644 index 62dc575115..0000000000 --- a/lib/open_food_network/proxy_order_syncer.rb +++ /dev/null @@ -1,95 +0,0 @@ -module OpenFoodNetwork - class ProxyOrderSyncer - attr_reader :subscription - - delegate :order_cycles, :proxy_orders, :begins_at, :ends_at, to: :subscription - - def initialize(subscriptions) - case subscriptions - when Subscription - @subscription = subscriptions - when ActiveRecord::Relation - @subscriptions = subscriptions.not_ended.not_canceled - else - raise "ProxyOrderSyncer must be initialized with " \ - "an instance of Subscription or ActiveRecord::Relation" - end - end - - def sync! - return sync_subscriptions! if @subscriptions - - return initialise_proxy_orders! unless @subscription.id - - sync_subscription! - end - - private - - def sync_subscriptions! - @subscriptions.each do |subscription| - @subscription = subscription - sync_subscription! - end - end - - def initialise_proxy_orders! - uninitialised_order_cycle_ids.each do |order_cycle_id| - Rails.logger.info "Initializing Proxy Order " \ - "of subscription #{@subscription.id} in order cycle #{order_cycle_id}" - proxy_orders << ProxyOrder.new(subscription: subscription, order_cycle_id: order_cycle_id) - end - end - - def sync_subscription! - Rails.logger.info "Syncing Proxy Orders of subscription #{@subscription.id}" - create_proxy_orders! - remove_orphaned_proxy_orders! - end - - def create_proxy_orders! - return unless not_closed_in_range_order_cycles.any? - - query = "INSERT INTO proxy_orders (subscription_id, order_cycle_id, updated_at, created_at)" - query << " VALUES #{insert_values}" - query << " ON CONFLICT DO NOTHING" - - ActiveRecord::Base.connection.exec_query(query) - end - - def uninitialised_order_cycle_ids - not_closed_in_range_order_cycles.pluck(:id) - proxy_orders.map(&:order_cycle_id) - end - - def remove_orphaned_proxy_orders! - orphaned_proxy_orders.scoped.delete_all - end - - # Remove Proxy Orders that have not been placed yet - # and are in Order Cycles that are out of range - def orphaned_proxy_orders - orphaned = proxy_orders.where(placed_at: nil) - order_cycle_ids = in_range_order_cycles.pluck(:id) - return orphaned unless order_cycle_ids.any? - - orphaned.where('order_cycle_id NOT IN (?)', order_cycle_ids) - end - - def insert_values - now = Time.now.utc.iso8601 - not_closed_in_range_order_cycles - .map{ |oc| "(#{subscription.id},#{oc.id},'#{now}','#{now}')" } - .join(",") - end - - def not_closed_in_range_order_cycles - in_range_order_cycles.merge(OrderCycle.not_closed) - end - - def in_range_order_cycles - order_cycles.where("orders_close_at >= ? AND orders_close_at <= ?", - begins_at, - ends_at || 100.years.from_now) - end - end -end diff --git a/spec/controllers/admin/schedules_controller_spec.rb b/spec/controllers/admin/schedules_controller_spec.rb index 19f2e4b032..5f213b4292 100644 --- a/spec/controllers/admin/schedules_controller_spec.rb +++ b/spec/controllers/admin/schedules_controller_spec.rb @@ -90,7 +90,7 @@ describe Admin::SchedulesController, type: :controller do it "syncs proxy orders when order_cycle_ids change" do syncer_mock = double(:syncer) - allow(OpenFoodNetwork::ProxyOrderSyncer).to receive(:new) { syncer_mock } + allow(OrderManagement::Subscriptions::ProxyOrderSyncer).to receive(:new) { syncer_mock } expect(syncer_mock).to receive(:sync!).exactly(2).times spree_put :update, format: :json, id: coordinated_schedule.id, schedule: { order_cycle_ids: [coordinated_order_cycle.id, coordinated_order_cycle2.id] } @@ -150,7 +150,7 @@ describe Admin::SchedulesController, type: :controller do it "sync proxy orders" do syncer_mock = double(:syncer) - allow(OpenFoodNetwork::ProxyOrderSyncer).to receive(:new) { syncer_mock } + allow(OrderManagement::Subscriptions::ProxyOrderSyncer).to receive(:new) { syncer_mock } expect(syncer_mock).to receive(:sync!).once create_schedule params diff --git a/spec/lib/open_food_network/proxy_order_syncer_spec.rb b/spec/lib/open_food_network/proxy_order_syncer_spec.rb deleted file mode 100644 index 9b059d178f..0000000000 --- a/spec/lib/open_food_network/proxy_order_syncer_spec.rb +++ /dev/null @@ -1,400 +0,0 @@ -require 'open_food_network/proxy_order_syncer' - -module OpenFoodNetwork - describe ProxyOrderSyncer do - describe "initialization" do - let!(:subscription) { create(:subscription) } - - it "raises an error when initialized with an object that is not a Subscription or an ActiveRecord::Relation" do - expect{ ProxyOrderSyncer.new(subscription) }.to_not raise_error - expect{ ProxyOrderSyncer.new(Subscription.where(id: subscription.id)) }.to_not raise_error - expect{ ProxyOrderSyncer.new("something") }.to raise_error RuntimeError - end - end - - describe "#sync!" do - let(:now) { Time.zone.now } - let(:schedule) { create(:schedule) } - let(:closed_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now) } # Closed - let(:open_oc_closes_before_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now + 59.seconds) } # Open, but closes before begins at - let(:open_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now + 90.seconds) } # Open & closes between begins at and ends at - let(:upcoming_closes_before_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 59.seconds) } # Upcoming, but closes before begins at - let(:upcoming_closes_on_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 1.minute) } # Upcoming & closes on begins at - let(:upcoming_closes_on_ends_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 2.minutes) } # Upcoming & closes on ends at - let(:upcoming_closes_after_ends_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 121.seconds) } # Upcoming & closes after ends at - let(:subscription) { build(:subscription, schedule: schedule, begins_at: now + 1.minute, ends_at: now + 2.minutes) } - let(:proxy_orders) { subscription.reload.proxy_orders } - let(:order_cycles) { proxy_orders.map(&:order_cycle) } - let(:syncer) { ProxyOrderSyncer.new(subscription) } - - context "when the subscription is not persisted" do - before do - oc # Ensure oc is created before we attempt to sync - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) - end - - context "and the schedule includes a closed oc (ie. closed before opens_at)" do - let(:oc) { closed_oc } - it "does not create a new proxy order for that oc" do - expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - - context "and the schedule includes an open oc that closes before begins_at" do - let(:oc) { open_oc_closes_before_begins_at_oc } - it "does not create a new proxy order for that oc" do - expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - - context "and the schedule includes an open oc that closes between begins_at and ends_at" do - let(:oc) { open_oc } - it "creates a new proxy order for that oc" do - expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc - end - end - - context "and the schedule includes upcoming oc that closes before begins_at" do - let(:oc) { upcoming_closes_before_begins_at_oc } - it "does not create a new proxy order for that oc" do - expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - - context "and the schedule includes upcoming oc that closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } - it "creates a new proxy order for that oc" do - expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc - end - end - - context "and the schedule includes upcoming oc that closes after ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } - it "creates a new proxy order for that oc" do - expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc - end - end - - context "and the schedule includes upcoming oc that closes after ends_at" do - let(:oc) { upcoming_closes_after_ends_at_oc } - it "does not create a new proxy order for that oc" do - expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - end - - context "when the subscription is persisted" do - before { expect(subscription.save!).to be true } - - context "when a proxy order exists" do - let!(:proxy_order) { create(:proxy_order, subscription: subscription, order_cycle: oc) } - - context "for an oc included in the relevant schedule" do - context "and the proxy order has already been placed" do - before { proxy_order.update_attributes(placed_at: 5.minutes.ago) } - - context "the oc is closed (ie. closed before opens_at)" do - let(:oc) { closed_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the schedule includes an open oc that closes before begins_at" do - let(:oc) { open_oc_closes_before_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is open and closes between begins_at and ends_at" do - let(:oc) { open_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes before begins_at" do - let(:oc) { upcoming_closes_before_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes on ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes after ends_at" do - let(:oc) { upcoming_closes_after_ends_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - end - - context "and the proxy order has not already been placed" do - context "the oc is closed (ie. closed before opens_at)" do - let(:oc) { closed_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the schedule includes an open oc that closes before begins_at" do - let(:oc) { open_oc_closes_before_begins_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the oc is open and closes between begins_at and ends_at" do - let(:oc) { open_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes before begins_at" do - let(:oc) { upcoming_closes_before_begins_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the oc is upcoming and closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes on ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes after ends_at" do - let(:oc) { upcoming_closes_after_ends_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - end - end - - context "for an oc not included in the relevant schedule" do - let!(:proxy_order) { create(:proxy_order, subscription: subscription, order_cycle: open_oc) } - before do - open_oc.schedule_ids = [] - expect(open_oc.save!).to be true - end - - context "and the proxy order has already been placed" do - before { proxy_order.update_attributes(placed_at: 5.minutes.ago) } - - context "the oc is closed (ie. closed before opens_at)" do - let(:oc) { closed_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the schedule includes an open oc that closes before begins_at" do - let(:oc) { open_oc_closes_before_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is open and closes between begins_at and ends_at" do - let(:oc) { open_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes before begins_at" do - let(:oc) { upcoming_closes_before_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes on ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - - context "and the oc is upcoming and closes after ends_at" do - let(:oc) { upcoming_closes_after_ends_at_oc } - it "keeps the proxy order" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(1) - expect(proxy_orders).to include proxy_order - end - end - end - - context "and the proxy order has not already been placed" do - # This shouldn't really happen, but it is possible - context "the oc is closed (ie. closed before opens_at)" do - let(:oc) { closed_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - # This shouldn't really happen, but it is possible - context "and the oc is open and closes between begins_at and ends_at" do - let(:oc) { open_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the oc is upcoming and closes before begins_at" do - let(:oc) { upcoming_closes_before_begins_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the oc is upcoming and closes on begins_at" do - let(:oc) { upcoming_closes_on_begins_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the oc is upcoming and closes on ends_at" do - let(:oc) { upcoming_closes_on_ends_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - - context "and the oc is upcoming and closes after ends_at" do - let(:oc) { upcoming_closes_after_ends_at_oc } - it "removes the proxy order" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(1).to(0) - expect(proxy_orders).to_not include proxy_order - end - end - end - end - end - - context "when a proxy order does not exist" do - context "and the schedule includes a closed oc (ie. closed before opens_at)" do - let!(:oc) { closed_oc } - it "does not create a new proxy order for that oc" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - - context "and the schedule includes an open oc that closes before begins_at" do - let(:oc) { open_oc_closes_before_begins_at_oc } - it "does not create a new proxy order for that oc" do - expect{ subscription.save! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - - context "and the schedule includes an open oc that closes between begins_at and ends_at" do - let!(:oc) { open_oc } - it "creates a new proxy order for that oc" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc - end - end - - context "and the schedule includes upcoming oc that closes before begins_at" do - let!(:oc) { upcoming_closes_before_begins_at_oc } - it "does not create a new proxy order for that oc" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - - context "and the schedule includes upcoming oc that closes on begins_at" do - let!(:oc) { upcoming_closes_on_begins_at_oc } - it "creates a new proxy order for that oc" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc - end - end - - context "and the schedule includes upcoming oc that closes on ends_at" do - let!(:oc) { upcoming_closes_on_ends_at_oc } - it "creates a new proxy order for that oc" do - expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) - expect(order_cycles).to include oc - end - end - - context "and the schedule includes upcoming oc that closes after ends_at" do - let!(:oc) { upcoming_closes_after_ends_at_oc } - it "does not create a new proxy order for that oc" do - expect{ syncer.sync! }.to_not change(ProxyOrder, :count).from(0) - expect(order_cycles).to_not include oc - end - end - end - end - end - end -end diff --git a/spec/performance/proxy_order_syncer_spec.rb b/spec/performance/proxy_order_syncer_spec.rb deleted file mode 100644 index 95678c68a2..0000000000 --- a/spec/performance/proxy_order_syncer_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -require 'open_food_network/proxy_order_syncer' - -module OpenFoodNetwork - describe ProxyOrderSyncer, performance: true do - let(:start) { Time.zone.now.beginning_of_day } - let!(:schedule) { create(:schedule, order_cycles: order_cycles) } - - let!(:order_cycles) do - Array.new(10) do |i| - create(:simple_order_cycle, orders_open_at: start + i.days, - orders_close_at: start + (i + 1).days ) - end - end - - let!(:subscriptions) do - Array.new(150) do |_i| - create(:subscription, schedule: schedule, begins_at: start, ends_at: start + 10.days) - end - Subscription.where(schedule_id: schedule) - end - - context "measuring performance for initialisation" do - it "reports the average run time for adding 10 OCs to 150 subscriptions" do - expect(ProxyOrder.count).to be 0 - times = [] - 10.times do - syncer = ProxyOrderSyncer.new(subscriptions.reload) - - t1 = Time.zone.now - syncer.sync! - t2 = Time.zone.now - diff = t2 - t1 - times << diff - puts diff.round(2) - - expect(ProxyOrder.count).to be 1500 - ProxyOrder.destroy_all - end - puts "AVG: #{(times.sum / times.count).round(2)}" - end - end - - context "measuring performance for removal" do - it "reports the average run time for removing 8 OCs from 150 subscriptions" do - times = [] - 10.times do - syncer = ProxyOrderSyncer.new(subscriptions.reload) - syncer.sync! - expect(ProxyOrder.count).to be 1500 - subscriptions.update_all(begins_at: start + 8.days + 1.minute) - syncer = ProxyOrderSyncer.new(subscriptions.reload) - - t1 = Time.zone.now - syncer.sync! - t2 = Time.zone.now - diff = t2 - t1 - times << diff - puts diff.round(2) - - expect(ProxyOrder.count).to be 300 - subscriptions.update_all(begins_at: start) - end - puts "AVG: #{(times.sum / times.count).round(2)}" - end - end - end -end diff --git a/spec/services/order_cycle_form_spec.rb b/spec/services/order_cycle_form_spec.rb index 476adb3e39..e4d5d144d1 100644 --- a/spec/services/order_cycle_form_spec.rb +++ b/spec/services/order_cycle_form_spec.rb @@ -1,3 +1,5 @@ +require 'order_management/subscriptions/proxy_order_syncer' + describe OrderCycleForm do describe "save" do describe "creating a new order cycle from params" do @@ -66,10 +68,10 @@ describe OrderCycleForm do context "where I manage the order_cycle's coordinator" do let(:form) { OrderCycleForm.new(coordinated_order_cycle, params, user) } - let(:syncer_mock) { instance_double(OpenFoodNetwork::ProxyOrderSyncer, sync!: true) } + let(:syncer_mock) { instance_double(OrderManagement::Subscriptions::ProxyOrderSyncer, sync!: true) } before do - allow(OpenFoodNetwork::ProxyOrderSyncer).to receive(:new) { syncer_mock } + allow(OrderManagement::Subscriptions::ProxyOrderSyncer).to receive(:new) { syncer_mock } end context "and I add an schedule that I own, and remove another that I own" do From 3901c49af9009e0f0776762860f9cfb6c3f9c69d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 18:37:34 +0000 Subject: [PATCH 011/166] Fix rubocop issues --- .rubocop_manual_todo.yml | 2 +- .rubocop_todo.yml | 8 --- .../admin/subscriptions_controller.rb | 1 - .../subscriptions/subscription_summary.rb | 2 +- .../subscriptions/proxy_order_syncer_spec.rb | 59 +++++++++++++++---- .../subscription_summarizer_spec.rb | 4 +- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 9494595048..bd710779cc 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -101,7 +101,6 @@ Layout/LineLength: - app/services/subscriptions_count.rb - app/services/variants_stock_levels.rb - engines/web/app/helpers/web/cookies_policy_helper.rb - - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - lib/discourse/single_sign_on.rb - lib/open_food_network/available_payment_method_filter.rb - lib/open_food_network/bulk_coop_report.rb @@ -686,6 +685,7 @@ Metrics/ModuleLength: - app/helpers/spree/admin/base_helper.rb - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb + - engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb - lib/open_food_network/column_preference_defaults.rb - spec/controllers/admin/enterprises_controller_spec.rb - spec/controllers/admin/order_cycles_controller_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 1c003c0504..e498ce594a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -70,7 +70,6 @@ Lint/DuplicateHashKey: # Offense count: 4 Lint/DuplicateMethods: Exclude: - - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'lib/discourse/single_sign_on.rb' # Offense count: 10 @@ -882,9 +881,6 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/report_service.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/summarizer.rb' - - 'engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb' - - 'engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb' - - 'engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb' - 'engines/order_management/app/services/reports.rb' - 'engines/order_management/app/services/reports/authorizer.rb' - 'engines/order_management/app/services/reports/parameters/base.rb' @@ -904,9 +900,6 @@ Style/FrozenStringLiteralComment: - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total_spec.rb' - 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb' - - 'engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb' - - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summizer_spec.rb' - - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb' - 'engines/order_management/spec/spec_helper.rb' - 'engines/web/app/controllers/web/angular_templates_controller.rb' - 'engines/web/app/controllers/web/api/cookies_consent_controller.rb' @@ -1542,7 +1535,6 @@ Style/Send: Exclude: - 'app/controllers/spree/checkout_controller.rb' - 'app/models/spree/shipping_method_decorator.rb' - - 'engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb' - 'spec/controllers/admin/subscriptions_controller_spec.rb' - 'spec/controllers/checkout_controller_spec.rb' - 'spec/controllers/spree/admin/base_controller_spec.rb' diff --git a/app/controllers/admin/subscriptions_controller.rb b/app/controllers/admin/subscriptions_controller.rb index da99409469..0b3952d5a6 100644 --- a/app/controllers/admin/subscriptions_controller.rb +++ b/app/controllers/admin/subscriptions_controller.rb @@ -1,5 +1,4 @@ require 'open_food_network/permissions' -require 'open_food_network/proxy_order_syncer' module Admin class SubscriptionsController < ResourceController diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb b/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb index aa9a61c469..2faa93b6ee 100644 --- a/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb +++ b/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb @@ -3,7 +3,7 @@ module OrderManagement module Subscriptions class SubscriptionSummary - attr_reader :shop_id, :order_count, :success_count, :issues + attr_reader :shop_id, :issues def initialize(shop_id) @shop_id = shop_id diff --git a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb index ab01eddc4c..501f6fa67e 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb @@ -6,7 +6,8 @@ module OrderManagement describe "initialization" do let!(:subscription) { create(:subscription) } - it "raises an error when initialized with an object that is not a Subscription or an ActiveRecord::Relation" do + it "raises an error when initialized with an object + that is not a Subscription or an ActiveRecord::Relation" do expect{ ProxyOrderSyncer.new(subscription) }.to_not raise_error expect{ ProxyOrderSyncer.new(Subscription.where(id: subscription.id)) }.to_not raise_error expect{ ProxyOrderSyncer.new("something") }.to raise_error RuntimeError @@ -16,14 +17,46 @@ module OrderManagement describe "#sync!" do let(:now) { Time.zone.now } let(:schedule) { create(:schedule) } - let(:closed_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now) } # Closed - let(:open_oc_closes_before_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now + 59.seconds) } # Open, but closes before begins at - let(:open_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now - 1.minute, orders_close_at: now + 90.seconds) } # Open & closes between begins at and ends at - let(:upcoming_closes_before_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 59.seconds) } # Upcoming, but closes before begins at - let(:upcoming_closes_on_begins_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 1.minute) } # Upcoming & closes on begins at - let(:upcoming_closes_on_ends_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 2.minutes) } # Upcoming & closes on ends at - let(:upcoming_closes_after_ends_at_oc) { create(:simple_order_cycle, schedules: [schedule], orders_open_at: now + 30.seconds, orders_close_at: now + 121.seconds) } # Upcoming & closes after ends at - let(:subscription) { build(:subscription, schedule: schedule, begins_at: now + 1.minute, ends_at: now + 2.minutes) } + let(:closed_oc) { # Closed + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now - 1.minute, + orders_close_at: now) + } + let(:open_oc_closes_before_begins_at_oc) { # Open, but closes before begins at + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now - 1.minute, + orders_close_at: now + 59.seconds) + } + let(:open_oc) { # Open & closes between begins at and ends at + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now - 1.minute, + orders_close_at: now + 90.seconds) + } + let(:upcoming_closes_before_begins_at_oc) { # Upcoming, but closes before begins at + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now + 30.seconds, + orders_close_at: now + 59.seconds) + } + let(:upcoming_closes_on_begins_at_oc) { # Upcoming & closes on begins at + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now + 30.seconds, + orders_close_at: now + 1.minute) + } + let(:upcoming_closes_on_ends_at_oc) { # Upcoming & closes on ends at + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now + 30.seconds, + orders_close_at: now + 2.minutes) + } + let(:upcoming_closes_after_ends_at_oc) { # Upcoming & closes after ends at + create(:simple_order_cycle, schedules: [schedule], + orders_open_at: now + 30.seconds, + orders_close_at: now + 121.seconds) + } + let(:subscription) { + build(:subscription, schedule: schedule, + begins_at: now + 1.minute, + ends_at: now + 2.minutes) + } let(:proxy_orders) { subscription.reload.proxy_orders } let(:order_cycles) { proxy_orders.map(&:order_cycle) } let(:syncer) { ProxyOrderSyncer.new(subscription) } @@ -50,7 +83,7 @@ module OrderManagement end end - context "and the schedule includes an open oc that closes between begins_at and ends_at" do + context "and the schedule has an open OC that closes between begins_at and ends_at" do let(:oc) { open_oc } it "creates a new proxy order for that oc" do expect{ subscription.save! }.to change(ProxyOrder, :count).from(0).to(1) @@ -218,7 +251,9 @@ module OrderManagement end context "for an oc not included in the relevant schedule" do - let!(:proxy_order) { create(:proxy_order, subscription: subscription, order_cycle: open_oc) } + let!(:proxy_order) { + create(:proxy_order, subscription: subscription, order_cycle: open_oc) + } before do open_oc.schedule_ids = [] expect(open_oc.save!).to be true @@ -355,7 +390,7 @@ module OrderManagement end end - context "and the schedule includes an open oc that closes between begins_at and ends_at" do + context "and the schedule has an open oc that closes between begins_at and ends_at" do let!(:oc) { open_oc } it "creates a new proxy order for that oc" do expect{ syncer.sync! }.to change(ProxyOrder, :count).from(0).to(1) diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb index 26a79af4d1..2da6d1f7fb 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb @@ -16,7 +16,7 @@ module OrderManagement context "when a summary for the order's distributor doesn't already exist" do it "initializes a new summary object, and returns it" do expect(summarizer.instance_variable_get(:@summaries).count).to be 0 - summary = summarizer.send(:summary_for, order) + summary = summarizer.__send__(:summary_for, order) expect(summary.shop_id).to be 123 expect(summarizer.instance_variable_get(:@summaries).count).to be 1 end @@ -31,7 +31,7 @@ module OrderManagement it "returns the existing summary object" do expect(summarizer.instance_variable_get(:@summaries).count).to be 1 - expect(summarizer.send(:summary_for, order)).to eq summary + expect(summarizer.__send__(:summary_for, order)).to eq summary expect(summarizer.instance_variable_get(:@summaries).count).to be 1 end end From f68d0c2a0f73314d249a888e3e439868c88b01a8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 19:14:43 +0000 Subject: [PATCH 012/166] Remove Subscription from the name of the subscription summarizer and summary because it is already in the namespace --- .rubocop_manual_todo.yml | 2 +- app/jobs/subscription_confirm_job.rb | 4 ++-- app/jobs/subscription_placement_job.rb | 4 ++-- .../{subscription_summarizer.rb => summarizer.rb} | 4 ++-- .../subscriptions/{subscription_summary.rb => summary.rb} | 2 +- .../{subscription_summarizer_spec.rb => summarizer_spec.rb} | 4 ++-- .../{subscription_summary_spec.rb => summary_spec.rb} | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) rename engines/order_management/app/services/order_management/subscriptions/{subscription_summarizer.rb => summarizer.rb} (94%) rename engines/order_management/app/services/order_management/subscriptions/{subscription_summary.rb => summary.rb} (97%) rename engines/order_management/spec/services/order_management/subscriptions/{subscription_summarizer_spec.rb => summarizer_spec.rb} (97%) rename engines/order_management/spec/services/order_management/subscriptions/{subscription_summary_spec.rb => summary_spec.rb} (97%) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index bd710779cc..0ae58c725c 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -685,7 +685,7 @@ Metrics/ModuleLength: - app/helpers/spree/admin/base_helper.rb - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb - - engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb + - engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb - lib/open_food_network/column_preference_defaults.rb - spec/controllers/admin/enterprises_controller_spec.rb - spec/controllers/admin/order_cycles_controller_spec.rb diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index 9b1ae7a79f..3612b7e0d4 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -1,4 +1,4 @@ -require 'order_management/subscriptions/subscription_summarizer' +require 'order_management/subscriptions/summarizer' # Confirms orders of unconfirmed proxy orders in recently closed Order Cycles class SubscriptionConfirmJob @@ -12,7 +12,7 @@ class SubscriptionConfirmJob delegate :record_and_log_error, :send_confirmation_summary_emails, to: :summarizer def summarizer - @summarizer ||= OrderManagement::Subscriptions::SubscriptionSummarizer.new + @summarizer ||= OrderManagement::Subscriptions::Summarizer.new end def confirm_proxy_orders! diff --git a/app/jobs/subscription_placement_job.rb b/app/jobs/subscription_placement_job.rb index 8a77367217..44a4a27c75 100644 --- a/app/jobs/subscription_placement_job.rb +++ b/app/jobs/subscription_placement_job.rb @@ -1,4 +1,4 @@ -require 'order_management/subscriptions/subscription_summarizer' +require 'order_management/subscriptions/summarizer' class SubscriptionPlacementJob def perform @@ -17,7 +17,7 @@ class SubscriptionPlacementJob delegate :record_and_log_error, :send_placement_summary_emails, to: :summarizer def summarizer - @summarizer ||= OrderManagement::Subscriptions::SubscriptionSummarizer.new + @summarizer ||= OrderManagement::Subscriptions::Summarizer.new end def proxy_orders diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb b/engines/order_management/app/services/order_management/subscriptions/summarizer.rb similarity index 94% rename from engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb rename to engines/order_management/app/services/order_management/subscriptions/summarizer.rb index dbffcb96ab..0642e22044 100644 --- a/engines/order_management/app/services/order_management/subscriptions/subscription_summarizer.rb +++ b/engines/order_management/app/services/order_management/subscriptions/summarizer.rb @@ -4,7 +4,7 @@ # result of automatic processing of subscriptions for the relevant shop owners. module OrderManagement module Subscriptions - class SubscriptionSummarizer + class Summarizer def initialize @summaries = {} end @@ -48,7 +48,7 @@ module OrderManagement def summary_for(order) shop_id = order.distributor_id - @summaries[shop_id] ||= SubscriptionSummary.new(shop_id) + @summaries[shop_id] ||= Summary.new(shop_id) end end end diff --git a/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb b/engines/order_management/app/services/order_management/subscriptions/summary.rb similarity index 97% rename from engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb rename to engines/order_management/app/services/order_management/subscriptions/summary.rb index 2faa93b6ee..c37272c6d3 100644 --- a/engines/order_management/app/services/order_management/subscriptions/subscription_summary.rb +++ b/engines/order_management/app/services/order_management/subscriptions/summary.rb @@ -2,7 +2,7 @@ module OrderManagement module Subscriptions - class SubscriptionSummary + class Summary attr_reader :shop_id, :issues def initialize(shop_id) diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb similarity index 97% rename from engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb rename to engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb index 2da6d1f7fb..09013c204c 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/subscription_summarizer_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb @@ -4,9 +4,9 @@ require 'spec_helper' module OrderManagement module Subscriptions - describe SubscriptionSummarizer do + describe Summarizer do let(:order) { create(:order) } - let(:summarizer) { OrderManagement::Subscriptions::SubscriptionSummarizer.new } + let(:summarizer) { OrderManagement::Subscriptions::Summarizer.new } before { allow(Rails.logger).to receive(:info) } diff --git a/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb similarity index 97% rename from engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb rename to engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb index e24aa6449b..5e6360c542 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/subscription_summary_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/summary_spec.rb @@ -2,8 +2,8 @@ module OrderManagement module Subscriptions - describe SubscriptionSummary do - let(:summary) { OrderManagement::Subscriptions::SubscriptionSummary.new(123) } + describe Summary do + let(:summary) { OrderManagement::Subscriptions::Summary.new(123) } describe "#initialize" do it "initializes instance variables: shop_id, order_count, success_count and issues" do From 29377bbff9704110a0f615e6513379a3fbe8ff50 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 19:34:14 +0000 Subject: [PATCH 013/166] Move 5 subscriptions services from app/services to the engines/order_management/app/services --- .rubocop_manual_todo.yml | 7 +- .rubocop_todo.yml | 12 +- .../admin/order_cycles_controller.rb | 4 +- .../subscription_line_items_controller.rb | 2 +- .../admin/subscriptions_controller.rb | 2 +- .../subscription_line_item_serializer.rb | 6 +- app/services/subscription_estimator.rb | 63 --- app/services/subscription_form.rb | 34 -- app/services/subscription_validator.rb | 127 ----- app/services/subscription_variants_service.rb | 39 -- app/services/subscriptions_count.rb | 20 - config/locales/en.yml | 2 +- .../order_management/subscriptions/count.rb | 30 ++ .../subscriptions/estimator.rb | 69 +++ .../order_management/subscriptions/form.rb | 41 ++ .../subscriptions/validator.rb | 132 +++++ .../subscriptions/variants_list.rb | 46 ++ .../subscriptions/count_spec.rb | 40 ++ .../subscriptions/estimator_spec.rb | 135 +++++ .../subscriptions/form_spec.rb | 103 ++++ .../subscriptions/validator_spec.rb | 476 ++++++++++++++++++ .../subscriptions/variants_list_spec.rb | 136 +++++ .../scope_variants_for_search.rb | 2 +- spec/services/subscription_estimator_spec.rb | 129 ----- spec/services/subscription_form_spec.rb | 97 ---- spec/services/subscription_validator_spec.rb | 470 ----------------- .../subscription_variants_service_spec.rb | 130 ----- spec/services/subscriptions_count_spec.rb | 34 -- 28 files changed, 1219 insertions(+), 1169 deletions(-) delete mode 100644 app/services/subscription_estimator.rb delete mode 100644 app/services/subscription_form.rb delete mode 100644 app/services/subscription_validator.rb delete mode 100644 app/services/subscription_variants_service.rb delete mode 100644 app/services/subscriptions_count.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/count.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/estimator.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/form.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/validator.rb create mode 100644 engines/order_management/app/services/order_management/subscriptions/variants_list.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/count_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/form_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb delete mode 100644 spec/services/subscription_estimator_spec.rb delete mode 100644 spec/services/subscription_form_spec.rb delete mode 100644 spec/services/subscription_validator_spec.rb delete mode 100644 spec/services/subscription_variants_service_spec.rb delete mode 100644 spec/services/subscriptions_count_spec.rb diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 0ae58c725c..83de12879f 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -98,7 +98,6 @@ Layout/LineLength: - app/services/embedded_page_service.rb - app/services/order_cycle_form.rb - app/services/order_factory.rb - - app/services/subscriptions_count.rb - app/services/variants_stock_levels.rb - engines/web/app/helpers/web/cookies_policy_helper.rb - lib/discourse/single_sign_on.rb @@ -314,10 +313,6 @@ Layout/LineLength: - spec/services/permissions/order_spec.rb - spec/services/product_tag_rules_filterer_spec.rb - spec/services/products_renderer_spec.rb - - spec/services/subscription_estimator_spec.rb - - spec/services/subscription_form_spec.rb - - spec/services/subscription_validator_spec.rb - - spec/services/subscription_variants_service_spec.rb - spec/spec_helper.rb - spec/support/cancan_helper.rb - spec/support/delayed_job_helper.rb @@ -408,7 +403,7 @@ Metrics/AbcSize: - app/services/cart_service.rb - app/services/create_order_cycle.rb - app/services/order_syncer.rb - - app/services/subscription_validator.rb + - engines/order_management/app/services/order_management/subscriptions/validator.rb - lib/active_merchant/billing/gateways/stripe_decorator.rb - lib/active_merchant/billing/gateways/stripe_payment_intents.rb - lib/discourse/single_sign_on.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e498ce594a..984791e600 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -158,7 +158,7 @@ Naming/MethodParameterName: Exclude: - 'app/helpers/spree/admin/base_helper_decorator.rb' - 'app/helpers/spree/base_helper_decorator.rb' - - 'app/services/subscription_validator.rb' + - 'engines/order_management/app/services/order_management/subscriptions/validator.rb' - 'lib/open_food_network/reports/bulk_coop_report.rb' - 'lib/open_food_network/xero_invoices_report.rb' - 'spec/lib/open_food_network/reports/report_spec.rb' @@ -849,11 +849,6 @@ Style/FrozenStringLiteralComment: - 'app/services/reset_order_service.rb' - 'app/services/restart_checkout.rb' - 'app/services/search_orders.rb' - - 'app/services/subscription_estimator.rb' - - 'app/services/subscription_form.rb' - - 'app/services/subscription_validator.rb' - - 'app/services/subscription_variants_service.rb' - - 'app/services/subscriptions_count.rb' - 'app/services/tax_rate_finder.rb' - 'app/services/upload_sanitizer.rb' - 'app/services/variant_deleter.rb' @@ -1350,11 +1345,6 @@ Style/FrozenStringLiteralComment: - 'spec/services/reset_order_service_spec.rb' - 'spec/services/restart_checkout_spec.rb' - 'spec/services/search_orders_spec.rb' - - 'spec/services/subscription_estimator_spec.rb' - - 'spec/services/subscription_form_spec.rb' - - 'spec/services/subscription_validator_spec.rb' - - 'spec/services/subscription_variants_service_spec.rb' - - 'spec/services/subscriptions_count_spec.rb' - 'spec/services/tax_rate_finder_spec.rb' - 'spec/services/upload_sanitizer_spec.rb' - 'spec/services/variants_stock_levels_spec.rb' diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 14d075514a..4a3ad149cb 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -16,7 +16,7 @@ module Admin render_as_json @collection, ams_prefix: params[:ams_prefix], current_user: spree_current_user, - subscriptions_count: SubscriptionsCount.new(@collection) + subscriptions_count: OrderManagement::Subscriptions::Count.new(@collection) end end end @@ -74,7 +74,7 @@ module Admin render_as_json @order_cycles, ams_prefix: 'index', current_user: spree_current_user, - subscriptions_count: SubscriptionsCount.new(@collection) + subscriptions_count: OrderManagement::Subscriptions::Count.new(@collection) else order_cycle = order_cycle_set.collection.find{ |oc| oc.errors.present? } render json: { errors: order_cycle.errors.full_messages }, status: :unprocessable_entity diff --git a/app/controllers/admin/subscription_line_items_controller.rb b/app/controllers/admin/subscription_line_items_controller.rb index b3649696ac..f8e4945c26 100644 --- a/app/controllers/admin/subscription_line_items_controller.rb +++ b/app/controllers/admin/subscription_line_items_controller.rb @@ -56,7 +56,7 @@ module Admin end def variant_if_eligible(variant_id) - SubscriptionVariantsService.eligible_variants(@shop).find_by_id(variant_id) + OrderManagement::Subscriptions::VariantsList.eligible_variants(@shop).find_by_id(variant_id) end end end diff --git a/app/controllers/admin/subscriptions_controller.rb b/app/controllers/admin/subscriptions_controller.rb index 0b3952d5a6..867c9d2351 100644 --- a/app/controllers/admin/subscriptions_controller.rb +++ b/app/controllers/admin/subscriptions_controller.rb @@ -64,7 +64,7 @@ module Admin private def save_form_and_render(render_issues = true) - form = SubscriptionForm.new(@subscription, params[:subscription]) + form = OrderManagement::Subscriptions::Form.new(@subscription, params[:subscription]) unless form.save render json: { errors: form.json_errors }, status: :unprocessable_entity return diff --git a/app/serializers/api/admin/subscription_line_item_serializer.rb b/app/serializers/api/admin/subscription_line_item_serializer.rb index 34bc00c6c0..f1411e040f 100644 --- a/app/serializers/api/admin/subscription_line_item_serializer.rb +++ b/app/serializers/api/admin/subscription_line_item_serializer.rb @@ -13,9 +13,9 @@ module Api end def in_open_and_upcoming_order_cycles - SubscriptionVariantsService.in_open_and_upcoming_order_cycles?(option_or_assigned_shop, - option_or_assigned_schedule, - object.variant) + OrderManagement::Subscriptions::VariantsList.in_open_and_upcoming_order_cycles?(option_or_assigned_shop, + option_or_assigned_schedule, + object.variant) end private diff --git a/app/services/subscription_estimator.rb b/app/services/subscription_estimator.rb deleted file mode 100644 index 6e4d7b0938..0000000000 --- a/app/services/subscription_estimator.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'open_food_network/scope_variant_to_hub' - -# Responsible for estimating prices and fees for subscriptions -# Used by SubscriptionForm as part of the create/update process -# The values calculated here are intended to be persisted in the db - -class SubscriptionEstimator - def initialize(subscription) - @subscription = subscription - end - - def estimate! - assign_price_estimates - assign_fee_estimates - end - - private - - attr_accessor :subscription - - delegate :subscription_line_items, :shipping_method, :payment_method, :shop, to: :subscription - - def assign_price_estimates - subscription_line_items.each do |item| - item.price_estimate = - price_estimate_for(item.variant, item.price_estimate_was) - end - end - - def price_estimate_for(variant, fallback) - return fallback unless fee_calculator && variant - - scoper.scope(variant) - fees = fee_calculator.indexed_fees_for(variant) - (variant.price + fees).to_d - end - - def fee_calculator - return @fee_calculator unless @fee_calculator.nil? - - next_oc = subscription.schedule.andand.current_or_next_order_cycle - return nil unless shop && next_oc - - @fee_calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(shop, next_oc) - end - - def scoper - OpenFoodNetwork::ScopeVariantToHub.new(shop) - end - - def assign_fee_estimates - subscription.shipping_fee_estimate = shipping_fee_estimate - subscription.payment_fee_estimate = payment_fee_estimate - end - - def shipping_fee_estimate - shipping_method.calculator.compute(subscription) - end - - def payment_fee_estimate - payment_method.calculator.compute(subscription) - end -end diff --git a/app/services/subscription_form.rb b/app/services/subscription_form.rb deleted file mode 100644 index fa33b216b2..0000000000 --- a/app/services/subscription_form.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'order_management/subscriptions/proxy_order_syncer' - -class SubscriptionForm - attr_accessor :subscription, :params, :order_update_issues, :validator, :order_syncer, :estimator - - delegate :json_errors, :valid?, to: :validator - delegate :order_update_issues, to: :order_syncer - - def initialize(subscription, params = {}) - @subscription = subscription - @params = params - @estimator = SubscriptionEstimator.new(subscription) - @validator = SubscriptionValidator.new(subscription) - @order_syncer = OrderSyncer.new(subscription) - end - - def save - subscription.assign_attributes(params) - return false unless valid? - - subscription.transaction do - estimator.estimate! - proxy_order_syncer.sync! - order_syncer.sync! - subscription.save! - end - end - - private - - def proxy_order_syncer - OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscription) - end -end diff --git a/app/services/subscription_validator.rb b/app/services/subscription_validator.rb deleted file mode 100644 index 4cce8a3af3..0000000000 --- a/app/services/subscription_validator.rb +++ /dev/null @@ -1,127 +0,0 @@ -# Encapsulation of all of the validation logic required for subscriptions -# Public interface consists of #valid? method provided by ActiveModel::Validations -# and #json_errors which compiles a serializable hash of errors - -class SubscriptionValidator - include ActiveModel::Naming - include ActiveModel::Conversion - include ActiveModel::Validations - - attr_reader :subscription - - validates :shop, :customer, :schedule, :shipping_method, :payment_method, presence: true - validates :bill_address, :ship_address, :begins_at, presence: true - validate :shipping_method_allowed? - validate :payment_method_allowed? - validate :payment_method_type_allowed? - validate :ends_at_after_begins_at? - validate :customer_allowed? - validate :schedule_allowed? - validate :credit_card_ok? - validate :subscription_line_items_present? - validate :requested_variants_available? - - delegate :shop, :customer, :schedule, :shipping_method, :payment_method, to: :subscription - delegate :bill_address, :ship_address, :begins_at, :ends_at, to: :subscription - delegate :subscription_line_items, to: :subscription - - def initialize(subscription) - @subscription = subscription - end - - def json_errors - errors.messages.each_with_object({}) do |(k, v), errors| - errors[k] = v.map { |msg| build_msg_from(k, msg) } - end - end - - private - - def shipping_method_allowed? - return unless shipping_method - return if shipping_method.distributors.include?(shop) - - errors.add(:shipping_method, :not_available_to_shop, shop: shop.name) - end - - def payment_method_allowed? - return unless payment_method - return if payment_method.distributors.include?(shop) - - errors.add(:payment_method, :not_available_to_shop, shop: shop.name) - end - - def payment_method_type_allowed? - return unless payment_method - return if Subscription::ALLOWED_PAYMENT_METHOD_TYPES.include? payment_method.type - - errors.add(:payment_method, :invalid_type) - end - - def ends_at_after_begins_at? - # Only validates ends_at if it is present - return if begins_at.blank? || ends_at.blank? - return if ends_at > begins_at - - errors.add(:ends_at, :after_begins_at) - end - - def customer_allowed? - return unless customer - return if customer.enterprise == shop - - errors.add(:customer, :does_not_belong_to_shop, shop: shop.name) - end - - def schedule_allowed? - return unless schedule - return if schedule.coordinators.include?(shop) - - errors.add(:schedule, :not_coordinated_by_shop, shop: shop.name) - end - - def credit_card_ok? - return unless customer && payment_method - return unless stripe_payment_method?(payment_method) - return errors.add(:payment_method, :charges_not_allowed) unless customer.allow_charges - return if customer.user.andand.default_card.present? - - errors.add(:payment_method, :no_default_card) - end - - def stripe_payment_method?(payment_method) - payment_method.type == "Spree::Gateway::StripeConnect" || - payment_method.type == "Spree::Gateway::StripeSCA" - end - - def subscription_line_items_present? - return if subscription_line_items.reject(&:marked_for_destruction?).any? - - errors.add(:subscription_line_items, :at_least_one_product) - end - - def requested_variants_available? - subscription_line_items.each { |sli| verify_availability_of(sli.variant) } - end - - def verify_availability_of(variant) - return if available_variant_ids.include? variant.id - - name = "#{variant.product.name} - #{variant.full_name}" - errors.add(:subscription_line_items, :not_available, name: name) - end - - def available_variant_ids - return @available_variant_ids if @available_variant_ids.present? - - subscription_variant_ids = subscription_line_items.map(&:variant_id) - @available_variant_ids = SubscriptionVariantsService.eligible_variants(shop) - .where(id: subscription_variant_ids).pluck(:id) - end - - def build_msg_from(k, msg) - return msg[1..-1] if msg.starts_with?("^") - - errors.full_message(k, msg) - end -end diff --git a/app/services/subscription_variants_service.rb b/app/services/subscription_variants_service.rb deleted file mode 100644 index fbdef71e56..0000000000 --- a/app/services/subscription_variants_service.rb +++ /dev/null @@ -1,39 +0,0 @@ -class SubscriptionVariantsService - # Includes the following variants: - # - Variants of permitted producers - # - Variants of hub - # - Variants that are in outgoing exchanges where the hub is receiver - def self.eligible_variants(distributor) - variant_conditions = ["spree_products.supplier_id IN (?)", permitted_producer_ids(distributor)] - exchange_variant_ids = outgoing_exchange_variant_ids(distributor) - if exchange_variant_ids.present? - variant_conditions[0] << " OR spree_variants.id IN (?)" - variant_conditions << exchange_variant_ids - end - - Spree::Variant.joins(:product).where(is_master: false).where(*variant_conditions) - end - - def self.in_open_and_upcoming_order_cycles?(distributor, schedule, variant) - scope = ExchangeVariant.joins(exchange: { order_cycle: :schedules }) - .where(variant_id: variant, exchanges: { incoming: false, receiver_id: distributor }) - .merge(OrderCycle.not_closed) - scope = scope.where(schedules: { id: schedule }) - scope.any? - end - - def self.permitted_producer_ids(distributor) - other_permitted_producer_ids = EnterpriseRelationship.joins(:parent) - .permitting(distributor.id).with_permission(:add_to_order_cycle) - .merge(Enterprise.is_primary_producer) - .pluck(:parent_id) - - other_permitted_producer_ids | [distributor.id] - end - - def self.outgoing_exchange_variant_ids(distributor) - ExchangeVariant.select("DISTINCT exchange_variants.variant_id").joins(:exchange) - .where(exchanges: { incoming: false, receiver_id: distributor.id }) - .pluck(:variant_id) - end -end diff --git a/app/services/subscriptions_count.rb b/app/services/subscriptions_count.rb deleted file mode 100644 index ee1126c0d2..0000000000 --- a/app/services/subscriptions_count.rb +++ /dev/null @@ -1,20 +0,0 @@ -class SubscriptionsCount - def initialize(order_cycles) - @order_cycles = order_cycles - end - - def for(order_cycle_id) - active[order_cycle_id] || 0 - end - - private - - attr_accessor :order_cycles - - def active - return @active unless @active.nil? - return @active = [] if order_cycles.blank? - - @active ||= ProxyOrder.not_canceled.group(:order_cycle_id).where(order_cycle_id: order_cycles).count - end -end diff --git a/config/locales/en.yml b/config/locales/en.yml index 7b9c07620f..8f2e0b53b1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -74,7 +74,7 @@ en: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/engines/order_management/app/services/order_management/subscriptions/count.rb b/engines/order_management/app/services/order_management/subscriptions/count.rb new file mode 100644 index 0000000000..80f066d209 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/count.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + class Count + def initialize(order_cycles) + @order_cycles = order_cycles + end + + def for(order_cycle_id) + active[order_cycle_id] || 0 + end + + private + + attr_accessor :order_cycles + + def active + return @active unless @active.nil? + return @active = [] if order_cycles.blank? + + @active ||= ProxyOrder. + not_canceled. + group(:order_cycle_id). + where(order_cycle_id: order_cycles). + count + end + end + end +end diff --git a/engines/order_management/app/services/order_management/subscriptions/estimator.rb b/engines/order_management/app/services/order_management/subscriptions/estimator.rb new file mode 100644 index 0000000000..e358e031bf --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/estimator.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'open_food_network/scope_variant_to_hub' + +# Responsible for estimating prices and fees for subscriptions +# Used by Form as part of the create/update process +# The values calculated here are intended to be persisted in the db + +module OrderManagement + module Subscriptions + class Estimator + def initialize(subscription) + @subscription = subscription + end + + def estimate! + assign_price_estimates + assign_fee_estimates + end + + private + + attr_accessor :subscription + + delegate :subscription_line_items, :shipping_method, :payment_method, :shop, to: :subscription + + def assign_price_estimates + subscription_line_items.each do |item| + item.price_estimate = + price_estimate_for(item.variant, item.price_estimate_was) + end + end + + def price_estimate_for(variant, fallback) + return fallback unless fee_calculator && variant + + scoper.scope(variant) + fees = fee_calculator.indexed_fees_for(variant) + (variant.price + fees).to_d + end + + def fee_calculator + return @fee_calculator unless @fee_calculator.nil? + + next_oc = subscription.schedule.andand.current_or_next_order_cycle + return nil unless shop && next_oc + + @fee_calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(shop, next_oc) + end + + def scoper + OpenFoodNetwork::ScopeVariantToHub.new(shop) + end + + def assign_fee_estimates + subscription.shipping_fee_estimate = shipping_fee_estimate + subscription.payment_fee_estimate = payment_fee_estimate + end + + def shipping_fee_estimate + shipping_method.calculator.compute(subscription) + end + + def payment_fee_estimate + payment_method.calculator.compute(subscription) + end + end + end +end diff --git a/engines/order_management/app/services/order_management/subscriptions/form.rb b/engines/order_management/app/services/order_management/subscriptions/form.rb new file mode 100644 index 0000000000..02994e3b50 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/form.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'order_management/subscriptions/proxy_order_syncer' + +module OrderManagement + module Subscriptions + class Form + attr_accessor :subscription, :params, :order_update_issues, + :validator, :order_syncer, :estimator + + delegate :json_errors, :valid?, to: :validator + delegate :order_update_issues, to: :order_syncer + + def initialize(subscription, params = {}) + @subscription = subscription + @params = params + @estimator = OrderManagement::Subscriptions::Estimator.new(subscription) + @validator = OrderManagement::Subscriptions::Validator.new(subscription) + @order_syncer = OrderSyncer.new(subscription) + end + + def save + subscription.assign_attributes(params) + return false unless valid? + + subscription.transaction do + estimator.estimate! + proxy_order_syncer.sync! + order_syncer.sync! + subscription.save! + end + end + + private + + def proxy_order_syncer + OrderManagement::Subscriptions::ProxyOrderSyncer.new(subscription) + end + end + end +end diff --git a/engines/order_management/app/services/order_management/subscriptions/validator.rb b/engines/order_management/app/services/order_management/subscriptions/validator.rb new file mode 100644 index 0000000000..a8bc6b3086 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/validator.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +# Encapsulation of all of the validation logic required for subscriptions +# Public interface consists of #valid? method provided by ActiveModel::Validations +# and #json_errors which compiles a serializable hash of errors +module OrderManagement + module Subscriptions + class Validator + include ActiveModel::Naming + include ActiveModel::Conversion + include ActiveModel::Validations + + attr_reader :subscription + + validates :shop, :customer, :schedule, :shipping_method, :payment_method, presence: true + validates :bill_address, :ship_address, :begins_at, presence: true + validate :shipping_method_allowed? + validate :payment_method_allowed? + validate :payment_method_type_allowed? + validate :ends_at_after_begins_at? + validate :customer_allowed? + validate :schedule_allowed? + validate :credit_card_ok? + validate :subscription_line_items_present? + validate :requested_variants_available? + + delegate :shop, :customer, :schedule, :shipping_method, :payment_method, to: :subscription + delegate :bill_address, :ship_address, :begins_at, :ends_at, to: :subscription + delegate :subscription_line_items, to: :subscription + + def initialize(subscription) + @subscription = subscription + end + + def json_errors + errors.messages.each_with_object({}) do |(key, value), errors| + errors[key] = value.map { |msg| build_msg_from(key, msg) } + end + end + + private + + def shipping_method_allowed? + return unless shipping_method + return if shipping_method.distributors.include?(shop) + + errors.add(:shipping_method, :not_available_to_shop, shop: shop.name) + end + + def payment_method_allowed? + return unless payment_method + return if payment_method.distributors.include?(shop) + + errors.add(:payment_method, :not_available_to_shop, shop: shop.name) + end + + def payment_method_type_allowed? + return unless payment_method + return if Subscription::ALLOWED_PAYMENT_METHOD_TYPES.include? payment_method.type + + errors.add(:payment_method, :invalid_type) + end + + def ends_at_after_begins_at? + # Only validates ends_at if it is present + return if begins_at.blank? || ends_at.blank? + return if ends_at > begins_at + + errors.add(:ends_at, :after_begins_at) + end + + def customer_allowed? + return unless customer + return if customer.enterprise == shop + + errors.add(:customer, :does_not_belong_to_shop, shop: shop.name) + end + + def schedule_allowed? + return unless schedule + return if schedule.coordinators.include?(shop) + + errors.add(:schedule, :not_coordinated_by_shop, shop: shop.name) + end + + def credit_card_ok? + return unless customer && payment_method + return unless stripe_payment_method?(payment_method) + return errors.add(:payment_method, :charges_not_allowed) unless customer.allow_charges + return if customer.user.andand.default_card.present? + + errors.add(:payment_method, :no_default_card) + end + + def stripe_payment_method?(payment_method) + payment_method.type == "Spree::Gateway::StripeConnect" || + payment_method.type == "Spree::Gateway::StripeSCA" + end + + def subscription_line_items_present? + return if subscription_line_items.reject(&:marked_for_destruction?).any? + + errors.add(:subscription_line_items, :at_least_one_product) + end + + def requested_variants_available? + subscription_line_items.each { |sli| verify_availability_of(sli.variant) } + end + + def verify_availability_of(variant) + return if available_variant_ids.include? variant.id + + name = "#{variant.product.name} - #{variant.full_name}" + errors.add(:subscription_line_items, :not_available, name: name) + end + + def available_variant_ids + return @available_variant_ids if @available_variant_ids.present? + + subscription_variant_ids = subscription_line_items.map(&:variant_id) + @available_variant_ids = OrderManagement::Subscriptions::VariantsList.eligible_variants(shop) + .where(id: subscription_variant_ids).pluck(:id) + end + + def build_msg_from(key, msg) + return msg[1..-1] if msg.starts_with?("^") + + errors.full_message(key, msg) + end + end + end +end diff --git a/engines/order_management/app/services/order_management/subscriptions/variants_list.rb b/engines/order_management/app/services/order_management/subscriptions/variants_list.rb new file mode 100644 index 0000000000..5c5a3fddb3 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/variants_list.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: false + +module OrderManagement + module Subscriptions + class VariantsList + # Includes the following variants: + # - Variants of permitted producers + # - Variants of hub + # - Variants that are in outgoing exchanges where the hub is receiver + def self.eligible_variants(distributor) + variant_conditions = ["spree_products.supplier_id IN (?)", + permitted_producer_ids(distributor)] + exchange_variant_ids = outgoing_exchange_variant_ids(distributor) + if exchange_variant_ids.present? + variant_conditions[0] << " OR spree_variants.id IN (?)" + variant_conditions << exchange_variant_ids + end + + Spree::Variant.joins(:product).where(is_master: false).where(*variant_conditions) + end + + def self.in_open_and_upcoming_order_cycles?(distributor, schedule, variant) + scope = ExchangeVariant.joins(exchange: { order_cycle: :schedules }) + .where(variant_id: variant, exchanges: { incoming: false, receiver_id: distributor }) + .merge(OrderCycle.not_closed) + scope = scope.where(schedules: { id: schedule }) + scope.any? + end + + def self.permitted_producer_ids(distributor) + other_permitted_producer_ids = EnterpriseRelationship.joins(:parent) + .permitting(distributor.id).with_permission(:add_to_order_cycle) + .merge(Enterprise.is_primary_producer) + .pluck(:parent_id) + + other_permitted_producer_ids | [distributor.id] + end + + def self.outgoing_exchange_variant_ids(distributor) + ExchangeVariant.select("DISTINCT exchange_variants.variant_id").joins(:exchange) + .where(exchanges: { incoming: false, receiver_id: distributor.id }) + .pluck(:variant_id) + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb new file mode 100644 index 0000000000..14b5a8c041 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/count_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + describe Count do + let(:oc1) { create(:simple_order_cycle) } + let(:oc2) { create(:simple_order_cycle) } + let(:subscriptions_count) { Count.new(order_cycles) } + + describe "#for" do + context "when the collection has not been set" do + let(:order_cycles) { nil } + it "returns 0" do + expect(subscriptions_count.for(oc1.id)).to eq 0 + end + end + + context "when the collection has been set" do + let(:order_cycles) { OrderCycle.where(id: [oc1]) } + let!(:po1) { create(:proxy_order, order_cycle: oc1) } + let!(:po2) { create(:proxy_order, order_cycle: oc1) } + let!(:po3) { create(:proxy_order, order_cycle: oc2) } + + context "but the requested id is not present in the list of order cycles provided" do + it "returns 0" do + # Note that po3 applies to oc2, but oc2 in not in the collection + expect(subscriptions_count.for(oc2.id)).to eq 0 + end + end + + context "and the requested id is present in the list of order cycles provided" do + it "returns a count of active proxy orders associated with the requested order cycle" do + expect(subscriptions_count.for(oc1.id)).to eq 2 + end + end + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb new file mode 100644 index 0000000000..78020f6578 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + describe Estimator do + describe "estimating prices for subscription line items" do + let!(:subscription) { create(:subscription, with_items: true) } + let!(:sli1) { subscription.subscription_line_items.first } + let!(:sli2) { subscription.subscription_line_items.second } + let!(:sli3) { subscription.subscription_line_items.third } + let(:estimator) { Estimator.new(subscription) } + + before do + sli1.update_attributes(price_estimate: 4.0) + sli2.update_attributes(price_estimate: 5.0) + sli3.update_attributes(price_estimate: 6.0) + sli1.variant.update_attributes(price: 1.0) + sli2.variant.update_attributes(price: 2.0) + sli3.variant.update_attributes(price: 3.0) + + # Simulating assignment of attrs from params + sli1.assign_attributes(price_estimate: 7.0) + sli2.assign_attributes(price_estimate: 8.0) + sli3.assign_attributes(price_estimate: 9.0) + end + + context "when a insufficient information exists to calculate price estimates" do + before do + # This might be because a shop has not been assigned yet, or no + # current or future order cycles exist for the schedule + allow(estimator).to receive(:fee_calculator) { nil } + end + + it "resets the price estimates for all items" do + estimator.estimate! + expect(sli1.price_estimate).to eq 4.0 + expect(sli2.price_estimate).to eq 5.0 + expect(sli3.price_estimate).to eq 6.0 + end + end + + context "when sufficient information to calculate price estimates exists" do + let(:fee_calculator) { instance_double(OpenFoodNetwork::EnterpriseFeeCalculator) } + + before do + allow(estimator).to receive(:fee_calculator) { fee_calculator } + allow(fee_calculator).to receive(:indexed_fees_for).with(sli1.variant) { 1.0 } + allow(fee_calculator).to receive(:indexed_fees_for).with(sli2.variant) { 0.0 } + allow(fee_calculator).to receive(:indexed_fees_for).with(sli3.variant) { 3.0 } + end + + context "when no variant overrides apply" do + it "recalculates price_estimates based on variant prices and associated fees" do + estimator.estimate! + expect(sli1.price_estimate).to eq 2.0 + expect(sli2.price_estimate).to eq 2.0 + expect(sli3.price_estimate).to eq 6.0 + end + end + + context "when variant overrides apply" do + let!(:override1) { create(:variant_override, hub: subscription.shop, variant: sli1.variant, price: 1.2) } + let!(:override2) { create(:variant_override, hub: subscription.shop, variant: sli2.variant, price: 2.3) } + + it "recalculates price_estimates based on override prices and associated fees" do + estimator.estimate! + expect(sli1.price_estimate).to eq 2.2 + expect(sli2.price_estimate).to eq 2.3 + expect(sli3.price_estimate).to eq 6.0 + end + end + end + end + + describe "updating estimates for shipping and payment fees" do + let(:subscription) { create(:subscription, with_items: true, payment_method: payment_method, shipping_method: shipping_method) } + let!(:sli1) { subscription.subscription_line_items.first } + let!(:sli2) { subscription.subscription_line_items.second } + let!(:sli3) { subscription.subscription_line_items.third } + let(:estimator) { OrderManagement::Subscriptions::Estimator.new(subscription) } + + before do + allow(estimator).to receive(:assign_price_estimates) + sli1.update_attributes(price_estimate: 4.0) + sli2.update_attributes(price_estimate: 5.0) + sli3.update_attributes(price_estimate: 6.0) + end + + context "using flat rate calculators" do + let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 12.34)) } + let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 9.12)) } + + it "calculates fees based on the rates provided" do + estimator.estimate! + expect(subscription.shipping_fee_estimate.to_f).to eq 12.34 + expect(subscription.payment_fee_estimate.to_f).to eq 9.12 + end + end + + context "using flat percent item total calculators" do + let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)) } + let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 20)) } + + it "calculates fees based on the estimated item total and percentage provided" do + estimator.estimate! + expect(subscription.shipping_fee_estimate.to_f).to eq 1.5 + expect(subscription.payment_fee_estimate.to_f).to eq 3.0 + end + end + + context "using flat percent per item calculators" do + let(:shipping_method) { create(:shipping_method, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 5)) } + let(:payment_method) { create(:payment_method, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 10)) } + + it "calculates fees based on the estimated item prices and percentage provided" do + estimator.estimate! + expect(subscription.shipping_fee_estimate.to_f).to eq 0.75 + expect(subscription.payment_fee_estimate.to_f).to eq 1.5 + end + end + + context "using per item calculators" do + let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::PerItem.new(preferred_amount: 1.2)) } + let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::PerItem.new(preferred_amount: 0.3)) } + + it "calculates fees based on the number of items and rate provided" do + estimator.estimate! + expect(subscription.shipping_fee_estimate.to_f).to eq 3.6 + expect(subscription.payment_fee_estimate.to_f).to eq 0.9 + end + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb new file mode 100644 index 0000000000..f9c0798671 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module OrderManagement + module Subscriptions + describe Form do + describe "creating a new subscription" do + let!(:shop) { create(:distributor_enterprise) } + let!(:customer) { create(:customer, enterprise: shop) } + let!(:product1) { create(:product, supplier: shop) } + let!(:product2) { create(:product, supplier: shop) } + let!(:product3) { create(:product, supplier: shop) } + let!(:variant1) { create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) } + let!(:variant2) { create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) } + let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], on_hand: 1) } + let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) } + let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.ago, orders_close_at: 2.days.ago) } + let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.ago, orders_close_at: 5.days.from_now) } + let!(:order_cycle3) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 5.days.from_now, orders_close_at: 12.days.from_now) } + let!(:order_cycle4) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 12.days.from_now, orders_close_at: 19.days.from_now) } + let!(:outgoing_exchange1) { order_cycle1.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } + let!(:outgoing_exchange2) { order_cycle2.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } + let!(:outgoing_exchange3) { order_cycle3.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant3], enterprise_fees: []) } + let!(:outgoing_exchange4) { order_cycle4.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } + let!(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2, order_cycle3, order_cycle4]) } + let!(:payment_method) { create(:payment_method, distributors: [shop]) } + let!(:shipping_method) { create(:shipping_method, distributors: [shop]) } + let!(:address) { create(:address) } + let(:subscription) { Subscription.new } + + let!(:params) { + { + shop_id: shop.id, + customer_id: customer.id, + schedule_id: schedule.id, + bill_address_attributes: address.clone.attributes, + ship_address_attributes: address.clone.attributes, + payment_method_id: payment_method.id, + shipping_method_id: shipping_method.id, + begins_at: 4.days.ago, + ends_at: 14.days.from_now, + subscription_line_items_attributes: [ + { variant_id: variant1.id, quantity: 1, price_estimate: 7.0 }, + { variant_id: variant2.id, quantity: 2, price_estimate: 8.0 }, + { variant_id: variant3.id, quantity: 3, price_estimate: 9.0 } + ] + } + } + + let(:form) { OrderManagement::Subscriptions::Form.new(subscription, params) } + + it "creates orders for each order cycle in the schedule" do + expect(form.save).to be true + + expect(subscription.proxy_orders.count).to be 2 + expect(subscription.subscription_line_items.count).to be 3 + expect(subscription.subscription_line_items[0].price_estimate).to eq 13.75 + expect(subscription.subscription_line_items[1].price_estimate).to eq 7.75 + expect(subscription.subscription_line_items[2].price_estimate).to eq 4.25 + + # This order cycle has already closed, so no order is initialized + proxy_order1 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle1.id) + expect(proxy_order1).to be nil + + # Currently open order cycle, closing after begins_at and before ends_at + proxy_order2 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle2.id) + expect(proxy_order2).to be_a ProxyOrder + order2 = proxy_order2.initialise_order! + expect(order2.line_items.count).to eq 3 + expect(order2.line_items.find_by_variant_id(variant3.id).quantity).to be 3 + expect(order2.shipments.count).to eq 1 + expect(order2.shipments.first.shipping_method).to eq shipping_method + expect(order2.payments.count).to eq 1 + expect(order2.payments.first.payment_method).to eq payment_method + expect(order2.payments.first.state).to eq 'checkout' + expect(order2.total).to eq 42 + expect(order2.completed?).to be false + + # Future order cycle, closing after begins_at and before ends_at + # Adds line items for variants that aren't yet available from the order cycle + proxy_order3 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle3.id) + expect(proxy_order3).to be_a ProxyOrder + order3 = proxy_order3.initialise_order! + expect(order3).to be_a Spree::Order + expect(order3.line_items.count).to eq 3 + expect(order2.line_items.find_by_variant_id(variant3.id).quantity).to be 3 + expect(order3.shipments.count).to eq 1 + expect(order3.shipments.first.shipping_method).to eq shipping_method + expect(order3.payments.count).to eq 1 + expect(order3.payments.first.payment_method).to eq payment_method + expect(order3.payments.first.state).to eq 'checkout' + expect(order3.total).to eq 31.50 + expect(order3.completed?).to be false + + # Future order cycle closing after ends_at + proxy_order4 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle4.id) + expect(proxy_order4).to be nil + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb new file mode 100644 index 0000000000..a072262b47 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb @@ -0,0 +1,476 @@ +# frozen_string_literal: true + +require "spec_helper" + +module OrderManagement + module Subscriptions + describe Validator do + let(:owner) { create(:user) } + let(:shop) { create(:enterprise, name: "Shop", owner: owner) } + + describe "delegation" do + let(:subscription) { create(:subscription, shop: shop) } + let(:validator) { Validator.new(subscription) } + + it "delegates to subscription" do + expect(validator.shop).to eq subscription.shop + expect(validator.customer).to eq subscription.customer + expect(validator.schedule).to eq subscription.schedule + expect(validator.shipping_method).to eq subscription.shipping_method + expect(validator.payment_method).to eq subscription.payment_method + expect(validator.bill_address).to eq subscription.bill_address + expect(validator.ship_address).to eq subscription.ship_address + expect(validator.begins_at).to eq subscription.begins_at + expect(validator.ends_at).to eq subscription.ends_at + end + end + + describe "validations" do + let(:subscription_stubs) do + { + shop: shop, + customer: true, + schedule: true, + shipping_method: true, + payment_method: true, + bill_address: true, + ship_address: true, + begins_at: true, + ends_at: true, + } + end + + let(:validation_stubs) do + { + shipping_method_allowed?: true, + payment_method_allowed?: true, + payment_method_type_allowed?: true, + ends_at_after_begins_at?: true, + customer_allowed?: true, + schedule_allowed?: true, + credit_card_ok?: true, + subscription_line_items_present?: true, + requested_variants_available?: true + } + end + + let(:subscription) { instance_double(Subscription, subscription_stubs) } + let(:validator) { OrderManagement::Subscriptions::Validator.new(subscription) } + + def stub_validations(validator, methods) + methods.each do |name, value| + allow(validator).to receive(name) { value } + end + end + + describe "shipping method validation" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:shipping_method)) } + before { stub_validations(validator, validation_stubs.except(:shipping_method_allowed?)) } + + context "when no shipping method is present" do + before { expect(subscription).to receive(:shipping_method).at_least(:once) { nil } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:shipping_method]).to_not be_empty + end + end + + context "when a shipping method is present" do + let(:shipping_method) { instance_double(Spree::ShippingMethod, distributors: [shop]) } + before { expect(subscription).to receive(:shipping_method).at_least(:once) { shipping_method } } + + context "and the shipping method is not associated with the shop" do + before { allow(shipping_method).to receive(:distributors) { [double(:enterprise)] } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:shipping_method]).to_not be_empty + end + end + + context "and the shipping method is associated with the shop" do + before { allow(shipping_method).to receive(:distributors) { [shop] } } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:shipping_method]).to be_empty + end + end + end + end + + describe "payment method validation" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } + before { stub_validations(validator, validation_stubs.except(:payment_method_allowed?)) } + + context "when no payment method is present" do + before { expect(subscription).to receive(:payment_method).at_least(:once) { nil } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:payment_method]).to_not be_empty + end + end + + context "when a payment method is present" do + let(:payment_method) { instance_double(Spree::PaymentMethod, distributors: [shop]) } + before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } + + context "and the payment method is not associated with the shop" do + before { allow(payment_method).to receive(:distributors) { [double(:enterprise)] } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:payment_method]).to_not be_empty + end + end + + context "and the payment method is associated with the shop" do + before { allow(payment_method).to receive(:distributors) { [shop] } } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:payment_method]).to be_empty + end + end + end + end + + describe "payment method type validation" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } + before { stub_validations(validator, validation_stubs.except(:payment_method_type_allowed?)) } + + context "when a payment method is present" do + let(:payment_method) { instance_double(Spree::PaymentMethod, distributors: [shop]) } + before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } + + context "and the payment method type is not in the approved list" do + before { allow(payment_method).to receive(:type) { "Blah" } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:payment_method]).to_not be_empty + end + end + + context "and the payment method is in the approved list" do + let(:approved_type) { Subscription::ALLOWED_PAYMENT_METHOD_TYPES.first } + before { allow(payment_method).to receive(:type) { approved_type } } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:payment_method]).to be_empty + end + end + end + end + + describe "dates" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:begins_at, :ends_at)) } + before { stub_validations(validator, validation_stubs.except(:ends_at_after_begins_at?)) } + before { expect(subscription).to receive(:begins_at).at_least(:once) { begins_at } } + + context "when no begins_at is present" do + let(:begins_at) { nil } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:begins_at]).to_not be_empty + end + end + + context "when a start date is present" do + let(:begins_at) { Time.zone.today } + before { expect(subscription).to receive(:ends_at).at_least(:once) { ends_at } } + + context "when no ends_at is present" do + let(:ends_at) { nil } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:ends_at]).to be_empty + end + end + + context "when ends_at is equal to begins_at" do + let(:ends_at) { Time.zone.today } + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:ends_at]).to_not be_empty + end + end + + context "when ends_at is before begins_at" do + let(:ends_at) { Time.zone.today - 1.day } + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:ends_at]).to_not be_empty + end + end + + context "when ends_at is after begins_at" do + let(:ends_at) { Time.zone.today + 1.day } + it "adds an error and returns false" do + expect(validator.valid?).to be true + expect(validator.errors[:ends_at]).to be_empty + end + end + end + end + + describe "addresses" do + before { stub_validations(validator, validation_stubs) } + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:bill_address, :ship_address)) } + before { expect(subscription).to receive(:bill_address).at_least(:once) { bill_address } } + before { expect(subscription).to receive(:ship_address).at_least(:once) { ship_address } } + + context "when bill_address and ship_address are not present" do + let(:bill_address) { nil } + let(:ship_address) { nil } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:bill_address]).to_not be_empty + expect(validator.errors[:ship_address]).to_not be_empty + end + end + + context "when bill_address and ship_address are present" do + let(:bill_address) { instance_double(Spree::Address) } + let(:ship_address) { instance_double(Spree::Address) } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:bill_address]).to be_empty + expect(validator.errors[:ship_address]).to be_empty + end + end + end + + describe "customer" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:customer)) } + before { stub_validations(validator, validation_stubs.except(:customer_allowed?)) } + before { expect(subscription).to receive(:customer).at_least(:once) { customer } } + + context "when no customer is present" do + let(:customer) { nil } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:customer]).to_not be_empty + end + end + + context "when a customer is present" do + let(:customer) { instance_double(Customer) } + + context "and the customer is not associated with the shop" do + before { allow(customer).to receive(:enterprise) { double(:enterprise) } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:customer]).to_not be_empty + end + end + + context "and the customer is associated with the shop" do + before { allow(customer).to receive(:enterprise) { shop } } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:customer]).to be_empty + end + end + end + end + + describe "schedule" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:schedule)) } + before { stub_validations(validator, validation_stubs.except(:schedule_allowed?)) } + before { expect(subscription).to receive(:schedule).at_least(:once) { schedule } } + + context "when no schedule is present" do + let(:schedule) { nil } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:schedule]).to_not be_empty + end + end + + context "when a schedule is present" do + let(:schedule) { instance_double(Schedule) } + + context "and the schedule is not associated with the shop" do + before { allow(schedule).to receive(:coordinators) { [double(:enterprise)] } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:schedule]).to_not be_empty + end + end + + context "and the schedule is associated with the shop" do + before { allow(schedule).to receive(:coordinators) { [shop] } } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:schedule]).to be_empty + end + end + end + end + + describe "credit card" do + let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } + before { stub_validations(validator, validation_stubs.except(:credit_card_ok?)) } + before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } + + context "when using a Check payment method" do + let(:payment_method) { instance_double(Spree::PaymentMethod, type: "Spree::PaymentMethod::Check") } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:subscription_line_items]).to be_empty + end + end + + context "when using the StripeConnect payment gateway" do + let(:payment_method) { instance_double(Spree::PaymentMethod, type: "Spree::Gateway::StripeConnect") } + before { expect(subscription).to receive(:customer).at_least(:once) { customer } } + + context "when the customer does not allow charges" do + let(:customer) { instance_double(Customer, allow_charges: false) } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:payment_method]).to_not be_empty + end + end + + context "when the customer allows charges" do + let(:customer) { instance_double(Customer, allow_charges: true) } + + context "and the customer is not associated with a user" do + before { allow(customer).to receive(:user) { nil } } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:payment_method]).to_not be_empty + end + end + + context "and the customer is associated with a user" do + before { expect(customer).to receive(:user).once { user } } + + context "and the user has no default card set" do + let(:user) { instance_double(Spree::User, default_card: nil) } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:payment_method]).to_not be_empty + end + end + + context "and the user has a default card set" do + let(:user) { instance_double(Spree::User, default_card: 'some card') } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:payment_method]).to be_empty + end + end + end + end + end + end + + describe "subscription line items" do + let(:subscription) { instance_double(Subscription, subscription_stubs) } + before { stub_validations(validator, validation_stubs.except(:subscription_line_items_present?)) } + before { expect(subscription).to receive(:subscription_line_items).at_least(:once) { subscription_line_items } } + + context "when no subscription line items are present" do + let(:subscription_line_items) { [] } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:subscription_line_items]).to_not be_empty + end + end + + context "when subscription line items are present but they are all marked for destruction" do + let(:subscription_line_item1) { instance_double(SubscriptionLineItem, marked_for_destruction?: true) } + let(:subscription_line_items) { [subscription_line_item1] } + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:subscription_line_items]).to_not be_empty + end + end + + context "when subscription line items are present and some and not marked for destruction" do + let(:subscription_line_item1) { instance_double(SubscriptionLineItem, marked_for_destruction?: true) } + let(:subscription_line_item2) { instance_double(SubscriptionLineItem, marked_for_destruction?: false) } + let(:subscription_line_items) { [subscription_line_item1, subscription_line_item2] } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:subscription_line_items]).to be_empty + end + end + end + + describe "variant availability" do + let(:subscription) { instance_double(Subscription, subscription_stubs) } + before { stub_validations(validator, validation_stubs.except(:requested_variants_available?)) } + before { expect(subscription).to receive(:subscription_line_items).at_least(:once) { subscription_line_items } } + + context "when no subscription line items are present" do + let(:subscription_line_items) { [] } + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:subscription_line_items]).to be_empty + end + end + + context "when subscription line items are present" do + let(:variant1) { instance_double(Spree::Variant, id: 1) } + let(:variant2) { instance_double(Spree::Variant, id: 2) } + let(:subscription_line_item1) { instance_double(SubscriptionLineItem, variant: variant1) } + let(:subscription_line_item2) { instance_double(SubscriptionLineItem, variant: variant2) } + let(:subscription_line_items) { [subscription_line_item1] } + + context "but some variants are unavailable" do + let(:product) { instance_double(Spree::Product, name: "some_name") } + + before do + allow(validator).to receive(:available_variant_ids) { [variant2.id] } + allow(variant1).to receive(:product) { product } + allow(variant1).to receive(:full_name) { "some name" } + end + + it "adds an error and returns false" do + expect(validator.valid?).to be false + expect(validator.errors[:subscription_line_items]).to_not be_empty + end + end + + context "and all requested variants are available" do + before do + allow(validator).to receive(:available_variant_ids) { [variant1.id, variant2.id] } + end + + it "returns true" do + expect(validator.valid?).to be true + expect(validator.errors[:subscription_line_items]).to be_empty + end + end + end + end + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb new file mode 100644 index 0000000000..8dc97b128e --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +require "spec_helper" + +module OrderManagement + module Subscriptions + describe VariantsList do + describe "variant eligibility for subscription" do + let!(:shop) { create(:distributor_enterprise) } + let!(:producer) { create(:supplier_enterprise) } + let!(:product) { create(:product, supplier: producer) } + let!(:variant) { product.variants.first } + + let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } + let!(:subscription) { create(:subscription, shop: shop, schedule: schedule) } + let!(:subscription_line_item) do + create(:subscription_line_item, subscription: subscription, variant: variant) + end + + let(:current_order_cycle) do + create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.week.ago, + orders_close_at: 1.week.from_now) + end + + let(:future_order_cycle) do + create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.week.from_now, + orders_close_at: 2.weeks.from_now) + end + + let(:past_order_cycle) do + create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.weeks.ago, + orders_close_at: 1.week.ago) + end + + let!(:order_cycle) { current_order_cycle } + + context "if the shop is the supplier for the product" do + let!(:producer) { shop } + + it "is eligible" do + expect(described_class.eligible_variants(shop)).to include(variant) + end + end + + context "if the supplier is permitted for the shop" do + let!(:enterprise_relationship) { create(:enterprise_relationship, child: shop, parent: product.supplier, permissions_list: [:add_to_order_cycle]) } + + it "is eligible" do + expect(described_class.eligible_variants(shop)).to include(variant) + end + end + + context "if the variant is involved in an exchange" do + let!(:order_cycle) { create(:simple_order_cycle, coordinator: shop) } + let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } + + context "if it is an incoming exchange where the shop is the receiver" do + let!(:incoming_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: true, variants: [variant]) } + + it "is not eligible" do + expect(described_class.eligible_variants(shop)).to_not include(variant) + end + end + + context "if it is an outgoing exchange where the shop is the receiver" do + let!(:outgoing_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: false, variants: [variant]) } + + context "if the order cycle is currently open" do + let!(:order_cycle) { current_order_cycle } + + it "is eligible" do + expect(described_class.eligible_variants(shop)).to include(variant) + end + end + + context "if the order cycle opens in the future" do + let!(:order_cycle) { future_order_cycle } + + it "is eligible" do + expect(described_class.eligible_variants(shop)).to include(variant) + end + end + + context "if the order cycle closed in the past" do + let!(:order_cycle) { past_order_cycle } + + it "is eligible" do + expect(described_class.eligible_variants(shop)).to include(variant) + end + end + end + end + + context "if the variant is unrelated" do + it "is not eligible" do + expect(described_class.eligible_variants(shop)).to_not include(variant) + end + end + end + + describe "checking if variant in open and upcoming order cycles" do + let!(:shop) { create(:enterprise) } + let!(:product) { create(:product) } + let!(:variant) { product.variants.first } + let!(:schedule) { create(:schedule) } + + context "if the variant is involved in an exchange" do + let!(:order_cycle) { create(:simple_order_cycle, coordinator: shop) } + let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } + + context "if it is an incoming exchange where the shop is the receiver" do + let!(:incoming_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: true, variants: [variant]) } + + it "is is false" do + expect(described_class).not_to be_in_open_and_upcoming_order_cycles(shop, schedule, variant) + end + end + + context "if it is an outgoing exchange where the shop is the receiver" do + let!(:outgoing_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: false, variants: [variant]) } + + it "is true" do + expect(described_class).to be_in_open_and_upcoming_order_cycles(shop, schedule, variant) + end + end + end + + context "if the variant is unrelated" do + it "is false" do + expect(described_class).to_not be_in_open_and_upcoming_order_cycles(shop, schedule, variant) + end + end + end + end + end +end diff --git a/lib/open_food_network/scope_variants_for_search.rb b/lib/open_food_network/scope_variants_for_search.rb index ddf1d48771..5d16eafefe 100644 --- a/lib/open_food_network/scope_variants_for_search.rb +++ b/lib/open_food_network/scope_variants_for_search.rb @@ -61,7 +61,7 @@ module OpenFoodNetwork end def scope_to_eligible_for_subscriptions_in_distributor - eligible_variants_scope = SubscriptionVariantsService.eligible_variants(distributor) + eligible_variants_scope = OrderManagement::Subscriptions::VariantsList.eligible_variants(distributor) @variants = @variants.merge(eligible_variants_scope) scope_variants_to_distributor(@variants, distributor) end diff --git a/spec/services/subscription_estimator_spec.rb b/spec/services/subscription_estimator_spec.rb deleted file mode 100644 index 5230057888..0000000000 --- a/spec/services/subscription_estimator_spec.rb +++ /dev/null @@ -1,129 +0,0 @@ -describe SubscriptionEstimator do - describe "estimating prices for subscription line items" do - let!(:subscription) { create(:subscription, with_items: true) } - let!(:sli1) { subscription.subscription_line_items.first } - let!(:sli2) { subscription.subscription_line_items.second } - let!(:sli3) { subscription.subscription_line_items.third } - let(:estimator) { SubscriptionEstimator.new(subscription) } - - before do - sli1.update_attributes(price_estimate: 4.0) - sli2.update_attributes(price_estimate: 5.0) - sli3.update_attributes(price_estimate: 6.0) - sli1.variant.update_attributes(price: 1.0) - sli2.variant.update_attributes(price: 2.0) - sli3.variant.update_attributes(price: 3.0) - - # Simulating assignment of attrs from params - sli1.assign_attributes(price_estimate: 7.0) - sli2.assign_attributes(price_estimate: 8.0) - sli3.assign_attributes(price_estimate: 9.0) - end - - context "when a insufficient information exists to calculate price estimates" do - before do - # This might be because a shop has not been assigned yet, or no - # current or future order cycles exist for the schedule - allow(estimator).to receive(:fee_calculator) { nil } - end - - it "resets the price estimates for all items" do - estimator.estimate! - expect(sli1.price_estimate).to eq 4.0 - expect(sli2.price_estimate).to eq 5.0 - expect(sli3.price_estimate).to eq 6.0 - end - end - - context "when sufficient information to calculate price estimates exists" do - let(:fee_calculator) { instance_double(OpenFoodNetwork::EnterpriseFeeCalculator) } - - before do - allow(estimator).to receive(:fee_calculator) { fee_calculator } - allow(fee_calculator).to receive(:indexed_fees_for).with(sli1.variant) { 1.0 } - allow(fee_calculator).to receive(:indexed_fees_for).with(sli2.variant) { 0.0 } - allow(fee_calculator).to receive(:indexed_fees_for).with(sli3.variant) { 3.0 } - end - - context "when no variant overrides apply" do - it "recalculates price_estimates based on variant prices and associated fees" do - estimator.estimate! - expect(sli1.price_estimate).to eq 2.0 - expect(sli2.price_estimate).to eq 2.0 - expect(sli3.price_estimate).to eq 6.0 - end - end - - context "when variant overrides apply" do - let!(:override1) { create(:variant_override, hub: subscription.shop, variant: sli1.variant, price: 1.2) } - let!(:override2) { create(:variant_override, hub: subscription.shop, variant: sli2.variant, price: 2.3) } - - it "recalculates price_estimates based on override prices and associated fees" do - estimator.estimate! - expect(sli1.price_estimate).to eq 2.2 - expect(sli2.price_estimate).to eq 2.3 - expect(sli3.price_estimate).to eq 6.0 - end - end - end - end - - describe "updating estimates for shipping and payment fees" do - let(:subscription) { create(:subscription, with_items: true, payment_method: payment_method, shipping_method: shipping_method) } - let!(:sli1) { subscription.subscription_line_items.first } - let!(:sli2) { subscription.subscription_line_items.second } - let!(:sli3) { subscription.subscription_line_items.third } - let(:estimator) { SubscriptionEstimator.new(subscription) } - - before do - allow(estimator).to receive(:assign_price_estimates) - sli1.update_attributes(price_estimate: 4.0) - sli2.update_attributes(price_estimate: 5.0) - sli3.update_attributes(price_estimate: 6.0) - end - - context "using flat rate calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 12.34)) } - let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 9.12)) } - - it "calculates fees based on the rates provided" do - estimator.estimate! - expect(subscription.shipping_fee_estimate.to_f).to eq 12.34 - expect(subscription.payment_fee_estimate.to_f).to eq 9.12 - end - end - - context "using flat percent item total calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)) } - let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 20)) } - - it "calculates fees based on the estimated item total and percentage provided" do - estimator.estimate! - expect(subscription.shipping_fee_estimate.to_f).to eq 1.5 - expect(subscription.payment_fee_estimate.to_f).to eq 3.0 - end - end - - context "using flat percent per item calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 5)) } - let(:payment_method) { create(:payment_method, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 10)) } - - it "calculates fees based on the estimated item prices and percentage provided" do - estimator.estimate! - expect(subscription.shipping_fee_estimate.to_f).to eq 0.75 - expect(subscription.payment_fee_estimate.to_f).to eq 1.5 - end - end - - context "using per item calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::PerItem.new(preferred_amount: 1.2)) } - let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::PerItem.new(preferred_amount: 0.3)) } - - it "calculates fees based on the number of items and rate provided" do - estimator.estimate! - expect(subscription.shipping_fee_estimate.to_f).to eq 3.6 - expect(subscription.payment_fee_estimate.to_f).to eq 0.9 - end - end - end -end diff --git a/spec/services/subscription_form_spec.rb b/spec/services/subscription_form_spec.rb deleted file mode 100644 index 9a06ef7164..0000000000 --- a/spec/services/subscription_form_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -require 'spec_helper' - -describe SubscriptionForm do - describe "creating a new subscription" do - let!(:shop) { create(:distributor_enterprise) } - let!(:customer) { create(:customer, enterprise: shop) } - let!(:product1) { create(:product, supplier: shop) } - let!(:product2) { create(:product, supplier: shop) } - let!(:product3) { create(:product, supplier: shop) } - let!(:variant1) { create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) } - let!(:variant2) { create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) } - let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], on_hand: 1) } - let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) } - let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.ago, orders_close_at: 2.days.ago) } - let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.ago, orders_close_at: 5.days.from_now) } - let!(:order_cycle3) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 5.days.from_now, orders_close_at: 12.days.from_now) } - let!(:order_cycle4) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 12.days.from_now, orders_close_at: 19.days.from_now) } - let!(:outgoing_exchange1) { order_cycle1.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:outgoing_exchange2) { order_cycle2.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:outgoing_exchange3) { order_cycle3.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant3], enterprise_fees: []) } - let!(:outgoing_exchange4) { order_cycle4.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2, order_cycle3, order_cycle4]) } - let!(:payment_method) { create(:payment_method, distributors: [shop]) } - let!(:shipping_method) { create(:shipping_method, distributors: [shop]) } - let!(:address) { create(:address) } - let(:subscription) { Subscription.new } - - let!(:params) { - { - shop_id: shop.id, - customer_id: customer.id, - schedule_id: schedule.id, - bill_address_attributes: address.clone.attributes, - ship_address_attributes: address.clone.attributes, - payment_method_id: payment_method.id, - shipping_method_id: shipping_method.id, - begins_at: 4.days.ago, - ends_at: 14.days.from_now, - subscription_line_items_attributes: [ - { variant_id: variant1.id, quantity: 1, price_estimate: 7.0 }, - { variant_id: variant2.id, quantity: 2, price_estimate: 8.0 }, - { variant_id: variant3.id, quantity: 3, price_estimate: 9.0 } - ] - } - } - - let(:form) { SubscriptionForm.new(subscription, params) } - - it "creates orders for each order cycle in the schedule" do - expect(form.save).to be true - - expect(subscription.proxy_orders.count).to be 2 - expect(subscription.subscription_line_items.count).to be 3 - expect(subscription.subscription_line_items[0].price_estimate).to eq 13.75 - expect(subscription.subscription_line_items[1].price_estimate).to eq 7.75 - expect(subscription.subscription_line_items[2].price_estimate).to eq 4.25 - - # This order cycle has already closed, so no order is initialized - proxy_order1 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle1.id) - expect(proxy_order1).to be nil - - # Currently open order cycle, closing after begins_at and before ends_at - proxy_order2 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle2.id) - expect(proxy_order2).to be_a ProxyOrder - order2 = proxy_order2.initialise_order! - expect(order2.line_items.count).to eq 3 - expect(order2.line_items.find_by_variant_id(variant3.id).quantity).to be 3 - expect(order2.shipments.count).to eq 1 - expect(order2.shipments.first.shipping_method).to eq shipping_method - expect(order2.payments.count).to eq 1 - expect(order2.payments.first.payment_method).to eq payment_method - expect(order2.payments.first.state).to eq 'checkout' - expect(order2.total).to eq 42 - expect(order2.completed?).to be false - - # Future order cycle, closing after begins_at and before ends_at - # Adds line items for variants that aren't yet available from the order cycle - proxy_order3 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle3.id) - expect(proxy_order3).to be_a ProxyOrder - order3 = proxy_order3.initialise_order! - expect(order3).to be_a Spree::Order - expect(order3.line_items.count).to eq 3 - expect(order2.line_items.find_by_variant_id(variant3.id).quantity).to be 3 - expect(order3.shipments.count).to eq 1 - expect(order3.shipments.first.shipping_method).to eq shipping_method - expect(order3.payments.count).to eq 1 - expect(order3.payments.first.payment_method).to eq payment_method - expect(order3.payments.first.state).to eq 'checkout' - expect(order3.total).to eq 31.50 - expect(order3.completed?).to be false - - # Future order cycle closing after ends_at - proxy_order4 = subscription.proxy_orders.find_by_order_cycle_id(order_cycle4.id) - expect(proxy_order4).to be nil - end - end -end diff --git a/spec/services/subscription_validator_spec.rb b/spec/services/subscription_validator_spec.rb deleted file mode 100644 index bdcd14bea5..0000000000 --- a/spec/services/subscription_validator_spec.rb +++ /dev/null @@ -1,470 +0,0 @@ -require "spec_helper" - -describe SubscriptionValidator do - let(:owner) { create(:user) } - let(:shop) { create(:enterprise, name: "Shop", owner: owner) } - - describe "delegation" do - let(:subscription) { create(:subscription, shop: shop) } - let(:validator) { SubscriptionValidator.new(subscription) } - - it "delegates to subscription" do - expect(validator.shop).to eq subscription.shop - expect(validator.customer).to eq subscription.customer - expect(validator.schedule).to eq subscription.schedule - expect(validator.shipping_method).to eq subscription.shipping_method - expect(validator.payment_method).to eq subscription.payment_method - expect(validator.bill_address).to eq subscription.bill_address - expect(validator.ship_address).to eq subscription.ship_address - expect(validator.begins_at).to eq subscription.begins_at - expect(validator.ends_at).to eq subscription.ends_at - end - end - - describe "validations" do - let(:subscription_stubs) do - { - shop: shop, - customer: true, - schedule: true, - shipping_method: true, - payment_method: true, - bill_address: true, - ship_address: true, - begins_at: true, - ends_at: true, - } - end - - let(:validation_stubs) do - { - shipping_method_allowed?: true, - payment_method_allowed?: true, - payment_method_type_allowed?: true, - ends_at_after_begins_at?: true, - customer_allowed?: true, - schedule_allowed?: true, - credit_card_ok?: true, - subscription_line_items_present?: true, - requested_variants_available?: true - } - end - - let(:subscription) { instance_double(Subscription, subscription_stubs) } - let(:validator) { SubscriptionValidator.new(subscription) } - - def stub_validations(validator, methods) - methods.each do |name, value| - allow(validator).to receive(name) { value } - end - end - - describe "shipping method validation" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:shipping_method)) } - before { stub_validations(validator, validation_stubs.except(:shipping_method_allowed?)) } - - context "when no shipping method is present" do - before { expect(subscription).to receive(:shipping_method).at_least(:once) { nil } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:shipping_method]).to_not be_empty - end - end - - context "when a shipping method is present" do - let(:shipping_method) { instance_double(Spree::ShippingMethod, distributors: [shop]) } - before { expect(subscription).to receive(:shipping_method).at_least(:once) { shipping_method } } - - context "and the shipping method is not associated with the shop" do - before { allow(shipping_method).to receive(:distributors) { [double(:enterprise)] } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:shipping_method]).to_not be_empty - end - end - - context "and the shipping method is associated with the shop" do - before { allow(shipping_method).to receive(:distributors) { [shop] } } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:shipping_method]).to be_empty - end - end - end - end - - describe "payment method validation" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } - before { stub_validations(validator, validation_stubs.except(:payment_method_allowed?)) } - - context "when no payment method is present" do - before { expect(subscription).to receive(:payment_method).at_least(:once) { nil } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:payment_method]).to_not be_empty - end - end - - context "when a payment method is present" do - let(:payment_method) { instance_double(Spree::PaymentMethod, distributors: [shop]) } - before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } - - context "and the payment method is not associated with the shop" do - before { allow(payment_method).to receive(:distributors) { [double(:enterprise)] } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:payment_method]).to_not be_empty - end - end - - context "and the payment method is associated with the shop" do - before { allow(payment_method).to receive(:distributors) { [shop] } } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:payment_method]).to be_empty - end - end - end - end - - describe "payment method type validation" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } - before { stub_validations(validator, validation_stubs.except(:payment_method_type_allowed?)) } - - context "when a payment method is present" do - let(:payment_method) { instance_double(Spree::PaymentMethod, distributors: [shop]) } - before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } - - context "and the payment method type is not in the approved list" do - before { allow(payment_method).to receive(:type) { "Blah" } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:payment_method]).to_not be_empty - end - end - - context "and the payment method is in the approved list" do - let(:approved_type) { Subscription::ALLOWED_PAYMENT_METHOD_TYPES.first } - before { allow(payment_method).to receive(:type) { approved_type } } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:payment_method]).to be_empty - end - end - end - end - - describe "dates" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:begins_at, :ends_at)) } - before { stub_validations(validator, validation_stubs.except(:ends_at_after_begins_at?)) } - before { expect(subscription).to receive(:begins_at).at_least(:once) { begins_at } } - - context "when no begins_at is present" do - let(:begins_at) { nil } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:begins_at]).to_not be_empty - end - end - - context "when a start date is present" do - let(:begins_at) { Time.zone.today } - before { expect(subscription).to receive(:ends_at).at_least(:once) { ends_at } } - - context "when no ends_at is present" do - let(:ends_at) { nil } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:ends_at]).to be_empty - end - end - - context "when ends_at is equal to begins_at" do - let(:ends_at) { Time.zone.today } - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:ends_at]).to_not be_empty - end - end - - context "when ends_at is before begins_at" do - let(:ends_at) { Time.zone.today - 1.day } - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:ends_at]).to_not be_empty - end - end - - context "when ends_at is after begins_at" do - let(:ends_at) { Time.zone.today + 1.day } - it "adds an error and returns false" do - expect(validator.valid?).to be true - expect(validator.errors[:ends_at]).to be_empty - end - end - end - end - - describe "addresses" do - before { stub_validations(validator, validation_stubs) } - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:bill_address, :ship_address)) } - before { expect(subscription).to receive(:bill_address).at_least(:once) { bill_address } } - before { expect(subscription).to receive(:ship_address).at_least(:once) { ship_address } } - - context "when bill_address and ship_address are not present" do - let(:bill_address) { nil } - let(:ship_address) { nil } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:bill_address]).to_not be_empty - expect(validator.errors[:ship_address]).to_not be_empty - end - end - - context "when bill_address and ship_address are present" do - let(:bill_address) { instance_double(Spree::Address) } - let(:ship_address) { instance_double(Spree::Address) } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:bill_address]).to be_empty - expect(validator.errors[:ship_address]).to be_empty - end - end - end - - describe "customer" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:customer)) } - before { stub_validations(validator, validation_stubs.except(:customer_allowed?)) } - before { expect(subscription).to receive(:customer).at_least(:once) { customer } } - - context "when no customer is present" do - let(:customer) { nil } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:customer]).to_not be_empty - end - end - - context "when a customer is present" do - let(:customer) { instance_double(Customer) } - - context "and the customer is not associated with the shop" do - before { allow(customer).to receive(:enterprise) { double(:enterprise) } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:customer]).to_not be_empty - end - end - - context "and the customer is associated with the shop" do - before { allow(customer).to receive(:enterprise) { shop } } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:customer]).to be_empty - end - end - end - end - - describe "schedule" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:schedule)) } - before { stub_validations(validator, validation_stubs.except(:schedule_allowed?)) } - before { expect(subscription).to receive(:schedule).at_least(:once) { schedule } } - - context "when no schedule is present" do - let(:schedule) { nil } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:schedule]).to_not be_empty - end - end - - context "when a schedule is present" do - let(:schedule) { instance_double(Schedule) } - - context "and the schedule is not associated with the shop" do - before { allow(schedule).to receive(:coordinators) { [double(:enterprise)] } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:schedule]).to_not be_empty - end - end - - context "and the schedule is associated with the shop" do - before { allow(schedule).to receive(:coordinators) { [shop] } } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:schedule]).to be_empty - end - end - end - end - - describe "credit card" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } - before { stub_validations(validator, validation_stubs.except(:credit_card_ok?)) } - before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } - - context "when using a Check payment method" do - let(:payment_method) { instance_double(Spree::PaymentMethod, type: "Spree::PaymentMethod::Check") } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:subscription_line_items]).to be_empty - end - end - - context "when using the StripeConnect payment gateway" do - let(:payment_method) { instance_double(Spree::PaymentMethod, type: "Spree::Gateway::StripeConnect") } - before { expect(subscription).to receive(:customer).at_least(:once) { customer } } - - context "when the customer does not allow charges" do - let(:customer) { instance_double(Customer, allow_charges: false) } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:payment_method]).to_not be_empty - end - end - - context "when the customer allows charges" do - let(:customer) { instance_double(Customer, allow_charges: true) } - - context "and the customer is not associated with a user" do - before { allow(customer).to receive(:user) { nil } } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:payment_method]).to_not be_empty - end - end - - context "and the customer is associated with a user" do - before { expect(customer).to receive(:user).once { user } } - - context "and the user has no default card set" do - let(:user) { instance_double(Spree::User, default_card: nil) } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:payment_method]).to_not be_empty - end - end - - context "and the user has a default card set" do - let(:user) { instance_double(Spree::User, default_card: 'some card') } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:payment_method]).to be_empty - end - end - end - end - end - end - - describe "subscription line items" do - let(:subscription) { instance_double(Subscription, subscription_stubs) } - before { stub_validations(validator, validation_stubs.except(:subscription_line_items_present?)) } - before { expect(subscription).to receive(:subscription_line_items).at_least(:once) { subscription_line_items } } - - context "when no subscription line items are present" do - let(:subscription_line_items) { [] } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:subscription_line_items]).to_not be_empty - end - end - - context "when subscription line items are present but they are all marked for destruction" do - let(:subscription_line_item1) { instance_double(SubscriptionLineItem, marked_for_destruction?: true) } - let(:subscription_line_items) { [subscription_line_item1] } - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:subscription_line_items]).to_not be_empty - end - end - - context "when subscription line items are present and some and not marked for destruction" do - let(:subscription_line_item1) { instance_double(SubscriptionLineItem, marked_for_destruction?: true) } - let(:subscription_line_item2) { instance_double(SubscriptionLineItem, marked_for_destruction?: false) } - let(:subscription_line_items) { [subscription_line_item1, subscription_line_item2] } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:subscription_line_items]).to be_empty - end - end - end - - describe "variant availability" do - let(:subscription) { instance_double(Subscription, subscription_stubs) } - before { stub_validations(validator, validation_stubs.except(:requested_variants_available?)) } - before { expect(subscription).to receive(:subscription_line_items).at_least(:once) { subscription_line_items } } - - context "when no subscription line items are present" do - let(:subscription_line_items) { [] } - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:subscription_line_items]).to be_empty - end - end - - context "when subscription line items are present" do - let(:variant1) { instance_double(Spree::Variant, id: 1) } - let(:variant2) { instance_double(Spree::Variant, id: 2) } - let(:subscription_line_item1) { instance_double(SubscriptionLineItem, variant: variant1) } - let(:subscription_line_item2) { instance_double(SubscriptionLineItem, variant: variant2) } - let(:subscription_line_items) { [subscription_line_item1] } - - context "but some variants are unavailable" do - let(:product) { instance_double(Spree::Product, name: "some_name") } - - before do - allow(validator).to receive(:available_variant_ids) { [variant2.id] } - allow(variant1).to receive(:product) { product } - allow(variant1).to receive(:full_name) { "some name" } - end - - it "adds an error and returns false" do - expect(validator.valid?).to be false - expect(validator.errors[:subscription_line_items]).to_not be_empty - end - end - - context "and all requested variants are available" do - before do - allow(validator).to receive(:available_variant_ids) { [variant1.id, variant2.id] } - end - - it "returns true" do - expect(validator.valid?).to be true - expect(validator.errors[:subscription_line_items]).to be_empty - end - end - end - end - end -end diff --git a/spec/services/subscription_variants_service_spec.rb b/spec/services/subscription_variants_service_spec.rb deleted file mode 100644 index 31d0ff4ca7..0000000000 --- a/spec/services/subscription_variants_service_spec.rb +++ /dev/null @@ -1,130 +0,0 @@ -require "spec_helper" - -describe SubscriptionVariantsService do - describe "variant eligibility for subscription" do - let!(:shop) { create(:distributor_enterprise) } - let!(:producer) { create(:supplier_enterprise) } - let!(:product) { create(:product, supplier: producer) } - let!(:variant) { product.variants.first } - - let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } - let!(:subscription) { create(:subscription, shop: shop, schedule: schedule) } - let!(:subscription_line_item) do - create(:subscription_line_item, subscription: subscription, variant: variant) - end - - let(:current_order_cycle) do - create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.week.ago, - orders_close_at: 1.week.from_now) - end - - let(:future_order_cycle) do - create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.week.from_now, - orders_close_at: 2.weeks.from_now) - end - - let(:past_order_cycle) do - create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.weeks.ago, - orders_close_at: 1.week.ago) - end - - let!(:order_cycle) { current_order_cycle } - - context "if the shop is the supplier for the product" do - let!(:producer) { shop } - - it "is eligible" do - expect(described_class.eligible_variants(shop)).to include(variant) - end - end - - context "if the supplier is permitted for the shop" do - let!(:enterprise_relationship) { create(:enterprise_relationship, child: shop, parent: product.supplier, permissions_list: [:add_to_order_cycle]) } - - it "is eligible" do - expect(described_class.eligible_variants(shop)).to include(variant) - end - end - - context "if the variant is involved in an exchange" do - let!(:order_cycle) { create(:simple_order_cycle, coordinator: shop) } - let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } - - context "if it is an incoming exchange where the shop is the receiver" do - let!(:incoming_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: true, variants: [variant]) } - - it "is not eligible" do - expect(described_class.eligible_variants(shop)).to_not include(variant) - end - end - - context "if it is an outgoing exchange where the shop is the receiver" do - let!(:outgoing_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: false, variants: [variant]) } - - context "if the order cycle is currently open" do - let!(:order_cycle) { current_order_cycle } - - it "is eligible" do - expect(described_class.eligible_variants(shop)).to include(variant) - end - end - - context "if the order cycle opens in the future" do - let!(:order_cycle) { future_order_cycle } - - it "is eligible" do - expect(described_class.eligible_variants(shop)).to include(variant) - end - end - - context "if the order cycle closed in the past" do - let!(:order_cycle) { past_order_cycle } - - it "is eligible" do - expect(described_class.eligible_variants(shop)).to include(variant) - end - end - end - end - - context "if the variant is unrelated" do - it "is not eligible" do - expect(described_class.eligible_variants(shop)).to_not include(variant) - end - end - end - - describe "checking if variant in open and upcoming order cycles" do - let!(:shop) { create(:enterprise) } - let!(:product) { create(:product) } - let!(:variant) { product.variants.first } - let!(:schedule) { create(:schedule) } - - context "if the variant is involved in an exchange" do - let!(:order_cycle) { create(:simple_order_cycle, coordinator: shop) } - let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } - - context "if it is an incoming exchange where the shop is the receiver" do - let!(:incoming_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: true, variants: [variant]) } - - it "is is false" do - expect(described_class).not_to be_in_open_and_upcoming_order_cycles(shop, schedule, variant) - end - end - - context "if it is an outgoing exchange where the shop is the receiver" do - let!(:outgoing_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: false, variants: [variant]) } - - it "is true" do - expect(described_class).to be_in_open_and_upcoming_order_cycles(shop, schedule, variant) - end - end - end - - context "if the variant is unrelated" do - it "is false" do - expect(described_class).to_not be_in_open_and_upcoming_order_cycles(shop, schedule, variant) - end - end - end -end diff --git a/spec/services/subscriptions_count_spec.rb b/spec/services/subscriptions_count_spec.rb deleted file mode 100644 index 2446bcc8bf..0000000000 --- a/spec/services/subscriptions_count_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -describe SubscriptionsCount do - let(:oc1) { create(:simple_order_cycle) } - let(:oc2) { create(:simple_order_cycle) } - let(:subscriptions_count) { SubscriptionsCount.new(order_cycles) } - - describe "#for" do - context "when the collection has not been set" do - let(:order_cycles) { nil } - it "returns 0" do - expect(subscriptions_count.for(oc1.id)).to eq 0 - end - end - - context "when the collection has been set" do - let(:order_cycles) { OrderCycle.where(id: [oc1]) } - let!(:po1) { create(:proxy_order, order_cycle: oc1) } - let!(:po2) { create(:proxy_order, order_cycle: oc1) } - let!(:po3) { create(:proxy_order, order_cycle: oc2) } - - context "but the requested id is not present in the list of order cycles provided" do - it "returns 0" do - # Note that po3 applies to oc2, but oc2 in not in the collection - expect(subscriptions_count.for(oc2.id)).to eq 0 - end - end - - context "and the requested id is present in the list of order cycles provided" do - it "returns a count of active proxy orders associated with the requested order cycle" do - expect(subscriptions_count.for(oc1.id)).to eq 2 - end - end - end - end -end From f8a4f00d52a13d07ff6fdb8521b555028a79bdf6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 11 Feb 2020 20:04:22 +0000 Subject: [PATCH 014/166] Fix rubocop issues in subs specs --- .rubocop_manual_todo.yml | 4 + .../subscriptions/estimator_spec.rb | 58 ++++++++-- .../subscriptions/form_spec.rb | 69 +++++++++--- .../subscriptions/validator_spec.rb | 102 +++++++++++++----- .../subscriptions/variants_list_spec.rb | 45 ++++++-- 5 files changed, 220 insertions(+), 58 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 83de12879f..a1908cdc5d 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -678,9 +678,13 @@ Metrics/ModuleLength: - app/helpers/injection_helper.rb - app/helpers/spree/admin/navigation_helper.rb - app/helpers/spree/admin/base_helper.rb + - engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb + - engines/order_management/spec/services/order_management/subscriptions/form_spec.rb - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb - engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb + - engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb + - engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb - lib/open_food_network/column_preference_defaults.rb - spec/controllers/admin/enterprises_controller_spec.rb - spec/controllers/admin/order_cycles_controller_spec.rb diff --git a/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb index 78020f6578..e8fe7bf957 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb @@ -59,8 +59,12 @@ module OrderManagement end context "when variant overrides apply" do - let!(:override1) { create(:variant_override, hub: subscription.shop, variant: sli1.variant, price: 1.2) } - let!(:override2) { create(:variant_override, hub: subscription.shop, variant: sli2.variant, price: 2.3) } + let!(:override1) { + create(:variant_override, hub: subscription.shop, variant: sli1.variant, price: 1.2) + } + let!(:override2) { + create(:variant_override, hub: subscription.shop, variant: sli2.variant, price: 2.3) + } it "recalculates price_estimates based on override prices and associated fees" do estimator.estimate! @@ -73,7 +77,11 @@ module OrderManagement end describe "updating estimates for shipping and payment fees" do - let(:subscription) { create(:subscription, with_items: true, payment_method: payment_method, shipping_method: shipping_method) } + let(:subscription) { + create(:subscription, with_items: true, + payment_method: payment_method, + shipping_method: shipping_method) + } let!(:sli1) { subscription.subscription_line_items.first } let!(:sli2) { subscription.subscription_line_items.second } let!(:sli3) { subscription.subscription_line_items.third } @@ -87,8 +95,14 @@ module OrderManagement end context "using flat rate calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 12.34)) } - let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 9.12)) } + let(:shipping_method) { + create(:shipping_method, + calculator: Spree::Calculator::FlatRate.new(preferred_amount: 12.34)) + } + let(:payment_method) { + create(:payment_method, + calculator: Spree::Calculator::FlatRate.new(preferred_amount: 9.12)) + } it "calculates fees based on the rates provided" do estimator.estimate! @@ -98,8 +112,18 @@ module OrderManagement end context "using flat percent item total calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)) } - let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 20)) } + let(:shipping_method) { + create(:shipping_method, + calculator: Spree::Calculator::FlatPercentItemTotal.new( + preferred_flat_percent: 10 + )) + } + let(:payment_method) { + create(:payment_method, + calculator: Spree::Calculator::FlatPercentItemTotal.new( + preferred_flat_percent: 20 + )) + } it "calculates fees based on the estimated item total and percentage provided" do estimator.estimate! @@ -109,8 +133,14 @@ module OrderManagement end context "using flat percent per item calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 5)) } - let(:payment_method) { create(:payment_method, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 10)) } + let(:shipping_method) { + create(:shipping_method, + calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 5)) + } + let(:payment_method) { + create(:payment_method, + calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 10)) + } it "calculates fees based on the estimated item prices and percentage provided" do estimator.estimate! @@ -120,8 +150,14 @@ module OrderManagement end context "using per item calculators" do - let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::PerItem.new(preferred_amount: 1.2)) } - let(:payment_method) { create(:payment_method, calculator: Spree::Calculator::PerItem.new(preferred_amount: 0.3)) } + let(:shipping_method) { + create(:shipping_method, + calculator: Spree::Calculator::PerItem.new(preferred_amount: 1.2)) + } + let(:payment_method) { + create(:payment_method, + calculator: Spree::Calculator::PerItem.new(preferred_amount: 0.3)) + } it "calculates fees based on the number of items and rate provided" do estimator.estimate! diff --git a/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb index f9c0798671..3e849d5c82 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/form_spec.rb @@ -11,19 +11,64 @@ module OrderManagement let!(:product1) { create(:product, supplier: shop) } let!(:product2) { create(:product, supplier: shop) } let!(:product3) { create(:product, supplier: shop) } - let!(:variant1) { create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) } - let!(:variant2) { create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) } - let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: [], on_hand: 1) } + let!(:variant1) { + create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: []) + } + let!(:variant2) { + create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) + } + let!(:variant3) { + create(:variant, product: product2, unit_value: '1000', + price: 2.50, option_values: [], on_hand: 1) + } let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) } - let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.ago, orders_close_at: 2.days.ago) } - let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.ago, orders_close_at: 5.days.from_now) } - let!(:order_cycle3) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 5.days.from_now, orders_close_at: 12.days.from_now) } - let!(:order_cycle4) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 12.days.from_now, orders_close_at: 19.days.from_now) } - let!(:outgoing_exchange1) { order_cycle1.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:outgoing_exchange2) { order_cycle2.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:outgoing_exchange3) { order_cycle3.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant3], enterprise_fees: []) } - let!(:outgoing_exchange4) { order_cycle4.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2, order_cycle3, order_cycle4]) } + let!(:order_cycle1) { + create(:simple_order_cycle, coordinator: shop, + orders_open_at: 9.days.ago, + orders_close_at: 2.days.ago) + } + let!(:order_cycle2) { + create(:simple_order_cycle, coordinator: shop, + orders_open_at: 2.days.ago, + orders_close_at: 5.days.from_now) + } + let!(:order_cycle3) { + create(:simple_order_cycle, coordinator: shop, + orders_open_at: 5.days.from_now, + orders_close_at: 12.days.from_now) + } + let!(:order_cycle4) { + create(:simple_order_cycle, coordinator: shop, + orders_open_at: 12.days.from_now, + orders_close_at: 19.days.from_now) + } + let!(:outgoing_exchange1) { + order_cycle1.exchanges.create(sender: shop, + receiver: shop, + variants: [variant1, variant2, variant3], + enterprise_fees: [enterprise_fee]) + } + let!(:outgoing_exchange2) { + order_cycle2.exchanges.create(sender: shop, + receiver: shop, + variants: [variant1, variant2, variant3], + enterprise_fees: [enterprise_fee]) + } + let!(:outgoing_exchange3) { + order_cycle3.exchanges.create(sender: shop, + receiver: shop, + variants: [variant1, variant3], + enterprise_fees: []) + } + let!(:outgoing_exchange4) { + order_cycle4.exchanges.create(sender: shop, + receiver: shop, + variants: [variant1, variant2, variant3], + enterprise_fees: [enterprise_fee]) + } + let!(:schedule) { + create(:schedule, order_cycles: [order_cycle1, order_cycle2, order_cycle3, order_cycle4]) + } let!(:payment_method) { create(:payment_method, distributors: [shop]) } let!(:shipping_method) { create(:shipping_method, distributors: [shop]) } let!(:address) { create(:address) } diff --git a/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb index a072262b47..7c52fba12a 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb @@ -64,7 +64,9 @@ module OrderManagement end describe "shipping method validation" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:shipping_method)) } + let(:subscription) { + instance_double(Subscription, subscription_stubs.except(:shipping_method)) + } before { stub_validations(validator, validation_stubs.except(:shipping_method_allowed?)) } context "when no shipping method is present" do @@ -78,7 +80,9 @@ module OrderManagement context "when a shipping method is present" do let(:shipping_method) { instance_double(Spree::ShippingMethod, distributors: [shop]) } - before { expect(subscription).to receive(:shipping_method).at_least(:once) { shipping_method } } + before { + expect(subscription).to receive(:shipping_method).at_least(:once) { shipping_method } + } context "and the shipping method is not associated with the shop" do before { allow(shipping_method).to receive(:distributors) { [double(:enterprise)] } } @@ -101,7 +105,9 @@ module OrderManagement end describe "payment method validation" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } + let(:subscription) { + instance_double(Subscription, subscription_stubs.except(:payment_method)) + } before { stub_validations(validator, validation_stubs.except(:payment_method_allowed?)) } context "when no payment method is present" do @@ -115,7 +121,9 @@ module OrderManagement context "when a payment method is present" do let(:payment_method) { instance_double(Spree::PaymentMethod, distributors: [shop]) } - before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } + before { + expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } + } context "and the payment method is not associated with the shop" do before { allow(payment_method).to receive(:distributors) { [double(:enterprise)] } } @@ -138,12 +146,18 @@ module OrderManagement end describe "payment method type validation" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } - before { stub_validations(validator, validation_stubs.except(:payment_method_type_allowed?)) } + let(:subscription) { + instance_double(Subscription, subscription_stubs.except(:payment_method)) + } + before { + stub_validations(validator, validation_stubs.except(:payment_method_type_allowed?)) + } context "when a payment method is present" do let(:payment_method) { instance_double(Spree::PaymentMethod, distributors: [shop]) } - before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } + before { + expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } + } context "and the payment method type is not in the approved list" do before { allow(payment_method).to receive(:type) { "Blah" } } @@ -167,7 +181,9 @@ module OrderManagement end describe "dates" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:begins_at, :ends_at)) } + let(:subscription) { + instance_double(Subscription, subscription_stubs.except(:begins_at, :ends_at)) + } before { stub_validations(validator, validation_stubs.except(:ends_at_after_begins_at?)) } before { expect(subscription).to receive(:begins_at).at_least(:once) { begins_at } } @@ -221,7 +237,9 @@ module OrderManagement describe "addresses" do before { stub_validations(validator, validation_stubs) } - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:bill_address, :ship_address)) } + let(:subscription) { + instance_double(Subscription, subscription_stubs.except(:bill_address, :ship_address)) + } before { expect(subscription).to receive(:bill_address).at_least(:once) { bill_address } } before { expect(subscription).to receive(:ship_address).at_least(:once) { ship_address } } @@ -323,12 +341,18 @@ module OrderManagement end describe "credit card" do - let(:subscription) { instance_double(Subscription, subscription_stubs.except(:payment_method)) } + let(:subscription) { + instance_double(Subscription, subscription_stubs.except(:payment_method)) + } before { stub_validations(validator, validation_stubs.except(:credit_card_ok?)) } - before { expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } } + before { + expect(subscription).to receive(:payment_method).at_least(:once) { payment_method } + } context "when using a Check payment method" do - let(:payment_method) { instance_double(Spree::PaymentMethod, type: "Spree::PaymentMethod::Check") } + let(:payment_method) { + instance_double(Spree::PaymentMethod, type: "Spree::PaymentMethod::Check") + } it "returns true" do expect(validator.valid?).to be true @@ -337,7 +361,9 @@ module OrderManagement end context "when using the StripeConnect payment gateway" do - let(:payment_method) { instance_double(Spree::PaymentMethod, type: "Spree::Gateway::StripeConnect") } + let(:payment_method) { + instance_double(Spree::PaymentMethod, type: "Spree::Gateway::StripeConnect") + } before { expect(subscription).to receive(:customer).at_least(:once) { customer } } context "when the customer does not allow charges" do @@ -388,10 +414,16 @@ module OrderManagement describe "subscription line items" do let(:subscription) { instance_double(Subscription, subscription_stubs) } - before { stub_validations(validator, validation_stubs.except(:subscription_line_items_present?)) } - before { expect(subscription).to receive(:subscription_line_items).at_least(:once) { subscription_line_items } } + before { + stub_validations(validator, validation_stubs.except(:subscription_line_items_present?)) + } + before { + expect(subscription).to receive(:subscription_line_items).at_least(:once) { + subscription_line_items + } + } - context "when no subscription line items are present" do + context "when no subscription line items exist" do let(:subscription_line_items) { [] } it "adds an error and returns false" do @@ -400,8 +432,10 @@ module OrderManagement end end - context "when subscription line items are present but they are all marked for destruction" do - let(:subscription_line_item1) { instance_double(SubscriptionLineItem, marked_for_destruction?: true) } + context "when subscription line items exist but all are marked for destruction" do + let(:subscription_line_item1) { + instance_double(SubscriptionLineItem, marked_for_destruction?: true) + } let(:subscription_line_items) { [subscription_line_item1] } it "adds an error and returns false" do @@ -410,9 +444,13 @@ module OrderManagement end end - context "when subscription line items are present and some and not marked for destruction" do - let(:subscription_line_item1) { instance_double(SubscriptionLineItem, marked_for_destruction?: true) } - let(:subscription_line_item2) { instance_double(SubscriptionLineItem, marked_for_destruction?: false) } + context "when subscription line items exist and some are not marked for destruction" do + let(:subscription_line_item1) { + instance_double(SubscriptionLineItem, marked_for_destruction?: true) + } + let(:subscription_line_item2) { + instance_double(SubscriptionLineItem, marked_for_destruction?: false) + } let(:subscription_line_items) { [subscription_line_item1, subscription_line_item2] } it "returns true" do @@ -424,10 +462,16 @@ module OrderManagement describe "variant availability" do let(:subscription) { instance_double(Subscription, subscription_stubs) } - before { stub_validations(validator, validation_stubs.except(:requested_variants_available?)) } - before { expect(subscription).to receive(:subscription_line_items).at_least(:once) { subscription_line_items } } + before { + stub_validations(validator, validation_stubs.except(:requested_variants_available?)) + } + before { + expect(subscription).to receive(:subscription_line_items).at_least(:once) { + subscription_line_items + } + } - context "when no subscription line items are present" do + context "when no subscription line items exist" do let(:subscription_line_items) { [] } it "returns true" do @@ -436,11 +480,15 @@ module OrderManagement end end - context "when subscription line items are present" do + context "when subscription line items exist" do let(:variant1) { instance_double(Spree::Variant, id: 1) } let(:variant2) { instance_double(Spree::Variant, id: 2) } - let(:subscription_line_item1) { instance_double(SubscriptionLineItem, variant: variant1) } - let(:subscription_line_item2) { instance_double(SubscriptionLineItem, variant: variant2) } + let(:subscription_line_item1) { + instance_double(SubscriptionLineItem, variant: variant1) + } + let(:subscription_line_item2) { + instance_double(SubscriptionLineItem, variant: variant2) + } let(:subscription_line_items) { [subscription_line_item1] } context "but some variants are unavailable" do diff --git a/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb index 8dc97b128e..2ea3206045 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb @@ -43,7 +43,11 @@ module OrderManagement end context "if the supplier is permitted for the shop" do - let!(:enterprise_relationship) { create(:enterprise_relationship, child: shop, parent: product.supplier, permissions_list: [:add_to_order_cycle]) } + let!(:enterprise_relationship) { + create(:enterprise_relationship, child: shop, + parent: product.supplier, + permissions_list: [:add_to_order_cycle]) + } it "is eligible" do expect(described_class.eligible_variants(shop)).to include(variant) @@ -55,7 +59,11 @@ module OrderManagement let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } context "if it is an incoming exchange where the shop is the receiver" do - let!(:incoming_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: true, variants: [variant]) } + let!(:incoming_exchange) { + order_cycle.exchanges.create(sender: product.supplier, + receiver: shop, + incoming: true, variants: [variant]) + } it "is not eligible" do expect(described_class.eligible_variants(shop)).to_not include(variant) @@ -63,7 +71,12 @@ module OrderManagement end context "if it is an outgoing exchange where the shop is the receiver" do - let!(:outgoing_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: false, variants: [variant]) } + let!(:outgoing_exchange) { + order_cycle.exchanges.create(sender: product.supplier, + receiver: shop, + incoming: false, + variants: [variant]) + } context "if the order cycle is currently open" do let!(:order_cycle) { current_order_cycle } @@ -109,25 +122,41 @@ module OrderManagement let!(:schedule) { create(:schedule, order_cycles: [order_cycle]) } context "if it is an incoming exchange where the shop is the receiver" do - let!(:incoming_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: true, variants: [variant]) } + let!(:incoming_exchange) { + order_cycle.exchanges.create(sender: product.supplier, + receiver: shop, + incoming: true, + variants: [variant]) + } it "is is false" do - expect(described_class).not_to be_in_open_and_upcoming_order_cycles(shop, schedule, variant) + expect(described_class).not_to be_in_open_and_upcoming_order_cycles(shop, + schedule, + variant) end end context "if it is an outgoing exchange where the shop is the receiver" do - let!(:outgoing_exchange) { order_cycle.exchanges.create(sender: product.supplier, receiver: shop, incoming: false, variants: [variant]) } + let!(:outgoing_exchange) { + order_cycle.exchanges.create(sender: product.supplier, + receiver: shop, + incoming: false, + variants: [variant]) + } it "is true" do - expect(described_class).to be_in_open_and_upcoming_order_cycles(shop, schedule, variant) + expect(described_class).to be_in_open_and_upcoming_order_cycles(shop, + schedule, + variant) end end end context "if the variant is unrelated" do it "is false" do - expect(described_class).to_not be_in_open_and_upcoming_order_cycles(shop, schedule, variant) + expect(described_class).to_not be_in_open_and_upcoming_order_cycles(shop, + schedule, + variant) end end end From 0a2941ed9617b51319328659d9a9bca591400048 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 12 Feb 2020 15:57:09 +0000 Subject: [PATCH 015/166] Extract StripePaymentSetup from PaymentSetup --- app/jobs/subscription_confirm_job.rb | 3 + .../subscriptions/payment_setup.rb | 55 +++---------------- .../subscriptions/stripe_payment_setup.rb | 52 ++++++++++++++++++ 3 files changed, 63 insertions(+), 47 deletions(-) create mode 100644 engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index 3612b7e0d4..d7f4dcae8e 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -67,6 +67,9 @@ class SubscriptionConfirmJob def setup_payment!(order) OrderManagement::Subscriptions::PaymentSetup.new(order).call! + return if order.errors.any? + + OrderManagement::Subscriptions::StripePaymentSetup.new(order).call! end def send_confirmation_email(order) diff --git a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb index 86ce1f2c29..1824247e37 100644 --- a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb @@ -8,62 +8,23 @@ module OrderManagement end def call! - create_payment - ensure_payment_source - return if order.errors.any? + payment = create_payment + return if @order.errors.any? - payment.update_attributes(amount: order.outstanding_balance) + payment.update_attributes(amount: @order.outstanding_balance) + payment end private - attr_reader :order - - def payment - @payment ||= order.pending_payments.last - end - def create_payment - return if payment.present? + payment = @order.pending_payments.last + return payment if payment.present? - @payment = order.payments.create( - payment_method_id: order.subscription.payment_method_id, - amount: order.outstanding_balance + @order.payments.create( + payment_method_id: @order.subscription.payment_method_id ) end - - def card_required? - [Spree::Gateway::StripeConnect, - Spree::Gateway::StripeSCA].include? payment.payment_method.class - end - - def card_set? - payment.source is_a? Spree::CreditCard - end - - def ensure_payment_source - return unless card_required? && !card_set? - - ensure_credit_card || order.errors.add(:base, :no_card) - end - - def ensure_credit_card - return false if saved_credit_card.blank? || !allow_charges? - - payment.update_attributes(source: saved_credit_card) - end - - def allow_charges? - order.customer.allow_charges? - end - - def saved_credit_card - order.user.default_card - end - - def errors_present? - order.errors.any? - end end end end diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb new file mode 100644 index 0000000000..4160b24bcc --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + class StripePaymentSetup + def initialize(order) + @order = order + @payment = @order.pending_payments.last + end + + def call! + return if @payment.blank? + + ensure_payment_source + @payment + end + + private + + def ensure_payment_source + return if !card_required? || card_set? + + if saved_credit_card.present? && allow_charges? + use_saved_credit_card + else + @order.errors.add(:base, :no_card) + end + end + + def card_required? + [Spree::Gateway::StripeConnect, + Spree::Gateway::StripeSCA].include? @payment.payment_method.class + end + + def card_set? + @payment.source is_a? Spree::CreditCard + end + + def use_saved_credit_card + @payment.update_attributes(source: saved_credit_card) + end + + def saved_credit_card + @order.user.default_card + end + + def allow_charges? + @order.customer.allow_charges? + end + end + end +end From aac7a5e5590dad8298d8d6c402ca1c089fb01329 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 13 Feb 2020 12:24:47 +0000 Subject: [PATCH 016/166] Adapt PaymentSetup spec to new version and remove some private method testing (payment) as well as some tests testing order.pending_payments logic --- .rubocop_manual_todo.yml | 1 - .../subscriptions/payment_setup_spec.rb | 198 ++---------------- 2 files changed, 17 insertions(+), 182 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index a1908cdc5d..da0470689e 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -681,7 +681,6 @@ Metrics/ModuleLength: - engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb - engines/order_management/spec/services/order_management/subscriptions/form_spec.rb - engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb - - engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb - engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb - engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb - engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb diff --git a/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb index 442fb64cb5..32bf3874d0 100644 --- a/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb +++ b/engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb @@ -8,44 +8,6 @@ module OrderManagement let(:order) { create(:order) } let(:payment_setup) { OrderManagement::Subscriptions::PaymentSetup.new(order) } - describe "#payment" do - context "when only one payment exists on the order" do - let!(:payment) { create(:payment, order: order) } - - context "where the payment is pending" do - it { expect(payment_setup.__send__(:payment)).to eq payment } - end - - context "where the payment is failed" do - before { payment.update_attribute(:state, 'failed') } - it { expect(payment_setup.__send__(:payment)).to be nil } - end - end - - context "when more that one payment exists on the order" do - let!(:payment1) { create(:payment, order: order) } - let!(:payment2) { create(:payment, order: order) } - - context "where more than one payment is pending" do - it { expect([payment1, payment2]).to include payment_setup.__send__(:payment) } - end - - context "where only one payment is pending" do - before { payment1.update_attribute(:state, 'failed') } - it { expect(payment_setup.__send__(:payment)).to eq payment2 } - end - - context "where no payments are pending" do - before do - payment1.update_attribute(:state, 'failed') - payment2.update_attribute(:state, 'failed') - end - - it { expect(payment_setup.__send__(:payment)).to be nil } - end - end - end - describe "#call!" do let!(:payment){ create(:payment, amount: 10) } @@ -68,161 +30,35 @@ module OrderManagement context "when a payment is present" do before { allow(order).to receive(:pending_payments).once { [payment] } } - context "when a credit card is not required" do - before do - allow(payment_setup).to receive(:card_required?) { false } - expect(payment_setup).to_not receive(:card_available?) - expect(payment_setup).to_not receive(:ensure_credit_card) - end - - context "when the payment total doesn't match the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 5 } } - it "updates the payment total to reflect the outstanding balance" do - expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) - end - end - - context "when the payment total matches the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 10 } } - - it "does nothing" do - expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) - end + context "when the payment total doesn't match the outstanding balance on the order" do + before { allow(order).to receive(:outstanding_balance) { 5 } } + it "updates the payment total to reflect the outstanding balance" do + expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) end end - context "when a credit card is required" do - before do - expect(payment_setup).to receive(:card_required?) { true } - end + context "when the payment total matches the outstanding balance on the order" do + before { allow(order).to receive(:outstanding_balance) { 10 } } - context "and the payment source is not a credit card" do - before { expect(payment_setup).to receive(:card_set?) { false } } - - context "and no default credit card has been set by the customer" do - before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } - end - - it "adds an error to the order and does not update the payment" do - expect(payment).to_not receive(:update_attributes) - expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) - end - end - - context "and the customer has not authorised the shop to charge to credit cards" do - before do - allow(order).to receive(:user) { - instance_double(Spree::User, default_card: create(:credit_card)) - } - allow(order).to receive(:customer) { - instance_double(Customer, allow_charges?: false) - } - end - - it "adds an error to the order and does not update the payment" do - expect(payment).to_not receive(:update_attributes) - expect{ payment_setup.call! }.to change(order.errors[:base], :count).from(0).to(1) - end - end - - context "and an authorised default credit card is available to charge" do - before do - allow(order).to receive(:user) { - instance_double(Spree::User, default_card: create(:credit_card)) - } - allow(order).to receive(:customer) { - instance_double(Customer, allow_charges?: true) - } - end - - context "when the payment total doesn't match the order's outstanding balance" do - before { allow(order).to receive(:outstanding_balance) { 5 } } - it "updates the payment total to reflect the outstanding balance" do - expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) - end - end - - context "when the payment total matches the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 10 } } - - it "does nothing" do - expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) - end - end - end - end - - context "and the payment source is already a credit card" do - before { expect(payment_setup).to receive(:card_set?) { true } } - - context "when the payment total doesn't match the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 5 } } - it "updates the payment total to reflect the outstanding balance" do - expect{ payment_setup.call! }.to change(payment, :amount).from(10).to(5) - end - end - - context "when the payment total matches the outstanding balance on the order" do - before { allow(order).to receive(:outstanding_balance) { 10 } } - - it "does nothing" do - expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) - end - end + it "does nothing" do + expect{ payment_setup.call! }.to_not change(payment, :amount).from(10) end end end - end - describe "#ensure_credit_card" do - let!(:payment) { create(:payment, source: nil) } - before { allow(payment_setup).to receive(:payment) { payment } } + context "when more that one payment exists on the order" do + let!(:payment1) { create(:payment, order: order) } + let!(:payment2) { create(:payment, order: order) } - context "when no default credit card is found" do before do - allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } + allow(order).to receive(:outstanding_balance) { 7 } + allow(order).to receive(:pending_payments).once { [payment1, payment2] } end - it "returns false and down not update the payment source" do - expect do - expect(payment_setup.__send__(:ensure_credit_card)).to be false - end.to_not change(payment, :source).from(nil) - end - end - - context "when a default credit card is found" do - let(:credit_card) { create(:credit_card) } - before do - allow(order).to receive(:user) { - instance_double(Spree::User, default_card: credit_card) - } - end - - context "and charge have not been authorised by the customer" do - before do - allow(order).to receive(:customer) { - instance_double(Customer, allow_charges?: false) - } - end - - it "returns false and does not update the payment source" do - expect do - expect(payment_setup.__send__(:ensure_credit_card)).to be false - end.to_not change(payment, :source).from(nil) - end - end - - context "and charges have been authorised by the customer" do - before do - allow(order).to receive(:customer) { instance_double(Customer, allow_charges?: true) } - end - - it "returns true and stores the credit card as the payment source" do - expect do - expect(payment_setup.__send__(:ensure_credit_card)).to be true - end.to change(payment, :source_id).from(nil).to(credit_card.id) - end + it "updates the amount of the last payment to reflect the outstanding balance" do + payment_setup.call! + expect(payment1.amount).to eq 45.75 + expect(payment2.amount).to eq 7 end end end From 84745e4ccbfeb0c134be68382682f6c5755f4d22 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 13 Feb 2020 12:25:14 +0000 Subject: [PATCH 017/166] Add stripe payment setup spec and make minor tweaks to the code itself. Also, add a missing . to card_set? that eanbles it! If the card was already set, it would anyway set the default card. Now it will use the defined card if there is one already. --- .../subscriptions/stripe_payment_setup.rb | 14 +-- .../stripe_payment_setup_spec.rb | 109 ++++++++++++++++++ 2 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb index 4160b24bcc..8bc7e4cb9e 100644 --- a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb @@ -18,7 +18,7 @@ module OrderManagement private def ensure_payment_source - return if !card_required? || card_set? + return unless stripe_payment_method? && !card_set? if saved_credit_card.present? && allow_charges? use_saved_credit_card @@ -27,17 +27,13 @@ module OrderManagement end end - def card_required? + def stripe_payment_method? [Spree::Gateway::StripeConnect, Spree::Gateway::StripeSCA].include? @payment.payment_method.class end def card_set? - @payment.source is_a? Spree::CreditCard - end - - def use_saved_credit_card - @payment.update_attributes(source: saved_credit_card) + @payment.source.is_a? Spree::CreditCard end def saved_credit_card @@ -47,6 +43,10 @@ module OrderManagement def allow_charges? @order.customer.allow_charges? end + + def use_saved_credit_card + @payment.update_attributes(source: saved_credit_card) + end end end end diff --git a/engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb new file mode 100644 index 0000000000..c928ddd95b --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module OrderManagement + module Subscriptions + describe StripePaymentSetup do + let(:order) { create(:order) } + let(:payment_setup) { OrderManagement::Subscriptions::StripePaymentSetup.new(order) } + + describe "#call!" do + context "when no pending payments are present" do + before do + allow(order).to receive(:pending_payments).once { [] } + end + + it "does nothing" do + expect(payment_setup.call!).to eq nil + end + end + + context "when a payment is present" do + let(:payment) { create(:payment, payment_method: payment_method, amount: 10) } + + before { allow(order).to receive(:pending_payments).once { [payment] } } + + context "when the payment method is not a stripe payment method" do + let(:payment_method) { create(:payment_method) } + + it "returns the pending payment with no change" do + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + end + end + + context "when the payment method is a stripe payment method" do + let(:payment_method) { create(:stripe_payment_method) } + + context "and the card is already set (the payment source is a credit card)" do + it "returns the pending payment with no change" do + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + end + end + + context "and the card is not set (the payment source is not a credit card)" do + before { payment.update_attribute :source, nil } + + context "and no default credit card has been saved by the customer" do + before do + allow(order).to receive(:user) { instance_double(Spree::User, default_card: nil) } + end + + it "adds an error to the order and does not update the payment" do + payment_setup.call! + + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + expect(order.errors[:base].first).to eq "There are no authorised "\ + "credit cards available to charge" + end + end + + context "and a default credit card has been saved by the customer" do + let(:saved_credit_card) { create(:credit_card) } + + before do + allow(order).to receive(:user) { + instance_double(Spree::User, default_card: saved_credit_card) + } + end + + context "but the customer has not authorised the shop to charge credit cards" do + before do + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: false) + } + end + + it "adds an error to the order and does not update the payment" do + payment_setup.call! + + expect(payment).to_not receive(:update_attributes) + expect(payment_setup.call!).to eq payment + expect(order.errors[:base].first).to eq "There are no authorised "\ + "credit cards available to charge" + end + end + + context "and the customer has authorised the shop to charge credit cards" do + before do + allow(order).to receive(:customer) { + instance_double(Customer, allow_charges?: true) + } + end + + it "uses the saved credit card as the source for the payment" do + payment_setup.call! + expect(payment.source).to eq saved_credit_card + end + end + end + end + end + end + end + end + end +end From 26769b41507e999f730997ce28c4e8020d59b4d8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 13 Feb 2020 18:47:57 +0000 Subject: [PATCH 018/166] Add StripeSCA payment authorize and use it both subs_confirm job as well as on teh checkout stripe redirect --- app/jobs/subscription_confirm_job.rb | 13 +++- app/services/checkout/stripe_redirect.rb | 7 +- .../stripe_sca_payment_authorize.rb | 22 +++++++ .../stripe_sca_payment_authorize_spec.rb | 65 +++++++++++++++++++ 4 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb create mode 100644 engines/order_management/spec/services/order_management/subscriptions/stripe_sca_payment_authorize_spec.rb diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb index d7f4dcae8e..748257a340 100644 --- a/app/jobs/subscription_confirm_job.rb +++ b/app/jobs/subscription_confirm_job.rb @@ -57,10 +57,13 @@ class SubscriptionConfirmJob return true unless order.payment_required? setup_payment!(order) - return false if order.errors.present? + return false if order.errors.any? + + authorize_payment!(order) + return false if order.errors.any? order.process_payments! - return false if order.errors.present? + return false if order.errors.any? true end @@ -72,6 +75,12 @@ class SubscriptionConfirmJob OrderManagement::Subscriptions::StripePaymentSetup.new(order).call! end + def authorize_payment!(order) + return if order.subscription.payment_method.class != Spree::Gateway::StripeSCA + + OrderManagement::Subscriptions::StripeScaPaymentAuthorize.new(order).call! + end + def send_confirmation_email(order) order.update! record_success(order) diff --git a/app/services/checkout/stripe_redirect.rb b/app/services/checkout/stripe_redirect.rb index 40feebfde8..e7c40a4b9e 100644 --- a/app/services/checkout/stripe_redirect.rb +++ b/app/services/checkout/stripe_redirect.rb @@ -12,11 +12,8 @@ module Checkout def path return unless stripe_payment_method? - payment = @order.pending_payments.last - return unless payment&.checkout? - - payment.authorize! - raise unless payment.pending? + payment = OrderManagement::Subscriptions::StripeScaPaymentAuthorize.new(@order).call! + raise if @order.errors.any? field_with_url(payment) if url?(field_with_url(payment)) end diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb new file mode 100644 index 0000000000..da8830ce70 --- /dev/null +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module OrderManagement + module Subscriptions + class StripeScaPaymentAuthorize + def initialize(order) + @order = order + @payment = @order.pending_payments.last + end + + def call! + return unless @payment&.checkout? + + @payment.authorize! + + @order.errors.add(:base, I18n.t('authorization_failure')) unless @payment.pending? + + @payment + end + end + end +end diff --git a/engines/order_management/spec/services/order_management/subscriptions/stripe_sca_payment_authorize_spec.rb b/engines/order_management/spec/services/order_management/subscriptions/stripe_sca_payment_authorize_spec.rb new file mode 100644 index 0000000000..17ece20be4 --- /dev/null +++ b/engines/order_management/spec/services/order_management/subscriptions/stripe_sca_payment_authorize_spec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module OrderManagement + module Subscriptions + describe StripeScaPaymentAuthorize do + let(:order) { create(:order) } + let(:payment_authorize) { + OrderManagement::Subscriptions::StripeScaPaymentAuthorize.new(order) + } + + describe "#call!" do + context "when no pending payments are present" do + before { allow(order).to receive(:pending_payments).once { [] } } + + it "does nothing" do + expect(payment_authorize.call!).to eq nil + end + end + + context "when a payment is present" do + let(:payment) { create(:payment, amount: 10) } + + before { allow(order).to receive(:pending_payments).once { [payment] } } + + context "in a state that is not checkout" do + before { payment.state = "processing" } + + it "does nothing" do + payment_authorize.call! + + expect(payment.state).to eq "processing" + expect(order.errors.size).to eq 0 + end + end + + context "in the checkout state" do + before { payment.state = "checkout" } + + context "and payment authorize moves the payment state to pending" do + before { expect(payment).to receive(:authorize!) { payment.state = "pending" } } + + it "does nothing" do + payment_authorize.call! + + expect(order.errors.size).to eq 0 + end + end + + context "and payment authorize does not move the payment state to pending" do + before { allow(payment).to receive(:authorize!) { payment.state = "failed" } } + + it "adds an error to the order indicating authorization failure" do + payment_authorize.call! + + expect(order.errors[:base].first).to eq "Authorization Failure" + end + end + end + end + end + end + end +end From a6e48932873e7e2a41d75949b5286ff3a58d3c29 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 11:33:42 +0000 Subject: [PATCH 019/166] Remove taxons list field from product edit form. It is not working and it's not used in any other place in the app, there's the product category already (product.primary_taxon_id) --- app/views/spree/admin/products/_form.html.haml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/views/spree/admin/products/_form.html.haml b/app/views/spree/admin/products/_form.html.haml index cbc7718325..616f7977f3 100644 --- a/app/views/spree/admin/products/_form.html.haml +++ b/app/views/spree/admin/products/_form.html.haml @@ -16,11 +16,6 @@ = sanitize(@product.description) = f.error_message_on :description - = f.field_container :taxons do - = f.label :taxon_ids, t(:taxons) - %br - = f.hidden_field :taxon_ids, :value => @product.taxon_ids.join(',') - .right.four.columns.omega .variant_units_form{ 'ng-app' => 'admin.products', 'ng-controller' => 'editUnitsCtrl' } From 0308f1465dcbfb88abf4227b59e4f3c08558d7cd Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 11:34:19 +0000 Subject: [PATCH 020/166] Remove taxons/search action and respective rabl view This is dead code --- .rubocop_todo.yml | 1 - app/controllers/spree/admin/taxons_controller.rb | 8 -------- app/views/spree/admin/taxons/search.rabl | 4 ---- config/routes/spree.rb | 6 ------ 4 files changed, 19 deletions(-) delete mode 100644 app/views/spree/admin/taxons/search.rabl diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 894146e628..e3b612d862 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -861,7 +861,6 @@ Style/FrozenStringLiteralComment: - 'app/validators/date_time_string_validator.rb' - 'app/validators/distributors_validator.rb' - 'app/validators/integer_array_validator.rb' - - 'app/views/spree/admin/taxons/search.rabl' - 'config.ru' - 'engines/order_management/app/controllers/order_management/application_controller.rb' - 'engines/order_management/app/services/order_management/reports/enterprise_fee_summary/authorizer.rb' diff --git a/app/controllers/spree/admin/taxons_controller.rb b/app/controllers/spree/admin/taxons_controller.rb index ddc1b63c70..240cb2cd03 100644 --- a/app/controllers/spree/admin/taxons_controller.rb +++ b/app/controllers/spree/admin/taxons_controller.rb @@ -3,14 +3,6 @@ module Spree class TaxonsController < Spree::Admin::BaseController respond_to :html, :json, :js - def search - @taxons = if params[:ids] - Spree::Taxon.where(id: params[:ids].split(',')) - else - Spree::Taxon.limit(20).search(name_cont: params[:q]).result - end - end - def create @taxonomy = Taxonomy.find(params[:taxonomy_id]) @taxon = @taxonomy.taxons.build(params[:taxon]) diff --git a/app/views/spree/admin/taxons/search.rabl b/app/views/spree/admin/taxons/search.rabl deleted file mode 100644 index 5214337d12..0000000000 --- a/app/views/spree/admin/taxons/search.rabl +++ /dev/null @@ -1,4 +0,0 @@ -object false -child(@taxons => :taxons) do - attributes :name, :pretty_name, :id -end diff --git a/config/routes/spree.rb b/config/routes/spree.rb index 095350b699..1fb8d9c1d0 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -154,12 +154,6 @@ Spree::Core::Engine.routes.draw do resources :taxons end - resources :taxons, :only => [] do - collection do - get :search - end - end - resources :tax_rates resource :tax_settings resources :tax_categories From da2598282b08fcf80e4ce79fd6f42e41867d5cea Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 13:02:31 +0000 Subject: [PATCH 021/166] Can be object or {}, it's what the injector is doing, not related to rabl any more --- app/assets/javascripts/darkswarm/services/order_cycle.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee b/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee index 0c5176328b..c3f9a0a48f 100644 --- a/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee +++ b/app/assets/javascripts/darkswarm/services/order_cycle.js.coffee @@ -1,6 +1,6 @@ Darkswarm.factory 'OrderCycle', ($resource, orderCycleData) -> class OrderCycle - @order_cycle = orderCycleData # Object or {} due to RABL + @order_cycle = orderCycleData # Object or {} @push_order_cycle: (callback) -> new $resource("/shop/order_cycle").save {order_cycle_id: @order_cycle.order_cycle_id}, (order_data)-> OrderCycle.order_cycle.orders_close_at = order_data.orders_close_at From da837ff1005814e2f4592044184855d1abb4cdff Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 25 Feb 2020 13:03:55 +0000 Subject: [PATCH 022/166] Remove rabl dependency :tada: --- Gemfile | 1 - Gemfile.lock | 3 --- 2 files changed, 4 deletions(-) diff --git a/Gemfile b/Gemfile index e7613ec156..b3ee31f53e 100644 --- a/Gemfile +++ b/Gemfile @@ -59,7 +59,6 @@ gem 'aws-sdk' gem 'bugsnag' gem 'db2fog' gem 'haml' -gem 'rabl' gem 'redcarpet' gem 'sass', "~> 3.3" gem 'sass-rails', '~> 3.2.3' diff --git a/Gemfile.lock b/Gemfile.lock index 2870003606..759c81e2d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -518,8 +518,6 @@ GEM byebug (>= 9.0, < 9.1) pry (~> 0.10) public_suffix (4.0.3) - rabl (0.8.4) - activesupport (>= 2.3.14) rack (1.4.7) rack-cache (1.11.0) rack (>= 0.4) @@ -767,7 +765,6 @@ DEPENDENCIES paperclip (~> 3.4.1) pg (~> 0.21.0) pry-byebug (>= 3.4.3) - rabl rack-mini-profiler (< 3.0.0) rack-rewrite rack-ssl From 45b5e838b715938e0526ae13dcdf7bc1424987ec Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 17 Mar 2020 15:15:37 +0100 Subject: [PATCH 023/166] Remove simple_form It looks like we don't use this at all. Discovered during the Spree 2.1 upgrade. --- Gemfile | 4 - Gemfile.lock | 9 -- config/initializers/simple_form.rb | 138 ---------------------- config/locales/simple_form.en.yml | 25 ---- lib/templates/erb/scaffold/_form.html.erb | 13 -- 5 files changed, 189 deletions(-) delete mode 100644 config/initializers/simple_form.rb delete mode 100644 config/locales/simple_form.en.yml delete mode 100644 lib/templates/erb/scaffold/_form.html.erb diff --git a/Gemfile b/Gemfile index e7613ec156..c463a488b1 100644 --- a/Gemfile +++ b/Gemfile @@ -45,10 +45,6 @@ gem 'daemons' gem 'delayed_job_active_record' gem 'delayed_job_web' -# Fix bug in simple_form preventing collection_check_boxes usage within form_for block -# When merged, revert to upstream gem -gem 'simple_form', github: 'RohanM/simple_form' - # Spree's default pagination gem (locked to the current version used by Spree) # We use it's methods in OFN code as well, so this is a direct dependency gem 'kaminari', '~> 0.14.1' diff --git a/Gemfile.lock b/Gemfile.lock index 2870003606..190be2a7e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,3 @@ -GIT - remote: https://github.com/RohanM/simple_form.git - revision: 45f08a213b40f3d4bda5f5398db841137587160a - specs: - simple_form (2.0.2) - actionpack (~> 3.0) - activemodel (~> 3.0) - GIT remote: https://github.com/jeremydurham/custom-err-msg.git revision: 3a8ec9dddc7a5b0aab7c69a6060596de300c68f4 @@ -786,7 +778,6 @@ DEPENDENCIES select2-rails (~> 3.4.7) selenium-webdriver shoulda-matchers - simple_form! simplecov spinjs-rails spree_core! diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb deleted file mode 100644 index 59c7d2528b..0000000000 --- a/config/initializers/simple_form.rb +++ /dev/null @@ -1,138 +0,0 @@ -# Use this setup block to configure all options available in SimpleForm. -SimpleForm.setup do |config| - # Wrappers are used by the form builder to generate a - # complete input. You can remove any component from the - # wrapper, change the order or even add your own to the - # stack. The options given below are used to wrap the - # whole input. - config.wrappers :default, :class => :input, - :hint_class => :field_with_hint, :error_class => :field_with_errors do |b| - ## Extensions enabled by default - # Any of these extensions can be disabled for a - # given input by passing: `f.input EXTENSION_NAME => false`. - # You can make any of these extensions optional by - # renaming `b.use` to `b.optional`. - - # Determines whether to use HTML5 (:email, :url, ...) - # and required attributes - b.use :html5 - - # Calculates placeholders automatically from I18n - # You can also pass a string as f.input :placeholder => "Placeholder" - b.use :placeholder - - ## Optional extensions - # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup` - # to the input. If so, they will retrieve the values from the model - # if any exists. If you want to enable the lookup for any of those - # extensions by default, you can change `b.optional` to `b.use`. - - # Calculates maxlength from length validations for string inputs - b.optional :maxlength - - # Calculates pattern from format validations for string inputs - b.optional :pattern - - # Calculates min and max from length validations for numeric inputs - b.optional :min_max - - # Calculates readonly automatically from readonly attributes - b.optional :readonly - - ## Inputs - b.use :label_input - b.use :hint, :wrap_with => { :tag => :span, :class => :hint } - b.use :error, :wrap_with => { :tag => :span, :class => :error } - end - - # The default wrapper to be used by the FormBuilder. - config.default_wrapper = :default - - # Define the way to render check boxes / radio buttons with labels. - # Defaults to :nested for bootstrap config. - # :inline => input + label - # :nested => label > input - config.boolean_style = :nested - - # Default class for buttons - config.button_class = 'btn' - - # Method used to tidy up errors. Specify any Rails Array method. - # :first lists the first message for each field. - # Use :to_sentence to list all errors for each field. - # config.error_method = :first - - # Default tag used for error notification helper. - config.error_notification_tag = :div - - # CSS class to add for error notification helper. - config.error_notification_class = 'alert alert-error' - - # ID to add for error notification helper. - # config.error_notification_id = nil - - # Series of attempts to detect a default label method for collection. - # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] - - # Series of attempts to detect a default value method for collection. - # config.collection_value_methods = [ :id, :to_s ] - - # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. - # config.collection_wrapper_tag = nil - - # You can define the class to use on all collection wrappers. Defaulting to none. - # config.collection_wrapper_class = nil - - # You can wrap each item in a collection of radio/check boxes with a tag, - # defaulting to :span. Please note that when using :boolean_style = :nested, - # SimpleForm will force this option to be a label. - # config.item_wrapper_tag = :span - - # You can define a class to use in all item wrappers. Defaulting to none. - # config.item_wrapper_class = nil - - # How the label text should be generated altogether with the required text. - # config.label_text = lambda { |label, required| "#{required} #{label}" } - - # You can define the class to use on all labels. Default is nil. - config.label_class = 'control-label' - - # You can define the class to use on all forms. Default is simple_form. - # config.form_class = :simple_form - - # You can define which elements should obtain additional classes - # config.generate_additional_classes_for = [:wrapper, :label, :input] - - # Whether attributes are required by default (or not). Default is true. - # config.required_by_default = true - - # Tell browsers whether to use default HTML5 validations (novalidate option). - # Default is enabled. - config.browser_validations = false - - # Collection of methods to detect if a file type was given. - # config.file_methods = [ :mounted_as, :file?, :public_filename ] - - # Custom mappings for input types. This should be a hash containing a regexp - # to match as key, and the input type that will be used when the field name - # matches the regexp as value. - # config.input_mappings = { /count/ => :integer } - - # Default priority for time_zone inputs. - # config.time_zone_priority = nil - - # Default priority for country inputs. - # config.country_priority = nil - - # Default size for text inputs. - # config.default_input_size = 50 - - # When false, do not use translations for labels. - # config.translate_labels = true - - # Automatically discover new inputs in Rails' autoload path. - # config.inputs_discovery = true - - # Cache SimpleForm inputs discovery - # config.cache_discovery = !Rails.env.development? -end diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml deleted file mode 100644 index 9810cea163..0000000000 --- a/config/locales/simple_form.en.yml +++ /dev/null @@ -1,25 +0,0 @@ -en: - simple_form: - "yes": 'Yes' - "no": 'No' - required: - text: 'required' - mark: '*' - # You can uncomment the line below if you need to overwrite the whole required html. - # When using html, text and mark won't be used. - # html: '*' - error_notification: - default_message: "Please review the problems below:" - # Labels and hints examples - # labels: - # defaults: - # password: 'Password' - # user: - # new: - # email: 'E-mail to sign in.' - # edit: - # email: 'E-mail.' - # hints: - # defaults: - # username: 'User name to sign in.' - # password: 'No special characters, please.' diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb deleted file mode 100644 index 201a069e2c..0000000000 --- a/lib/templates/erb/scaffold/_form.html.erb +++ /dev/null @@ -1,13 +0,0 @@ -<%%= simple_form_for(@<%= singular_table_name %>) do |f| %> - <%%= f.error_notification %> - -
- <%- attributes.each do |attribute| -%> - <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %> - <%- end -%> -
- -
- <%%= f.button :submit %> -
-<%% end %> From a8078b22f889724684d0a65e4f596384d70b61ed Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 13 Mar 2020 10:11:46 +0000 Subject: [PATCH 024/166] Move enterprise fees summaries controller and views to ordermanagement engine --- .../enterprise_fee_summaries_controller.rb | 66 ------------------- .../enterprise_fee_summaries_controller.rb | 64 ++++++++++++++++++ .../_filters.html.haml | 0 .../_report.html.haml | 0 .../enterprise_fee_summaries/create.html.haml | 0 .../enterprise_fee_summaries/new.html.haml | 0 ...nterprise_fee_summaries_controller_spec.rb | 4 +- 7 files changed, 66 insertions(+), 68 deletions(-) delete mode 100644 app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb create mode 100644 engines/order_management/app/controllers/order_management/reports/enterprise_fee_summaries_controller.rb rename {app/views/spree/admin => engines/order_management/app/views/order_management}/reports/enterprise_fee_summaries/_filters.html.haml (100%) rename {app/views/spree/admin => engines/order_management/app/views/order_management}/reports/enterprise_fee_summaries/_report.html.haml (100%) rename {app/views/spree/admin => engines/order_management/app/views/order_management}/reports/enterprise_fee_summaries/create.html.haml (100%) rename {app/views/spree/admin => engines/order_management/app/views/order_management}/reports/enterprise_fee_summaries/new.html.haml (100%) rename {spec/controllers/spree/admin => engines/order_management/spec/controllers/order_management}/reports/enterprise_fee_summaries_controller_spec.rb (94%) diff --git a/app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb b/app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb deleted file mode 100644 index e6b750b904..0000000000 --- a/app/controllers/spree/admin/reports/enterprise_fee_summaries_controller.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Spree - module Admin - module Reports - class EnterpriseFeeSummariesController < BaseController - before_filter :load_report_parameters - before_filter :load_permissions - - def new; end - - def create - return respond_to_invalid_parameters unless @report_parameters.valid? - - @report_parameters.authorize!(@permissions) - - @report = report_klass::ReportService.new(@permissions, @report_parameters) - renderer.render(self) - rescue ::Reports::Authorizer::ParameterNotAllowedError => e - flash[:error] = e.message - render_report_form - end - - private - - def respond_to_invalid_parameters - flash[:error] = I18n.t("invalid_filter_parameters", scope: i18n_scope) - render_report_form - end - - def i18n_scope - "order_management.reports.enterprise_fee_summary" - end - - def render_report_form - render action: :new - end - - def report_klass - OrderManagement::Reports::EnterpriseFeeSummary - end - - def load_report_parameters - @report_parameters = report_klass::Parameters.new(params[:report] || {}) - end - - def load_permissions - @permissions = report_klass::Permissions.new(spree_current_user) - end - - def report_renderer_klass - case params[:report_format] - when "csv" - report_klass::Renderers::CsvRenderer - when nil, "", "html" - report_klass::Renderers::HtmlRenderer - else - raise Reports::UnsupportedReportFormatException - end - end - - def renderer - @renderer ||= report_renderer_klass.new(@report) - end - end - end - end -end diff --git a/engines/order_management/app/controllers/order_management/reports/enterprise_fee_summaries_controller.rb b/engines/order_management/app/controllers/order_management/reports/enterprise_fee_summaries_controller.rb new file mode 100644 index 0000000000..08b6c602c5 --- /dev/null +++ b/engines/order_management/app/controllers/order_management/reports/enterprise_fee_summaries_controller.rb @@ -0,0 +1,64 @@ +module OrderManagement + module Reports + class EnterpriseFeeSummariesController < Spree::Admin::BaseController + before_filter :load_report_parameters + before_filter :load_permissions + + def new; end + + def create + return respond_to_invalid_parameters unless @report_parameters.valid? + + @report_parameters.authorize!(@permissions) + + @report = report_klass::ReportService.new(@permissions, @report_parameters) + renderer.render(self) + rescue ::Reports::Authorizer::ParameterNotAllowedError => e + flash[:error] = e.message + render_report_form + end + + private + + def respond_to_invalid_parameters + flash[:error] = I18n.t("invalid_filter_parameters", scope: i18n_scope) + render_report_form + end + + def i18n_scope + "order_management.reports.enterprise_fee_summary" + end + + def render_report_form + render action: :new + end + + def report_klass + OrderManagement::Reports::EnterpriseFeeSummary + end + + def load_report_parameters + @report_parameters = report_klass::Parameters.new(params[:report] || {}) + end + + def load_permissions + @permissions = report_klass::Permissions.new(spree_current_user) + end + + def report_renderer_klass + case params[:report_format] + when "csv" + report_klass::Renderers::CsvRenderer + when nil, "", "html" + report_klass::Renderers::HtmlRenderer + else + raise Reports::UnsupportedReportFormatException + end + end + + def renderer + @renderer ||= report_renderer_klass.new(@report) + end + end + end +end diff --git a/app/views/spree/admin/reports/enterprise_fee_summaries/_filters.html.haml b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_filters.html.haml similarity index 100% rename from app/views/spree/admin/reports/enterprise_fee_summaries/_filters.html.haml rename to engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_filters.html.haml diff --git a/app/views/spree/admin/reports/enterprise_fee_summaries/_report.html.haml b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_report.html.haml similarity index 100% rename from app/views/spree/admin/reports/enterprise_fee_summaries/_report.html.haml rename to engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_report.html.haml diff --git a/app/views/spree/admin/reports/enterprise_fee_summaries/create.html.haml b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/create.html.haml similarity index 100% rename from app/views/spree/admin/reports/enterprise_fee_summaries/create.html.haml rename to engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/create.html.haml diff --git a/app/views/spree/admin/reports/enterprise_fee_summaries/new.html.haml b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/new.html.haml similarity index 100% rename from app/views/spree/admin/reports/enterprise_fee_summaries/new.html.haml rename to engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/new.html.haml diff --git a/spec/controllers/spree/admin/reports/enterprise_fee_summaries_controller_spec.rb b/engines/order_management/spec/controllers/order_management/reports/enterprise_fee_summaries_controller_spec.rb similarity index 94% rename from spec/controllers/spree/admin/reports/enterprise_fee_summaries_controller_spec.rb rename to engines/order_management/spec/controllers/order_management/reports/enterprise_fee_summaries_controller_spec.rb index d9d8962f9b..3282bd7258 100644 --- a/spec/controllers/spree/admin/reports/enterprise_fee_summaries_controller_spec.rb +++ b/engines/order_management/spec/controllers/order_management/reports/enterprise_fee_summaries_controller_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe Spree::Admin::Reports::EnterpriseFeeSummariesController, type: :controller do +describe OrderManagement::Reports::EnterpriseFeeSummariesController, type: :controller do let(:report_klass) { OrderManagement::Reports::EnterpriseFeeSummary } let!(:distributor) { create(:distributor_enterprise) } @@ -76,6 +76,6 @@ describe Spree::Admin::Reports::EnterpriseFeeSummariesController, type: :control end def new_template_path - "spree/admin/reports/enterprise_fee_summaries/new" + "order_management/reports/enterprise_fee_summaries/new" end end From e209452f8b06c577ba223258a9afbf00f94d2337 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 13 Mar 2020 10:13:37 +0000 Subject: [PATCH 025/166] Make engine routes just prepend to apps routes instead of creating engine routes This makes things a bit simpler in terms of routing, we avoid a problem running specs and we can still have the engine routes separated in specific files --- config/routes.rb | 5 ----- engines/order_management/config/routes.rb | 4 ++-- engines/web/config/routes.rb | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index ae3c131ac3..dcb828b3be 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -89,11 +89,6 @@ Openfoodnetwork::Application.routes.draw do get 'sitemap.xml', to: 'sitemap#index', defaults: { format: 'xml' } - # Mount engine routes - mount Web::Engine, :at => '/' - mount Catalog::Engine, :at => '/' - mount OrderManagement::Engine, :at => '/' - # Mount Spree's routes mount Spree::Core::Engine, :at => '/' end diff --git a/engines/order_management/config/routes.rb b/engines/order_management/config/routes.rb index e221867e7e..79706c635a 100644 --- a/engines/order_management/config/routes.rb +++ b/engines/order_management/config/routes.rb @@ -1,5 +1,5 @@ -Spree::Core::Engine.routes.prepend do - namespace :admin do +Openfoodnetwork::Application.routes.prepend do + namespace :order_management do namespace :reports do resource :enterprise_fee_summary, only: [:new, :create] end diff --git a/engines/web/config/routes.rb b/engines/web/config/routes.rb index 121f3bdd9a..9126f5f621 100644 --- a/engines/web/config/routes.rb +++ b/engines/web/config/routes.rb @@ -1,4 +1,4 @@ -Web::Engine.routes.draw do +Openfoodnetwork::Application.routes.prepend do namespace :api do scope '/cookies' do resource :consent, only: [:show, :create, :destroy], controller: "cookies_consent" From 0b05312f1940055a3881079a05bc0999c7205389 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 13 Mar 2020 10:37:59 +0000 Subject: [PATCH 026/166] Move cookies spec to web engine and adapt routes to the fact they are now normal main apps routes --- engines/web/config/routes.rb | 8 +++----- .../web/spec}/features/consumer/cookies_spec.rb | 0 2 files changed, 3 insertions(+), 5 deletions(-) rename {spec => engines/web/spec}/features/consumer/cookies_spec.rb (100%) diff --git a/engines/web/config/routes.rb b/engines/web/config/routes.rb index 9126f5f621..0b56f00a6d 100644 --- a/engines/web/config/routes.rb +++ b/engines/web/config/routes.rb @@ -1,9 +1,7 @@ Openfoodnetwork::Application.routes.prepend do - namespace :api do - scope '/cookies' do - resource :consent, only: [:show, :create, :destroy], controller: "cookies_consent" - end + scope '/api/cookies' do + resource :consent, only: [:show, :create, :destroy], controller: "web/api/cookies_consent" end - get "/angular-templates/:id", to: "angular_templates#show", constraints: { name: %r{[\/\w\.]+} } + get "/angular-templates/:id", to: "web/angular_templates#show", constraints: { name: %r{[\/\w\.]+} } end diff --git a/spec/features/consumer/cookies_spec.rb b/engines/web/spec/features/consumer/cookies_spec.rb similarity index 100% rename from spec/features/consumer/cookies_spec.rb rename to engines/web/spec/features/consumer/cookies_spec.rb From 58465c4645594818ec2cfbd8d11f35f080b5148c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 16 Mar 2020 20:19:04 +0000 Subject: [PATCH 027/166] Adapt routes placeholder in the new catalog engine to make it similar to the other engines --- engines/catalog/config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/catalog/config/routes.rb b/engines/catalog/config/routes.rb index a56f4a0b70..166898de46 100644 --- a/engines/catalog/config/routes.rb +++ b/engines/catalog/config/routes.rb @@ -1,2 +1,2 @@ -Catalog::Engine.routes.draw do +Openfoodnetwork::Application.routes.prepend do end From b4befea60651e4894d7938f1cdda43a528f73d8e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 16 Mar 2020 23:44:32 +0000 Subject: [PATCH 028/166] Fix namespace in spec --- .../enterprise_fee_summary/renderers/html_renderer_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb b/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb index 5b9c62b03c..1bd591e021 100644 --- a/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb +++ b/engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/renderers/html_renderer_spec.rb @@ -5,7 +5,7 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::Renderers::HtmlRenderer let!(:permissions) { report_klass::Permissions.new(current_user) } let!(:parameters) { report_klass::Parameters.new } - let!(:controller) { Spree::Admin::Reports::EnterpriseFeeSummariesController.new } + let!(:controller) { OrderManagement::Reports::EnterpriseFeeSummariesController.new } let!(:service) { report_klass::ReportService.new(permissions, parameters) } let!(:renderer) { described_class.new(service) } From 3f5a964dec6d0d3add6292cb74227d7674f51e44 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 18 Mar 2020 12:09:12 +0000 Subject: [PATCH 029/166] Move enterprise_fee_summaries_spec to order_management engine, moving translation keys for the views and adapting some routes --- config/locales/en.yml | 16 ++++++++-------- .../enterprise_fee_summaries/_filters.html.haml | 2 +- .../enterprise_fee_summaries/_report.html.haml | 2 +- .../reports/enterprise_fee_summaries_spec.rb | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) rename {spec/features/admin => engines/order_management/spec/features/order_management}/reports/enterprise_fee_summaries_spec.rb (93%) diff --git a/config/locales/en.yml b/config/locales/en.yml index 804ccbbcef..e407732f70 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2816,6 +2816,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using order_management: reports: + enterprise_fee_summaries: + filters: + date_range: "Date Range" + report_format_csv: "Download as CSV" + generate_report: "Generate Report" + report: + none: "None" + select_and_search: "Select filters and click on GENERATE REPORT to access your data." enterprise_fee_summary: date_end_before_start_error: "must be after start" parameter_not_allowed_error: "You are not authorized to use one or more selected filters for this report." @@ -3318,14 +3326,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using bulk_coop_allocation: 'Bulk Co-op - Allocation' bulk_coop_packing_sheets: 'Bulk Co-op - Packing Sheets' bulk_coop_customer_payments: 'Bulk Co-op - Customer Payments' - enterprise_fee_summaries: - filters: - date_range: "Date Range" - report_format_csv: "Download as CSV" - generate_report: "Generate Report" - report: - none: "None" - select_and_search: "Select filters and click on GENERATE REPORT to access your data." users: index: listing_users: "Listing Users" diff --git a/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_filters.html.haml b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_filters.html.haml index 744097e9a5..0aee85d71e 100644 --- a/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_filters.html.haml +++ b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_filters.html.haml @@ -1,4 +1,4 @@ -= form_for @report_parameters, as: :report, url: spree.admin_reports_enterprise_fee_summary_path, method: :post do |f| += form_for @report_parameters, as: :report, url: main_app.order_management_reports_enterprise_fee_summary_path, method: :post do |f| .row.date-range-filter .sixteen.columns.alpha = label_tag nil, t(".date_range") diff --git a/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_report.html.haml b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_report.html.haml index 4427c511ba..332253b143 100644 --- a/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_report.html.haml +++ b/engines/order_management/app/views/order_management/reports/enterprise_fee_summaries/_report.html.haml @@ -13,7 +13,7 @@ - if @renderer.data_rows.empty? %tr - %td{colspan: @renderer.header.length}= t(:none) + %td{colspan: @renderer.header.length}= t('.none') - else %p.report__message = t(".select_and_search") diff --git a/spec/features/admin/reports/enterprise_fee_summaries_spec.rb b/engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb similarity index 93% rename from spec/features/admin/reports/enterprise_fee_summaries_spec.rb rename to engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb index 57a8de346e..7930ea75a3 100644 --- a/spec/features/admin/reports/enterprise_fee_summaries_spec.rb +++ b/engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb @@ -41,7 +41,7 @@ feature "enterprise fee summaries", js: true do it "does not allow access to the report" do visit spree.admin_reports_path expect(page).to have_no_link(I18n.t("admin.reports.enterprise_fee_summary.name")) - visit spree.new_admin_reports_enterprise_fee_summary_path + visit main_app.new_order_management_reports_enterprise_fee_summary_path expect(page).to have_content(I18n.t("unauthorized")) end end @@ -49,7 +49,7 @@ feature "enterprise fee summaries", js: true do describe "smoke test for filters" do before do - visit spree.new_admin_reports_enterprise_fee_summary_path + visit main_app.new_order_management_reports_enterprise_fee_summary_path end context "when logged in as admin" do @@ -80,7 +80,7 @@ feature "enterprise fee summaries", js: true do describe "smoke test for generation of report based on permissions" do before do - visit spree.new_admin_reports_enterprise_fee_summary_path + visit main_app.new_order_management_reports_enterprise_fee_summary_path end context "when logged in as admin" do @@ -138,7 +138,7 @@ feature "enterprise fee summaries", js: true do let(:current_user) { create(:admin_user) } before do - visit spree.new_admin_reports_enterprise_fee_summary_path + visit main_app.new_order_management_reports_enterprise_fee_summary_path end it "generates file with data for selected order cycle" do @@ -155,6 +155,6 @@ feature "enterprise fee summaries", js: true do end def i18n_scope - "spree.admin.reports.enterprise_fee_summaries" + "order_management.reports.enterprise_fee_summaries" end end From 9994bc75ca929f0c54835a40d406bac6ed54298a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 18 Mar 2020 12:11:27 +0000 Subject: [PATCH 030/166] Adapt reports controller to handle routes of reports in the order_management engine differently --- app/controllers/spree/admin/reports_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index ec08bca29c..9583fe7134 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -298,11 +298,20 @@ module Spree end def url_for_report(report) - public_send("#{report}_admin_reports_url".to_sym) + if report_in_order_management_engine?(report) + main_app.public_send("new_order_management_reports_#{report}_url".to_sym) + else + public_send("#{report}_admin_reports_url".to_sym) + end rescue NoMethodError url_for([:new, :admin, :reports, report.to_s.singularize]) end + # List of reports that have been moved to the Order Management engine + def report_in_order_management_engine?(report) + report == :enterprise_fee_summary + end + def timestamp Time.zone.now.strftime("%Y%m%d") end From e014e6c1a4f9e9625813d8850daec2168b637acf Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:12:42 +0100 Subject: [PATCH 031/166] Ensure perform_deliveries is correctly set when testing user confirmation emails --- spec/models/spree/user_spec.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb index d73042c67a..7ed818fee2 100644 --- a/spec/models/spree/user_spec.rb +++ b/spec/models/spree/user_spec.rb @@ -76,9 +76,11 @@ describe Spree.user_class do it "should send a confirmation email" do setup_email - expect do - create(:user, email: 'new_user@example.com', confirmation_sent_at: nil, confirmed_at: nil) - end.to send_confirmation_instructions + performing_deliveries do + expect do + create(:user, email: 'new_user@example.com', confirmation_sent_at: nil, confirmed_at: nil) + end.to send_confirmation_instructions + end sent_mail = ActionMailer::Base.deliveries.last expect(sent_mail.to).to eq ['new_user@example.com'] From 2e4f8003b62e2085d074dfba901ff56297b96242 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 24 Mar 2020 19:16:49 +0000 Subject: [PATCH 032/166] Fix group factory in rails 4 params[:address] was breaking the creation of the EnterpriseGroup --- lib/tasks/sample_data/group_factory.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/tasks/sample_data/group_factory.rb b/lib/tasks/sample_data/group_factory.rb index 15e1ed1fb9..1e63866582 100644 --- a/lib/tasks/sample_data/group_factory.rb +++ b/lib/tasks/sample_data/group_factory.rb @@ -10,19 +10,21 @@ class GroupFactory return if EnterpriseGroup.where(name: "Producer group").exists? create_group( - name: "Producer group", - owner: enterprises.first.owner, - on_front_page: true, - description: "The seed producers", - address: "6 Rollings Road, Upper Ferntree Gully, 3156" + { + name: "Producer group", + owner: enterprises.first.owner, + on_front_page: true, + description: "The seed producers" + }, + "6 Rollings Road, Upper Ferntree Gully, 3156" ) end private - def create_group(params) + def create_group(params, group_address) group = EnterpriseGroup.new(params) - group.address = address(params[:address]) + group.address = address(group_address) group.enterprises = enterprises group.save! end From e5e9325499c442f1701db58806c22e803723955d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 24 Mar 2020 19:17:16 +0000 Subject: [PATCH 033/166] Fix paper_trail custom_data for order_cycle, custom data must be a string, cant be an array --- app/models/order_cycle.rb | 2 +- app/models/schedule.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index e9afe06e5a..c4b0bbcda3 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -17,7 +17,7 @@ class OrderCycle < ActiveRecord::Base has_many :distributors, source: :receiver, through: :cached_outgoing_exchanges, uniq: true has_and_belongs_to_many :schedules, join_table: 'order_cycle_schedules' - has_paper_trail meta: { custom_data: :schedule_ids } + has_paper_trail meta: { custom_data: proc { |order_cycle| order_cycle.schedule_ids.to_s } } attr_accessor :incoming_exchanges, :outgoing_exchanges diff --git a/app/models/schedule.rb b/app/models/schedule.rb index 1f8c5b9b3a..3c5bf1918d 100644 --- a/app/models/schedule.rb +++ b/app/models/schedule.rb @@ -1,6 +1,6 @@ class Schedule < ActiveRecord::Base has_and_belongs_to_many :order_cycles, join_table: 'order_cycle_schedules' - has_paper_trail meta: { custom_data: :order_cycle_ids } + has_paper_trail meta: { custom_data: proc { |schedule| schedule.order_cycle_ids.to_s } } has_many :coordinators, uniq: true, through: :order_cycles From 904e89e325ca9e2d7fe39ce8cbc0ac6b59f838d2 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 27 Mar 2020 12:17:09 +0100 Subject: [PATCH 034/166] Do not reset the dev env when booting docker The current web container's command destroys anything you might have in your local DB from a previous session, assuming you always want start from a clean environment. This is hardly the case and makes `docker-compose up` take quite long. What if you just stopped containers temporally while developing? This changes the approach to not assume anything. If you need to install a new gem or reset your DB just run the commands you would without docker. You can run anything you want with `docker-compose run web bundle exec ` anyway. For someone setting things for the first time, the `Dockerfile` process still installs all dependencies. --- docker-compose.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5025cfd929..f4407eb6a4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,10 +28,7 @@ services: ADMIN_PASSWORD: ofn123 OFN_DB_HOST: db command: > - bash -c "(bundle check || bundle install) && - wait-for-it -t 30 db:5432 && - bundle exec rake db:reset && - bundle exec rake db:test:prepare ofn:sample_data || true && + bash -c "wait-for-it -t 30 db:5432 && rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" From 69b57544f15790b5d1dd4fb68bdd41f15936da32 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 4 Mar 2020 15:18:04 +0000 Subject: [PATCH 035/166] Bring Spree::Variant#active so that we can make it return just variants without includes This makes the variants returned not readonly in rails 4 and thus fixes a spec in Spree::VariantsController#destroy --- app/models/spree/variant_decorator.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index 566394d946..bd4b2bcb14 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -85,6 +85,10 @@ Spree::Variant.class_eval do ] end + def self.active(currency = nil) + where(id: joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL').select("spree_variants.id")) + end + # We override in_stock? to avoid depending on the non-overridable method Spree::Stock::Quantifier.can_supply? # VariantStock implements can_supply? itself which depends on overridable methods def in_stock?(quantity = 1) From a5184cce9d16882c38b05472e3d14c823f271c76 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 22 Mar 2020 10:01:46 +0000 Subject: [PATCH 036/166] Make method a bit more readable and add comment with details --- app/models/spree/variant_decorator.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index bd4b2bcb14..3bc8c10fe2 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -86,7 +86,13 @@ Spree::Variant.class_eval do end def self.active(currency = nil) - where(id: joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL').select("spree_variants.id")) + # "where(id:" is necessary so that the returned relation has no includes + # The relation without includes will not be readonly and allow updates on it + where(id: joins(:prices). + where(deleted_at: nil). + where('spree_prices.currency' => currency || Spree::Config[:currency]). + where('spree_prices.amount IS NOT NULL'). + select("spree_variants.id")) end # We override in_stock? to avoid depending on the non-overridable method Spree::Stock::Quantifier.can_supply? From fbbe586996dd4a1fd55c9d15a7386431de79259b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 27 Mar 2020 09:52:45 +0000 Subject: [PATCH 037/166] Avoid rails 3 bug where the first where clause is overriden by a second where clause Co-Authored-By: Maikel --- app/models/spree/variant_decorator.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index 3bc8c10fe2..a1c4aa2fab 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -88,11 +88,12 @@ Spree::Variant.class_eval do def self.active(currency = nil) # "where(id:" is necessary so that the returned relation has no includes # The relation without includes will not be readonly and allow updates on it - where(id: joins(:prices). - where(deleted_at: nil). - where('spree_prices.currency' => currency || Spree::Config[:currency]). - where('spree_prices.amount IS NOT NULL'). - select("spree_variants.id")) + where("spree_variants.id in (?)", joins(:prices). + where(deleted_at: nil). + where('spree_prices.currency' => + currency || Spree::Config[:currency]). + where('spree_prices.amount IS NOT NULL'). + select("spree_variants.id")) end # We override in_stock? to avoid depending on the non-overridable method Spree::Stock::Quantifier.can_supply? From 635ea9c5050044593b4df9d30066c85673da8204 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 27 Mar 2020 10:05:25 +0000 Subject: [PATCH 038/166] Fix some long lines on variant_decorator --- .rubocop_manual_todo.yml | 1 - app/models/spree/variant_decorator.rb | 23 ++++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 77b598ad3c..2ae337c9bd 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -89,7 +89,6 @@ Layout/LineLength: - app/models/spree/tax_rate_decorator.rb - app/models/spree/taxon_decorator.rb - app/models/spree/user.rb - - app/models/spree/variant_decorator.rb - app/models/subscription.rb - app/models/variant_override.rb - app/models/variant_override_set.rb diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index a1c4aa2fab..c23ab202cd 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -16,7 +16,8 @@ Spree::Variant.class_eval do has_many :variant_overrides has_many :inventory_items - attr_accessible :unit_value, :unit_description, :images_attributes, :display_as, :display_name, :import_date + attr_accessible :unit_value, :unit_description, :images_attributes, + :display_as, :display_name, :import_date accepts_nested_attributes_for :images validates :unit_value, presence: true, if: ->(variant) { @@ -53,13 +54,23 @@ Spree::Variant.class_eval do } scope :visible_for, lambda { |enterprise| - joins(:inventory_items).where('inventory_items.enterprise_id = (?) AND inventory_items.visible = (?)', enterprise, true) + joins(:inventory_items). + where( + 'inventory_items.enterprise_id = (?) AND inventory_items.visible = (?)', + enterprise, + true + ) } scope :not_hidden_for, lambda { |enterprise| return where("1=0") if enterprise.blank? - joins("LEFT OUTER JOIN (SELECT * from inventory_items WHERE enterprise_id = #{sanitize enterprise.andand.id}) AS o_inventory_items ON o_inventory_items.variant_id = spree_variants.id") + joins(" + LEFT OUTER JOIN (SELECT * + FROM inventory_items + WHERE enterprise_id = #{sanitize enterprise.andand.id}) + AS o_inventory_items + ON o_inventory_items.variant_id = spree_variants.id") .where("o_inventory_items.id IS NULL OR o_inventory_items.visible = (?)", true) } @@ -68,7 +79,8 @@ Spree::Variant.class_eval do scope :stockable_by, lambda { |enterprise| return where("1=0") if enterprise.blank? - joins(:product).where(spree_products: { id: Spree::Product.stockable_by(enterprise).pluck(:id) }) + joins(:product). + where(spree_products: { id: Spree::Product.stockable_by(enterprise).pluck(:id) }) } # Define sope as class method to allow chaining with other scopes filtering id. @@ -96,7 +108,8 @@ Spree::Variant.class_eval do select("spree_variants.id")) end - # We override in_stock? to avoid depending on the non-overridable method Spree::Stock::Quantifier.can_supply? + # We override in_stock? to avoid depending + # on the non-overridable method Spree::Stock::Quantifier.can_supply? # VariantStock implements can_supply? itself which depends on overridable methods def in_stock?(quantity = 1) can_supply?(quantity) From 5b4dd5738020470e4722f0c6e6015a1362deaee8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2020 19:15:11 +0000 Subject: [PATCH 039/166] Bump rubocop-rails from 2.5.0 to 2.5.1 Bumps [rubocop-rails](https://github.com/rubocop-hq/rubocop-rails) from 2.5.0 to 2.5.1. - [Release notes](https://github.com/rubocop-hq/rubocop-rails/releases) - [Changelog](https://github.com/rubocop-hq/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop-hq/rubocop-rails/compare/v2.5.0...v2.5.1) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a8d86824fe..f6f39e81ad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -602,7 +602,7 @@ GEM rexml ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-rails (2.5.0) + rubocop-rails (2.5.1) activesupport rack (>= 1.1) rubocop (>= 0.72.0) From 97063bf47ee3588e7c6722e844e15ba24b77074f Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 3 Apr 2020 23:24:25 +1100 Subject: [PATCH 040/166] Updating translations for config/locales/en_GB.yml --- config/locales/en_GB.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index dfa17eb46e..a29c2fb0eb 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -31,6 +31,10 @@ en_GB: taken: "There's already an account for this email. Please login or reset your password." spree/order: no_card: There are no authorised credit cards available to charge + spree/credit_card: + attributes: + base: + card_expired: "has expired" order_cycle: attributes: orders_close_at: From a049e7a4332ee98bae1019896d1a949545eb8067 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 3 Apr 2020 14:48:06 +0100 Subject: [PATCH 041/166] Add product to includes to avoid N+1 queries to fetch products when VO authorization is done right after this --- app/controllers/admin/variant_overrides_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index e12b43825b..b644536215 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -73,8 +73,10 @@ module Admin end def collection - @variant_overrides = VariantOverride.includes(:variant).for_hubs(params[:hub_id] || @hubs) - @variant_overrides.select { |vo| vo.variant.present? } + @variant_overrides = VariantOverride. + includes(variant: :product). + for_hubs(params[:hub_id] || @hubs). + select { |vo| vo.variant.present? } end def collection_actions From 452ab3a842dde430a0c084b9970dff76440fa286 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 3 Apr 2020 15:36:19 +0100 Subject: [PATCH 042/166] Add comment to better explain variant_override_set.collection_to_delete --- app/models/variant_override_set.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/variant_override_set.rb b/app/models/variant_override_set.rb index c64b4cdc32..d380df4144 100644 --- a/app/models/variant_override_set.rb +++ b/app/models/variant_override_set.rb @@ -15,8 +15,10 @@ class VariantOverrideSet < ModelSet tag_list.empty? end + # Override of ModelSet method to allow us to check presence of a tag_list (which is not an attribute) + # This method will delete VariantOverrides that have no values (see deletable? above) + # If the user sets all values to nil in the UI the VO will be deleted from the DB def collection_to_delete - # Override of ModelSet method to allow us to check presence of a tag_list (which is not an attribute) deleted = [] collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes, e.tag_list) } deleted From 55b3f4d54ffc76182d56a7453e335de68f5a2b25 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 3 Apr 2020 19:47:33 +0100 Subject: [PATCH 043/166] Move search params test case to a different context so that we dont have to set the producer of the products in the order This is working in master by chance of the factories but breaks in rails 4 because the orders in this test dont have products supplied by the producer which is a necessary condition in the context where it was --- spec/services/permissions/order_spec.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/services/permissions/order_spec.rb b/spec/services/permissions/order_spec.rb index d60d6968e2..88e3666aca 100644 --- a/spec/services/permissions/order_spec.rb +++ b/spec/services/permissions/order_spec.rb @@ -47,6 +47,18 @@ module Permissions it "should let me see the order" do expect(permissions.visible_orders).to include order end + + context "with search params" do + let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } } + let(:permissions) { Permissions::Order.new(user, search_params) } + + it "only returns completed, non-cancelled orders within search filter range" do + expect(permissions.visible_orders).to include order_completed + expect(permissions.visible_orders).to_not include order_cancelled + expect(permissions.visible_orders).to_not include order_cart + expect(permissions.visible_orders).to_not include order_from_last_year + end + end end context "as a producer which has granted P-OC to the distributor of an order" do @@ -71,18 +83,6 @@ module Permissions expect(permissions.visible_orders).to_not include order end end - - context "with search params" do - let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } } - let(:permissions) { Permissions::Order.new(user, search_params) } - - it "only returns completed, non-cancelled orders within search filter range" do - expect(permissions.visible_orders).to include order_completed - expect(permissions.visible_orders).to_not include order_cancelled - expect(permissions.visible_orders).to_not include order_cart - expect(permissions.visible_orders).to_not include order_from_last_year - end - end end context "as an enterprise that is a distributor in the order cycle, but not the distributor of the order" do From 8a544f3ab3566d80ae74f1dabd2646f4220f0eb4 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 4 Apr 2020 10:12:15 +0200 Subject: [PATCH 044/166] Add missing indexes to spree_orders and spree_products --- .../20200404080853_add_user_id_index_to_spree_orders.rb | 5 +++++ ...20200404081018_add_supplier_id_index_to_spree_products.rb | 5 +++++ db/schema.rb | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb create mode 100644 db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb diff --git a/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb b/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb new file mode 100644 index 0000000000..cb8ef67b0e --- /dev/null +++ b/db/migrate/20200404080853_add_user_id_index_to_spree_orders.rb @@ -0,0 +1,5 @@ +class AddUserIdIndexToSpreeOrders < ActiveRecord::Migration + def change + add_index :spree_orders, :user_id + end +end diff --git a/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb b/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb new file mode 100644 index 0000000000..eadc5a7c50 --- /dev/null +++ b/db/migrate/20200404081018_add_supplier_id_index_to_spree_products.rb @@ -0,0 +1,5 @@ +class AddSupplierIdIndexToSpreeProducts < ActiveRecord::Migration + def change + add_index :spree_products, :supplier_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 40badc11bf..8d6a796309 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20200327105910) do +ActiveRecord::Schema.define(:version => 20200404081018) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -575,6 +575,7 @@ ActiveRecord::Schema.define(:version => 20200327105910) do add_index "spree_orders", ["distributor_id"], :name => "index_spree_orders_on_distributor_id" add_index "spree_orders", ["number"], :name => "index_orders_on_number" add_index "spree_orders", ["order_cycle_id"], :name => "index_spree_orders_on_order_cycle_id" + add_index "spree_orders", ["user_id"], :name => "index_spree_orders_on_user_id" create_table "spree_payment_methods", :force => true do |t| t.string "type" @@ -724,6 +725,7 @@ ActiveRecord::Schema.define(:version => 20200327105910) do add_index "spree_products", ["permalink"], :name => "index_products_on_permalink" add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true add_index "spree_products", ["primary_taxon_id"], :name => "index_spree_products_on_primary_taxon_id" + add_index "spree_products", ["supplier_id"], :name => "index_spree_products_on_supplier_id" create_table "spree_products_promotion_rules", :id => false, :force => true do |t| t.integer "product_id" From af48cac1400c3f0a3b83e8e842f46fa2b03777f0 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 4 Apr 2020 13:15:42 +0200 Subject: [PATCH 045/166] Load closed shops in a separate request on /shops page --- .../enterprises_controller.js.coffee | 9 ++++++++ .../services/enterprise_resource.js.coffee | 4 ++++ .../darkswarm/services/enterprises.js.coffee | 19 +++++++++++---- app/controllers/api/enterprises_controller.rb | 15 +++++++++++- app/controllers/shops_controller.rb | 9 +------- app/services/shops_list_service.rb | 23 +++++++++++++++++++ config/routes/api.rb | 4 ++++ .../api/enterprises_controller_spec.rb | 16 +++++++++++-- spec/controllers/shops_controller_spec.rb | 6 +---- .../services/enterprise_spec.js.coffee | 8 ++++--- 10 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 app/services/shops_list_service.rb diff --git a/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee index 4f85093df5..280e584562 100644 --- a/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee @@ -9,8 +9,12 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location $scope.show_closed = false $scope.filtersActive = false $scope.distanceMatchesShown = false + $scope.closed_shops_loaded = false $scope.$watch "query", (query)-> + $scope.resetSearch(query) + + $scope.resetSearch = (query) -> Enterprises.flagMatching query Search.search query $rootScope.$broadcast 'enterprisesChanged' @@ -73,6 +77,11 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location undefined $scope.showClosedShops = -> + unless $scope.closed_shops_loaded + $scope.closed_shops_loaded = true + Enterprises.loadClosedEnterprises().then -> + $scope.resetSearch($scope.query) + $scope.show_closed = true $location.search('show_closed', '1') diff --git a/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee index e66ec7c176..06b362216c 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee @@ -5,4 +5,8 @@ Darkswarm.factory 'EnterpriseResource', ($resource) -> url: '/enterprises/:id/relatives.json' isArray: true cache: true + 'closed_shops': + method: 'GET' + isArray: true + url: '/api/enterprises/closed_shops.json' }) diff --git a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee index b7b43ca040..57f4fd6f82 100644 --- a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee @@ -1,27 +1,30 @@ -Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) -> +Darkswarm.factory 'Enterprises', (enterprises, EnterpriseResource, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) -> new class Enterprises + enterprises: [] enterprises_by_id: {} constructor: -> # Populate Enterprises.enterprises from json in page. - @enterprises = enterprises + @initEnterprises(enterprises) + initEnterprises: (enterprises) -> # Map enterprises to id/object pairs for lookup. for enterprise in enterprises + @enterprises.push enterprise @enterprises_by_id[enterprise.id] = enterprise # Replace enterprise and taxons ids with actual objects. - @dereferenceEnterprises() + @dereferenceEnterprises(enterprises) @producers = @enterprises.filter (enterprise)-> enterprise.category in ["producer_hub", "producer_shop", "producer"] @hubs = @enterprises.filter (enterprise)-> enterprise.category in ["hub", "hub_profile", "producer_hub", "producer_shop"] - dereferenceEnterprises: -> + dereferenceEnterprises: (enteprises) -> if CurrentHub.hub?.id CurrentHub.hub = @enterprises_by_id[CurrentHub.hub.id] - for enterprise in @enterprises + for enterprise in enterprises @dereferenceEnterprise enterprise dereferenceEnterprise: (enterprise) -> @@ -42,6 +45,12 @@ Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer, for enterprise in new_enterprises @enterprises_by_id[enterprise.id] = enterprise + loadClosedEnterprises: -> + request = EnterpriseResource.closed_shops {}, (data) => + @initEnterprises(data) + + request.$promise + flagMatching: (query) -> for enterprise in @enterprises enterprise.matches_name_query = if query? && query.length > 0 diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index 82ae80d31e..6ebeb378b3 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -5,7 +5,7 @@ module Api before_filter :override_sells, only: [:create, :update] before_filter :override_visible, only: [:create, :update] respond_to :json - skip_authorization_check only: [:shopfront] + skip_authorization_check only: [:shopfront, :closed_shops] def create authorize! :create, Enterprise @@ -48,6 +48,19 @@ module Api render text: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok end + def closed_shops + @active_distributor_ids = [] + @earliest_closing_times = [] + + serialized_closed_shops = ActiveModel::ArraySerializer.new( + ShopsListService.new.closed_shops, + each_serializer: Api::EnterpriseSerializer, + data: OpenFoodNetwork::EnterpriseInjectionData.new + ) + + render json: serialized_closed_shops + end + private def override_owner diff --git a/app/controllers/shops_controller.rb b/app/controllers/shops_controller.rb index d4f350b47f..b57c6f5063 100644 --- a/app/controllers/shops_controller.rb +++ b/app/controllers/shops_controller.rb @@ -4,13 +4,6 @@ class ShopsController < BaseController before_filter :enable_embedded_shopfront def index - @enterprises = Enterprise - .activated - .visible - .is_distributor - .includes(address: [:state, :country]) - .includes(:properties) - .includes(supplied_products: :properties) - .all + @enterprises = ShopsListService.new.open_shops end end diff --git a/app/services/shops_list_service.rb b/app/services/shops_list_service.rb new file mode 100644 index 0000000000..030010bea1 --- /dev/null +++ b/app/services/shops_list_service.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class ShopsListService + def open_shops + shops_list.ready_for_checkout.all + end + + def closed_shops + shops_list.not_ready_for_checkout.all + end + + private + + def shops_list + Enterprise + .activated + .visible + .is_distributor + .includes(address: [:state, :country]) + .includes(:properties) + .includes(supplied_products: :properties) + end +end diff --git a/config/routes/api.rb b/config/routes/api.rb index fbd7b23378..8f2ff18972 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -37,6 +37,10 @@ Openfoodnetwork::Application.routes.draw do member do get :shopfront end + + collection do + get :closed_shops + end end resources :order_cycles do diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index d2b27c1254..dc5c39b476 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -90,13 +90,15 @@ module Api let!(:category) { create(:taxon, name: 'Fruit') } let!(:product) { create(:product, supplier: producer, primary_taxon: category ) } let!(:relationship) { create(:enterprise_relationship, parent: hub, child: producer) } + let!(:closed_hub1) { create(:distributor_enterprise) } + let!(:closed_hub2) { create(:distributor_enterprise) } before do allow(controller).to receive(:spree_current_user) { nil } end - describe "fetching shopfronts data" do - it "returns data for an enterprise" do + describe "#shopfront" do + it "returns shopfront data for an enterprise" do spree_get :shopfront, id: producer.id, format: :json expect(json_response['name']).to eq 'Shopfront Test Producer' @@ -104,6 +106,16 @@ module Api expect(json_response['supplied_taxons'][0]['name']).to eq 'Fruit' end end + + describe "#closed_shops" do + it "returns data for all closed shops" do + spree_get :closed_shops, nil, format: :json + + expect(json_response).not_to match hub.name + expect(json_response[0]['id']).to eq closed_hub1.id + expect(json_response[1]['id']).to eq closed_hub2.id + end + end end end end diff --git a/spec/controllers/shops_controller_spec.rb b/spec/controllers/shops_controller_spec.rb index 023e7b0245..9d468b7995 100644 --- a/spec/controllers/shops_controller_spec.rb +++ b/spec/controllers/shops_controller_spec.rb @@ -4,11 +4,7 @@ describe ShopsController, type: :controller do include WebHelper render_views - let!(:distributor) { create(:distributor_enterprise) } - - before do - allow(OpenFoodNetwork::EnterpriseInjectionData).to receive(:active_distributor_ids) { [distributor.id] } - end + let!(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } it 'renders distributed product properties' do product_property = create(:property, presentation: 'eggs') diff --git a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee index 8b393a6aab..82c26397ca 100644 --- a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee @@ -1,5 +1,5 @@ describe "Enterprises service", -> - Enterprises = null + Enterprises = $rootScope = null CurrentHubMock = {} Geo = OK: 'ok' @@ -36,15 +36,17 @@ describe "Enterprises service", -> angular.module('Darkswarm').value('enterprises', enterprises) angular.module('Darkswarm').value('taxons', taxons) - inject ($injector)-> + inject ($injector, _$rootScope_)-> Enterprises = $injector.get("Enterprises") + $rootScope = _$rootScope_ it "stores enterprises as id/object pairs", -> expect(Enterprises.enterprises_by_id["1"]).toBe enterprises[0] expect(Enterprises.enterprises_by_id["2"]).toBe enterprises[1] it "stores enterprises as an array", -> - expect(Enterprises.enterprises).toBe enterprises + $rootScope.$digest() + expect(Enterprises.enterprises).toEqual enterprises it "puts the same objects in enterprises and enterprises_by_id", -> expect(Enterprises.enterprises[0]).toBe Enterprises.enterprises_by_id["1"] From bc859cf9f70f9c299f368bb17556de3a7be07773 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 4 Apr 2020 16:28:04 +0200 Subject: [PATCH 046/166] Add api/shops_controller and refactor --- .../controllers/hub_node_controller.js.coffee | 2 +- .../producer_node_controller.js.coffee | 2 +- .../services/enterprise_modal.js.coffee | 2 +- .../services/enterprise_resource.js.coffee | 4 -- .../darkswarm/services/enterprises.js.coffee | 4 +- .../services/shops_resource.js.coffee | 7 +++ app/controllers/api/enterprises_controller.rb | 20 -------- app/controllers/api/shops_controller.rb | 27 +++++++++++ config/routes/api.rb | 6 +-- .../api/enterprises_controller_spec.rb | 36 --------------- spec/controllers/api/shops_controller_spec.rb | 46 +++++++++++++++++++ 11 files changed, 87 insertions(+), 69 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/services/shops_resource.js.coffee create mode 100644 app/controllers/api/shops_controller.rb create mode 100644 spec/controllers/api/shops_controller_spec.rb diff --git a/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee index 8b0a1159e6..f96d2d454f 100644 --- a/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/hub_node_controller.js.coffee @@ -24,7 +24,7 @@ Darkswarm.controller "HubNodeCtrl", ($scope, HashNavigation, CurrentHub, $http, $scope.shopfront_loading = true $scope.toggle_tab(event) - $http.get("/api/enterprises/" + $scope.hub.id + "/shopfront") + $http.get("/api/shops/" + $scope.hub.id) .success (data) -> $scope.shopfront_loading = false $scope.hub = data diff --git a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee index 0cacb566d5..3aa5045bee 100644 --- a/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/producer_node_controller.js.coffee @@ -24,7 +24,7 @@ Darkswarm.controller "ProducerNodeCtrl", ($scope, HashNavigation, $anchorScroll, $scope.shopfront_loading = true $scope.toggle_tab(event) - $http.get("/api/enterprises/" + $scope.producer.id + "/shopfront") + $http.get("/api/shops/" + $scope.producer.id) .success (data) -> $scope.shopfront_loading = false $scope.producer = data diff --git a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee index 19361fe508..37dafef776 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee @@ -5,7 +5,7 @@ Darkswarm.factory "EnterpriseModal", ($modal, $rootScope, $http)-> scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1 - $http.get("/api/enterprises/" + enterprise.id + "/shopfront").success (data) -> + $http.get("/api/shops/" + enterprise.id).success (data) -> scope.enterprise = data $modal.open(templateUrl: "enterprise_modal.html", scope: scope) .error (data) -> diff --git a/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee index 06b362216c..e66ec7c176 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_resource.js.coffee @@ -5,8 +5,4 @@ Darkswarm.factory 'EnterpriseResource', ($resource) -> url: '/enterprises/:id/relatives.json' isArray: true cache: true - 'closed_shops': - method: 'GET' - isArray: true - url: '/api/enterprises/closed_shops.json' }) diff --git a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee index 57f4fd6f82..46e50cb574 100644 --- a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee @@ -1,4 +1,4 @@ -Darkswarm.factory 'Enterprises', (enterprises, EnterpriseResource, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) -> +Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) -> new class Enterprises enterprises: [] enterprises_by_id: {} @@ -46,7 +46,7 @@ Darkswarm.factory 'Enterprises', (enterprises, EnterpriseResource, CurrentHub, T @enterprises_by_id[enterprise.id] = enterprise loadClosedEnterprises: -> - request = EnterpriseResource.closed_shops {}, (data) => + request = ShopsResource.closed_shops {}, (data) => @initEnterprises(data) request.$promise diff --git a/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee b/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee new file mode 100644 index 0000000000..2726b25496 --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/shops_resource.js.coffee @@ -0,0 +1,7 @@ +Darkswarm.factory 'ShopsResource', ($resource) -> + $resource('/api/shops/:id.json', {}, { + 'closed_shops': + method: 'GET' + isArray: true + url: '/api/shops/closed_shops.json' + }) diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index 6ebeb378b3..a555cb0a86 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -5,7 +5,6 @@ module Api before_filter :override_sells, only: [:create, :update] before_filter :override_visible, only: [:create, :update] respond_to :json - skip_authorization_check only: [:shopfront, :closed_shops] def create authorize! :create, Enterprise @@ -42,25 +41,6 @@ module Api end end - def shopfront - enterprise = Enterprise.find_by_id(params[:id]) - - render text: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok - end - - def closed_shops - @active_distributor_ids = [] - @earliest_closing_times = [] - - serialized_closed_shops = ActiveModel::ArraySerializer.new( - ShopsListService.new.closed_shops, - each_serializer: Api::EnterpriseSerializer, - data: OpenFoodNetwork::EnterpriseInjectionData.new - ) - - render json: serialized_closed_shops - end - private def override_owner diff --git a/app/controllers/api/shops_controller.rb b/app/controllers/api/shops_controller.rb new file mode 100644 index 0000000000..66740c5cbd --- /dev/null +++ b/app/controllers/api/shops_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Api + class ShopsController < BaseController + respond_to :json + skip_authorization_check only: [:show, :closed_shops] + + def show + enterprise = Enterprise.find_by_id(params[:id]) + + render text: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok + end + + def closed_shops + @active_distributor_ids = [] + @earliest_closing_times = [] + + serialized_closed_shops = ActiveModel::ArraySerializer.new( + ShopsListService.new.closed_shops, + each_serializer: Api::EnterpriseSerializer, + data: OpenFoodNetwork::EnterpriseInjectionData.new + ) + + render json: serialized_closed_shops + end + end +end diff --git a/config/routes/api.rb b/config/routes/api.rb index 8f2ff18972..1147076112 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -33,11 +33,9 @@ Openfoodnetwork::Application.routes.draw do resource :logo, only: [:destroy] resource :promo_image, only: [:destroy] + end - member do - get :shopfront - end - + resources :shops, only: [:show] do collection do get :closed_shops end diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index dc5c39b476..6e716eb5c2 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -81,41 +81,5 @@ module Api end end end - - context "as a non-authenticated user" do - let!(:hub) { - create(:distributor_enterprise, with_payment_and_shipping: true, name: 'Shopfront Test Hub') - } - let!(:producer) { create(:supplier_enterprise, name: 'Shopfront Test Producer') } - let!(:category) { create(:taxon, name: 'Fruit') } - let!(:product) { create(:product, supplier: producer, primary_taxon: category ) } - let!(:relationship) { create(:enterprise_relationship, parent: hub, child: producer) } - let!(:closed_hub1) { create(:distributor_enterprise) } - let!(:closed_hub2) { create(:distributor_enterprise) } - - before do - allow(controller).to receive(:spree_current_user) { nil } - end - - describe "#shopfront" do - it "returns shopfront data for an enterprise" do - spree_get :shopfront, id: producer.id, format: :json - - expect(json_response['name']).to eq 'Shopfront Test Producer' - expect(json_response['hubs'][0]['name']).to eq 'Shopfront Test Hub' - expect(json_response['supplied_taxons'][0]['name']).to eq 'Fruit' - end - end - - describe "#closed_shops" do - it "returns data for all closed shops" do - spree_get :closed_shops, nil, format: :json - - expect(json_response).not_to match hub.name - expect(json_response[0]['id']).to eq closed_hub1.id - expect(json_response[1]['id']).to eq closed_hub2.id - end - end - end end end diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/shops_controller_spec.rb new file mode 100644 index 0000000000..3ae4e55a01 --- /dev/null +++ b/spec/controllers/api/shops_controller_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +module Api + describe ShopsController, type: :controller do + include AuthenticationWorkflow + render_views + + context "as a non-authenticated user" do + let!(:hub) { + create(:distributor_enterprise, with_payment_and_shipping: true, name: 'Shopfront Test Hub') + } + let!(:producer) { create(:supplier_enterprise, name: 'Shopfront Test Producer') } + let!(:category) { create(:taxon, name: 'Fruit') } + let!(:product) { create(:product, supplier: producer, primary_taxon: category ) } + let!(:relationship) { create(:enterprise_relationship, parent: hub, child: producer) } + let!(:closed_hub1) { create(:distributor_enterprise) } + let!(:closed_hub2) { create(:distributor_enterprise) } + + before do + allow(controller).to receive(:spree_current_user) { nil } + end + + describe "#show" do + it "returns shopfront data for an enterprise" do + spree_get :show, id: producer.id + + expect(json_response['name']).to eq 'Shopfront Test Producer' + expect(json_response['hubs'][0]['name']).to eq 'Shopfront Test Hub' + expect(json_response['supplied_taxons'][0]['name']).to eq 'Fruit' + end + end + + describe "#closed_shops" do + it "returns data for all closed shops" do + spree_get :closed_shops, nil + + expect(json_response).not_to match hub.name + expect(json_response[0]['id']).to eq closed_hub1.id + expect(json_response[1]['id']).to eq closed_hub2.id + end + end + end + end +end From 7612415991f2b5bb9cc011aa900871bd543ff79c Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Sun, 5 Apr 2020 00:16:10 +0200 Subject: [PATCH 047/166] Enable Ruby Runtime Metrics in Datadog This automatically collects a bunch of Ruby's GC-related metrics that will come in handy while we tune the Unicorn workers. Some of theres are: * runtime.ruby.class_count * runtime.ruby.gc.malloc_increase_bytes * runtime.ruby.gc.total_allocated_objects * runtime.ruby.gc.total_freed_objects * runtime.ruby.gc.heap_marked_slots * runtime.ruby.gc.heap_available_slots * runtime.ruby.gc.heap_free_slots * runtime.ruby.thread_count Check https://docs.datadoghq.com/tracing/runtime_metrics/ruby/#data-collected for the complete list. The cool thing is that > Runtime metrics can be viewed in correlation with your Ruby services --- config/initializers/datadog.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/initializers/datadog.rb b/config/initializers/datadog.rb index eb82b340ff..c1265c7802 100644 --- a/config/initializers/datadog.rb +++ b/config/initializers/datadog.rb @@ -4,5 +4,6 @@ if ENV['DATADOG_RAILS_APM'] c.use :delayed_job, service_name: 'delayed_job' c.use :dalli, service_name: 'memcached' c.analytics_enabled = true + c.runtime_metrics_enabled = true end end From 63138aef3019346f3e150ab3e9def818915a6095 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sun, 5 Apr 2020 00:06:31 +0100 Subject: [PATCH 048/166] Re-add setup instructions removed from docker-compose into Dockerfile and Docker.md --- DOCKER.md | 11 +++++++++-- Dockerfile | 6 ++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/DOCKER.md b/DOCKER.md index 994f582fde..3df0f7d345 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -35,13 +35,20 @@ Download the Docker images and build the containers: $ docker-compose build ``` -Run the app with all the required containers: +Setup the database and seed it with sample data: +```sh +$ docker-compose run web bundle exec rake db:reset +$ docker-compose run web bundle exec rake db:test:prepare +$ docker-compose run web bundle exec rake ofn:sample_data +``` + +Finally, run the app with all the required containers: ```sh $ docker-compose up ``` -This command will setup the database and seed it with sample data. The default admin user is 'ofn@example.com' with 'ofn123' password. +The default admin user is 'ofn@example.com' with 'ofn123' password. Check the app in the browser at `http://localhost:3000`. You will then get the trace of the containers in the terminal. You can stop the containers using Ctrl-C in the terminal. diff --git a/Dockerfile b/Dockerfile index fa7718f2ee..93caceecc1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ ENV BUNDLE_PATH /bundles WORKDIR /usr/src/app COPY .ruby-version . -# Rbenv & Ruby part +# Install Rbenv & Ruby RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ git clone https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \ ${RBENV_ROOT}/plugins/ruby-build/install.sh && \ @@ -21,7 +21,7 @@ RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ rbenv global $(cat .ruby-version) && \ gem install bundler --version=1.17.2 -# Postgres +# Install Postgres RUN sh -c "echo 'deb https://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main' > /etc/apt/sources.list.d/pgdg.list" && \ wget --quiet -O - https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add - && \ apt-get update && \ @@ -38,4 +38,6 @@ RUN wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.z unzip chromedriver_linux64.zip -d /usr/bin && \ chmod u+x /usr/bin/chromedriver +# Copy code and install app dependencies COPY . /usr/src/app/ +RUN bundle install From dcfb1aec6df2c7f179e6c25a5f829e57babb9804 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Mon, 6 Apr 2020 18:11:07 +1000 Subject: [PATCH 049/166] Updating translations for config/locales/en_PH.yml --- config/locales/en_PH.yml | 3373 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 3373 insertions(+) create mode 100644 config/locales/en_PH.yml diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml new file mode 100644 index 0000000000..d5cd28c690 --- /dev/null +++ b/config/locales/en_PH.yml @@ -0,0 +1,3373 @@ +en_PH: + language_name: "English" + activerecord: + attributes: + enterprise_fee: + fee_type: Fee Type + spree/order: + payment_state: Payment State + shipment_state: Shipment State + completed_at: Completed At + number: Number + state: State + email: Customer E-Mail + spree/payment: + amount: Amount + spree/product: + primary_taxon: "Product Category" + supplier: "Supplier" + shipping_category_id: "Shipping Category" + variant_unit: "Variant Unit" + variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" + order_cycle: + orders_close_at: Close date + errors: + models: + spree/user: + attributes: + email: + taken: "There's already an account for this email. Please login or reset your password." + spree/order: + no_card: There are no authorised credit cards available to charge + spree/credit_card: + attributes: + base: + card_expired: "has expired" + order_cycle: + attributes: + orders_close_at: + after_orders_open_at: must be after open date + variant_override: + count_on_hand: + using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" + on_demand_but_count_on_hand_set: "must be blank if on demand" + limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" + activemodel: + attributes: + order_management/reports/enterprise_fee_summary/parameters: + start_at: "Start" + end_at: "End" + distributor_ids: "Hubs" + producer_ids: "Producers" + order_cycle_ids: "Order Cycles" + enterprise_fee_ids: "Fees Names" + shipping_method_ids: "Shipping Methods" + payment_method_ids: "Payment Methods" + errors: + messages: + inclusion: "is not included in the list" + models: + subscription_validator: + attributes: + subscription_line_items: + at_least_one_product: "^Please add at least one product" + not_available: "^%{name} is not available from the selected schedule" + ends_at: + after_begins_at: "must be after begins at" + customer: + does_not_belong_to_shop: "does not belong to %{shop}" + schedule: + not_coordinated_by_shop: "is not coordinated by %{shop}" + payment_method: + not_available_to_shop: "is not available to %{shop}" + invalid_type: "must be a Cash or Stripe method" + charges_not_allowed: "^Credit card charges are not allowed by this customer" + no_default_card: "^No default card available for this customer" + shipping_method: + not_available_to_shop: "is not available to %{shop}" + devise: + confirmations: + send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + failed_to_send: "An error occurred whilst sending your confirmation email." + resend_confirmation_email: "Resend confirmation email." + confirmed: "Thanks for confirming your email! You can now log in." + not_confirmed: "Your email address could not be confirmed. Perhaps you have already completed this step?" + user_confirmations: + spree_user: + send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + confirmation_sent: "Email confirmation sent" + confirmation_not_sent: "Error sending confirmation email" + user_registrations: + spree_user: + signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account." + unknown_error: "Something went wrong while creating your account. Check your email address and try again." + failure: + invalid: | + Invalid email or password. + Were you a guest last time? Perhaps you need to create an account or reset your password. + unconfirmed: "You have to confirm your account before continuing." + already_registered: "This email address is already registered. Please log in to continue, or go back and use another email address." + success: + logged_in_succesfully: "Logged in successfully" + user_passwords: + spree_user: + updated_not_active: "Your password has been reset, but your email has not been confirmed yet." + updated: "Your password was changed successfully. You are now signed in." + send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes." + models: + order_cycle: + cloned_order_cycle_name: "COPY OF %{order_cycle}" + validators: + date_time_string_validator: + not_string_error: "must be a string" + invalid_format_error: "must be valid" + integer_array_validator: + not_array_error: "must be an array" + invalid_element_error: "must contain only valid integers" + enterprise_mailer: + confirmation_instructions: + subject: "Please confirm the email address for %{enterprise}" + welcome: + subject: "%{enterprise} is now on %{sitename}" + email_welcome: "Welcome" + email_registered: "is now part of" + email_userguide_html: "The User Guide with detailed support for setting up your Producer or Hub is here: %{link}" + userguide: "Open Food Network User Guide" + email_admin_html: "You can manage your account by logging into the %{link} or by clicking on the cog in the top right hand side of the homepage, and selecting Administration." + admin_panel: "Admin Panel" + email_community_html: "We also have an online forum for community discussion related to OFN software and the unique challenges of running a food enterprise. You are encouraged to join in. We are constantly evolving and your input into this forum will shape what happens next. %{link}" + join_community: "Join the community" + invite_manager: + subject: "%{enterprise} has invited you to be a manager" + producer_mailer: + order_cycle: + subject: "Order cycle report for %{producer}" + shipment_mailer: + shipped_email: + dear_customer: "Dear Customer," + instructions: "Your order has been shipped" + shipment_summary: "Shipment Summary" + subject: "Shipment Notification" + thanks: "Thank you for your business." + track_information: "Tracking Information: %{tracking}" + track_link: "Tracking Link: %{url}" + subscription_mailer: + placement_summary_email: + subject: A summary of recently placed subscription orders + greeting: "Hi %{name}," + intro: "Below is a summary of the subscription orders that have just been placed for %{shop}." + confirmation_summary_email: + subject: A summary of recently confirmed subscription orders + greeting: "Hi %{name}," + intro: "Below is a summary of the subscription orders that have just been finalised for %{shop}." + summary_overview: + total: A total of %{count} subscriptions were marked for automatic processing. + success_zero: Of these, none were processed successfully. + success_some: Of these, %{count} were processed successfully. + success_all: All were processed successfully. + issues: Details of the issues encountered are provided below. + summary_detail: + no_message_provided: No error message provided + changes: + title: Insufficient Stock (%{count} orders) + explainer: These orders were processed but insufficient stock was available for some requested items + empty: + title: No Stock (%{count} orders) + explainer: These orders were unable to be processed because no stock was available for any requested items + complete: + title: Already Processed (%{count} orders) + explainer: These orders were already marked as complete, and were therefore left untouched + processing: + title: Error Encountered (%{count} orders) + explainer: Automatic processing of these orders failed due to an error. The error has been listed where possible. + failed_payment: + title: Failed Payment (%{count} orders) + explainer: Automatic processing of payment for these orders failed due to an error. The error has been listed where possible. + other: + title: Other Failure (%{count} orders) + explainer: Automatic processing of these orders failed for an unknown reason. This should not occur, please contact us if you are seeing this. + home: "OFN" + title: Open Food Network + welcome_to: 'Welcome to ' + site_meta_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…" + search_by_name: Search by name or city... + producers_join: Philippine producers are now welcome to join the Open Food Network. + charges_sales_tax: Charges VAT? + print_invoice: "Print Invoice" + print_ticket: "Print Ticket" + select_ticket_printer: "Select printer for tickets" + send_invoice: "Send Invoice" + resend_confirmation: "Resend Confirmation" + view_order: "View Order" + edit_order: "Edit Order" + ship_order: "Ship Order" + cancel_order: "Cancel Order" + confirm_send_invoice: "An invoice for this order will be sent to the customer. Are you sure you want to continue?" + confirm_resend_order_confirmation: "Are you sure you want to resend the order confirmation email?" + must_have_valid_business_number: "%{enterprise_name} must have a valid TIN before invoices can be sent." + invoice: "Invoice" + more: "More" + say_no: "No" + say_yes: "Yes" + ongoing: Ongoing + bill_address: Billing Address + ship_address: Shipping Address + sort_order_cycles_on_shopfront_by: "Sort Order Cycles On Shopfront By" + required_fields: Required fields are denoted with an asterisk + select_continue: Select and Continue + remove: Remove + or: or + collapse_all: Collapse all + expand_all: Expand all + loading: Loading... + show_more: Show more + show_all: Show all + show_all_with_more: "Show All (%{num} More)" + cancel: Cancel + edit: Edit + clone: Clone + distributors: Distributors + bulk_order_management: Bulk Order Management + enterprises: Enterprises + enterprise_groups: Groups + reports: Reports + variant_overrides: Inventory + import: Import + spree_products: Spree Products + all: All + current: Current + available: Available + dashboard: Dashboard + undefined: undefined + unused: unused + admin_and_handling: Admin & Handling + profile: Profile + supplier_only: Supplier Only + has_shopfront: Has Shopfront + weight: Weight + volume: Volume + items: Items + summary: Summary + detailed: Detailed + updated: Updated + 'yes': "Yes" + 'no': "No" + y: 'Y' + n: 'N' + powered_by: Powered by + blocked_cookies_alert: "Your browser may be blocking cookies needed to use this shopfront. Click below to allow cookies and reload the page." + allow_cookies: "Allow Cookies" + notes: Notes + error: Error + processing_payment: "Processing payment..." + no_pending_payments: "No pending payments" + invalid_payment_state: "Invalid payment state" + filter_results: Filter Results + quantity: Quantity + pick_up: Pick up + copy: Copy + change_my_password: "Change my password" + update_password: "Update password" + password_confirmation: Password Confirmation + reset_password_token: Reset password token + expired: has expired, please request a new one + back_to_payments_list: "Back to Payments List" + maestro_or_solo_cards: "Maestro/Solo cards" + backordered: "Backordered" + on hand: "On Hand" + ship: "Ship" + actions: + create_and_add_another: "Create and Add Another" + create: "Create" + cancel: "Cancel" + save: "Save" + edit: "Edit" + update: "Update" + delete: "Delete" + admin: + begins_at: Begins At + begins_on: Begins On + customer: Customer + date: Date + email: Email + ends_at: Ends At + ends_on: Ends On + name: Name + on_hand: On Hand + on_demand: On Demand + on_demand?: On Demand? + order_cycle: Order Cycle + payment: Payment + payment_method: Payment Method + phone: Phone + price: Price + producer: Producer + image: Image + product: Product + quantity: Quantity + schedule: Schedule + shipping: Shipping + shipping_method: Shipping Method + shop: Shop + sku: SKU + status_state: State + tags: Tags + variant: Variant + weight: Weight + volume: Volume + items: Items + select_all: Select all + quick_search: Quick Search + clear_all: Clear All + start_date: "Start Date" + end_date: "End Date" + form_invalid: "Form contains missing or invalid fields" + clear_filters: Clear Filters + clear: Clear + save: Save + cancel: Cancel + back: Back + show_more: Show more + show_n_more: Show %{num} more + choose: "Choose..." + please_select: Please select... + columns: Columns + actions: Actions + viewing: "Viewing: %{current_view_name}" + description: Description + whats_this: What's this? + tag_has_rules: "Existing rules for this tag: %{num}" + has_one_rule: "has one rule" + has_n_rules: "has %{num} rules" + unsaved_confirm_leave: "There are unsaved changed on this page. Continue without saving?" + unsaved_changes: "You have unsaved changes" + shopfront_settings: + embedded_shopfront_settings: "Embedded Shopfront Settings" + enable_embedded_shopfronts: "Enable Embedded Shopfronts" + embedded_shopfronts_whitelist: "External Domains Whitelist" + number_localization: + number_localization_settings: "Number Localization Settings" + enable_localized_number: "Use the international thousand/decimal separator logic" + invoice_settings: + edit: + title: "Invoice Settings" + enable_invoices?: "Enable Invoices?" + invoice_style2?: "Use the alternative invoice model that includes total tax breakdown per rate and tax rate info per item (not yet suitable for countries displaying prices excluding tax)" + enable_receipt_printing?: "Show options for printing receipts using thermal printers in order dropdown?" + stripe_connect_settings: + edit: + title: "Stripe Connect" + settings: "Settings" + stripe_connect_enabled: Enable shops to accept payments using Stripe Connect? + no_api_key_msg: No Stripe account exists for this enterprise. + configuration_explanation_html: For detailed instructions on configuring the Stripe Connect integration, please consult this guide. + status: Status + ok: Ok + instance_secret_key: Instance Secret Key + account_id: Account ID + business_name: Business Name + charges_enabled: Charges Enabled + charges_enabled_warning: "Warning: Charges are not enabled for your account" + auth_fail_error: The API key you provided is invalid + empty_api_key_error_html: No Stripe API key has been provided. To set your API key, please follow these instructions + matomo_settings: + edit: + title: "Matomo Settings" + matomo_url: "Matomo URL" + matomo_site_id: "Matomo Site ID" + info_html: "Matomo is a Web and Mobile Analytics. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." + config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." + customers: + index: + new_customer: "New Customer" + code: Code + duplicate_code: "This code is used already." + bill_address: "Billing Address" + ship_address: "Shipping Address" + update_address_success: 'Address updated successfully.' + update_address_error: 'Sorry! Please input all of the required fields!' + edit_bill_address: 'Edit Billing Address' + edit_ship_address: 'Edit Shipping Address' + required_fileds: 'Required fields are denoted with an asterisk ' + select_country: 'Select Country' + select_state: 'Select Province' + edit: 'Edit' + update_address: 'Update Address' + confirm_delete: 'Sure to delete?' + search_by_email: "Search by email/code..." + guest_label: 'Guest checkout' + destroy: + has_associated_orders: 'Delete failed: customer has associated orders with his shop' + contents: + edit: + title: Content + header: Header + home_page: Home page + producer_signup_page: Producer signup page + hub_signup_page: Hub signup page + group_signup_page: Group signup page + main_links: Main Menu Links + footer_and_external_links: Footer and External Links + your_content: Your content + user_guide: User Guide + enterprise_fees: + index: + title: "Enterprise Fees" + enterprise: "Enterprise" + fee_type: "Fee Type" + name: "Name" + tax_category: "Tax Category" + calculator: "Calculator" + calculator_values: "Calculator Values" + search: "Search" + name_placeholder: "e.g. packing fee" + enterprise_groups: + index: + new_button: New Enterprise Group + enterprise_roles: + form: + manages: manages + enterprise_role: + manages: manages + products: + unit_name_placeholder: 'eg. bunches' + index: + unit: Unit + display_as: Display As + category: Category + tax_category: Tax Category + inherits_properties?: Inherits Properties? + available_on: Available On + av_on: "Av. On" + import_date: Imported + upload_an_image: Upload an image + seo: + product_search_keywords: "Product Search Keywords" + product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword." + SEO_keywords: "SEO Keywords" + seo_tip: "Type words to help search your products in the web. Use space to separate each keyword." + search: "Search" + properties: + property_name: "Property Name" + inherited_property: "Inherited Property" + variants: + infinity: "Infinity" + to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." + back_to_products_list: "Back to products list" + editing_product: "Editing Product" + tabs: + product_details: "Product Details" + group_buy_options: "Group Buy Options" + images: "Images" + variants: "Variants" + product_properties: "Product Properties" + product_import: + title: Product Import + file_not_found: File not found or could not be opened + no_data: No data found in spreadsheet + confirm_reset: "This will set stock level to zero on all products for this \n enterprise that are not present in the uploaded file" + model: + no_file: "error: no file uploaded" + could_not_process: "could not process file: invalid filetype" + incorrect_value: incorrect value + conditional_blank: can't be blank if unit_type is blank + no_product: did not match any products in the database + not_found: not found in database + not_updatable: cannot be updated on existing products via product import + blank: can't be blank + products_no_permission: you do not have permission to manage products for this enterprise + inventory_no_permission: you do not have permission to create inventory for this producer + none_saved: did not save any products successfully + line_number: "Line %{number}:" + encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding" + unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}" + index: + notice: "Notice" + beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support." + select_file: Select a spreadsheet to upload + spreadsheet: Spreadsheet + choose_import_type: Select import type + import_into: Import type + product_list: Product list + inventories: Inventories + import: Import + upload: Upload + csv_templates: CSV Templates + product_list_template: Download Product List template + inventory_template: Download Inventory template + category_values: Available Category Values + product_categories: Product Categories + tax_categories: Tax Categories + shipping_categories: Shipping Categories + import: + review: Review + import: Import + save: Save + results: Results + save_imported: Save imported products + no_valid_entries: No valid entries found + none_to_save: There are no entries that can be saved + some_invalid_entries: Imported file contains invalid entries + fix_before_import: Please fix these errors and try importing the file again + save_valid?: Save valid entries for now and discard the others? + no_errors: No errors detected! + save_all_imported?: Save all imported products? + options_and_defaults: Import options and defaults + no_permission: you do not have permission to manage this enterprise + not_found: enterprise could not be found in database + no_name: No name + blank_enterprise: some products do not have an enterprise defined + reset_absent?: Reset absent products + reset_absent_tip: Set stock to zero for all exiting products not present in the file + overwrite_all: Overwrite all + overwrite_empty: Overwrite if empty + default_stock: Set stock level + default_tax_cat: Set tax category + default_shipping_cat: Set shipping category + default_available_date: Set available date + validation_overview: Import validation overview + entries_found: Entries found in imported file + entries_with_errors: Items contain errors and will not be imported + products_to_create: Products will be created + products_to_update: Products will be updated + inventory_to_create: Inventory items will be created + inventory_to_update: Inventory items will be updated + products_to_reset: Existing products will have their stock reset to zero + inventory_to_reset: Existing inventory items will have their stock reset to zero + line: Line + item_line: Item line + import_review: + not_updatable_tip: "The following fields cannot be updated via bulk import for existing products:" + fields_ignored: These fields will be ignored when the imported products are saved. + entries_table: + not_updatable: This field is not updatable via bulk import on existing products + save_results: + final_results: Import final results + products_created: Products created + products_updated: Products updated + inventory_created: Inventory items created + inventory_updated: Inventory items updated + products_reset: Products had stock level reset to zero + inventory_reset: Inventory items had stock level reset to zero + all_saved: "All items saved successfully" + some_saved: "items saved successfully" + save_errors: Save errors + import_again: Upload Another File + view_products: Go To Products Page + view_inventory: Go To Inventory Page + variant_overrides: + loading_flash: + loading_inventory: LOADING INVENTORY + index: + title: Inventory + description: Use this page to manage inventories for your enterprises. Any product details set here will override those set on the 'Products' page + enable_reset?: Enable Stock Reset? + default_stock: "Default stock" + inherit?: Inherit? + add: Add + hide: Hide + import_date: Imported + select_a_shop: Select A Shop + review_now: Review Now + new_products_alert_message: There are %{new_product_count} new products available to add to your inventory. + currently_empty: Your inventory is currently empty + no_matching_products: No matching products found in your inventory + no_hidden_products: No products have been hidden from this inventory + no_matching_hidden_products: No hidden products match your search criteria + no_new_products: No new products are available to add to this inventory + no_matching_new_products: No new products match your search criteria + inventory_powertip: This is your inventory of products. To add products to your inventory, select 'New Products' from the Viewing dropdown. + hidden_powertip: These products have been hidden from your inventory and will not be available to add to your shop. You can click 'Add' to add a product to you inventory. + new_powertip: These products are available to be added to your inventory. Click 'Add' to add a product to your inventory, or 'Hide' to hide it from view. You can always change your mind later! + controls: + back_to_my_inventory: Back to my inventory + orders: + invoice_email_sent: 'Invoice email has been sent' + order_email_resent: 'Order email has been resent' + bulk_management: + tip: "Use this page to alter product quantities across multiple orders. Products may also be removed from orders entirely, if required." + shared: "Shared Resource?" + order_no: "Order No." + order_date: "Completed at" + max: "Max" + product_unit: "Product: Unit" + weight_volume: "Weight/Volume" + ask: "Ask?" + page_title: "Bulk Order Management" + actions_delete: "Delete Selected" + loading: "Loading orders" + no_results: "No orders found." + group_buy_unit_size: "Group Buy Unit Size" + total_qtt_ordered: "Total Quantity Ordered" + max_qtt_ordered: "Max Quantity Ordered" + current_fulfilled_units: "Current Fulfilled Units" + max_fulfilled_units: "Max Fulfilled Units" + order_error: "Some errors must be resolved before you can update orders.\nAny fields with red borders contain errors." + variants_without_unit_value: "WARNING: Some variants do not have a unit value" + select_variant: "Select a variant" + enterprise: + select_outgoing_oc_products_from: Select outgoing OC products from + enterprises: + index: + title: Enterprises + new_enterprise: New Enterprise + producer?: "Producer?" + package: Package + status: Status + manage: Manage + form: + about_us: + desc_short: Short Description + desc_short_placeholder: Tell us about your enterprise in one or two sentences + desc_long: About Us + desc_long_placeholder: Tell customers about yourself. This information appears on your public profile. + business_details: + abn: TIN + abn_placeholder: eg. 99 123 456 789 + acn: Branch TIN + acn_placeholder: eg. 123 456 789 + display_invoice_logo: Display logo in invoices + invoice_text: Add customized text at the end of invoices + contact: + name: Name + name_placeholder: eg. Gustav Plum + email_address: Public Email Address + email_address_placeholder: eg. inquiries@fresh-food.com + email_address_tip: "This email address will be displayed in your public profile" + phone: Phone + phone_placeholder: eg. 98 7654 3210 + website: Website + website_placeholder: eg. www.truffles.com + enterprise_fees: + name: Name + fee_type: Fee Type + manage_fees: Manage Enterprise Fees + no_fees_yet: You don't have any enterprise fees yet. + create_button: Create One Now + images: + logo: Logo + promo_image_placeholder: 'This image is displayed in "About Us"' + promo_image_note1: 'PLEASE NOTE:' + promo_image_note2: Any promo image uploaded here will be cropped to 1200 x 260. + promo_image_note3: The promo image is displayed at the top of an enterprise's profile page and pop-ups. + inventory_settings: + text1: You may opt to manage stock levels and prices in via your + inventory: inventory + text2: > + If you are using the inventory tool, you can select whether new products + added by your suppliers need to be added to your inventory before they + can be stocked. If you are not using your inventory to manage your products + you should select the 'recommended' option below: + preferred_product_selection_from_inventory_only_yes: New products can be put into my shopfront (recommended) + preferred_product_selection_from_inventory_only_no: New products must be added to my inventory before they can be put into my shopfront + payment_methods: + name: Name + applies: Applies? + manage: Manage Payment Methods + no_method_yet: You don't have any payment methods yet. + create_button: Create New Payment Method + create_one_button: Create One Now + primary_details: + name: Name + name_placeholder: eg. Professor Plum's Biodynamic Truffles + groups: Groups + groups_tip: Select any groups or regions that you are a member of. This will help customers find your enterprise. + groups_placeholder: Start typing to search available groups... + primary_producer: Primary Producer? + primary_producer_tip: Select 'Producer' if you are a primary producer of food. + producer: Producer + any: Any + none: None + own: Own + sells: Sells + sells_tip: "None - enterprise does not sell to customers directly.
Own - Enterprise sells own products to customers.
Any - Enterprise can sell own or other enterprises products.
" + visible_in_search: Visible in search? + visible_in_search_tip: Determines whether this enterprise will be visible to customers when searching the site. + visible: Visible + not_visible: Not visible + permalink: Permalink (no spaces) + permalink_tip: "This permalink is used to create the url to your shop: %{link}your-shop-name/shop" + link_to_front: Link to shop front + link_to_front_tip: A direct link to your shopfront on the Open Food Network. + ofn_uid: OFN UID + ofn_uid_tip: The unique id used to identify the enterprise on Open Food Network. + shipping_methods: + name: Name + applies: Applies? + manage: Manage Shipping Methods + create_button: Create New Shipping Method + create_one_button: Create One Now + no_method_yet: You don't have any shipping methods yet. + shop_preferences: + shopfront_requires_login: "Publicly visible shopfront?" + shopfront_requires_login_tip: "Choose whether customers must login to view the shopfront or if it's visible to everybody." + shopfront_requires_login_false: "Public" + shopfront_requires_login_true: "Visible to registered customers only" + recommend_require_login: "We recommend to require users to login when orders can be changed." + allow_guest_orders: "Guest orders" + allow_guest_orders_tip: "Allow checkout as guest or require a registered user." + allow_guest_orders_false: "Require login to order" + allow_guest_orders_true: "Allow guest checkout" + allow_order_changes: "Change orders" + allow_order_changes_tip: "Allow customers to change their order as long the order cycle is open." + allow_order_changes_false: "Placed orders cannot be changed / cancelled" + allow_order_changes_true: "Customers can change / cancel orders while order cycle is open" + enable_subscriptions: "Subscriptions" + enable_subscriptions_tip: "Enable subscriptions functionality?" + enable_subscriptions_false: "Disabled" + enable_subscriptions_true: "Enabled" + shopfront_message: "Shopfront Message" + shopfront_message_placeholder: > + An optional message to welcome customers and explain how to shop with + you. If text is entered here it will be displayed in a home tab when + customers first arrive at your shopfront. + shopfront_message_link_tooltip: "Insert / edit link" + shopfront_message_link_prompt: "Please enter a URL to insert" + shopfront_closed_message: "Shopfront Closed Message" + shopfront_closed_message_placeholder: > + A message which provides a more detailed explanation about why your + shop is closed and/or when customers can expect it to open again. This + is displayed on your shop only when you have no active order cycles + (ie. shop is closed). + shopfront_category_ordering: "Shopfront Category Ordering" + open_date: "Open Date" + close_date: "Close Date" + social: + twitter_placeholder: "e.g. @OFNPhilippines" + instagram_placeholder: "e.g. OFNPhilippines" + facebook_placeholder: "eg. www.facebook.com/PageNameHere" + linkedin_placeholder: "eg. www.linkedin.com/in/YourNameHere" + stripe_connect: + connect_with_stripe: "Connect with Stripe" + stripe_connect_intro: "To accept payments using credit card, you will need to connect your stripe account to the Open Food Network. Use the button to the right to get started." + stripe_account_connected: "Stripe account connected." + disconnect: "Disconnect account" + confirm_modal: + title: Connect with Stripe + part1: Stripe is a payment processing service that allows shops on the OFN to accept credit card payments from customers. + part2: To use this feature, you must connect your Stripe account to the OFN. Clicking 'I Agree' below will redirect to you the Stripe website where you can connect an existing Stripe account, or create a new one if you don't already have one. + part3: This will allow the Open Food Network to accept credit card payments from customers on your behalf. Please note that you will need to maintain your own Stripe account, pay the fees Stripe charges and handle any chargebacks and customer service yourself. + i_agree: I Agree + cancel: Cancel + tag_rules: + default_rules: + by_default: By Default + no_rules_yet: No default rules apply yet + add_new_button: '+ Add A New Default Rule' + no_tags_yet: No tags apply to this enterprise yet + no_rules_yet: No rules apply to this tag yet + for_customers_tagged: 'For customers tagged:' + add_new_rule: '+ Add A New Rule' + add_new_tag: '+ Add A New Tag' + users: + email_confirmation_notice_html: "Email confirmation is pending. We've sent a confirmation email to %{email}." + resend: Resend + owner: 'Owner' + contact: "Contact" + contact_tip: "The manager who will receive enterprise emails for orders and notifications. Must have a confirmed email adress." + owner_tip: The primary user responsible for this enterprise. + notifications: Notifications + notifications_tip: Notifications about orders will be send to this email address. + notifications_placeholder: eg. gustav@truffles.com + notifications_note: 'Note: A new email address may need to be confirmed prior to use' + managers: Managers + managers_tip: The other users with permission to manage this enterprise. + invite_manager: "Invite Manager" + invite_manager_tip: "Invite an unregistered user to sign up and become a manager of this enterprise." + add_unregistered_user: "Add an unregistered user" + email_confirmed: "Email confirmed" + email_not_confirmed: "Email not confirmed" + actions: + edit_profile: Settings + properties: Properties + payment_methods: Payment Methods + payment_methods_tip: This enterprise has no payment methods + shipping_methods: Shipping Methods + shipping_methods_tip: This enterprise has shipping methods + enterprise_fees: Enterprise Fees + enterprise_fees_tip: This enterprise has no fees + admin_index: + name: Name + role: Role + sells: Sells + visible: Visible? + owner: Owner + producer: Producer + change_type_form: + producer_profile: Producer Profile + connect_ofn: Connect through OFN + always_free: ALWAYS FREE + producer_description_text: Add your products to Open Food Network, allowing hubs to stock your products in their stores. + producer_shop: Producer Shop + sell_your_produce: Sell your own produce + producer_shop_description_text: Sell your products directly to customers through your very own Open Food Network shopfront. + producer_shop_description_text2: A Producer Shop is for your produce only, if you want to sell produce grown/produced off site, select 'Producer Hub'. + producer_hub: Producer Hub + producer_hub_text: Sell produce from self and others + producer_hub_description_text: Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network. + profile: Profile Only + get_listing: Get a listing + profile_description_text: People can find and contact you on the Open Food Network. Your enterprise will be visible on the map, and will be searchable in listings. + hub_shop: Hub Shop + hub_shop_text: Sell produce from others + hub_shop_description_text: Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network. + choose_option: Please choose one of the options above. + change_now: Change now + enterprise_user_index: + loading_enterprises: LOADING ENTERPRISES + no_enterprises_found: No enterprises found. + search_placeholder: Search By Name + manage: Manage + manage_link: Settings + producer?: "Producer?" + package: "Package" + status: "Status" + new_form: + owner: Owner + owner_tip: The primary user responsible for this enterprise. + i_am_producer: I am a Producer + contact_name: Contact Name + edit: + editing: 'Settings:' + back_link: Back to enterprises list + new: + title: New Enterprise + back_link: Back to enterprises list + remove_logo: + remove: "Remove Image" + removed_successfully: "Logo removed successfully" + immediate_removal_warning: "The logo will be removed immediately after you confirm." + remove_promo_image: + remove: "Remove Image" + removed_successfully: "Promo image removed successfully" + immediate_removal_warning: "The promo image will be removed immediately after you confirm." + welcome: + welcome_title: Welcome to the Open Food Network! + welcome_text: You have successfully created a + next_step: Next step + choose_starting_point: 'Choose your package:' + profile: 'Profile' + producer_profile: 'Producer Profile' + invite_manager: + user_already_exists: "User already exists" + error: "Something went wrong" + order_cycles: + loading_flash: + loading_order_cycles: LOADING ORDER CYCLES + loading: LOADING... + new: + create: "Create" + cancel: "Cancel" + back_to_list: "Back To List" + edit: + advanced_settings: "Advanced Settings" + save: "Save" + save_and_next: "Save and Next" + next: "Next" + cancel: "Cancel" + back_to_list: "Back To List" + save_and_back_to_list: "Save and Back to List" + choose_products_from: "Choose Products From:" + incoming: + save: "Save" + save_and_next: "Save and Next" + next: "Next" + cancel: "Cancel" + back_to_list: "Back To List" + outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + delivery_details: "Delivery Details" + fees: "Fees" + previous: "Previous" + save: "Save" + save_and_back_to_list: "Save and Back to List" + cancel: "Cancel" + back_to_list: "Back To List" + wizard_progress: + edit: "1. General Settings" + incoming: "2. Incoming Products" + outgoing: "3. Outgoing Products" + exchange_form: + pickup_time_tip: When orders from this OC will be ready for the customer + pickup_instructions_placeholder: "Pick-up instructions" + pickup_instructions_tip: These instructions are shown to customers after they complete an order + pickup_time_placeholder: "Ready for (ie. Date / Time)" + receival_instructions_placeholder: "Receival instructions" + add_fee: 'Add fee' + remove: 'Remove' + selected: 'selected' + add_exchange_form: + add_supplier: 'Add supplier' + add_distributor: 'Add distributor' + advanced_settings: + title: Advanced Settings + choose_product_tip: You can restrict products incoming and outgoing to only %{inventory}'s inventory. + preferred_product_selection_from_coordinator_inventory_only_here: Coordinator's Inventory Only + preferred_product_selection_from_coordinator_inventory_only_all: All Available Products + save_reload: Save and Reload Page + coordinator_fees: + add: Add coordinator fee + filters: + search_by_order_cycle_name: "Search by Order Cycle name..." + involving: "Involving" + any_enterprise: "Any Enterprise" + any_schedule: "Any Schedule" + form: + general_settings: "General Settings" + incoming: Incoming + supplier: Supplier + receival_details: Receival details + fees: Fees + outgoing: Outgoing + distributor: Distributor + products: Products + tags: Tags + add_a_tag: Add a tag + delivery_details: Pickup / Delivery details + index: + schedule: Schedule + schedules: Schedules + new_schedule: New Schedule + name_and_timing_form: + name: Name + orders_open: Orders open at + coordinator: Coordinator + orders_close: Orders close + row: + suppliers: suppliers + distributors: distributors + variants: variants + simple_form: + ready_for: Ready for + ready_for_placeholder: Date / time + customer_instructions: Customer instructions + customer_instructions_placeholder: Pick-up or delivery notes + products: Products + fees: Fees + destroy_errors: + orders_present: That order cycle has been selected by a customer and cannot be deleted. To prevent customers from accessing it, please close it instead. + schedule_present: That order cycle is linked to a schedule and cannot be deleted. Please unlink or delete the schedule first. + bulk_update: + no_data: Hm, something went wrong. No order cycle data found. + date_warning: + msg: This order cycle is linked to %{n} open subscription orders. Changing this date now will not affect any orders which have already been placed, but should be avoided if possible. Are you sure you want to proceed? + cancel: Cancel + proceed: Proceed + producer_properties: + index: + title: Producer Properties + proxy_orders: + cancel: + could_not_cancel_the_order: Could not cancel the order + resume: + could_not_resume_the_order: Could not resume the order + shared: + user_guide_link: + user_guide: User Guide + enterprises_hubs_tabs: + has_no_payment_methods: "%{enterprise} has no payment methods" + has_no_shipping_methods: "%{enterprise} has no shipping methods" + has_no_enterprise_fees: "%{enterprise} has no enterprise fees" + enterprise_issues: + create_new: Create New + resend_email: Resend Email + has_no_payment_methods: "%{enterprise} currently has no payment methods" + has_no_shipping_methods: "%{enterprise} currently has no shipping methods" + email_confirmation: "Email confirmation is pending. We've sent a confirmation email to %{email}." + not_visible: "%{enterprise} is not visible and so cannot be found on the map or in searches" + reports: + hidden: HIDDEN + unitsize: UNITSIZE + total: TOTAL + total_items: TOTAL ITEMS + supplier_totals: Order Cycle Supplier Totals + supplier_totals_by_distributor: Order Cycle Supplier Totals by Distributor + totals_by_supplier: Order Cycle Distributor Totals by Supplier + customer_totals: Order Cycle Customer Totals + all_products: All products + inventory: Inventory (on hand) + lettuce_share: LettuceShare + mailing_list: Mailing List + addresses: Addresses + payment_methods: Payment Methods Report + delivery: Delivery Report + tax_types: Tax Types + tax_rates: Tax Rates + pack_by_customer: Pack By Customer + pack_by_supplier: Pack By Supplier + orders_and_distributors: + name: Orders And Distributors + description: Orders with distributor details + bulk_coop: + name: Bulk Co-Op + description: Reports for Bulk Co-Op orders + payments: + name: Payment Reports + description: Reports for Payments + orders_and_fulfillment: + name: Orders & Fulfillment Reports + customers: + name: Customers + products_and_inventory: + name: Products & Inventory + users_and_enterprises: + name: Users & Enterprises + description: Enterprise Ownership & Status + order_cycle_management: + name: Order Cycle Management + sales_tax: + name: Sales Tax + xero_invoices: + name: Xero Invoices + description: Invoices for import into Xero + packing: + name: Packing Reports + enterprise_fee_summary: + name: "Enterprise Fee Summary" + description: "Summary of Enterprise Fees collected" + subscriptions: + subscriptions: Subscriptions + new: New Subscription + create: Create Subscription + edit: Edit Subscription + table: + edit_subscription: Edit Subscription + pause_subscription: Pause Subscription + unpause_subscription: Unpause Subscription + cancel_subscription: Cancel Subscription + filters: + query_placeholder: "Search by email..." + setup_explanation: + just_a_few_more_steps: 'Just a few more steps before you can begin:' + enable_subscriptions: "Enable subscriptions for at least one of your shops" + enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage" + enable_subscriptions_step_2: 2. Under "Shop Preferences", enable the Subscriptions option + set_up_shipping_and_payment_methods_html: Set up %{shipping_link} and %{payment_link} methods + set_up_shipping_and_payment_methods_note_html: Note that only Cash and Stripe payment methods may
be used with subscriptions + ensure_at_least_one_customer_html: Ensure that at least one %{customer_link} exists + create_at_least_one_schedule: Create at least one Schedule + create_at_least_one_schedule_step_1_html: 1. Go to the on the %{order_cycles_link} page + create_at_least_one_schedule_step_2: 2. Create an order cycle if you have not already done so + create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form + once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link} + reload_this_page: reload this page + steps: + details: 1. Basic Details + address: 2. Address + products: 3. Add Products + review: 4. Review & Save + subscription_line_items: + this_is_an_estimate: | + The displayed prices are only an estimate and calculated at the time the subscription is changed. + If you change prices or fees, orders will be updated, but the subscription will still display the old values. + not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product." + autocomplete: + name_or_sku: "NAME OR SKU" + quantity: "Quantity" + add: "Add" + details: + details: Details + invalid_error: Oops! Please fill in all of the required fields... + allowed_payment_method_types_tip: Only Cash and Stripe payment methods may be used at the moment + credit_card: Credit Card + charges_not_allowed: Charges are not allowed by this customer + no_default_card: Customer has no cards available to charge + card_ok: Customer has a card available to charge + begins_at_placeholder: "Select a Date" + ends_at_placeholder: "Optional" + loading_flash: + loading: LOADING SUBSCRIPTIONS + review: + details: Details + address: Address + products: Products + no_open_or_upcoming_order_cycle: "No Upcoming Order Cycle" + products_panel: + save: "SAVE" + saving: "SAVING" + saved: "SAVED" + product_already_in_order: This product has already been added to the order. Please edit the quantity directly. + stock: + insufficient_stock: "Insufficient stock available" + out_of_stock: "Out of Stock" + orders: + number: Number + confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future. + confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone." + cancel_failure_msg: "Sorry, cancellation failed!" + confirm_pause_msg: "Are you sure you want to pause this subscription?" + pause_failure_msg: "Sorry, pausing failed!" + confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?" + unpause_failure_msg: "Sorry, unpausing failed!" + confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?" + resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown." + yes_cancel_them: Cancel them + no_keep_them: Keep them + yes_i_am_sure: Yes, I'm sure + order_update_issues_msg: Some orders could not be automatically updated, this is most likely because they have been manually edited. Please review the issues listed below and make any adjustments to individual orders if required. + no_results: + no_subscriptions: No subscriptions yet... + why_dont_you_add_one: Why don't you add one? :) + no_matching_subscriptions: No matching subscriptions found + schedules: + destroy: + associated_subscriptions_error: This schedule cannot be deleted because it has associated subscriptions + controllers: + enterprises: + stripe_connect_cancelled: "Connection to Stripe has been cancelled" + stripe_connect_success: "Stripe account connected successfully" + stripe_connect_fail: Sorry, the connection of your Stripe account failed + stripe_connect_settings: + resource: Stripe Connect configuration + api: + enterprise_logo: + destroy_attachment_does_not_exist: "Logo does not exist" + enterprise_promo_image: + destroy_attachment_does_not_exist: "Promo image does not exist" + orders: + failed_to_update: "Failed to update order" + checkout: + already_ordered: + cart: "cart" + message_html: "You have an order for this order cycle already. Check the %{cart} to see the items you ordered before. You can also cancel items as long as the order cycle is open." + failed: "The checkout failed. Please let us know so that we can process your order." + shops: + hubs: + show_closed_shops: "Show closed shops" + hide_closed_shops: "Hide closed shops" + show_on_map: "Show all on the map" + shared: + menu: + cart: + cart: "Cart" + signed_in: + profile: "Profile" + mobile_menu: + cart: "Cart" + joyride: + checkout: "Checkout now" + already_ordered_products: "Already ordered in this order cycle" + register_call: + selling_on_ofn: "Interested in getting on the Open Food Network?" + register: "Register here" + footer: + footer_secure: "Secure and trusted." + footer_secure_text: "Open Food Network uses SSL encryption (2048 bit RSA) everywhere to keep your shopping and payment information private. Our servers do not store your credit card details and payments are processed by PCI-compliant services." + footer_contact_headline: "Keep in touch" + footer_contact_email: "Email us" + footer_nav_headline: "Navigate" + footer_join_headline: "Join us" + footer_join_body: "Create a listing, shop or group directory on the Open Food Network." + footer_join_cta: "Tell me more!" + footer_legal_call: "Read our" + footer_legal_tos: "Terms and conditions" + footer_legal_visit: "Find us on" + footer_legal_text_html: "Open Food Network is a free and open source software platform. Our content is licensed with %{content_license} and our code with %{code_license}." + footer_data_text_with_privacy_policy_html: "We take good care of your data. See our %{privacy_policy} and %{cookies_policy}" + footer_data_text_without_privacy_policy_html: "We take good care of your data. See our %{cookies_policy}" + footer_data_privacy_policy: "privacy policy" + footer_data_cookies_policy: "cookies policy" + shop: + messages: + login: "login" + signup: "signup" + contact: "contact" + require_customer_login: "Only approved customers can access this shop." + require_login_html: "If you're already an approved customer, %{login} or %{signup} to proceed. Want to start shopping here? Please %{contact} %{enterprise} and ask about joining." + require_customer_html: "If you'd like to start shopping here, please %{contact} %{enterprise} to ask about joining." + card_could_not_be_updated: Card could not be updated + card_could_not_be_saved: card could not be saved + spree_gateway_error_flash_for_checkout: "There was a problem with your payment information: %{error}" + invoice_billing_address: "Billing address:" + invoice_column_tax: "VAT" + invoice_column_price: "Price" + invoice_column_item: "Item" + invoice_column_qty: "Qty" + invoice_column_unit_price_with_taxes: "Unit price (Incl. tax)" + invoice_column_unit_price_without_taxes: "Unit price (Excl. tax)" + invoice_column_price_with_taxes: "Total price (Incl. tax)" + invoice_column_price_without_taxes: "Total price (Excl. tax)" + invoice_column_tax_rate: "Tax rate" + invoice_tax_total: "VAT Total:" + tax_invoice: "TAX INVOICE" + tax_total: "Total tax (%{rate}):" + total_excl_tax: "Total (Excl. tax):" + total_incl_tax: "Total (Incl. tax):" + abn: "TIN:" + acn: "Branch TIN:" + invoice_issued_on: "Invoice issued on:" + order_number: "Invoice number:" + date_of_transaction: "Date of transaction:" + ticket_column_qty: "Qty" + ticket_column_item: "Item" + ticket_column_unit_price: "Unit Price" + ticket_column_total_price: "Total Price" + menu_1_title: "Shops" + menu_1_url: "/shops" + menu_2_title: "Map" + menu_2_url: "/map" + menu_3_title: "Producers" + menu_3_url: "/producers" + menu_4_title: "Groups" + menu_4_url: "/groups" + menu_5_title: "About" + menu_5_url: "https://www.openfoodnetwork.org/about-us/" + menu_6_title: "Connect" + menu_6_url: "https://www.openfoodnetwork.org/contact/" + menu_7_title: "Learn" + menu_7_url: "https://www.openfoodnetwork.org/resources/" + logo: "Logo (640x130)" + logo_mobile: "Mobile logo (75x26)" + logo_mobile_svg: "Mobile logo (SVG)" + home_hero: "Hero image" + home_show_stats: "Show statistics" + footer_logo: "Logo (220x76)" + footer_facebook_url: "Facebook URL" + footer_twitter_url: "Twitter URL" + footer_instagram_url: "Instagram URL" + footer_linkedin_url: "LinkedIn URL" + footer_googleplus_url: "Google Plus URL" + footer_pinterest_url: "Pinterest URL" + footer_email: "Email" + footer_links_md: "Links" + footer_about_url: "About URL" + user_guide_link: "User Guide Link" + name: Name + first_name: First Name + last_name: Last Name + email: Email + phone: Phone + next: Next + address: Address + address_placeholder: e.g. 123 Kapayapaan St. + address2: Address (contd.) + city: City + city_placeholder: e.g. Mandaluyong + postcode: Postcode + postcode_placeholder: e.g. 1555 + suburb: City + state: Province + country: Country + unauthorized: Unauthorized + terms_of_service: "Terms of service" + on_demand: On demand + none: None + not_allowed: Not allowed + no_shipping: no shipping methods + no_payment: no payment methods + no_shipping_or_payment: no shipping or payment methods + unconfirmed: unconfirmed + days: days + authorization_failure: "Authorization Failure" + label_shop: "Shop" + label_shops: "Shops" + label_map: "Map" + label_producer: "Producer" + label_producers: "Producers" + label_groups: "Groups" + label_about: "About" + label_connect: "Connect" + label_learn: "Learn" + label_blog: "Blog" + label_support: "Support" + label_shopping: "Shopping" + label_login: "Login" + label_logout: "Logout" + label_signup: "Sign up" + label_administration: "Administration" + label_admin: "Admin" + label_account: "Account" + label_more: "Show more" + label_less: "Show less" + label_notices: "Notices" + cart_items: "items" + cart_headline: "Your shopping cart" + total: "Total" + cart_updating: "Updating cart..." + cart_empty: "Cart empty" + cart_edit: "Edit your cart" + card_number: Card Number + card_securitycode: "Security Code" + card_expiry_date: Expiry Date + card_masked_digit: "X" + card_expiry_abbreviation: "Exp" + new_credit_card: "New credit card" + my_credit_cards: My credit cards + add_new_credit_card: Add new credit card + saved_cards: Saved cards + add_a_card: Add a Card + add_card: Add Card + you_have_no_saved_cards: You haven't saved any cards yet + saving_credit_card: Saving credit card... + card_has_been_removed: "Your card has been removed (number: %{number})" + card_could_not_be_removed: Sorry, the card could not be removed + invalid_credit_card: "Invalid credit card" + ie_warning_headline: "Your browser is out of date :-(" + ie_warning_text: "For the best Open Food Network experience, we strongly recommend upgrading your browser:" + ie_warning_chrome: Download Chrome + ie_warning_firefox: Download Firefox + ie_warning_ie: Upgrade Internet Explorer + ie_warning_other: "Can't upgrade your browser? Try Open Food Network on your smartphone :-)" + legal: + cookies_policy: + header: "How We Use Cookies" + desc_part_1: "Cookies are very small text files that are stored on your computer when you visit some websites." + desc_part_2: "In OFN we are fully respectful of your privacy. We use only the cookies that are necessary for delivering you the service of selling/buying food online. We don’t sell any of your data. We might in the future propose you to share some of your data to build new commons services that could be useful for the ecosystem (like logistics services for short food systems) but we are not yet there, and we won’t do it without your authorization :-)" + desc_part_3: "We use cookies mainly to remember who you are if you 'log in' to the service, or to be able to remember the items you put in your cart even if you are not logged in. If you keep navigating on the website without clicking on “Accept cookies”, we assume you are giving us consent to store the cookies that are essential for the functioning of the website. Here is the list of cookies we use!" + essential_cookies: "Essential Cookies" + essential_cookies_desc: "The following cookies are strictly necessary for the operation of our website." + essential_cookies_note: "Most cookies only contain a unique identifier, but no other data, so your email address and password for instance are never contained in them and never exposed." + cookie_domain: "Set By:" + cookie_session_desc: "Used to allow the website to remember users between page visits, for example, remember items in your cart." + cookie_consent_desc: "Used to maintain status of user consent to store cookies" + cookie_remember_me_desc: "Used if the user has requested the website to remember him. This cookie is automatically deleted after 12 days. If as a user you want that cookie to be deleted, you only need to logout. If you don’t want that cookie to be installed on your computer you shouldn’t check the “remember me” checkbox when logging in." + cookie_openstreemap_desc: "Used by our friendly open source mapping provider (OpenStreetMap) to ensure that it does not receive too many requests during a given time period, to prevent abuse of their services." + cookie_stripe_desc: "Data collected by our payment processor Stripe for fraud detection https://stripe.com/cookies-policy/legal. Not all shops use Stripe as a payment method but it is a good practice to prevent fraud to apply it to all pages. Stripe probably build a picture of which of our pages usually interact with their API and then flag anything unusual. So setting the Stripe cookie has a broader function than simply the provision of a payment method to a user. Removing it could affect the security of the service itself. You can learn more about Stripe and read its privacy policy at https://stripe.com/privacy." + statistics_cookies: "Statistics Cookies" + statistics_cookies_desc: "The following are not strictly necessary, but help to provide you with the best user experience by allowing us to analyse user behaviour, identify which features you use most, or don’t use, understand user experience issues, etc." + statistics_cookies_analytics_desc_html: "To collect and analyse platform usage data, we use Google Analytics, as it was the default service connected with Spree (the e-commerce open source software that we built on) but our vision is to switch to Matomo (ex Piwik, open source analytics tool that is GDPR compliant and protects your privacy) as soon as we can." + statistics_cookies_matomo_desc_html: "To collect and analyse platform usage data, we use Matomo (ex Piwik), an open source analytics tool that is GDPR compliant and protects your privacy." + statistics_cookies_matomo_optout: "Do you want to opt-out of Matomo analytics? We don’t collect any personal data, and Matomo helps us to improve our service, but we respect your choice :-)" + cookie_analytics_utma_desc: "Used to distinguish users and sessions. The cookie is created when the javascript library executes and no existing __utma cookies exists. The cookie is updated every time data is sent to Google Analytics." + cookie_analytics_utmt_desc: "Used to throttle request rate." + cookie_analytics_utmb_desc: "Used to determine new sessions/visits. The cookie is created when the javascript library executes and no existing __utmb cookies exists. The cookie is updated every time data is sent to Google Analytics." + cookie_analytics_utmc_desc: "Not used in ga.js. Set for interoperability with urchin.js. Historically, this cookie operated in conjunction with the __utmb cookie to determine whether the user was in a new session/visit." + cookie_analytics_utmz_desc: "Stores the traffic source or campaign that explains how the user reached your site. The cookie is created when the javascript library executes and is updated every time data is sent to Google Analytics." + cookie_matomo_basics_desc: "Matomo first party cookies to collect statistics." + cookie_matomo_heatmap_desc: "Matomo Heatmap & Session Recording cookie." + cookie_matomo_ignore_desc: "Cookie used to exclude user from being tracked." + disabling_cookies_header: "Warning on disabling cookies" + disabling_cookies_desc: "As a user you can always allow, block or delete Open Food Network’s or any other website cookies whenever you want to through your browser’s setting control. Each browser has a different operative. Here are the links:" + disabling_cookies_firefox_link: "https://support.mozilla.org/en-US/kb/enable-and-disable-cookies-website-preferences" + disabling_cookies_chrome_link: "https://support.google.com/chrome/answer/95647" + disabling_cookies_ie_link: "https://support.microsoft.com/en-us/help/17442/windows-internet-explorer-delete-manage-cookies" + disabling_cookies_safari_link: "https://www.apple.com/legal/privacy/en-ww/cookies/" + disabling_cookies_note: "But be aware that if you delete or modify the essential cookies used by Open Food Network, the website won’t work, you will not be able to add anything to your cart neither to checkout for instance." + cookies_banner: + cookies_usage: "This site uses cookies in order to make your navigation frictionless and secure, and to help us understand how you use it in order to improve the features we offer." + cookies_definition: "Cookies are very small text files that are stored on your computer when you visit some websites." + cookies_desc: "We use only the cookies that are necessary for delivering you the service of selling/buying food online. We don’t sell any of your data. We use cookies mainly to remember who you are if you ‘log in’ to the service, or to be able to remember the items you put in your cart even if you are not logged in. If you keep navigating on the website without clicking on “Accept cookies”, we assume you are giving us consent to store the cookies that are essential for the functioning of the website." + cookies_policy_link_desc: "If you want to learn more, check our" + cookies_policy_link: "cookies policy" + cookies_accept_button: "Accept Cookies" + home_shop: Shop Now + brandstory_headline: "Food, unincorporated." + brandstory_intro: "Sometimes the best way to fix the system is to start a new one…" + brandstory_part1: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can seriously change the world." + brandstory_part2: "Then we need a way to make it real. A way to empower everyone who grows, sells and buys food. A way to tell all the stories, to handle all the logistics. A way to turn transaction into transformation every day." + brandstory_part3: "So we build an online marketplace that levels the playing field. It’s transparent, so it creates real relationships. It’s open source, so it’s owned by everyone. It scales to regions and nations, so people start versions across the world." + brandstory_part4: "It works everywhere. It changes everything." + brandstory_part5_strong: "We call it Open Food Network." + brandstory_part6: "We all love food. Now we can love our food system too." + learn_body: "Explore models, stories and resources to support you to develop your fair food business or organisation. Find training, events and other opportunities to learn from peers." + learn_cta: "Get Inspired" + connect_body: "Search our full directories of producers, hubs and groups to find fair food traders near you. List your business or organisation on the OFN so buyers can find you. Join the community to get advice and solve problems together." + connect_cta: "Go Exploring" + system_headline: "Shopping - here's how it works." + system_step1: "1. Search" + system_step1_text: "Search our diverse, independent shops for seasonal local food. Search by neighbourhood and food category, or whether you prefer delivery or pickup." + system_step2: "2. Shop" + system_step2_text: "Transform your transactions with affordable local food from diverse producers and hubs. Know the stories behind your food and the people who make it!" + system_step3: "3. Pick-up / Delivery" + system_step3_text: "Hang on for your delivery, or visit your producer or hub for a more personal connection with your food. Food shopping as diverse as nature intended it." + cta_headline: "Shopping that makes the world a better place." + cta_label: "I'm Ready" + stats_headline: "We're creating a new food system." + stats_producers: "food producers" + stats_shops: "food shops" + stats_shoppers: "food shoppers" + stats_orders: "food orders" + checkout_title: Checkout + checkout_now: Checkout now + checkout_order_ready: Order ready for + checkout_hide: Hide + checkout_expand: Expand + checkout_headline: "Ok, ready to checkout?" + checkout_as_guest: "Checkout as guest" + checkout_details: "Your details" + checkout_billing: "Billing info" + checkout_default_bill_address: "Save as default billing address" + checkout_shipping: Shipping info + checkout_default_ship_address: "Save as default shipping address" + checkout_method_free: Free + checkout_address_same: Shipping address same as billing address? + checkout_ready_for: "Ready for:" + checkout_instructions: "Any comments or special instructions?" + checkout_payment: Payment + checkout_send: Place order now + checkout_your_order: Your order + checkout_cart_total: Cart total + checkout_shipping_price: Shipping + checkout_total_price: Total + checkout_back_to_cart: "Back to Cart" + cost_currency: "Cost Currency" + order_paid: PAID + order_not_paid: NOT PAID + order_total: Total order + order_payment: "Paying via:" + order_billing_address: Billing address + order_delivery_on: Delivery on + order_delivery_address: Delivery address + order_delivery_time: Delivery time + order_special_instructions: "Your notes:" + order_pickup_time: Ready for collection + order_pickup_instructions: Collection Instructions + order_produce: Produce + order_total_price: Total + order_includes_tax: (includes tax) + order_payment_paypal_successful: Your payment via PayPal has been processed successfully. + order_hub_info: Hub Info + order_back_to_store: Back To Store + order_back_to_cart: Back To Cart + bom_tip: "Use this page to alter product quantities across multiple orders. Products may also be removed from orders entirely, if required." + unsaved_changes_warning: "Unsaved changes exist and will be lost if you continue." + unsaved_changes_error: "Fields with red borders contain errors." + products: "Products" + products_in: "in %{oc}" + products_at: "at %{distributor}" + products_elsewhere: "Products found elsewhere" + email_confirmed: "Thank you for confirming your email address." + email_confirmation_activate_account: "Before we can activate your new account, we need to confirm your email address." + email_confirmation_greeting: "Hi, %{contact}!" + email_confirmation_profile_created: "A profile for %{name} has been successfully created! To activate your Profile we need to confirm this email address." + email_confirmation_click_link: "Please click the link below to confirm your email and to continue setting up your profile." + email_confirmation_link_label: "Confirm this email address »" + email_confirmation_help_html: "After confirming your email you can access your administration account for this enterprise. See the %{link} to find out more about %{sitename}'s features and to start using your profile or online store." + email_confirmation_notice_unexpected: "You received this message because you signed up on %{sitename}, or were invited to sign up by someone you probably know. If you don't understand why you are receiving this email, please write to %{contact}." + email_social: "Connect with Us:" + email_contact: "Email us:" + email_signoff: "Cheers," + email_signature: "%{sitename} Team" + email_confirm_customer_greeting: "Hi %{name}," + email_confirm_customer_intro_html: "Thanks for shopping at %{distributor}!" + email_confirm_customer_number_html: "Order confirmation #%{number}" + email_confirm_customer_details_html: "Here are your order details from %{distributor}:" + email_confirm_customer_signoff: "Kind regards," + email_confirm_shop_greeting: "Hi %{name}," + email_confirm_shop_order_html: "Well done! You have a new order for %{distributor}!" + email_confirm_shop_number_html: "Order confirmation #%{number}" + email_order_summary_item: "Item" + email_order_summary_quantity: "Qty" + email_order_summary_sku: "SKU" + email_order_summary_price: "Price" + email_order_summary_subtotal: "Subtotal:" + email_order_summary_total: "Total:" + email_order_summary_includes_tax: "(includes tax):" + email_payment_paid: PAID + email_payment_not_paid: NOT PAID + email_payment_summary: Payment summary + email_payment_method: "Paying via:" + email_so_placement_intro_html: "You have a new order with %{distributor}" + email_so_placement_details_html: "Here are the details of your order for %{distributor}:" + email_so_placement_changes: "Unfortunately, not all products that you requested were available. The original quantities that you requested appear crossed-out below." + email_so_payment_success_intro_html: "An automatic payment has been processed for your order from %{distributor}." + email_so_placement_explainer_html: "This order was automatically created for you." + email_so_edit_true_html: "You can make changes until orders close on %{orders_close_at}." + email_so_edit_false_html: "You can view details of this order at any time." + email_so_contact_distributor_html: "If you have any questions you can contact %{distributor} via %{email}." + email_so_contact_distributor_to_change_order_html: "This order was automatically created for you. You can make changes until orders close on %{orders_close_at} by contacting %{distributor} via %{email}." + email_so_confirmation_intro_html: "Your order with %{distributor} is now confirmed" + email_so_confirmation_explainer_html: "This order was automatically placed for you, and it has now been finalised." + email_so_confirmation_details_html: "Here's everything you need to know about your order from %{distributor}:" + email_so_empty_intro_html: "We tried to place a new order with %{distributor}, but had some problems..." + email_so_empty_explainer_html: "Unfortunately, none of products that you ordered were available, so no order has been placed. The original quantities that you requested appear crossed-out below." + email_so_empty_details_html: "Here are the details of the unplaced order for %{distributor}:" + email_so_failed_payment_intro_html: "We tried to process a payment, but had some problems..." + email_so_failed_payment_explainer_html: "The payment for your subscription with %{distributor} failed because of a problem with your credit card. %{distributor} has been notified of this failed payment." + email_so_failed_payment_details_html: "Here are the details of the failure provided by the payment gateway:" + email_shipping_delivery_details: Delivery details + email_shipping_delivery_time: "Delivery on:" + email_shipping_delivery_address: "Delivery address:" + email_shipping_collection_details: Collection details + email_shipping_collection_time: "Ready for collection:" + email_shipping_collection_instructions: "Collection instructions:" + email_special_instructions: "Your notes:" + email_signup_greeting: Hello! + email_signup_welcome: "Welcome to %{sitename}!" + email_signup_confirmed_email: "Thanks for confirming your email." + email_signup_shop_html: "You can now log in at %{link}." + email_signup_text: "Thanks for joining the network. If you are a customer, we look forward to introducing you to many fantastic farmers, wonderful food hubs and delicious food! If you are a producer or food enterprise, we are excited to have you as a part of the network." + email_signup_help_html: "We welcome all your questions and feedback; you can use the Send Feedback button on the site or email us at %{email}" + invite_email: + greeting: "Hello!" + invited_to_manage: "You have been invited to manage %{enterprise} on %{instance}." + confirm_your_email: "You should have received or will soon receive an email with a confirmation link. You won’t be able to access %{enterprise}'s profile until you have confirmed your email." + set_a_password: "You will then be prompted to set a password before you are able to administer the enterprise." + mistakenly_sent: "Not sure why you have received this email? Please contact %{owner_email} for more information." + producer_mail_greeting: "Dear" + producer_mail_text_before: "We now have all the consumer orders for the next food drop." + producer_mail_order_text: "Here is a summary of the orders for your products:" + producer_mail_delivery_instructions: "Stock pickup/delivery instructions:" + producer_mail_signoff: "Thanks and best wishes" + shopping_oc_closed: Orders are closed + shopping_oc_closed_description: "Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)" + shopping_oc_last_closed: "The last cycle closed %{distance_of_time} ago" + shopping_oc_next_open: "The next cycle opens in %{distance_of_time}" + shopping_oc_select: "Select..." + shopping_tabs_home: "Home" + shopping_tabs_shop: "Shop" + shopping_tabs_about: "About" + shopping_tabs_contact: "Contact" + shopping_contact_address: "Address" + shopping_contact_web: "Contact" + shopping_contact_social: "Follow" + shopping_groups_part_of: "is part of:" + shopping_producers_of_hub: "%{hub}'s producers:" + enterprises_next_closing: "Next order closing" + enterprises_ready_for: "Ready for" + enterprises_choose: "Choose when you want your order:" + maps_open: "Open" + maps_closed: "Closed" + hubs_buy: "Shop for:" + hubs_shopping_here: "Shopping here" + hubs_orders_closed: "Orders closed" + hubs_profile_only: "Profile only" + hubs_delivery_options: "Delivery options" + hubs_pickup: "Pickup" + hubs_delivery: "Delivery" + hubs_producers: "Our producers" + hubs_filter_by: "Filter by" + hubs_filter_type: "Type" + hubs_filter_delivery: "Delivery" + hubs_filter_property: "Property" + hubs_matches: "Did you mean?" + hubs_intro: Shop in your local area + hubs_distance: Closest to + hubs_distance_filter: "Show me shops near %{location}" + shop_changeable_orders_alert_html: + one: Your order with %{shop} / %{order} is open for review. You can make changes until %{oc_close}. + other: You have %{count} orders with %{shop} currently open for review. You can make changes until %{oc_close}. + orders_changeable_orders_alert_html: This order has been confirmed, but you can make changes until %{oc_close}. + products_clear_all: Clear all + products_showing: "Showing:" + products_or: "OR" + products_with: with + products_search: "Search by product or producer" + products_loading: "Loading products..." + products_updating_cart: "Updating cart..." + products_cart_empty: "Cart empty" + products_edit_cart: "Edit your cart" + products_from: from + products_change: "No changes to save." + products_update_error: "Saving failed with the following error(s):" + products_update_error_msg: "Saving failed." + products_update_error_data: "Save failed due to invalid data:" + products_changes_saved: "Changes saved." + search_no_results_html: "Sorry, no results found for %{query}. Try another search?" + components_profiles_popover: "Profiles do not have a shopfront on the Open Food Network, but may have their own physical or online shop elsewhere" + components_profiles_show: "Show profiles" + components_filters_nofilters: "No filters" + components_filters_clearfilters: "Clear all filters" + groups_title: Groups + groups_headline: Groups / regions + groups_text: "Every producer is unique. Every business has something different to offer. Our groups are collectives of producers, hubs and distributors who share something in common like location, farmers market or philosophy. This makes your shopping experience easier. So explore our groups and have the curating done for you." + groups_search: "Search name or keyword" + groups_no_groups: "No groups found" + groups_about: "About Us" + groups_producers: "Our producers" + groups_hubs: "Our hubs" + groups_contact_web: Contact + groups_contact_social: Follow + groups_contact_address: Address + groups_contact_email: Email us + groups_contact_website: Visit our website + groups_contact_facebook: Follow us on Facebook + groups_signup_title: Sign up as a group + groups_signup_headline: Groups sign up + groups_signup_intro: "We're an amazing platform for collaborative marketing, the easiest way for your members and stakeholders to reach new markets. We're non-profit, affordable, and simple." + groups_signup_email: Email us + groups_signup_motivation1: We transform food systems fairly. + groups_signup_motivation2: It's why we get out of bed every day. We're a global non-profit, based on open source code. We play fair. You can always trust us. + groups_signup_motivation3: We know you have big ideas, and we want to help. We'll share our knowledge, networks and resources. We know that isolation doesn't create change, so we'll partner with you. + groups_signup_motivation4: We meet you where you are. + groups_signup_motivation5: You might be an alliance of food hubs, producers, or distributors, and an industry body, or a local government. + groups_signup_motivation6: Whatever your role in your local food movement, we're ready to help. However you come to wonder what Open Food Network would look like or is doing in your part of the world, let's start the conversation. + groups_signup_motivation7: We make food movements make more sense. + groups_signup_motivation8: You need to activate and enable your networks, we offer a platform for conversation and action. You need real engagement. We’ll help reach all the players, all the stakeholders, all the sectors. + groups_signup_motivation9: You need resourcing. We’ll bring all our experience to bear. You need cooperation. We’ll better connect you to a global network of peers. + groups_signup_pricing: Group Account + groups_signup_studies: Case Studies + groups_signup_contact: Ready to discuss? + groups_signup_contact_text: "Get in touch to discover what OFN can do for you:" + groups_signup_detail: "Here's the detail." + login_invalid: "Invalid email or password" + modal_hubs: "Food Hubs" + modal_hubs_abstract: Our food hubs are the point of contact between you and the people who make your food! + modal_hubs_content1: You can search for a convenient hub by location or name. Some hubs have multiple points where you can pick-up your purchases, and some will also provide delivery options. Each food hub is a sales point with independent business operations and logistics - so variations between hubs are to be expected. + modal_hubs_content2: You can only shop at one food hub at a time. + modal_groups: "Groups / Regions" + modal_groups_content1: These are the organisations and relationships between hubs which make up the Open Food Network. + modal_groups_content2: Some groups are clustered by location or council, others by non-geographic similarities. + modal_how: "How it works" + modal_how_shop: Shop the Open Food Network + modal_how_shop_explained: Search for a food hub near you to start shopping! You can expand each food hub to see what kinds of goodies are available, and click through to start shopping. (You can only shop one food hub at a time.) + modal_how_pickup: Pick-ups, delivery and shipping costs + modal_how_pickup_explained: Some food hubs deliver to your door, while others require you to pick-up your purchases. You can see which options are available on the homepage, and select which you'd like at the shopping and check-out pages. Delivery will cost more, and pricing differs from hub-to-hub. Each food hub is a sales point with independent business operations and logisitics - so variations between hubs are to be expected. + modal_how_more: Learn more + modal_how_more_explained: "If you want to learn more about the Open Food Network, how it works, and get involved, check out:" + modal_producers: "Producers" + modal_producers_explained: "Our producers make all the delicious food you can shop for on the Open Food Network." + producers_about: About us + producers_buy: Shop for + producers_contact: Contact + producers_contact_phone: Call + producers_contact_social: Follow + producers_buy_at_html: "Shop for %{enterprise} products at:" + producers_filter: Filter by + producers_filter_type: Type + producers_filter_property: Property + producers_title: Producers + producers_headline: Find local producers + producers_signup_title: Sign up as a producer + producers_signup_headline: Food producers, empowered. + producers_signup_motivation: Sell your food and tell your stories to diverse new markets. Save time and money on every overhead. We support innovation without the risk. We've levelled the playing field. + producers_signup_send: Join now + producers_signup_enterprise: Enterprise Accounts + producers_signup_studies: Stories from our producers. + producers_signup_cta_headline: Join now! + producers_signup_cta_action: Join now + producers_signup_detail: Here's the detail. + products_item: Item + products_description: Description + products_variant: Variant + products_quantity: Quantity + products_available: Available? + products_producer: "Producer" + products_price: "Price" + name_or_sku: "NAME OR SKU" + register_title: Register + sell_title: "Register" + sell_headline: "Get on the Open Food Network!" + sell_motivation: "Showcase your beautiful food." + sell_producers: "Producers" + sell_hubs: "Hubs" + sell_groups: "Groups" + sell_producers_detail: "Set up a profile for your business on the OFN in just minutes. At any time you can upgrade your profile to an online store and sell your products direct to customers." + sell_hubs_detail: "Set up a profile for your food enterprise or organisation on the OFN. At any time you can upgrade your profile to a multi-producer shop." + sell_groups_detail: "Set up a tailored directory of enterprises (producers and other food enterprises) for your region or for your organisation." + sell_user_guide: "Find out more in our user guide." + sell_listing_price: "Listing on the OFN is free. Opening and running a shop on OFN is free up to PHP 5,000 of monthly sales. If you sell more, you can choose your community contribution between 1.5% and 3% of sales. For more detail on pricing visit the Software Platform section via the About link in the top menu." + sell_embed: "We can also embed an OFN shop in your own customised website or build a customised local food network website for your region." + sell_ask_services: "Ask us about OFN services." + shops_title: Shops + shops_headline: Shopping, transformed. + shops_text: Food grows in cycles, farmers harvest in cycles, and we order food in cycles. If you find an order cycle closed, check back soon. + shops_signup_title: Sign up as a hub + shops_signup_headline: Food hubs, unlimited. + shops_signup_motivation: Whatever your model, we support you. However you change, we're with you. We're non-profit, independent, and open-sourced. We're the software partners you've dreamed of. + shops_signup_action: Join now + shops_signup_pricing: Enterprise Accounts + shops_signup_stories: Stories from our hubs. + shops_signup_help: We're ready to help. + shops_signup_help_text: You need a better return. You need new buyers and logistics partners. You need your story told across wholesale, retail, and the kitchen table. + shops_signup_detail: Here's the detail. + orders: Orders + orders_fees: Fees... + orders_edit_title: Shopping Cart + orders_edit_headline: Your shopping cart + orders_edit_time: Order ready for + orders_edit_continue: Continue shopping + orders_edit_checkout: Checkout + orders_form_empty_cart: "Empty cart" + orders_form_subtotal: Produce subtotal + orders_form_admin: Admin & Handling + orders_form_total: Total + orders_oc_expired_headline: Orders have closed for this order cycle + orders_oc_expired_text: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders." + orders_oc_expired_text_others_html: "Sorry, orders for this order cycle closed %{time} ago! Please contact your hub directly to see if they can accept late orders %{link}." + orders_oc_expired_text_link: "or see the other order cycles available at this hub" + orders_oc_expired_email: "Email:" + orders_oc_expired_phone: "Phone:" + orders_show_title: Order Confirmation + orders_show_time: Order ready on + orders_show_order_number: "Order #%{number}" + orders_show_cancelled: Cancelled + orders_show_confirmed: Confirmed + orders_your_order_has_been_cancelled: "Your order has been cancelled" + orders_could_not_cancel: "Sorry, the order could not be cancelled" + orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead." + orders_bought_items_notice: + one: "An additional item is already confirmed for this order cycle" + other: "%{count} additional items already confirmed for this order cycle" + orders_bought_edit_button: Edit confirmed items + orders_bought_already_confirmed: "* already confirmed" + orders_confirm_cancel: Are you sure you want to cancel this order? + order_processed_successfully: "Your order has been processed successfully" + products_cart_distributor_choice: "Distributor for your order:" + products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." + products_cart_distributor_is: "Your distributor for this order is %{name}." + products_distributor_error: "Please complete your order at %{link} before shopping with another distributor." + products_oc: "Order cycle for your order:" + products_oc_change: "Your order cycle for this order will be changed to %{name} if you add this product to your cart." + products_oc_is: "Your order cycle for this order is %{name}." + products_oc_error: "Please complete your order from %{link} before shopping in a different order cycle." + products_oc_current: "your current order cycle" + products_max_quantity: Max quantity + products_distributor: Distributor + products_distributor_info: When you select a distributor for your order, their address and pickup times will be displayed here. + password: Password + remember_me: Remember Me + are_you_sure: "Are you sure?" + orders_open: Orders open + closing: "Closing " + going_back_to_home_page: "Taking you back to the home page" + creating: Creating + updating: Updating + failed_to_create_enterprise: "Failed to create your enterprise." + failed_to_create_enterprise_unknown: "Failed to create your enterprise.\nPlease ensure all fields are completely filled out." + failed_to_update_enterprise_unknown: "Failed to update your enterprise.\nPlease ensure all fields are completely filled out." + enterprise_confirm_delete_message: "This will also delete the %{product} that this enterprise supplies. Are you sure you want to continue?" + order_not_saved_yet: "Your order hasn't been saved yet. Give us a few seconds to finish!" + filter_by: "Filter by" + hide_filters: "Hide filters" + one_filter_applied: "1 filter applied" + x_filters_applied: " filters applied" + submitting_order: "Submitting your order: please wait" + confirm_hub_change: "Are you sure? This will change your selected hub and remove any items in your shopping cart." + confirm_oc_change: "Are you sure? This will change your selected order cycle and remove any items in your shopping cart." + location_placeholder: "Type in a location..." + error_required: "can't be blank" + error_number: "must be number" + error_email: "must be email address" + error_not_found_in_database: "%{name} not found in database" + error_not_primary_producer: "%{name} is not enabled as a producer" + error_no_permission_for_enterprise: "\"%{name}\": you do not have permission to manage products for this enterprise" + item_handling_fees: "Item Handling Fees (included in item totals)" + january: "January" + february: "February" + march: "March" + april: "April" + may: "May" + june: "June" + july: "July" + august: "August" + september: "September" + october: "October" + november: "November" + december: "December" + email_not_found: "Email address not found" + email_unconfirmed: "You must confirm your email address before you can reset your password." + email_required: "You must provide an email address" + logging_in: "Hold on a moment, we're logging you in" + signup_email: "Your email" + choose_password: "Choose a password" + confirm_password: "Confirm password" + action_signup: "Sign up now" + forgot_password: "Forgot Password?" + password_reset_sent: "An email with instructions on resetting your password has been sent!" + reset_password: "Reset password" + update_and_recalculate_fees: "Update And Recalculate Fees" + registration: + steps: + introduction: + registration_greeting: "Hi there!" + registration_intro: "You can now create a profile for your Producer or Hub" + registration_checklist: "What do I need?" + registration_time: "5-10 minutes" + registration_enterprise_address: "Enterprise address" + registration_contact_details: "Primary contact details" + registration_logo: "Your logo image" + registration_promo_image: "Landscape image for your profile" + registration_about_us: "'About Us' text" + registration_outcome_headline: "What do I get?" + registration_outcome1_html: "Your profile helps people find and contact you on the Open Food Network." + registration_outcome2: "Use this space to tell the story of your enterprise, to help drive connections to your social and online presence." + registration_outcome3: "It's also the first step towards trading on the Open Food Network, or opening an online store." + registration_action: "Let's get started!" + details: + title: "Details" + headline: "Let's Get Started" + enterprise: "Woot! First need to know a little bit about your enterprise:" + producer: "Woot! First we need to know a little bit about your farm:" + enterprise_name_field: "Enterprise Name:" + producer_name_field: "Farm Name:" + producer_name_field_placeholder: "e.g. Jose's Awesome Farm" + producer_name_field_error: "Please choose a unique name for your enterprise" + address1_field: "Address line 1:" + address1_field_placeholder: "e.g. 123 Kapayapaan St." + address1_field_error: "Please enter an address" + address2_field: "Address line 2:" + suburb_field: "City:" + suburb_field_placeholder: "e.g. Tobias Fornier" + suburb_field_error: "Please enter a city/municipality" + postcode_field: "Postcode:" + postcode_field_placeholder: "e.g. 5716" + postcode_field_error: "Postcode required" + state_field: "Province:" + state_field_error: "Province required" + country_field: "Country:" + country_field_error: "Please select a country" + contact: + title: "Contact" + who_is_managing_enterprise: "Who is responsible for managing %{enterprise}?" + contact_field: "Primary Contact" + contact_field_placeholder: "Contact Name" + contact_field_required: "You need to enter a primary contact." + phone_field: "Phone number" + phone_field_placeholder: "eg. (03) 1234 5678" + type: + title: "Type" + headline: "Last step to add %{enterprise}!" + question: "Are you a producer?" + yes_producer: "Yes, I'm a producer" + no_producer: "No, I'm not a producer" + producer_field_error: "Please choose one. Are you are producer?" + yes_producer_help: "Producers make yummy things to eat and/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it." + no_producer_help: "If you’re not a producer, you’re probably someone who sells and distributes food. You might be a hub, coop, buying group, retailer, wholesaler or other." + create_profile: "Create Profile" + about: + title: "About" + headline: "Nice one!" + message: "Now let's flesh out the details about" + success: "Success! %{enterprise} added to the Open Food Network" + registration_exit_message: "If you exit this wizard at any stage, you can continue to create your profile by going to the admin interface." + enterprise_description: "Short Description" + enterprise_description_placeholder: "A short sentence describing your enterprise" + enterprise_long_desc: "Long Description" + enterprise_long_desc_placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words." + enterprise_long_desc_length: "%{num} characters / up to 600 recommended" + enterprise_abn: "TIN" + enterprise_abn_placeholder: "eg. 99 123 456 789" + enterprise_acn: "Branch TIN" + enterprise_acn_placeholder: "eg. 123 456 789" + enterprise_tax_required: "You need to make a selection." + images: + title: "Images" + headline: "Thanks!" + description: "Let's upload some pretty pictures so your profile looks great! :)" + uploading: "Uploading..." + continue: "Continue" + back: "Back" + logo: + select_logo: "Step 1. Select Logo Image" + logo_tip: "Tip: Square images will work best, preferably at least 300×300px" + logo_label: "Choose a logo image" + logo_drag: "Drag and drop your logo here" + review_logo: "Step 2. Review Your Logo" + review_logo_tip: "Tip: for best results, your logo should fill the available space" + logo_placeholder: "Your logo will appear here for review once uploaded" + promo: + select_promo_image: "Step 3. Select Promo Image" + promo_image_tip: "Tip: Shown as a banner, preferred size is 1200×260px" + promo_image_label: "Choose a promo image" + promo_image_drag: "Drag and drop your promo here" + review_promo_image: "Step 4. Review Your Promo Banner" + review_promo_image_tip: "Tip: for best results, your promo image should fill the available space" + promo_image_placeholder: "Your logo will appear here for review once uploaded" + social: + title: "Social" + enterprise_final_step: "Final step!" + enterprise_social_text: "How can people find %{enterprise} online?" + website: "Website" + website_placeholder: "e.g. www.openfoodnetwork.ph" + facebook: "Facebook" + facebook_placeholder: "eg. www.facebook.com/PageNameHere" + linkedin: "LinkedIn" + linkedin_placeholder: "eg. www.linkedin.com/YourNameHere" + twitter: "Twitter" + twitter_placeholder: "e.g. @OFNPhilippines" + instagram: "Instagram" + instagram_placeholder: "eg. @OFNPhilippines" + limit_reached: + headline: "Oh no!" + message: "You have reached the limit!" + text: "You have reached the limit for the number of enterprises you are allowed to own on the" + action: "Return to the homepage" + finished: + headline: "Finished!" + thanks: "Thanks for filling out the details for %{enterprise}." + login: "You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin." + action: "Go to Enterprise Dashboard" + back: "Back" + continue: "Continue" + action_or: "OR" + enterprise_limit: Enterprise Limit + shipping_method_destroy_error: "That shipping method cannot be deleted as it is referenced by an order: %{number}." + fees: "Fees" + item_cost: "Item cost" + bulk: "Bulk" + shop_variant_quantity_min: "min" + shop_variant_quantity_max: "max" + follow: "Follow" + shop_for_products_html: "Shop for %{enterprise} products at:" + change_shop: "Change shop to:" + shop_at: "Shop now at:" + price_breakdown: "Full price breakdown" + admin_fee: "Admin fee" + sales_fee: "Sales fee" + packing_fee: "Packing fee" + transport_fee: "Transport fee" + fundraising_fee: "Fundraising fee" + price_graph: "Price graph" + included_tax: "Included tax" + balance: "Balance" + transaction: "Transaction" + transaction_date: "Date" + payment_state: "Payment status" + shipping_state: "Shipping status" + value: "Value" + balance_due: "Balance due" + credit: "Credit" + Paid: "Paid" + Ready: "Ready" + ok: OK + not_visible: not visible + you_have_no_orders_yet: "You have no orders yet" + show_only_complete_orders: "Only show complete orders" + successfully_created: '%{resource} has been successfully created!' + successfully_removed: '%{resource} has been successfully removed!' + successfully_updated: '%{resource} has been successfully updated!' + running_balance: "Running balance" + outstanding_balance: "Outstanding balance" + admin_enterprise_relationships: "Enterprise Permissions" + admin_enterprise_relationships_everything: "Everything" + admin_enterprise_relationships_permits: "permits" + admin_enterprise_relationships_seach_placeholder: "Search" + admin_enterprise_relationships_button_create: "Create" + admin_enterprise_groups: "Enterprise Groups" + admin_enterprise_groups_name: "Name" + admin_enterprise_groups_owner: "Owner" + admin_enterprise_groups_on_front_page: "On front page ?" + admin_enterprise_groups_enterprise: "Enterprises" + admin_enterprise_groups_data_powertip: "The primary user responsible for this group." + admin_enterprise_groups_data_powertip_logo: "This is the logo for the group" + admin_enterprise_groups_data_powertip_promo_image: "This image is displayed at the top of the Group profile" + admin_enterprise_groups_contact: "Contact" + admin_enterprise_groups_contact_phone_placeholder: "eg. 98 7654 3210" + admin_enterprise_groups_contact_address1_placeholder: "123 Kapayapaan St." + admin_enterprise_groups_contact_city: "City" + admin_enterprise_groups_contact_city_placeholder: "e.g. Mandaluyong" + admin_enterprise_groups_contact_zipcode: "Postcode" + admin_enterprise_groups_contact_zipcode_placeholder: "e.g. 1555" + admin_enterprise_groups_contact_state_id: "Province" + admin_enterprise_groups_contact_country_id: "Country" + admin_enterprise_groups_web: "Web Resources" + admin_enterprise_groups_web_twitter: "e.g. @OFNPhilippines" + admin_enterprise_groups_web_website_placeholder: "eg. www.truffles.com" + admin_order_cycles: "Admin Order Cycles" + open: "Open" + close: "Close" + create: "Create" + search: "Search" + supplier: "Supplier" + product_name: "Product Name" + product_description: "Product Description" + units: "Unit Size" + coordinator: "Coordinator" + distributor: "Distributor" + enterprise_fees: "Enterprise Fees" + process_my_order: "Process My Order" + delivery_instructions: Delivery Instructions + delivery_method: Delivery Method + fee_type: "Fee Type" + tax_category: "Tax Category" + calculator: "Calculator" + calculator_values: "Calculator values" + calculator_settings_warning: "If you are changing the calculator type, you must save first before you can edit the calculator settings" + flat_percent_per_item: "Flat Percent (per item)" + flat_rate_per_item: "Flat Rate (per item)" + flat_rate_per_order: "Flat Rate (per order)" + flexible_rate: "Flexible Rate" + price_sack: "Price Sack" + new_order_cycles: "New Order Cycles" + new_order_cycle: "New Order Cycle" + select_a_coordinator_for_your_order_cycle: "Select a coordinator for your order cycle" + notify_producers: 'Notify producers' + edit_order_cycle: "Edit Order Cycle" + roles: "Roles" + update: "Update" + delete: Delete + add_producer_property: "Add producer property" + in_progress: "In Progress" + started_at: "Started at" + queued: "Queued" + scheduled_for: "Scheduled for" + customers: "Customers" + please_select_hub: "Please select a Hub" + loading_customers: "Loading Customers" + no_customers_found: "No customers found" + go: "Go" + hub: "Hub" + producer: "Producer" + product: "Product" + price: "Price" + on_hand: "On hand" + review: "Review" + save_changes: "Save Changes" + order_saved: "Order Saved" + no_products: No Products + spree_admin_overview_enterprises_header: "My Enterprises" + spree_admin_overview_enterprises_footer: "MANAGE MY ENTERPRISES" + spree_admin_enterprises_hubs_name: "Name" + spree_admin_enterprises_create_new: "CREATE NEW" + spree_admin_enterprises_shipping_methods: "Shipping Methods" + spree_admin_enterprises_fees: "Enterprise Fees" + spree_admin_enterprises_none_create_a_new_enterprise: "CREATE A NEW ENTERPRISE" + spree_admin_enterprises_none_text: "You don't have any enterprises yet" + spree_admin_enterprises_tabs_hubs: "HUBS" + spree_admin_enterprises_producers_manage_products: "MANAGE PRODUCTS" + spree_admin_enterprises_create_new_product: "CREATE A NEW PRODUCT" + spree_admin_single_enterprise_alert_mail_confirmation: "Please confirm the email address for" + spree_admin_single_enterprise_alert_mail_sent: "We've sent an email to" + spree_admin_overview_action_required: "Action Required" + spree_admin_overview_check_your_inbox: "Please check your inbox for further instructions. Thanks!" + spree_admin_unit_value: Unit Value + spree_admin_unit_description: Unit Description + spree_admin_variant_unit: Variant unit + spree_admin_variant_unit_scale: Variant unit scale + spree_admin_supplier: Supplier + spree_admin_product_category: Product Category + spree_admin_variant_unit_name: Variant unit name + unit_name: "Unit name" + change_package: "Change Package" + spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" + spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" + spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Kapayapaan St., Tobias Fornier, Antique 5716'" + spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" + spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" + spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." + spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle." + spree_distributors_error: "At least one hub must be selected" + spree_user_enterprise_limit_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})." + spree_variant_product_error: must have at least one variant + your_profil_live: "Your profile live" + on_ofn_map: "on the Open Food Network map" + see: "See" + live: "live" + manage: "Manage" + resend: "Resend" + add_and_manage_products: "Add & manage products" + add_and_manage_order_cycles: "Add & manage order cycles" + manage_order_cycles: "Manage order cycles" + manage_products: "Manage products" + edit_profile_details: "Edit profile details" + edit_profile_details_etc: "Change your profile description, images, etc." + order_cycle: "Order Cycle" + order_cycles: "Order Cycles" + enterprise_relationships: "Enterprise permissions" + remove_tax: "Remove tax" + first_name_begins_with: "First name begins with" + last_name_begins_with: "Last name begins with" + enterprise_tos_link: "Enterprise Terms of Service link" + enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our " + enterprise_tos_link_text: "Terms of Service." + enterprise_tos_agree: "I agree to the above Terms of Service" + tax_settings: "Tax Settings" + products_require_tax_category: "products require tax category" + admin_shared_address_1: "Address" + admin_shared_address_2: "Address (cont.)" + admin_share_city: "City" + admin_share_zipcode: "Postcode" + admin_share_country: "Country" + admin_share_state: "Province" + hub_sidebar_hubs: "Hubs" + hub_sidebar_none_available: "None Available" + hub_sidebar_manage: "Manage" + hub_sidebar_at_least: "At least one hub must be selected" + hub_sidebar_blue: "blue" + hub_sidebar_red: "red" + report_customers_distributor: "Distributor" + report_customers_supplier: "Supplier" + report_customers_cycle: "Order Cycle" + report_customers_type: "Report Type" + report_customers_csv: "Download as csv" + report_producers: "Producers: " + report_type: "Report Type: " + report_hubs: "Hubs: " + report_payment: "Payment Methods: " + report_distributor: "Distributor: " + report_payment_by: 'Payments By Type' + report_itemised_payment: 'Itemised Payment Totals' + report_payment_totals: 'Payment Totals' + report_all: 'all' + report_order_cycle: "Order Cycle: " + report_enterprises: "Enterprises: " + report_users: "Users: " + report_tax_rates: Tax rates + report_tax_types: Tax types + report_header_order_cycle: Order Cycle + report_header_user: User + report_header_email: Email + report_header_status: Status + report_header_comments: Comments + report_header_first_name: First Name + report_header_last_name: Last Name + report_header_phone: Phone + report_header_suburb: City + report_header_address: Address + report_header_billing_address: Billing Address + report_header_relationship: Relationship + report_header_hub: Hub + report_header_hub_address: Hub Address + report_header_to_hub: To Hub + report_header_hub_code: Hub Code + report_header_code: Code + report_header_paid: Paid? + report_header_delivery: Delivery? + report_header_shipping: Shipping + report_header_shipping_method: Shipping Method + report_header_shipping_instructions: Shipping instructions + report_header_ship_street: Ship Street + report_header_ship_street_2: Ship Street 2 + report_header_ship_city: Ship City + report_header_ship_postcode: Ship Postcode + report_header_ship_state: Ship State + report_header_billing_street: Billing Street + report_header_billing_street_2: Billing Street 2 + report_header_billing_street_3: Billing Street 3 + report_header_billing_street_4: Billing Street 4 + report_header_billing_city: Billing City + report_header_billing_postcode: Billing Postcode + report_header_billing_state: Billing State + report_header_incoming_transport: Incoming Transport + report_header_special_instructions: Special Instructions + report_header_order_number: Order number + report_header_date: Date + report_header_confirmation_date: Confirmation Date + report_header_tags: Tags + report_header_items: Items + report_header_items_total: "Items total %{currency_symbol}" + report_header_taxable_items_total: "Taxable Items Total (%{currency_symbol})" + report_header_sales_tax: "Sales Tax (%{currency_symbol})" + report_header_delivery_charge: "Delivery Charge (%{currency_symbol})" + report_header_tax_on_delivery: "Tax on Delivery (%{currency_symbol})" + report_header_tax_on_fees: "Tax on Fees (%{currency_symbol})" + report_header_total_tax: "Total Tax (%{currency_symbol})" + report_header_enterprise: Enterprise + report_header_customer: Customer + report_header_customer_code: Customer Code + report_header_product: Product + report_header_product_properties: Product Properties + report_header_quantity: Quantity + report_header_max_quantity: Max Quantity + report_header_variant: Variant + report_header_variant_value: Variant Value + report_header_variant_unit: Variant Unit + report_header_total_available: Total available + report_header_unallocated: Unallocated + report_header_max_quantity_excess: Max Quantity Excess + report_header_taxons: Taxons + report_header_supplier: Supplier + report_header_producer: Producer + report_header_producer_suburb: Producer City + report_header_unit: Unit + report_header_group_buy_unit_quantity: Group Buy Unit Quantity + report_header_cost: Cost + report_header_shipping_cost: Shipping Cost + report_header_curr_cost_per_unit: Curr. Cost per Unit + report_header_total_shipping_cost: Total Shipping Cost + report_header_payment_method: Payment Method + report_header_sells: Sells + report_header_visible: Visible + report_header_price: Price + report_header_unit_size: Unit Size + report_header_distributor: Distributor + report_header_distributor_address: Distributor address + report_header_distributor_city: Distributor city + report_header_distributor_postcode: Distributor postcode + report_header_delivery_address: Delivery Address + report_header_delivery_postcode: Delivery Postcode + report_header_bulk_unit_size: Bulk Unit Size + report_header_weight: Weight + report_header_sum_total: Sum Total + report_header_date_of_order: Date of Order + report_header_amount_owing: Amount Owing + report_header_amount_paid: Amount Paid + report_header_units_required: Units Required + report_header_remainder: Remainder + report_header_order_date: Order date + report_header_order_id: Order Id + report_header_item_name: Item name + report_header_temp_controlled_items: Temp Controlled Items? + report_header_customer_name: Customer Name + report_header_customer_email: Customer Email + report_header_customer_phone: Customer Phone + report_header_customer_city: Customer City + report_header_payment_state: Payment State + report_header_payment_type: Payment Type + report_header_item_price: "Item (%{currency})" + report_header_item_fees_price: "Item + Fees (%{currency})" + report_header_admin_handling_fees: "Admin & Handling (%{currency})" + report_header_ship_price: "Ship (%{currency})" + report_header_pay_fee_price: "Pay fee (%{currency})" + report_header_total_price: "Total (%{currency})" + report_header_product_total_price: "Product Total (%{currency})" + report_header_shipping_total_price: "Shipping Total (%{currency})" + report_header_outstanding_balance_price: "Outstanding Balance (%{currency})" + report_header_eft_price: "EFT (%{currency})" + report_header_paypal_price: "PayPal (%{currency})" + report_header_sku: SKU + report_header_amount: Amount + report_header_balance: Balance + report_header_total_cost: "Total Cost" + report_header_total_ordered: Total Ordered + report_header_total_max: Total Max + report_header_total_units: Total Units + report_header_sum_max_total: "Sum Max Total" + report_header_total_excl_vat: "Total excl. tax (%{currency_symbol})" + report_header_total_incl_vat: "Total incl. tax (%{currency_symbol})" + report_header_temp_controlled: TempControlled? + report_header_is_producer: Producer? + report_header_not_confirmed: Not Confirmed + report_header_gst_on_income: VAT on Income + report_header_gst_free_income: VAT Free Income + report_header_total_untaxable_produce: Total untaxable produce (no tax) + report_header_total_taxable_produce: Total taxable produce (tax inclusive) + report_header_total_untaxable_fees: Total untaxable fees (no tax) + report_header_total_taxable_fees: Total taxable fees (tax inclusive) + report_header_delivery_shipping_cost: Delivery Shipping Cost (tax inclusive) + report_header_transaction_fee: Transaction Fee (no tax) + report_header_total_untaxable_admin: Total untaxable admin adjustments (no tax) + report_header_total_taxable_admin: Total taxable admin adjustments (tax inclusive) + initial_invoice_number: "Initial invoice number:" + invoice_date: "Invoice date:" + due_date: "Due date:" + account_code: "Account code:" + equals: "Equals" + contains: "contains" + discount: "Discount" + filter_products: "Filter Products" + delete_product_variant: "The last variant cannot be deleted!" + progress: "progress" + saving: "Saving.." + success: "success" + failure: "failure" + unsaved_changes_confirmation: "Unsaved changes will be lost. Continue anyway?" + one_product_unsaved: "Changes to one product remain unsaved." + products_unsaved: "Changes to %{n} products remain unsaved." + is_already_manager: "is already a manager!" + no_change_to_save: " No change to save" + user_invited: "%{email} has been invited to manage this enterprise" + add_manager: "Add an existing user" + users: "Users" + about: "About" + images: "Images" + web: "Web" + primary_details: "Primary Details" + adrdress: "Address" + contact: "Contact" + social: "Social" + business_details: "Business Details" + properties: "Properties" + shipping: "Shipping" + shipping_methods: "Shipping Methods" + payment_methods: "Payment Methods" + payment_method_fee: "Transaction fee" + payment_processing_failed: "Payment could not be processed, please check the details you entered" + payment_method_not_supported: "That payment method is unsupported. Please choose another one." + payment_updated: "Payment Updated" + inventory_settings: "Inventory Settings" + tag_rules: "Tag Rules" + shop_preferences: "Shop Preferences" + enterprise_fee_whole_order: Whole order + enterprise_fee_by: "%{type} fee by %{role} %{enterprise_name}" + validation_msg_relationship_already_established: "^That relationship is already established." + validation_msg_at_least_one_hub: "^At least one hub must be selected" + validation_msg_tax_category_cant_be_blank: "^Tax Category can't be blank" + validation_msg_is_associated_with_an_exising_customer: "is associated with an existing customer" + content_configuration_pricing_table: "(TODO: Pricing table)" + content_configuration_case_studies: "(TODO: Case studies)" + content_configuration_detail: "(TODO: Detail)" + enterprise_name_error: "has already been taken. If this is your enterprise and you would like to claim ownership, or if you would like to trade with this enterprise please contact the current manager of this profile at %{email}." + enterprise_owner_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})." + enterprise_role_uniqueness_error: "^That role is already present." + inventory_item_visibility_error: must be true or false + product_importer_file_error: "error: no file uploaded" + product_importer_spreadsheet_error: "could not process file: invalid filetype" + product_importer_products_save_error: did not save any products successfully + product_import_file_not_found_notice: 'File not found or could not be opened' + product_import_no_data_in_spreadsheet_notice: 'No data found in spreadsheet' + order_choosing_hub_notice: Your hub has been selected. + order_cycle_selecting_notice: Your order cycle has been selected. + adjustments_tax_rate_error: "^Please check that the tax rate for this adjustment is correct." + active_distributors_not_ready_for_checkout_message_singular: >- + The hub %{distributor_names} is listed in an active order cycle, but does not + have valid shipping and payment methods. Until you set these up, customers will + not be able to shop at this hub. + active_distributors_not_ready_for_checkout_message_plural: >- + The hubs %{distributor_names} are listed in an active order cycle, but do not + have valid shipping and payment methods. Until you set these up, customers will + not be able to shop at these hubs. + enterprise_fees_update_notice: Your enterprise fees have been updated. + enterprise_register_package_error: "Please select a package" + enterprise_register_error: "Could not complete registration for %{enterprise}" + enterprise_register_success_notice: "Congratulations! Registration for %{enterprise} is complete!" + enterprise_bulk_update_success_notice: "Enterprises updated successfully" + enterprise_bulk_update_error: 'Update failed' + enterprise_shop_show_error: "The shop you are looking for doesn't exist or is inactive on OFN. Please check other shops." + order_cycles_create_notice: 'Your order cycle has been created.' + order_cycles_update_notice: 'Your order cycle has been updated.' + order_cycles_bulk_update_notice: 'Order cycles have been updated.' + order_cycles_clone_notice: "Your order cycle %{name} has been cloned." + order_cycles_email_to_producers_notice: 'Emails to be sent to producers have been queued for sending.' + order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" + order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" + back_to_orders_list: "Back to order list" + no_orders_found: "No Orders Found" + order_information: "Order Information" + date_completed: "Date Completed" + amount: "Amount" + state_names: + ready: Ready + pending: Pending + shipped: Shipped + js: + saving: 'Saving...' + changes_saved: 'Changes saved.' + save_changes_first: Save changes first. + all_changes_saved: All changes saved + unsaved_changes: You have unsaved changes + all_changes_saved_successfully: All changes saved successfully + oh_no: "Oh no! I was unable to save your changes." + unauthorized: "You are unauthorised to access this page." + error: Error + unavailable: Unavailable + profile: Profile + hub: Hub + shop: Shop + choose: Choose + resolve_errors: Please resolve the following errors + more_items: "+ %{count} More" + default_card_updated: Default Card Updated + admin: + enterprise_limit_reached: "You have reached the standard limit of enterprises per account. Write to %{contact_email} if you need to increase it." + modals: + got_it: Got it + close: "Close" + invite: "Invite" + invite_title: "Invite an unregistered user" + tag_rule_help: + title: Tag Rules + overview: Overview + overview_text: > + Tag rules provide a way to describe which items are visible or otherwise + to which customers. Items can be Shipping Methods, Payment Methods, + Products and Order Cycles. + by_default_rules: "'By Default...' Rules" + by_default_rules_text: > + Default rules allow you to hide items so that they are not visible by + default. This behaviour can then be overriden by non-default rules for + customers with particular tags. + customer_tagged_rules: "'Customers Tagged...' Rules" + customer_tagged_rules_text: > + By creating rules related to a specific customer tag, you can override + the default behaviour (whether it be to show or to hide items) for customers + with the specified tag. + panels: + save: SAVE + saved: SAVED + saving: SAVING + enterprise_package: + hub_profile: Hub Profile + hub_profile_cost: "COST: ALWAYS FREE" + hub_profile_text1: > + People can find and contact you on the Open Food Network. Your enterprise + will be visible on the map, and will be searchable in listings. + hub_profile_text2: > + Having a profile, and making connections within your local food system + through the Open Food Network will always be free. + hub_shop: Hub Shop + hub_shop_text1: > + Your enterprise is the backbone of your local food system. You aggregate + produce from other enterprises and can sell it through your shop on + the Open Food Network. + hub_shop_text2: > + Hubs can take many forms, whether they be a food co-op, a buying group, + a veggie-box program, or a local grocery store. + hub_shop_text3: > + If you also want to sell your own products, you will need to switch + this enterprise to be a producer. + choose_package: Please Choose a Package + choose_package_text1: > + Your enterprise will not be fully activated until a package is selected + from the options on the left. + choose_package_text2: > + Click on an option to see more detailed information about each package, + and hit the red SAVE button when you are done! + profile_only: Profile Only + profile_only_cost: "COST: ALWAYS FREE" + profile_only_text1: > + A profile makes you visible and contactable to others and is a way to + share your story. + profile_only_text2: > + If you prefer to focus on producing food, and want to leave the work + of selling it to someone else, you won't require a shop on the Open + Food Network. + profile_only_text3: > + Add your products to Open Food Network, allowing hubs to stock your + products in their stores. + producer_shop: Producer Shop + producer_shop_text1: > + Sell your products directly to customers through your very own Open + Food Network shopfront. + producer_shop_text2: > + A Producer Shop is for your produce only, if you want to sell produce + grown/produced off site, please select 'Producer Hub'. + producer_hub: Producer Hub + producer_hub_text1: > + Your enterprise is the backbone of your local food system. You can sell + your own produce as well as produce aggregated from other enterprises + through your shopfront on the Open Food Network. + producer_hub_text2: > + Producer Hubs can take many forms, whether they be a CSA, a veggie-box + program, or a food co-op with a rooftop garden. + producer_hub_text3: > + The Open Food Network aims to support as many hub models as possible, + so no matter your situation, we want to provide the tools you need to + run your organisation or local food business. + get_listing: Get a listing + always_free: ALWAYS FREE + sell_produce_others: Sell produce from others + sell_own_produce: Sell your own produce + sell_both: Sell produce from self and others + enterprise_producer: + producer: Producer + producer_text1: > + Producers make yummy things to eat or drink. You're a producer if you + grow it, raise it, brew it, bake it, ferment it, milk it or mould it. + producer_text2: > + Producers can also perform other functions, such as aggregating food + from other enterprises and selling it through a shop on the Open Food + Network. + non_producer: Non-producer + non_producer_text1: > + Non-producers do not produce any food themselves, meaning that they + cannot create their own products for sale through the Open Food Network. + non_producer_text2: > + Instead, non-producers specialise in linking producers to the end eater, + whether it be by aggregating, grading, packing, selling or delivering + food. + producer_desc: Producers of food + producer_example: eg. GROWERS, BAKERS, BREWERS, MAKERS + non_producer_desc: All other food enterprises + non_producer_example: eg. Grocery stores, Food co-ops, Buying groups + enterprise_status: + status_title: "%{name} is set up and ready to go!" + severity: Severity + description: Description + resolve: Resolve + exchange_products: + load_more_variants: "Load More Variants" + load_all_variants: "Load All Variants" + select_all_variants: "Select All %{total_number_of_variants} Variants" + variants_loaded: "%{num_of_variants_loaded} of %{total_number_of_variants} Variants Loaded" + loading_variants: "Loading Variants" + tag_rules: + shipping_method_tagged_top: "Shipping methods tagged" + shipping_method_tagged_bottom: "are:" + payment_method_tagged_top: "Payment methods tagged" + payment_method_tagged_bottom: "are:" + order_cycle_tagged_top: "Order Cycles tagged" + order_cycle_tagged_bottom: "are:" + inventory_tagged_top: "Inventory variants tagged" + inventory_tagged_bottom: "are:" + new_tag_rule_dialog: + select_rule_type: "Select a rule type:" + add_rule: "Add Rule" + enterprise_fees: + inherit_from_product: "Inherit From Product" + orders: + index: + per_page: "%{results} per page" + view_file: "View File" + compiling_invoices: "Compiling Invoices" + bulk_invoice_created: "Bulk Invoice created" + bulk_invoice_failed: "Failed to create Bulk Invoice" + please_wait: "Please wait until the PDF is ready before closing this modal." + order_state: + address: "address" + adjustments: "adjustments" + awaiting_return: "awaiting return" + canceled: "cancelled" + cart: "cart" + complete: "complete" + confirm: "confirm" + delivery: "delivery" + paused: "paused" + payment: "payment" + pending: "pending" + resumed: "resumed" + returned: "returned" + skrill: "skrill" + shipment_states: + backorder: "backorder" + partial: "partial" + pending: "pending" + ready: "ready" + shipped: "shipped" + canceled: "cancelled" + payment_states: + balance_due: "balance due" + completed: "completed" + checkout: "checkout" + credit_owed: "credit owed" + failed: "failed" + paid: "paid" + pending: "pending" + processing: "processing" + void: "void" + invalid: "invalid" + resend_user_email_confirmation: + resend: "Resend" + sending: "Resend..." + done: "Resend done ✓" + failed: "Resend failed ✗" + order_cycles: + schedules: + adding_a_new_schedule: "Adding A New Schedule" + updating_a_schedule: "Updating A Schedule" + create_schedule: "Create Schedule" + update_schedule: "Update Schedule" + delete_schedule: "Delete Schedule" + schedule_name_placeholder: "Schedule Name" + created_schedule: "Created schedule" + updated_schedule: "Updated schedule" + deleted_schedule: "Deleted schedule" + name_required_error: "Please enter a name for this schedule" + no_order_cycles_error: "Please select at least one order cycle (drag and drop)" + available: "Available" + selected: "Selected" + customers: + index: + add_customer: "Add Customer" + add_a_new_customer_for: "Add a new customer for %{shop_name}" + customer_placeholder: "customer@example.org" + valid_email_error: "Please enter a valid email address" + subscriptions: + error_saving: "Error saving subscription" + new: + please_select_a_shop: "Please select a shop" + insufficient_stock: "Insufficient stock available, only %{on_hand} remaining" + out_of_stock: + reduced_stock_available: Reduced stock available + out_of_stock_text: > + While you've been shopping, the stock levels for one or more of the products + in your cart have reduced. Here's what's changed: + now_out_of_stock: is now out of stock. + only_n_remainging: "now only has %{num} remaining." + variants: + on_demand: + 'yes': "On demand" + variant_overrides: + on_demand: + use_producer_settings: "Use producer stock settings" + 'yes': "Yes" + 'no': "No" + inventory_products: "Inventory Products" + hidden_products: "Hidden Products" + new_products: "New Products" + reset_stock_levels: Reset Stock Levels To Defaults + changes_to: Changes to + one_override: one override + overrides: overrides + remain_unsaved: remain unsaved. + no_changes_to_save: No changes to save.' + no_authorisation: "I couldn't get authorisation to save those changes, so they remain unsaved." + some_trouble: "I had some trouble saving: %{errors}" + changing_on_hand_stock: Changing on hand stock levels... + stock_reset: Stocks reset to defaults. + tag_rules: + show_hide_variants: 'Show or Hide variants in my shopfront' + show_hide_shipping: 'Show or Hide shipping methods at checkout' + show_hide_payment: 'Show or Hide payment methods at checkout' + show_hide_order_cycles: 'Show or Hide order cycles in my shopfront' + visible: VISIBLE + not_visible: NOT VISIBLE + services: + unsaved_changes_message: Unsaved changes currently exist, save now or ignore? + save: SAVE + ignore: IGNORE + add_to_order_cycle: "add to order cycle" + manage_products: "manage products" + edit_profile: "edit profile" + add_products_to_inventory: "add products to inventory" + resources: + could_not_delete_customer: 'Could not delete customer' + product_import: + confirmation: | + This will set stock level to zero on all products for this + enterprise that are not present in the uploaded file. + order_cycles: + create_failure: "Failed to create order cycle" + update_success: 'Your order cycle has been updated.' + update_failure: "Failed to update order cycle" + no_distributors: There are no distributors in this order cycle. This order cycle will not be visible to customers until you add one. Would you like to continue saving this order cycle?' + enterprises: + producer: "Producer" + non_producer: "Non-Producer" + customers: + select_shop: 'Please select a shop first' + could_not_create: Sorry! Could not create + subscriptions: + closes: closes + closed: closed + close_date_not_set: Close date not set + spree: + users: + order: "Order" + registration: + welcome_to_ofn: "Welcome to the Open Food Network!" + signup_or_login: "Start By Signing Up (or logging in)" + have_an_account: "Already have an account?" + action_login: "Log in now." + inflections: + each: + one: "each" + other: "each" + bunch: + one: "bunch" + other: "bunches" + pack: + one: "pack" + other: "packs" + box: + one: "box" + other: "boxes" + bottle: + one: "bottle" + other: "bottles" + jar: + one: "jar" + other: "jars" + head: + one: "head" + other: "heads" + bag: + one: "bag" + other: "bags" + loaf: + one: "loaf" + other: "loaves" + single: + one: "single" + other: "singles" + tub: + one: "tub" + other: "tubs" + punnet: + one: "punnet" + other: "punnets" + packet: + one: "packet" + other: "packets" + item: + one: "item" + other: "items" + dozen: + one: "dozen" + other: "dozens" + unit: + one: "unit" + other: "units" + serve: + one: "serve" + other: "serves" + tray: + one: "tray" + other: "trays" + piece: + one: "piece" + other: "pieces" + pot: + one: "pot" + other: "pots" + bundle: + one: "bundle" + other: "bundles" + flask: + one: "flask" + other: "flasks" + basket: + one: "basket" + other: "baskets" + sack: + one: "sack" + other: "sacks" + producers: + signup: + start_free_profile: "Start with a free profile, and expand when you're ready!" + order_management: + reports: + enterprise_fee_summary: + date_end_before_start_error: "must be after start" + parameter_not_allowed_error: "You are not authorized to use one or more selected filters for this report." + fee_calculated_on_transfer_through_all: "All" + fee_calculated_on_transfer_through_entire_orders: "Entire Orders through %{distributor}" + tax_category_various: "Various" + fee_type: + payment_method: "Payment Transaction" + shipping_method: "Shipment" + fee_placements: + supplier: "Incoming" + distributor: "Outgoing" + coordinator: "Coordinator" + tax_category_name: + shipping_instance_rate: "Platform Rate" + formats: + csv: + header: + fee_type: "Fee Type" + enterprise_name: "Enterprise Owner" + fee_name: "Fee Name" + customer_name: "Customer" + fee_placement: "Fee Placement" + fee_calculated_on_transfer_through_name: "Fee Calc on Transfer Through" + tax_category_name: "Tax Category" + total_amount: "$$ SUM" + html: + header: + fee_type: "Fee Type" + enterprise_name: "Enterprise Owner" + fee_name: "Fee Name" + customer_name: "Customer" + fee_placement: "Fee Placement" + fee_calculated_on_transfer_through_name: "Fee Calc on Transfer Through" + tax_category_name: "Tax Category" + total_amount: "$$ SUM" + invalid_filter_parameters: "The filters you selected for this report are invalid." + order: "Order" + distribution: "Distribution" + order_details: "Order Details" + customer_details: "Customer Details" + adjustments: "Adjustments" + payments: "Payments" + payment: "Payment" + payment_method: "Payment Method" + shipment: "Shipment" + shipment_inc_vat: "Shipment including VAT" + shipping_tax_rate: "Shipping Tax Rate" + category: "Category" + delivery: "Delivery" + temperature_controlled: "Temperature Controlled" + new_product: "New Product" + administration: "Administration" + logged_in_as: "Logged in as" + account: "Account" + logout: "Logout" + date_range: "Date Range" + status: "status" + new: "New" + start: "Start" + end: "End" + stop: "Stop" + first: "First" + previous: "Previous" + last: "Last" + spree: + your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" + add_product: "Add Product" + name_or_sku: "Name or SKU (enter at least first 4 characters of product name)" + resend: Resend + back_to_orders_list: Back To Orders List + return_authorizations: Return Authorizations + cannot_create_returns: Cannot create returns as this order has no shipped units. + select_stock: "Select stock" + location: "Location" + count_on_hand: "Count On Hand" + quantity: "Quantity" + package_from: "package from" + item_description: "Item Description" + price: "Price" + total: "Total" + edit: "Edit" + split: "Split" + delete: "Delete" + cannot_set_shipping_method_without_address: "Cannot set shipping method until customer details are provided." + no_tracking_present: "No tracking details provided." + order_total: "Order Total" + customer_details: "Customer Details" + customer_search: "Customer Search" + choose_a_customer: "Choose a customer" + account: "Account" + billing_address: "Billing Address" + shipping_address: "Shipping Address" + first_name: "First name" + last_name: "Last name" + street_address: "Street Address" + street_address_2: "Street Address (cont'd)" + city: "City" + zip: "ZIP" + country: "Country" + state: "Province" + phone: "Phone" + update: "Update" + use_billing_address: "Use Billing Address" + adjustments: "Adjustments" + continue: "Continue" + fill_in_customer_info: "Please fill in customer info" + new_payment: "New Payment" + capture: "Capture" + void: "Void" + configurations: "Configurations" + general_settings: "General Settings" + site_name: "Site Name" + site_url: "Site URL" + default_seo_title: "Default Seo Title" + default_meta_description: "Default Meta Description" + default_meta_keywords: "Default Meta Keywords" + security_settings: "Security Settings" + allow_ssl_in_development_and_test: "Allow SSL to be used when in development and test modes" + allow_ssl_in_production: "Allow SSL to be used in production mode" + allow_ssl_in_staging: "Allow SSL to be used in staging mode" + currency_decimal_mark: "Currency decimal mark" + currency_settings: "Currency Settings" + currency_symbol_position: Put "currency symbol before or after currency amount?" + currency_thousands_separator: "Currency thousands separator" + hide_cents: "Hide cents" + display_currency: "Display currency" + choose_currency: "Choose Currency" + mail_method_settings: "Mail Method Settings" + general: "General" + enable_mail_delivery: "Enable Mail Delivery" + send_mails_as: "Send Mails As" + smtp_send_all_emails_as_from_following_address: "Send all mails as from the following address." + send_copy_of_all_mails_to: "Send Copy of All Mails To" + smtp_send_copy_to_this_addresses: "Sends a copy of all outgoing mails to this address. For multiple addresses, separate with commas." + intercept_email_address: "Intercept Email Address" + intercept_email_instructions: "Override email recipient and replace with this address." + smtp: "SMTP" + smtp_domain: "SMTP Domain" + smtp_mail_host: "SMTP Mail Host" + smtp_port: "SMTP Port" + secure_connection_type: "Secure Connection Type" + smtp_authentication_type: "SMTP Authentication Type" + smtp_username: "SMTP Username" + smtp_password: "SMTP Password" + image_settings: "Image Settings" + image_settings_warning: "You will need to regenerate thumbnails if you update the paperclip styles. Use rake paperclip:refresh:thumbnails CLASS=Spree::Image to do this." + attachment_default_style: Attachments Style + attachment_default_url: "Attachments Default URL" + attachment_path: "Attachments Path" + attachment_styles: "Paperclip Styles" + attachment_url: "Attachments URL" + add_new_style: "Add New Style" + image_settings_updated: "Image Settings successfully updated." + tax_categories: "Tax Categories" + listing_tax_categories: "Listing Tax Categories" + back_to_tax_categories_list: "Back To Tax Categories List" + tax rate: "Tax Rates" + new_tax_rate: "New Tax Rate" + tax_category: "Tax Category" + rate: "Rate" + tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" + included_in_price: "Included in Price" + show_rate_in_label: "Show rate in label" + back_to_tax_rates_list: "Back to Tax Rates List" + tax_settings: "Tax Settings" + zones: "Zones" + new_zone: "New Zone" + default_tax: "Default Tax" + default_tax_zone: "Default Tax Zone" + country_based: "Country Based" + state_based: "Province Based" + countries: "Countries" + listing_countries: "Listing Countries" + iso_name: "ISO Name" + states_required: "Provinces Required" + editing_country: "Editing Country" + back_to_countries_list: "Back to Countries List" + states: "Provinces" + abbreviation: "Abbreviation" + new_state: "New Province" + payment_methods: "Payment Methods" + new_payment_method: "New Payment Method" + provider: "Provider" + taxonomies: "Taxonomies" + new_taxonomy: "New Category" + back_to_taxonomies_list: "Back to Taxonomies List" + shipping_methods: "Shipping Methods" + shipping_categories: "Shipping Categories" + new_shipping_category: "New Shipping Category" + back_to_shipping_categories: "Back To Shipping Categories" + analytics_trackers: "Analytics Trackers" + no_trackers_found: "No Trackers Found" + new_tracker: "New Tracker" + add_one: "Add One" + google_analytics_id: "Analytics ID" + back_to_trackers_list: "Back to Trackers List" + name: "Name" + description: "Description" + type: "Type" + default: "default" + calculator: "Calculator" + zone: "Zone" + display: "Display" + environment: "Environment" + active: "Active" + nore: "More" + no_results: "No results" + create: "Create" + loading: "Loading" + flat_percent: "Flat Percent" + per_kg: "Per Kg" + amount: "Amount" + currency: "Currency" + first_item: "First Item Cost" + additional_item: "Additional Item Cost" + max_items: "Max Items" + minimal_amount: "Minimal Amount" + normal_amount: "Normal Amount" + discount_amount: "Discount Amount" + no_images_found: "No Images Found" + new_image: "New Image" + filename: "Filename" + alt_text: "Alternative Text" + thumbnail: "Thumbnail" + back_to_images_list: "Back To Images List" + email: Email + account_updated: "Account updated!" + email_updated: "The account will be updated once the new email is confirmed." + my_account: "My account" + date: "Date" + time: "Time" + inventory_error_flash_for_insufficient_quantity: "An item in your cart has become unavailable." + inventory: Inventory + zipcode: Postcode + weight: Weight (per kg) + error_user_destroy_with_orders: "Users with completed orders may not be deleted" + cannot_create_payment_without_payment_methods: "You cannot create a payment for an order without any payment methods defined." + please_define_payment_methods: "Please define some payment methods first." + options: "Options" + actions: + update: "Update" + errors: + messages: + blank: "can't be blank" + layouts: + admin: + header: + store: Store + admin: + tab: + dashboard: "Dashboard" + orders: "Orders" + bulk_order_management: "Bulk Order Management" + subscriptions: "Subscriptions" + products: "Products" + option_types: "Option Types" + properties: "Properties" + variant_overrides: "Inventory" + reports: "Reports" + configuration: "Configuration" + users: "Users" + roles: "Roles" + order_cycles: "Order Cycles" + enterprises: "Enterprises" + enterprise_relationships: "Permissions" + customers: "Customers" + groups: "Groups" + product_properties: + index: + inherits_properties_checkbox_hint: "Inherit properties from %{supplier}? (unless overridden above)" + add_product_properties: "Add Product Properties" + select_from_prototype: "Select From Prototype" + properties: + index: + properties: "Properties" + new_property: "New Property" + name: "Name" + presentation: "Presentation" + new: + new_property: "New Property" + edit: + editing_property: "Editing Property" + back_to_properties_list: "Back To Properties List" + form: + name: "Name" + presentation: "Presentation" + return_authorizations: + index: + new_return_authorization: "New Return Authorization" + return_authorizations: "Return Authorizations" + back_to_orders_list: "Back To Orders List" + rma_number: "RMA Number" + status: "Status" + amount: "Amount" + cannot_create_returns: "Cannot create returns as this order has no shipped units." + continue: "Continue" + new: + new_return_authorization: "New Return Authorization" + back_to_return_authorizations_list: "Back To Return Authorization List" + continue: "Continue" + edit: + receive: "receive" + are_you_sure: "Are you sure?" + return_authorization: "Return Authorization" + form: + product: "Product" + quantity_shipped: "Quantity Shipped" + quantity_returned: "Quantity Returned" + return_quantity: "Return Quantity" + amount: "Amount" + rma_value: "RMA Value" + reason: "Reason" + stock_location: "Stock Location" + states: + authorized: "Authorized" + received: "Received" + canceled: "Canceled" + orders: + index: + listing_orders: "Listing Orders" + new_order: "New Order" + capture: "Capture" + ship: "Ship" + edit: "Edit" + order_not_updated: "The order could not be updated" + note: "Note" + first: "First" + last: "Last" + previous: "Previous" + next: "Next" + loading: "Loading" + no_orders_found: "No Orders Found" + results_found: "%{number} Results found." + viewing: "Viewing %{start} to %{end}." + print_invoices: "Print Invoices" + sortable_header: + payment_state: "Payment State" + shipment_state: "Shipment State" + completed_at: "Completed At" + number: "Number" + state: "State" + email: "Customer E-Mail" + invoice: + issued_on: "Issued on" + tax_invoice: "TAX INVOICE" + code: "Code" + from: "From" + to: "Bill to" + shipping: "Shipping" + form: + distribution_fields: + title: "Distribution" + distributor: "Distributor:" + order_cycle: "Order cycle:" + line_item_adjustments: "Line Item Adjustments" + order_adjustments: "Order Adjustments" + order_total: "Order Total" + overview: + enterprises_header: + ofn_with_tip: Enterprises are Producers and/or Hubs and are the basic unit of organisation within the Open Food Network. + products: + active_products: + zero: "You don't have any active products." + one: "You have one active product" + other: "You have %{count} active products" + order_cycles: + order_cycles: "Order Cycles" + order_cycles_tip: "Order cycles determine when and where your products are available to customers." + you_have_active: + zero: "You don't have any active order cycles." + one: "You have one active order cycle." + other: "You have %{count} active order cycles." + manage_order_cycles: "MANAGE ORDER CYCLES" + shipping_methods: + index: + shipping_methods: "Shipping Methods" + new_shipping_method: "New Shipping Method" + name: "Name" + products_distributor: "Distributor" + zone: "Zone" + calculator: "Calculator" + display: "Display" + both: "Both" + front_end: "Front End" + back_end: "Back End" + no_shipping_methods_found: "No shipping methods found" + new: + new_shipping_method: "New Shipping Method" + back_to_shipping_methods_list: "Back To Shipping Methods List" + edit: + editing_shipping_method: "Editing Shipping Method" + new: "New" + back_to_shipping_methods_list: "Back To Shipping Methods List" + form: + categories: "Categories" + zones: "Zones" + both: "Both" + front_end: "Front End" + back_end: "Back End" + payment_methods: + new: + new_payment_method: "New Payment Method" + back_to_payment_methods_list: "Back To Payment Methods List" + edit: + editing_payment_method: "Editing Payment Method" + back_to_payment_methods_list: "Back To Payment Methods List" + stripe_connect: + enterprise_select_placeholder: Choose... + loading_account_information_msg: Loading account information from stripe, please wait... + stripe_disabled_msg: Stripe payments have been disabled by the system administrator. + request_failed_msg: Sorry. Something went wrong when trying to verify account details with Stripe... + account_missing_msg: No Stripe account exists for this enterprise. + connect_one: Connect One + access_revoked_msg: Access to this Stripe account has been revoked, please reconnect your account. + status: Status + connected: Connected + account_id: Account ID + business_name: Business Name + charges_enabled: Charges Enabled + payments: + source_forms: + stripe: + error_saving_payment: Error saving payment + submitting_payment: Submitting payment... + products: + image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format." + new: + title: "New Product" + new_product: "New Product" + supplier: "Supplier" + product_name: "Product Name" + units: "Unit Size" + value: "Value" + unit_name: "Unit name" + price: "Price" + on_hand: "On Hand" + on_demand: "On Demand" + product_description: "Product Description" + image: "Image" + or: "or" + unit_name_placeholder: 'eg. bunches' + index: + header: + title: Bulk Edit Products + indicators: + title: LOADING PRODUCTS + no_products: "No products yet. Why don't you add some?" + no_results: "Sorry, no results match" + products_head: + name: Name + unit: Unit + display_as: Display As + category: Category + tax_category: Tax Category + inherits_properties?: Inherits Properties? + available_on: Available On + av_on: "Av. On" + import_date: "Import Date" + products_variant: + variant_has_n_overrides: "This variant has %{n} override(s)" + new_variant: "New variant" + product_name: Product Name + primary_taxon_form: + product_category: Product Category + group_buy_form: + group_buy: "Group Buy?" + bulk_unit_size: Bulk unit size + display_as: + display_as: Display As + reports: + table: + select_and_search: "Select filters and click on %{option} to access your data." + bulk_coop: + bulk_coop_supplier_report: 'Bulk Co-op - Totals by Supplier' + bulk_coop_allocation: 'Bulk Co-op - Allocation' + bulk_coop_packing_sheets: 'Bulk Co-op - Packing Sheets' + bulk_coop_customer_payments: 'Bulk Co-op - Customer Payments' + enterprise_fee_summaries: + filters: + date_range: "Date Range" + report_format_csv: "Download as CSV" + generate_report: "Generate Report" + report: + none: "None" + select_and_search: "Select filters and click on GENERATE REPORT to access your data." + users: + index: + listing_users: "Listing Users" + new_user: "New User" + user: "User" + enterprise_limit: "Enterprise Limit" + search: "Search" + email: "Email" + edit: + editing_user: "Editing User" + back_to_users_list: "Back To Users List" + general_settings: "General Settings" + form: + email: "Email" + roles: "Roles" + enterprise_limit: "Enterprise Limit" + confirm_password: "Confirm Password" + password: "Password" + email_confirmation: + confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}." + variants: + index: + sku: "SKU" + price: "Price" + options: "Options" + no_results: "No results" + to_add_variants_you_must_first_define: "To add variants, you must first define" + option_types: "Option Types" + option_values: "Option Values" + and: "and" + new_variant: "New Variant" + show_active: "Show Active" + show_deleted: "Show Deleted" + new: + new_variant: "New Variant" + form: + cost_price: "Cost Price" + sku: "SKU" + price: "Price" + display_as: "Display As" + display_name: "Display Name" + autocomplete: + producer_name: "Producer" + unit: "Unit" + general_settings: + edit: + legal_settings: "Legal Settings" + cookies_consent_banner_toggle: "Display cookies consent banner" + privacy_policy_url: "Privacy Policy URL" + enterprises_require_tos: "Enterprises must accept Terms of Service" + cookies_policy_matomo_section: "Display Matomo section on cookies policy page" + cookies_policy_ga_section: "Display Google Analytics section on cookies policy page" + footer_tos_url: "Terms of Service URL" + checkout: + payment: + stripe: + choose_one: Choose one + enter_new_card: Enter details for a new card + used_saved_card: "Use a saved card:" + or_enter_new_card: "Or, enter details for a new card:" + remember_this_card: Remember this card? + stripe_sca: + choose_one: Choose one + enter_new_card: Enter details for a new card + used_saved_card: "Use a saved card:" + or_enter_new_card: "Or, enter details for a new card:" + remember_this_card: Remember this card? + date_picker: + format: '%Y-%m-%d' + js_format: 'yy-mm-dd' + orders: + error_flash_for_unavailable_items: "An item in your cart has become unavailable." + edit: + login_to_view_order: "Please log in to view your order." + bought: + item: "Already ordered in this order cycle" + line_item: + insufficient_stock: "Insufficient stock available, only %{on_hand} remaining" + out_of_stock: "Out of Stock" + unavailable_item: "Currently unavailable" + shipment_states: + backorder: backorder + partial: partial + pending: pending + ready: ready + shipped: shipped + payment_states: + balance_due: balance due + completed: completed + checkout: checkout + credit_owed: credit owed + failed: failed + paid: paid + pending: pending + processing: processing + void: void + invalid: invalid + order_mailer: + cancel_email: + customer_greeting: "Hi %{name}!" + instructions: "Your order has been CANCELED. Please retain this cancellation information for your records." + order_summary_canceled: "Order Summary [CANCELED]" + subject: "Cancellation of Order" + confirm_email: + subject: "Order Confirmation" + invoice_email: + hi: "Hi %{name}" + invoice_attached_text: Please find attached an invoice for your recent order from + order_state: + address: address + adjustments: adjustments + awaiting_return: awaiting return + canceled: cancelled + cart: cart + complete: complete + confirm: confirm + delivery: delivery + paused: paused + payment: payment + pending: pending + resumed: resumed + returned: returned + skrill: skrill + subscription_state: + active: active + pending: pending + ended: ended + paused: paused + canceled: cancelled + user_mailer: + reset_password_instructions: + request_sent_text: | + A request to reset your password has been made. + If you did not make this request, simply ignore this email. + link_text: > + If you did make this request just click the link below: + issue_text: | + If the above URL does not work try copying and pasting it into your browser. + If you continue to have problems please feel free to contact us. + confirmation_instructions: + subject: Please confirm your OFN account + users: + form: + account_settings: Account Settings + show: + tabs: + orders: Orders + cards: Credit Cards + transactions: Transactions + settings: Account Settings + unconfirmed_email: "Pending email confirmation for: %{unconfirmed_email}. Your email address will be updated once the new email is confirmed." + orders: + open_orders: Open Orders + past_orders: Past Orders + transactions: + transaction_history: Transaction History + open_orders: + order: Order + shop: Shop + changes_allowed_until: Changes Allowed Until + items: Items + total: Total + edit: Edit + cancel: Cancel + closed: Closed + until: Until + past_orders: + order: Order + shop: Shop + completed_at: Completed At + items: Items + total: Total + paid?: Paid? + view: View + saved_cards: + default?: Default? + delete?: Delete? + cards: + authorised_shops: Authorised Shops + authorised_shops_popover: This is the list of shops which are permitted to charge your default credit card for any subscriptions (ie. repeating orders) you may have. Your card details will be kept secure and will not be shared with shop owners. You will always be notified when you are charged. + saved_cards_popover: This is the list of cards you have opted to save for later use. Your 'default' will be selected automatically when you checkout an order, and can be charged by any shops you have allowed to do so (see right). + authorised_shops: + shop_name: "Shop Name" + allow_charges?: "Allow Charges?" + localized_number: + invalid_format: has an invalid format. Please enter a number. + api: + invalid_api_key: "Invalid API key (%{key}) specified." + unauthorized: "You are not authorized to perform that action." + invalid_resource: "Invalid resource. Please fix errors and try again." + resource_not_found: "The resource you were looking for could not be found." + access: "API Access" + key: "Key" + clear_key: "Clear key" + regenerate_key: "Regenerate Key" + no_key: "No key" + generate_key: "Generate API key" + key_generated: "Key generated" + key_cleared: "Key cleared" + shipment: + cannot_ready: "Cannot ready shipment." + invalid_taxonomy_id: "Invalid category ID." From 276dcf4a3b918786eabccf2451a212553cb0385e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 4 Apr 2020 18:50:01 +0200 Subject: [PATCH 050/166] Add optional unicorn-worker-killer configs --- Gemfile | 1 + Gemfile.lock | 6 ++++++ config.ru | 9 +++++++++ 3 files changed, 16 insertions(+) diff --git a/Gemfile b/Gemfile index 72dc87335c..c8bed19ead 100644 --- a/Gemfile +++ b/Gemfile @@ -122,6 +122,7 @@ gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', ref: '60da2ae4c44cbb4c8d602f5 group :production, :staging do gem 'ddtrace' + gem 'unicorn-worker-killer' end group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index a8d86824fe..efb201586b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -411,6 +411,8 @@ GEM rspec-core (~> 3.0) ruby-progressbar (~> 1.4) geocoder (1.1.8) + get_process_mem (0.2.5) + ffi (~> 1.0) gmaps4rails (1.5.6) haml (4.0.7) tilt @@ -668,6 +670,9 @@ GEM unicorn-rails (2.2.1) rack unicorn + unicorn-worker-killer (0.4.4) + get_process_mem (~> 0) + unicorn (>= 4, < 6) uuidtools (2.1.5) warden (1.2.7) rack (>= 1.0) @@ -792,6 +797,7 @@ DEPENDENCIES uglifier (>= 1.0.3) unicorn unicorn-rails + unicorn-worker-killer web! webdrivers webmock diff --git a/config.ru b/config.ru index 45a4379990..c4c4031568 100644 --- a/config.ru +++ b/config.ru @@ -1,4 +1,13 @@ # This file is used by Rack-based servers to start the application. +if ENV.fetch('KILL_UNICORNS', false) && ['production', 'staging'].include?(ENV['RAILS_ENV']) + # Gracefully restart individual unicorn workers if they have: + # - performed between 25000 and 30000 requests + # - grown in memory usage to between 700 and 850 MB + require 'unicorn/worker_killer' + use Unicorn::WorkerKiller::MaxRequests, 25_000, 30_000 + use Unicorn::WorkerKiller::Oom, (700 * (1024**2)), (850 * (1024**2)) +end + require ::File.expand_path('../config/environment', __FILE__) run Openfoodnetwork::Application From ba5a56db1464f380eec1a8e01bbccf82d17bb6ce Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sun, 5 Apr 2020 09:31:27 +0200 Subject: [PATCH 051/166] Make upper and lower bounds configurable --- config.ru | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/config.ru b/config.ru index c4c4031568..e2d03deb47 100644 --- a/config.ru +++ b/config.ru @@ -5,8 +5,12 @@ if ENV.fetch('KILL_UNICORNS', false) && ['production', 'staging'].include?(ENV[' # - performed between 25000 and 30000 requests # - grown in memory usage to between 700 and 850 MB require 'unicorn/worker_killer' - use Unicorn::WorkerKiller::MaxRequests, 25_000, 30_000 - use Unicorn::WorkerKiller::Oom, (700 * (1024**2)), (850 * (1024**2)) + use Unicorn::WorkerKiller::MaxRequests, + ENV.fetch('UWK_REQS_MIN', 25_000).to_i, + ENV.fetch('UWK_REQS_MAX', 30_000).to_i + use Unicorn::WorkerKiller::Oom, + ( ENV.fetch('UWK_MEM_MIN', 700).to_i * (1024**2) ), + ( ENV.fetch('UWK_MEM_MAX', 850).to_i * (1024**2) ) end require ::File.expand_path('../config/environment', __FILE__) From 13cba3d2444d6fdb6a3a11c7a85b175bd5d52ba4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 11:27:10 +0000 Subject: [PATCH 052/166] Bump ddtrace from 0.34.0 to 0.34.1 Bumps [ddtrace](https://github.com/DataDog/dd-trace-rb) from 0.34.0 to 0.34.1. - [Release notes](https://github.com/DataDog/dd-trace-rb/releases) - [Changelog](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md) - [Commits](https://github.com/DataDog/dd-trace-rb/compare/v0.34.0...v0.34.1) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a774039223..4976e41a9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -198,7 +198,7 @@ GEM activerecord (>= 3.2.0, < 5.0) fog (~> 1.0) rails (>= 3.2.0, < 5.0) - ddtrace (0.34.0) + ddtrace (0.34.1) msgpack debugger-linecache (1.2.0) deface (1.0.2) From e7b780f96304180f5bb2dfd65a16edfbd09bd2c8 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Sun, 5 Apr 2020 20:58:52 -0300 Subject: [PATCH 053/166] make shop name a link on /account --- app/views/spree/users/_open_orders.html.haml | 3 ++- app/views/spree/users/_past_orders.html.haml | 3 ++- spec/features/consumer/account_spec.rb | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/views/spree/users/_open_orders.html.haml b/app/views/spree/users/_open_orders.html.haml index ed5e43b9b5..2b8578a658 100644 --- a/app/views/spree/users/_open_orders.html.haml +++ b/app/views/spree/users/_open_orders.html.haml @@ -13,7 +13,8 @@ %tr.order-row %td.order1 %a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"} - %td.order2{"ng-bind" => "::Orders.shopsByID[order.shop_id].name"} + %td.order2 + %a{"ng-href" => "{{::Orders.shopsByID[order.shop_id].hash}}#{main_app.shop_path}", "ng-bind" => "::Orders.shopsByID[order.shop_id].name"} %td.order3.show-for-large-up{"ng-bind" => "::order.changes_allowed_until"} %td.order4.show-for-large-up{"ng-bind" => "::order.item_count"} %td.order5.text-right{"ng-class" => "{'credit' : order.total < 0, 'debit' : order.total > 0, 'paid' : order.total == 0}","ng-bind" => "::order.total | localizeCurrency"} diff --git a/app/views/spree/users/_past_orders.html.haml b/app/views/spree/users/_past_orders.html.haml index 2abf5a273e..4ded53858d 100644 --- a/app/views/spree/users/_past_orders.html.haml +++ b/app/views/spree/users/_past_orders.html.haml @@ -13,7 +13,8 @@ %tr.order-row %td.order1 %a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"} - %td.order2{"ng-bind" => "::Orders.shopsByID[order.shop_id].name"} + %td.order2 + %a{"ng-href" => "{{::Orders.shopsByID[order.shop_id].hash}}#{main_app.shop_path}", "ng-bind" => "::Orders.shopsByID[order.shop_id].name"} %td.order3.show-for-large-up{"ng-bind" => "::order.completed_at"} %td.order4.show-for-large-up{"ng-bind" => "::order.item_count"} %td.order5.text-right{"ng-class" => "{'debit': order.payment_state != 'paid', 'credit': order.payment_state == 'paid'}","ng-bind" => "::order.total | localizeCurrency"} diff --git a/spec/features/consumer/account_spec.rb b/spec/features/consumer/account_spec.rb index 23494f6a2c..f6a205bd29 100644 --- a/spec/features/consumer/account_spec.rb +++ b/spec/features/consumer/account_spec.rb @@ -42,8 +42,14 @@ feature ' # Lists all other orders expect(page).to have_content d1o1.number.to_s expect(page).to have_content d1o2.number.to_s + expect(page).to have_link(distributor1.name, + href: "#{distributor1.permalink}/shop", count: 2) expect(page).to have_content d2o1.number.to_s + expect(page).to have_link(distributor2.name, + href: "#{distributor2.permalink}/shop", count: 1) expect(page).to have_content credit_order.number.to_s + expect(page).to have_link(distributor_credit.name, + href: "#{distributor_credit.permalink}/shop", count: 1) # Viewing transaction history click_link I18n.t('spree.users.show.tabs.transactions') @@ -75,6 +81,8 @@ feature ' expect(page).to have_link d1o1.number, href: spree.order_path(d1o1) expect(page).to have_link d1o2.number, href: spree.order_path(d1o2) + expect(page).to have_link(distributor1.name, + href: "#{distributor1.permalink}/shop", count: 2) expect(page).to have_link I18n.t('spree.users.open_orders.cancel'), href: spree.cancel_order_path(d1o1) expect(page).to have_link I18n.t('spree.users.open_orders.cancel'), href: spree.cancel_order_path(d1o2) end From 33ca6a209651182b67137d1cee7615a12169eae6 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Mon, 6 Apr 2020 16:03:06 +0200 Subject: [PATCH 054/166] Allow changing the connection pool size This allows us to tune for UK. The hypothesis from @kristinalim is: > From what I understand, it can result to Rails processes waiting for each other to complete, while the DB server can take more simultaneous connections. --- config/database.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/database.yml b/config/database.yml index 99ed20078d..20c6760868 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,7 +1,7 @@ defaults: &defaults adapter: postgresql encoding: unicode - pool: 5 + pool: <%= ENV.fetch('OFN_DB_POOL', 5) %> host: <%= ENV.fetch('OFN_DB_HOST', 'localhost') %> username: <%= ENV.fetch('OFN_DB_USERNAME', 'ofn') %> password: <%= ENV.fetch('OFN_DB_PASSWORD', 'f00d') %> From 2cb4c6bec2b5f5da6255f4b55173a13e95b16802 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 6 Apr 2020 19:41:05 +0200 Subject: [PATCH 055/166] Memoize OpenFoodNetwork::ScopeProductToHub This means we avoid fetching all of the hub's variants every time we scope a product. Applies to every product loaded when displaying a shops's product list. --- app/services/products_renderer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/products_renderer.rb b/app/services/products_renderer.rb index bfa7f4eaa5..72d61b50b1 100644 --- a/app/services/products_renderer.rb +++ b/app/services/products_renderer.rb @@ -40,7 +40,7 @@ class ProductsRenderer end def product_scoper - OpenFoodNetwork::ScopeProductToHub.new(distributor) + @product_scoper ||= OpenFoodNetwork::ScopeProductToHub.new(distributor) end def enterprise_fee_calculator From 7c5e511fde89696ac163394ff74d127b4c392493 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 19:24:48 +0000 Subject: [PATCH 056/166] Bump oj from 3.10.5 to 3.10.6 Bumps [oj](https://github.com/ohler55/oj) from 3.10.5 to 3.10.6. - [Release notes](https://github.com/ohler55/oj/releases) - [Changelog](https://github.com/ohler55/oj/blob/develop/CHANGELOG.md) - [Commits](https://github.com/ohler55/oj/compare/v3.10.5...v3.10.6) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index a774039223..bef4369750 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -469,7 +469,7 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - oj (3.10.5) + oj (3.10.6) orm_adapter (0.5.0) paper_trail (5.2.3) activerecord (>= 3.0, < 6.0) From 837a3459586f81388adc38ad60fce85ec145a5da Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Tue, 7 Apr 2020 13:54:46 +1000 Subject: [PATCH 057/166] Updating translations for config/locales/en_FR.yml --- config/locales/en_FR.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 5665f4422b..f9b0c831ca 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -59,7 +59,7 @@ en_FR: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" From 8060977786d097729d6a6d994b835363268da7d0 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Tue, 7 Apr 2020 13:54:53 +1000 Subject: [PATCH 058/166] Updating translations for config/locales/en_GB.yml --- config/locales/en_GB.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index a29c2fb0eb..948d6f0220 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -59,7 +59,7 @@ en_GB: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" From edde7689a9a72bd25772f0c16a8cb013d9375ec2 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Tue, 7 Apr 2020 13:57:54 +1000 Subject: [PATCH 059/166] Updating translations for config/locales/de_DE.yml --- config/locales/de_DE.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index bfdacc350e..5b6d318b8a 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -59,7 +59,7 @@ de_DE: messages: inclusion: "ist in der Liste nicht enthalten" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^ Bitte fügen Sie mindestens ein Produkt hinzu" From 1b119805b4455ffe5d310c54b51e762464740839 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Tue, 7 Apr 2020 15:15:12 +1000 Subject: [PATCH 060/166] Updating translations for config/locales/fil_PH.yml --- config/locales/fil_PH.yml | 3383 +++++++++++++++++++++++++++++++++++++ 1 file changed, 3383 insertions(+) create mode 100644 config/locales/fil_PH.yml diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml new file mode 100644 index 0000000000..73c43a25e4 --- /dev/null +++ b/config/locales/fil_PH.yml @@ -0,0 +1,3383 @@ +fil_PH: + language_name: "Filipino" + activerecord: + attributes: + enterprise_fee: + fee_type: uri ng bayarin + spree/order: + payment_state: Status ng Pagbabayad + shipment_state: kalagayan ng kargamento + completed_at: Natapos sa + number: Bilang + state: Status + email: Email ng Parokyano + spree/payment: + amount: Halaga + spree/product: + primary_taxon: "Kategorya ng Produkto" + supplier: "Suplayer" + shipping_category_id: "Kategorya ng Pagpapadala" + variant_unit: "Yunit ng variant" + variant_unit_name: "pangalan ng yunit ng variant" + spree/credit_card: + base: "Credit Card" + order_cycle: + orders_close_at: petsa ng pagsasara + errors: + models: + spree/user: + attributes: + email: + taken: "Mayroon ng account para sa email na ito. Maglog-in o i-reset ang inyong password." + spree/order: + no_card: walang mga awtorisadong credit card na maaaring i-charge + spree/credit_card: + attributes: + base: + card_expired: "ay nag-expire na" + order_cycle: + attributes: + orders_close_at: + after_orders_open_at: ay dapat pagkatapos ng open date + variant_override: + count_on_hand: + using_producer_stock_settings_but_count_on_hand_set: "ay dapat blanko sapagkat ginagamit ang stock settings ng producer" + on_demand_but_count_on_hand_set: "ay dapat blanko kung on demand" + limited_stock_but_no_count_on_hand: "ay dapat matukoy sapagkat pinupuwersa ang limitadong stock" + activemodel: + attributes: + order_management/reports/enterprise_fee_summary/parameters: + start_at: "simula" + end_at: "katapusan" + distributor_ids: "Hubs" + producer_ids: "Producers" + order_cycle_ids: "Order Cycles" + enterprise_fee_ids: "pangalan ng mga bayarin" + shipping_method_ids: "Mga Paraan ng Pagpapadala" + payment_method_ids: "Mga Paraan ng Pagbabayad" + errors: + messages: + inclusion: "ay hindi kasama sa listahan" + models: + order_management/subscriptions/validator: + attributes: + subscription_line_items: + at_least_one_product: "^Magdagdag ng kahit isang produkto" + not_available: "^%{name} ay hindi magagamit mula sa napiling iskedyul" + ends_at: + after_begins_at: "ay dapat pagkatapos ng nagsisimula sa" + customer: + does_not_belong_to_shop: "ay hindi nabibilang sa%{shop}" + schedule: + not_coordinated_by_shop: "ay hindi coordinated ng%{shop}" + payment_method: + not_available_to_shop: "ay hindi magagamit para%{shop}" + invalid_type: "ay dapat pamamaraang Cash o Stripe" + charges_not_allowed: "^ang paniningil gamit ang Credit card ay hindi pinahihintulutan ng Customer na ito" + no_default_card: "^walang card na maaring gamitin para sa Customer na ito" + shipping_method: + not_available_to_shop: "ay hindi magagamit para%{shop}" + devise: + confirmations: + send_instructions: "Kayo ay makakatanggap ng email na may panuto kung paano kumpirmahin ang inyong account sa loob ng ilang minuto." + failed_to_send: "May error na nangyari habang pinapadala ang email para sa pagkumpirma ng inyong account." + resend_confirmation_email: "Ipadala muli ang email para sa pagkumpirma ng account" + confirmed: "Salamat sa pagkumpirma ng inyong email! Maaari na kayong maglog-in." + not_confirmed: "Ang inyong email address ay hindi makumpirma. Marahil ay nakumpleto mo na ang hakbang na ito?" + user_confirmations: + spree_user: + send_instructions: "Kayo ay makakatanggap ng email na may panuto kung paano kumpirmahin ang inyong account sa loob ng ilang minuto." + confirmation_sent: "Napadala na ang email para sa pagkumpirma ng account" + confirmation_not_sent: "May error sa pagpapadala ng email para sa pagkumpirma ng account" + user_registrations: + spree_user: + signed_up_but_unconfirmed: "ang mensahe na may nakalakip na confirmation link ay napadala na sa inyong email address. Maaari lamang na buksan ang link para ma-activate ang inyong account." + unknown_error: "may maling nangyari habang ginagawa ang inyong account. I-check ang email address at subukang muli." + failure: + invalid: | + hindi valid ang email o password. + isa ka bang Guest dati? marahil ay kailangang gumawa ng account o i-reset ang inyong password. + unconfirmed: "Kailangang kumpirmahin ang inyong account bago magpatuloy." + already_registered: "ang email address ay nakaregister na. Maglog-in upang makapagpatuloy o bumalik at gumamit ng ibang email address" + success: + logged_in_succesfully: "Matagumpay na nakapaglog-in." + user_passwords: + spree_user: + updated_not_active: "ang inyong password ay na-reset na ngunit ang inyong email ay hindi pa nakumpirma." + updated: "Ang password ay matagumpay na napalitan. Ikaw ay nakasign-in na." + send_instructions: "Kayo ay makakatanggap ng email na may panuto kung paano kumpirmahin ang inyong account sa loob ng ilang minuto." + models: + order_cycle: + cloned_order_cycle_name: "KOPYA NG%{order_cycle}" + validators: + date_time_string_validator: + not_string_error: "ay dapat String" + invalid_format_error: "ay dapat valid" + integer_array_validator: + not_array_error: "ay dapat na pagpipilian" + invalid_element_error: "ay dapat naglalaman lamang ng valid na integers" + enterprise_mailer: + confirmation_instructions: + subject: "Pakikumpirma ang email address para sa %{enterprise}" + welcome: + subject: "%{enterprise}ay nasa %{sitename}na ngayon" + email_welcome: "Maligayang pagdating" + email_registered: "ay kabilang na ng/sa" + email_userguide_html: "ang user guide na may detalyadong suporta para sa pagset-up ng iyong Producer o Hub ay narito: %{link}" + userguide: "Open Food Network Gabay sa Gumagamit" + email_admin_html: "maaaring pamahalaan ang iyong account sa pamamagitan ng paglog-in sa%{link}o sa pagpindot sa cog sa pinakataas na kanang bahagi ng homepage at pagpili sa Administration." + admin_panel: "Admin Panel" + email_community_html: "Kami ay mayroon ding online forum para sa talakayang pangkomunidad na may kinalaman sa OFN software at sa mga natatanging hamon sa pagpapatakbo ng enterprise ng pagkain. Kayo ay hinihikayat namin na sumali rito. Kami ay patuloy na nagbabago para makapagbigay ng mas mabuting serbisyo, at ang inyong suhestiyon sa forum ay makakatulong para mga susunod na pagbabago.%{link}" + join_community: "Sumali sa Komunidad" + invite_manager: + subject: "%{enterprise}ay inanyayahan kang maging tagapamahala" + producer_mailer: + order_cycle: + subject: "ulat ng order cycle para sa %{producer}" + shipment_mailer: + shipped_email: + dear_customer: "Dear Customer," + instructions: "ang iyong order ay na-ship na " + shipment_summary: "buod ng kargamento" + subject: "notification ukol sa kargamento" + thanks: "Salamat sa inyong pagtangkilik" + track_information: "Impormasyon ukol sa pag-track: %{tracking}" + track_link: "Link ng pag-track:%{url}" + subscription_mailer: + placement_summary_email: + subject: Buod ng mga bagong subsciption orders + greeting: "Magandang araw%{name}," + intro: "Ang nasa ilalim ay buod ng mga subscription orders na na-place para sa %{shop}" + confirmation_summary_email: + subject: Buod ng mga bagong kumpirmadong subscription orders + greeting: "Magandang araw%{name}," + intro: "sa ilalim ay ang buod ng mga subscription order na na-finalize para sa%{shop}." + summary_overview: + total: may kabuuuan na %{count}subscriptions ang minarkahan para sa awtomatikong pagproseso. + success_zero: sa lahat ng ito, walang matagumpay na naproseso + success_some: sa lahat ng ito, %{count}ay matagumpay na naproseso + success_all: Ang lahat ay matagumpay na naproseso + issues: Ang mga detalye ukol sa mga isyu na kinaharap ay mababasa sa baba. + summary_detail: + no_message_provided: Walang dahilan ng error na ibinigay + changes: + title: Hindi Sapat Ang Stock (%{count} orders) + explainer: ang mga order na ito ay naproseso ngunit hindi sapat ang stock para sa ibang ni-request na mga item + empty: + title: Walang Stock (%{count}orders) + explainer: ang mga order na ito ay hindi naproseso sapagkat walang stock ng mga ni-request na item. + complete: + title: Naproseso Na (%{count}na order) + explainer: ang mga order na ito ay namarkahan na kumpleto at hindi na babaguhin + processing: + title: May Error na Kinaharap (%{count}na order) + explainer: ang awtomatikong pagproseso ng mga order na ito ay hindi nagtagumpay dahil sa isang error. ang error ay nailista upang mabusisi kung saan posibleng nagsimula. + failed_payment: + title: Hindi Nagtagumpay Ang Pagbayad (%{count}na order) + explainer: ang awtomatikong pagproseso ng bayad para sa mga order na ito ay hindi nagtagumpay dahil sa isang error. ang error ay nailista upang mabusisi kung saan posibleng nagsimula. + other: + title: Iba Pang Dahilan ng Error (%{count}na order) + explainer: Hindi naging matagumpay ang awtomatikong pagproseso ng mga order na ito dahil sa hindi maipaliwanag na kadahilanan. Makipag-uganayan sa amin kung nakita ang mensaheng ito. + home: "OFN" + title: Open Food Network + welcome_to: 'Maligayang Pagdating sa' + site_meta_description: "Kami ay nagsimula sa pinakaibaba pataas. Kasama ang mga magsasaka at tagatanim na may ipagmamalaki at handang ibahagi ang kanilang mga kuwento. Kasama rin namin ang mga tagapamahaging patas at tapat na handang makipag-usap sa mga taong may produkto. At mga mamimili na naniniwala na ang mabusising lingguhang pamimili ay..." + search_by_name: Hanapin gamit ang pangalan o lungsod + producers_join: ang mga Pilipinong producers ay inaanyayahang sumali sa Open Food Network. + charges_sales_tax: Charges GST? + print_invoice: "i-print ang invoice" + print_ticket: "i-print ang ticket" + select_ticket_printer: "pumili ng printer para sa tickets" + send_invoice: "ipadala ang invoice" + resend_confirmation: "ipadala muli ang kumpirmasyon" + view_order: "tignan ang order" + edit_order: "i-edit ang order" + ship_order: "i-ship ang order" + cancel_order: "i-cancel ang order" + confirm_send_invoice: "ang invoice para sa order na ito ay ipapadala sa customer. gusto mo bang magpatuloy?" + confirm_resend_order_confirmation: "nais mo bang ipadala muli ang order confirmation email?" + must_have_valid_business_number: "%{enterprise_name}ay dapat may valid na ABN bago makapagpadala ng mga invoice" + invoice: "invoice" + more: "Iba pa" + say_no: "hindi" + say_yes: "oo" + ongoing: Nagaganap + bill_address: Billing Address + ship_address: Shipping Address + sort_order_cycles_on_shopfront_by: "Uriin ang mga order cycle sa shopfront gamit ang" + required_fields: ang mga kailangang may sagot ay may nakalagay na asterisk + select_continue: pumili at magpatuloy + remove: Tanggalin + or: o + collapse_all: Itago lahat + expand_all: Ipakita lahat + loading: naglo-load... + show_more: Ipakita lahat + show_all: Ipakita lahat + show_all_with_more: "ipakita lahat (%{num}iba pa)" + cancel: i-cancel + edit: i-edit + clone: Clone + distributors: mga tagapamahagi + bulk_order_management: Pamamahala sa pangmaramihang order + enterprises: enterprises + enterprise_groups: Mga grupo + reports: mga ulat + variant_overrides: imbentaryo + import: i-import + spree_products: mga produktong Spree + all: Lahat + current: kasalukuyan + available: Available + dashboard: Dashboard + undefined: hindi matukoy + unused: hindi nagamit + admin_and_handling: Admin & Handling + profile: profile + supplier_only: Supplier lamang + has_shopfront: May Shopfront + weight: timbang + volume: dami + items: mga item + summary: Buod + detailed: detalyado + updated: na-update + 'yes': "oo" + 'no': "hindi" + y: 'Y' + n: 'N' + powered_by: Powered by + blocked_cookies_alert: " ang iyong browser ay maaaring hinaharang ang cookies na kailangan upang magamit ang shopfront na ito. Pindutin sa ibaba upang payagan ang mga cookies at i-reload ang pahina." + allow_cookies: "Payagan ang cookies" + notes: mga tala + error: pagkakamali + processing_payment: "pinoproseso ang bayad" + no_pending_payments: "walang nakabinbin na mga bayarin" + invalid_payment_state: "hindi valid na estado ng pagbabayad" + filter_results: i-filter ang mga resulta + quantity: dami + pick_up: kunin + copy: kopyahin + change_my_password: "palitan ang aking password" + update_password: "i-update ang password" + password_confirmation: kumpirmasyon ng password + reset_password_token: i-reset ang password token + expired: ay expired na, magrequest ng bago + back_to_payments_list: "ibalik sa listahan ng mga bayad" + maestro_or_solo_cards: "Maestro/Solo cards" + backordered: "na-backorder" + on hand: "on hand" + ship: "ship" + actions: + create_and_add_another: "gumawa at magdagdag ng isa pa" + create: "gumawa" + cancel: "i-cancel" + save: "i-save" + edit: "i-edit" + update: "i-update" + delete: "tanggalin" + admin: + begins_at: nagsimula sa + begins_on: nagsisimula sa + customer: customer + date: petsa + email: email + ends_at: nagtatapos sa + ends_on: natapos sa + name: pangalan + on_hand: on hand + on_demand: on demand + on_demand?: on demand? + order_cycle: order cycle + payment: kabayaran + payment_method: paraan ng pagbayad + phone: telepono + price: presyo + producer: Prodyuser + image: imahe + product: produkto + quantity: dami + schedule: iskedyul + shipping: pagpapadala + shipping_method: paraan ng pagpapadala + shop: Shop + sku: SKU + status_state: kalagayan + tags: tags + variant: Uri + weight: timbang + volume: dami + items: mga item + select_all: piliin ang lahat + quick_search: mabilis na paghahanap + clear_all: alisin lahat + start_date: "Petsa na nagsimula" + end_date: "Petsa na natapos" + form_invalid: "ang form ay may nawawala o hindi valid na sagutan" + clear_filters: alisin ang mga filter + clear: alisin + save: i-save + cancel: i-cancel + back: bumalik + show_more: ipakita lahat + show_n_more: ipakita%{num}iba pa + choose: "pumili" + please_select: pumili + columns: hanay + actions: mga kilos + viewing: "tinitignan: %{current_view_name}" + description: paglalarawan + whats_this: ano ito? + tag_has_rules: "mga umiiral na patakaran para sa tag na ito: %{num}" + has_one_rule: "may isang panuntunan" + has_n_rules: "ay may%{num}na panuntunan" + unsaved_confirm_leave: "may mga hindi naka-save na pagbabago sa pahina na ito. Magpatuloy ng hindi sine-save?" + unsaved_changes: "may mga hindi na-save na pagbabago" + shopfront_settings: + embedded_shopfront_settings: "Embedded Shopfront Settings" + enable_embedded_shopfronts: "Enable Embedded Shopfronts" + embedded_shopfronts_whitelist: "External Domains Whitelist" + number_localization: + number_localization_settings: "Number Localization Settings" + enable_localized_number: "gamitin ang international thousand/decimal separator logic" + invoice_settings: + edit: + title: "settings para sa invoice" + enable_invoices?: "paganahin ang mga invoice?" + invoice_style2?: "gamitin ang alternatibong modelo ng invoice na kinabibilangan ng kabuuang breakdown ng buwis bawat rate at impormasyon ng rate ng buwis kada item (hindi pa akma para sa mga bansang nagpapakita na presyo na hindi kasama ang tax)" + enable_receipt_printing?: "ipakita ang mga pagpipilian sa pag-print ng mga resibo gamit ang thermal printers sa dropdown ng order." + stripe_connect_settings: + edit: + title: "Stripe Connect" + settings: "settings" + stripe_connect_enabled: paganahin ang pagtanggap ng mga bayad gamit ang Stripe Connect sa mga Shop? + no_api_key_msg: walang Stripe account para sa enterprise na ito + configuration_explanation_html: para sa detalyadong panuto sa pag-configure ng pagsasama ng Stripe Connect, maaari lamang nakumonsulta sa gabay. + status: katayuan + ok: ok + instance_secret_key: Instance Secret Key + account_id: Account ID + business_name: pangalan ng negosyo + charges_enabled: pinagana ang paniningil + charges_enabled_warning: "Babala: Ang paniningil ay hindi pa napapagana sa iyong account" + auth_fail_error: ang API key na inyong binigay ay invalid + empty_api_key_error_html: Walang Stripe API key na naibigay. Upang i-set ang inyong API key, sundinang mga panuto + matomo_settings: + edit: + title: "Matomo Settings" + matomo_url: "Matomo URL" + matomo_site_id: "Matomo Site ID" + info_html: "ang Matomo ay isang Web at Mobile Analytics. Maaari kang mag-host ng Matomo sa mga lugar o gumamit ng mga serbisyong naka-cloud. Tignanmatomo.org para sa karagdagang impormasyon." + config_instructions_html: "Dito ay maaaring ayusin ang pagsasama ng OFN Matomo. ang URL ng Matomo sa ibaba ay ituturo ka sa Matomo kung saan ipapadala ang impormasyon ukol sa pagtatrack ng gumagamit; kung iiwanang blanko, ay hindi gagana ang pag-track ng Matomo. ang paglagay ng SITE ID ay hindi sapilitan ngunit maaaring makatulong kung ikaw ay nagta-track na mahigit sa isang website sa isang pagkakataon; ito ay matatagpuan sa Matomo instance console." + customers: + index: + new_customer: "bagong customer" + code: Code + duplicate_code: "ang code na ito ay nagamit na" + bill_address: "Billing Address" + ship_address: "Shipping Address" + update_address_success: 'matagumpay na na-update ang address' + update_address_error: 'pakisagutan lahat ng kailangang impormasyon' + edit_bill_address: 'i-edit ang Billing Address' + edit_ship_address: 'i-edit ang shipping address' + required_fileds: 'ang mga kailangang may sagot ay may nakalagay na asterisk' + select_country: 'Piliin ang bansa' + select_state: 'pumili ng estado' + edit: 'i-edit' + update_address: 'i-update ang address' + confirm_delete: 'siguradong tatanggalin?' + search_by_email: "hanapin gamit ang email/code..." + guest_label: 'Guest checkout' + destroy: + has_associated_orders: 'hindi tagumpay ang pagtanggal: ang customer ay may mga iniugnay na order sa kaniyang shop' + contents: + edit: + title: nilalaman + header: Header + home_page: Homepage + producer_signup_page: pahina para sa pagsign-up ng Producer + hub_signup_page: pahina para sa pagsign-up ng Hub + group_signup_page: pahina para sa pagsign-up ng Grupo + main_links: Link para sa pangunahing menu + footer_and_external_links: Footer at panlabas na mga link + your_content: ang iyong nilalaman + user_guide: gabay sa gumagamit + enterprise_fees: + index: + title: "bayad para sa enterprise" + enterprise: "Enterprise" + fee_type: "uri ng bayad" + name: "pangalan" + tax_category: "kategorya ng buwis" + calculator: "calculator" + calculator_values: "calculator values" + search: "hanapin" + name_placeholder: "hal. bayad sa pag-iimpake" + enterprise_groups: + index: + new_button: bagong grupo ng enterprise + enterprise_roles: + form: + manages: namamahala + enterprise_role: + manages: namamahala + products: + unit_name_placeholder: 'hal. mga kumpol' + index: + unit: yunit + display_as: ipakita bilang + category: kategorya + tax_category: kategorya ng buwis + inherits_properties?: minana ang mga katangian? + available_on: Magagamit Nakabukas + av_on: "Av On" + import_date: na-import + upload_an_image: maglagay ng larawan + seo: + product_search_keywords: "mga keyword sa paghahanap ng produkto" + product_search_tip: "isulat ang mga salita para mahanap ang inyong produkto sa mga shop. gumamit ng laktaw upang paghiwalayin ang bawat keyword." + SEO_keywords: "SEO Keywords" + seo_tip: "isulat ang mga salita para mahanap ang inyong produkto sa web. gumamit ng laktaw upang paghiwalayin ang bawat keyword." + search: "hanapin" + properties: + property_name: "Pangalan ng Pag-aari" + inherited_property: "minanang pag-aari" + variants: + infinity: "walang hanggan" + to_order_tip: "ang mga item na made to order ay walang paraan ng pag-set ng lebel ng stock, tulad ng mga tinapay na ginagawa lamang kapag may order." + back_to_products_list: "bumalik sa listahan ng produkto" + editing_product: "ine-edit ang mga produkto" + tabs: + product_details: "Detalye ng produkto" + group_buy_options: "pagpipilian para sa Grupong pagbili" + images: "larawan" + variants: "mga uri" + product_properties: "mga katangian ng produkto" + product_import: + title: paglipat ng produkto + file_not_found: 'ang file ay hindi mahanap o mabuksan ' + no_data: walang data na mahanap sa spreadsheet + confirm_reset: "ito ay ilalagay ang lebel ng stock ng lahat ng mga produkto sa zero\nmga enterprise na hindi makikita sa nilagay na file." + model: + no_file: "error: walang file na na-upload" + could_not_process: "hindi maproseso ang file: invalid na uri ng file" + incorrect_value: maling halaga + conditional_blank: ay hindi maaaring blanko kung yunit_uri ay blanko + no_product: walang katugmang produkto sa database + not_found: hindi mahanap sa database + not_updatable: ay hindi maaring i-update sa mga umiiral na produkto gamit ang paglilipat ng produkto + blank: hindi maaaring iwanang blanko + products_no_permission: walang permiso na pamahalaan ang mga produkto para sa enterprise na ito + inventory_no_permission: walang permiso na gumawa ng imbentaryo para sa producer na ito + none_saved: hindi matagumpay na na-save ang mga produkto + line_number: "linya%{number}:" + encoding_error: "Paki-check ang language setting ng inyong source file at siguraduhing ito ay naka-save gamit ang UTF-8 encoding" + unexpected_error: "ang paglilipat ng produkto ay may kinaharap na error habang binubuksan ang file: %{error_message}" + index: + notice: "Paalala" + beta_notice: "ang feature na ito ay nasa beta pa rin: maari kang makaranas ng mga error habang ginagamit ito. huwag mag-atubiling kumontak sa suporta." + select_file: pumili ng spreadsheet na i-a-upload + spreadsheet: spreadsheet + choose_import_type: pumili ng uri ng paglilipat + import_into: uri ng paglilipat + product_list: listahan ng produkto + inventories: mga imbentaryo + import: i-import + upload: i-upload + csv_templates: CSV Templates + product_list_template: i-download ang Product List template + inventory_template: i-download ang Inventory template + category_values: mga available na halaga ng kategorya + product_categories: kategorya ng produkto + tax_categories: kategorya ng buwis + shipping_categories: mga kategorya ng pagpapadala + import: + review: suriin + import: i-import + save: i-save + results: mga resulta + save_imported: i-save ang inilipat na mga produkto + no_valid_entries: walang nahanap na mga valid na entry + none_to_save: Walang mga entry na maaaring i-save + some_invalid_entries: ang mga nilipat na file ay naglalaman na hindi valid na mga entry + fix_before_import: Ayusin ang error na ito at subukang ilipat muli ang file + save_valid?: i-save ang mga valid na entry at hayaan ang iba? + no_errors: walang error na nakita! + save_all_imported?: i-save lahat ng mga nilipat na produkto? + options_and_defaults: mga pagpipiliaan sa paglilipat at mga default + no_permission: walang permiso na pamahalaan ang enterprise na ito + not_found: hindi mahanap ang enterprise sa database + no_name: walang pangalan + blank_enterprise: ang ibang mga produkto ay walang tinutukoy na enterprise + reset_absent?: i-reset ang mga nawawalang produkto + reset_absent_tip: i-set sa zero ang mga produkto na hindi makikita sa file + overwrite_all: sulatan lahat + overwrite_empty: sulatan kung walang nakalagay + default_stock: i-set ang lebel ng stock + default_tax_cat: i-set ang kategorya ng buwis + default_shipping_cat: i-set ang kategorya ng pagpapadala + default_available_date: i-set ang available na petsa + validation_overview: pagtingin sa pagpapatunay ng paglipat + entries_found: May mga entry na nahanap sa inilipat na file + entries_with_errors: ang mga item ay naglalaman ng error at hindi maililipat + products_to_create: ang mga produkto ay gagawin + products_to_update: ang mga produkto ay i-a-update + inventory_to_create: ang imbentaryo ng mga item ay gagawin + inventory_to_update: ang mga imbentaryong item ay i-a-update + products_to_reset: ang mga produkto na narito ay mare-reset ang stock sa zero + inventory_to_reset: ang imbentaryo ng mga item na narito ay mare-reset ang stock sa zero + line: linya + item_line: linya ng item + import_review: + not_updatable_tip: "ang mga patlang ay hindi ma-update sa pamamagitan ng maramihang paglipat para sa mga produkto:" + fields_ignored: ang mga linya na ito ay hindi mapapansin kapag sinave ang mga nilipat na produkto + entries_table: + not_updatable: ang patlang na ito ay hindi maaaring ma-update sa pamamagitan ng maramihang paglipat ng mga produkto + save_results: + final_results: Ilipat ang pinakahuling mga resulta + products_created: ang mga produkto ay nagawa na + products_updated: inupdate ang mga produkto + inventory_created: ang mga imbentaryo ng item ay nagawa na + inventory_updated: inupdate ang mga inimbentaryong item + products_reset: na-reset sa zero ang lebel ng stock ng mga produkto + inventory_reset: na-reset sa zero ang lebel ng stock ng mga imbentaryo ng item + all_saved: "lahat ng mga item ay matagumpay na na-save" + some_saved: "ang mga item ay matagumpay na na-save" + save_errors: i-save ang mga error + import_again: mag-upload ng isa pang file + view_products: pumunta sa pahina ng mga produkto + view_inventory: pumunta sa pahina ng mga imbentaryo + variant_overrides: + loading_flash: + loading_inventory: NILO-LOAD ANG IMBENTARYO + index: + title: imbentaryo + description: gamitin ang pahina na ito para pamahalaan ang mga imbentaryo ng inyong enterprise. ang kahit anong detalye ng produkto na sinet dito ay mapapalitan ang mga na-set sa pahina ng "Mga Produkto" + enable_reset?: paganahin ang pag-reset ng stock? + default_stock: "Default na Stock" + inherit?: gayahin? + add: idagdag + hide: itago + import_date: na-import + select_a_shop: pumili ng shop + review_now: tignan ngayon + new_products_alert_message: mayroong%{new_product_count}bagong mga produkto na maaaring idagdag sa inyong imbentaryo + currently_empty: ang iyong imbentaryo ay kasalukuyang walang laman + no_matching_products: Walang nahanap na katumbas na produkto sa inyong imbentaryo + no_hidden_products: Walang produkto na nakatago mula sa imbentaryong ito + no_matching_hidden_products: walang nakatagong produkto na tugma sa inyong hinahanap na pamantayan + no_new_products: walang bagong produkto na maaaring idagdag sa inyong imbentaryo + no_matching_new_products: walang bagong mga produkto na tugma sa inyong hinahanap na pamantayan + inventory_powertip: Ito ang imbentaryo ng inyong mga produkto. Upang magdagdag ng produkto sa inyong imbentaryo, piliin ang "Bagong Produkto" sa viewing dropdown. + hidden_powertip: ang mga produktong ito ay nakatago sa inyong imbentaryo at hindi maaaring idagdag sa inyong shop. maaaring pindutin ang "Idagdag" para madagdag ang produkto sa inyong imbentaryo. + new_powertip: ang mga produkto na ito ay maaaring idagdag sa inyong imbentaryo. pindutin ang "idagdag" para magdagdag ng produkto sa inyong imbentaryo, o "itago" para hindi ito makita. Maaari mo itong baguhin sa ibang panahon! + controls: + back_to_my_inventory: bumalik sa aking imbentaryo + orders: + invoice_email_sent: 'ang invoice email ay naipadala na' + order_email_resent: 'ang email ng order ay napadala na muli' + bulk_management: + tip: "gamitin ang pahina na ito para baguhin ang dami ng mga produkto sa maramihang mga order. maaari ding magtanggal ng mga produkto mula sa order kung kinakailangan." + shared: "ibinahaging pinagkuhanan?" + order_no: "Order No." + order_date: "nakumpleto sa" + max: "Labis" + product_unit: "Produkto: Yunit" + weight_volume: "Timbang/Dami" + ask: "itanong?" + page_title: "Pamamahala sa pangmaramihang order" + actions_delete: "burahin ang napili" + loading: "nilo-load ang mga order" + no_results: "walang nahanap na mga order" + group_buy_unit_size: "laki ng yunit para sa maramihang pagbili" + total_qtt_ordered: "Kabuuang dami ng in-order" + max_qtt_ordered: "sagad na dami ng na-order" + current_fulfilled_units: "kasalukuyang tapos na mga yunit" + max_fulfilled_units: "sagad na natapos na yunit" + order_error: "ang ibang error ay dapat munang ayusin bago makapag-update ng mga order.\nang mga linya na may pulang border ay may mga error." + variants_without_unit_value: "BABALA: Ang ibang variant ay walang halaga ang yunit" + select_variant: "pumili ng variant" + enterprise: + select_outgoing_oc_products_from: pumili ng lumalabas na mga produktong OC mula + enterprises: + index: + title: enterprises + new_enterprise: bagong enterprise + producer?: "Producer?" + package: Package + status: katayuan + manage: pamahalaan + form: + about_us: + desc_short: maikling paglalarawan + desc_short_placeholder: magsalaysay ukol sa inyong enterprise gamit ang isa hanggang dalawang pangungusap. + desc_long: tungkol sa amin + desc_long_placeholder: magkuwento sa Customer tungkol sa inyong sarili. Ang impormasyon na ito ay makikita at lalabas sa inyong profile. + business_details: + abn: ABN + abn_placeholder: hal. 99 123 456 789 + acn: ACN + acn_placeholder: hal. 123 456 789 + display_invoice_logo: ipakita ang Logo sa mga invoice + invoice_text: magdagdag ng sariling mensahe sa dulo ng bawat invoice + contact: + name: pangalan + name_placeholder: hal. Gustav Plum + email_address: pampublikong email address + email_address_placeholder: hal. inquiries@fresh-food.com + email_address_tip: "ang email address na ito ay makikita sa iyong pampublikong profile" + phone: telepono + phone_placeholder: hal. 98 7654 3210 + website: website + website_placeholder: hal. www.truffles.com + enterprise_fees: + name: pangalan + fee_type: uri ng kabayaran + manage_fees: pamahalaan ang mga bayarin para sa enterprise + no_fees_yet: wala ka pang kahit anong bayaring pang-enterprise + create_button: gumawa ng isa ngayon + images: + logo: Logo + promo_image_placeholder: 'ang larawan na ito ay makikita sa "tungkol sa amin"' + promo_image_note1: 'TANDAAN:' + promo_image_note2: ang kahit anong larawan na ilalagay rito ay maka-crop sa 1200 x 260. + promo_image_note3: ang promo na larawan ay makikita sa taas na pahina ng profile ng enterprise at pop-ups. + inventory_settings: + text1: maaari mong piliin na pamahalaan ang lebel ng mga stock at presyo sa iyong + inventory: imbentaryo + text2: > + kung ikaw ay gumagamit ng tool para sa imbentaryo, piliin na ang mga + bagong produktong dinagdag ng inyong suplayer ay kailangan munang idagdag + sa inyong imbentaryo bago ito mai-stock. kung hindi ka naman gumagamit + ng imbentaryo para pamahalaan ang inyong produkto, piliin ang "nirerekomenda" + sa pagpipilian sa baba: + preferred_product_selection_from_inventory_only_yes: mga bagong produkto ay maaaring ilagay sa aking shopfront (nirerekomenda) + preferred_product_selection_from_inventory_only_no: ang mga bagong produkto ay dapat idagdag muna sa aking imbentaryo bago mailagay sa aking shopfront. + payment_methods: + name: pangalan + applies: naaangkop? + manage: pamahalaan ang mga paraan ng pagbabayad + no_method_yet: wala ka pang kahit anong paraan ng pagbabayad. + create_button: gumawa ng bagong paraan ng pagbabayad + create_one_button: gumawa ng isa ngayon + primary_details: + name: pangalan + name_placeholder: hal. Professor Plum's Biodynamic Truffles + groups: mga grupo + groups_tip: pumili ng grupo o rehiyon kung saan ka kabilang. makakatulong ito sa mga customer sa paghahanap ng inyong enterprise. + groups_placeholder: magsimulang magsulat para maghanap ng mga grupo... + primary_producer: pangunahing prodyuser + primary_producer_tip: piliin ang "Producer" kung ikaw ay pangunahing producer ng pagkain. + producer: Producer + any: kahit ano + none: wala + own: sarili + sells: nagbebenta + sells_tip: "Wala- ang mga enterprise ay hindi nagbebenta ng direkta sa mga customer
Sarili- ang mga enterprise ay nagbebenta ng sariling mga produkto sa mga customer
Iba- ang enterprise ay maaaring magbenta ng sariling produkto pati na rin ang mga produkto ng enterprise.
" + visible_in_search: makikita sa paghahanap? + visible_in_search_tip: timutukoy kung ang enterprise na ito ay makikita ng mga customer kapag naghahanap sa site. + visible: nakikita + not_visible: hindi nakikita + permalink: Permalink (walang espasyo) + permalink_tip: "ang permalink na ito ay ginamit para gumawa ng url sa inyong shop: %{link}your-shop-name/shop" + link_to_front: Link sa shop front + link_to_front_tip: direktang link sa inyong shopfront sa Open Food Network. + ofn_uid: UID sa OFN + ofn_uid_tip: ang natatanging id na ito ay ginagamit para matukoy ang enterprise sa Open Food Network. + shipping_methods: + name: pangalan + applies: naaangkop? + manage: pamahalaan ang mga paraan ng pagpapadala + create_button: gumawa ng bagong paraan ng pagpapadala + create_one_button: gumawa ng isa ngayon + no_method_yet: wala ka pang inilagay na paraan ng pagpapadala. + shop_preferences: + shopfront_requires_login: "nakikita sa publiko ang shopfront?" + shopfront_requires_login_tip: "pumili kung nais na maglog-in muna ang customer bago makita ang shopfront o nakikita ito ng lahat." + shopfront_requires_login_false: "publiko" + shopfront_requires_login_true: "nakikita lamang ng rehistradong mga customer" + recommend_require_login: "nirerekomenda namin na kailangang maglog-in muna ang Users kapag ang mga order ay maaaring baguhin." + allow_guest_orders: "mga order ng guest" + allow_guest_orders_tip: "payagang mag-checkout bilang guest o kailangang rehistrado ang user." + allow_guest_orders_false: "kailangang maglog-in para makapag-order" + allow_guest_orders_true: "payagan ang guest checkout" + allow_order_changes: "magpalit ng mga order" + allow_order_changes_tip: "payagan ang mga kustomer na palitan ang kanilang order hanggang bukas ang order cycle" + allow_order_changes_false: "ang na-place na mga order ay hindi na maaaring palitan o i-cancel" + allow_order_changes_true: "maaari pang palitan ng customer o i-cancel ang kanilang mga order habang ang order cycle ay bukas pa." + enable_subscriptions: "mga subscription" + enable_subscriptions_tip: "paganahina ng paggamit ng mga subscription?" + enable_subscriptions_false: "huwag paganahin" + enable_subscriptions_true: "paganahin" + shopfront_message: "mensahe sa Shopfront" + shopfront_message_placeholder: > + opsyonal na mensahe para batiin ang mga customers at upang maipaliwanag + kung paano mamili sa iyong shop. kung ang teksto ay ipinasok dito, ito + ay makikita sa home tab kapag ang customer ay nasa loob na ng inyong + shopfront. + shopfront_message_link_tooltip: "ilagay/ i-edit ang link" + shopfront_message_link_prompt: "ilagay ang URL na ipapasok" + shopfront_closed_message: "pagsasarang mensahe ng Shopfront" + shopfront_closed_message_placeholder: > + isang mensahe na nagbibigay ng mas detalyadong paliwanag kung bakit + ang iyong shop ay sarado at/o kapag ang mga customer ay makakaasang + magbubukas ito muli. Ito ay makikita sa iyong shop kapag ikaw ay walang + aktibong order cycle (hal. sarado ang shop). + shopfront_category_ordering: "kategorya ng pag-order sa Shopfront" + open_date: "petsa ng pagbubukas" + close_date: "petsa ng pagsasara" + social: + twitter_placeholder: "hal. @the_prof" + instagram_placeholder: "hal. the_prof" + facebook_placeholder: "hal. www.facebook.com/PageNameHere" + linkedin_placeholder: "hal. www.linkedin.com/in/YourNameHere" + stripe_connect: + connect_with_stripe: "Kumonekta sa Stripe" + stripe_connect_intro: "upang tumanggap ng bayad gamit ang credit card, kailangan munang ikonekta ang iyong Stripe account sa Open Food Network. Gamitin ang pindutan sa kanan para magsimula." + stripe_account_connected: "ang Stripe account ay konektado na." + disconnect: "tanggalin ang koneksyon ng account" + confirm_modal: + title: Kumonekta sa Stripe + part1: ang Stripe ay isang serbisyong nagpoproseso ng mga bayad na ginagawang posible para sa mga shop sa OFN na tumanggap ng bayad gamit ang mga credit card mula sa mga customer. + part2: para magamit ito, kailangang ikonekta ang iyong Stripe account sa OFN. ang pagpindot ng "pumapayag ako" sa ibaba ay ididirekta ka sa Stripe website kung saan mo maaaring ikonek ang iyong Stripe account o gumawa ng bago kung wala ka pa nito. + part3: pinapayagan nito ang Open Food Network na tumanggap para sa iyo ng bayad gamit ang mga credit card mula sa mga customer. tandaan na kailangan mong pangalagaan ang sarili mong Stripe Account, bayaran ang serbisyo ng Stripe, isaayos ang mga paniningil at gawin ang serbisyo sa customer sa sarili mong paraan. + i_agree: pumapayag ako + cancel: i-cancel + tag_rules: + default_rules: + by_default: bilang default + no_rules_yet: wala pang panuntunan na ginagamit + add_new_button: '+ magdagdag ng bagong panuntunan' + no_tags_yet: walang pang tag na magagamit sa enterprise na ito + no_rules_yet: wala pang panuntunan na magagamit sa tag na ito + for_customers_tagged: 'Para sa mga customer na naka-tag:' + add_new_rule: '+ magdagdag ng bagong panuntunan' + add_new_tag: '+ Magdagdag ng bagong tag' + users: + email_confirmation_notice_html: "ang kumpirmasyon ng email ay nakabinbin pa. kami ay nagpadala ng kumpirmasyon ng email sa %{email}." + resend: Ipadala muli + owner: 'May-ari' + contact: "makipag-ugnayan" + contact_tip: "ang tagapamahala na makakatanggap ng enterprise emails at notipikasyon. kailangang may kumpirmadong email address." + owner_tip: ang pangunahing gumagamit na responsable sa enterprise na ito. + notifications: notipikasyon + notifications_tip: ang mga notipikasyon tungkol sa mga order ay ipapadala sa email address na ito. + notifications_placeholder: hal. gustav@truffles.com + notifications_note: 'Tandaan: ang bagong email address ay kailangang kumpirmado bago magamit' + managers: Tagapamahala + managers_tip: ang ibang gagamit na may permisong pamahalaan ang enterprise na ito. + invite_manager: "Mag-imbita ng Tagapamahala" + invite_manager_tip: "mag-imbita ng hindi rehistradong gagamit na mag-sign-up at maging tagapamahala ng enterprise na ito." + add_unregistered_user: "magdagdag ng hindi rehistradong user" + email_confirmed: "ang email ay kumpirmado" + email_not_confirmed: "ang email ay hindi kumpirmado" + actions: + edit_profile: Settings + properties: mga katangian + payment_methods: Mga Paraan ng Pagbabayad + payment_methods_tip: ang enterprise na ito ay walang mga paraan ng pagbabayad + shipping_methods: mga paraan ng pagpapadala + shipping_methods_tip: ang enterprise na ito ay may mga paraan ng pagpapadala + enterprise_fees: bayad para sa enterprise + enterprise_fees_tip: ang enterprise na ito walang mga bayarin + admin_index: + name: Pangalan + role: papel na gagampanan + sells: nagbebenta + visible: nakikita? + owner: May-ari + producer: Producer + change_type_form: + producer_profile: Profile ng Producer + connect_ofn: kumonekta gamit ang OFN + always_free: PALAGING LIBRE + producer_description_text: ilagay ang inyong mga produkto sa Open Food Network, upang mapayagan ang mga Hub na mag-stock ng iyong produkto sa kanilang mga tindahan. + producer_shop: Producer Shop + sell_your_produce: magbenta ng sariling produkto + producer_shop_description_text: ibenta ang iyong mga produkto direkta sa mga customer sa pamamagitan ng iyong sariling Open Foof Network shopfront. + producer_shop_description_text2: ang 'Producer Shop' ay para lamang sa iyong produkto, kung nais mong magbenta ng mga produktong itinanim o ginawa sa labas ng site, piliin ang 'Producer Hub' + producer_hub: Producer Hub + producer_hub_text: magbenta ng produkto mula sa sarili at sa iba + producer_hub_description_text: ang iyong enterprise ang saligan ng iyong lokal na sistema ng pagkain. maaari mong ibenta ang sarili mong produkto pati na rin ang mga produktong pinagsama sama mula sa ibang enterprise gamit ang iyong shop sa Open Food Network. + profile: Profile lamang + get_listing: kumuha ng listahan + profile_description_text: maaari kang mahanap ng mga tao at makipag-ugnayan sa kanila sa Open Food Network. Ang iyong enterprise ay makikita sa mapa at mahahanap sa mga listahan. + hub_shop: Hub Shop + hub_shop_text: magbenta ng produkto mula sa iba + hub_shop_description_text: ang iyong enterprise ang saligan ng iyong lokal na sistema ng pagkain. maaari mong pagsama samahin ang mga produkto mula sa ibang enterprise at ibenta ito gamit ang iyong shop sa Open Food Network. + choose_option: pumili mula sa pagpipilian sa itaas. + change_now: palitan ngayon + enterprise_user_index: + loading_enterprises: NILO-LOAD ANG MGA ENTERPRISE + no_enterprises_found: walang mahanap na enterprise + search_placeholder: hanapin gamit ang pangalan + manage: pamahalaan + manage_link: settings + producer?: "Producer?" + package: "Package" + status: "katayuan" + new_form: + owner: may-ari + owner_tip: ang pangunahing gumagamit na responsable sa enterprise na ito. + i_am_producer: ako ay isang producer + contact_name: Contact name + edit: + editing: 'Settings:' + back_link: bumalik sa listahan ng mga enterprise + new: + title: bagong enterprise + back_link: bumalik sa listahan ng mga enterprise + remove_logo: + remove: "alisin ang larawan" + removed_successfully: "matagumpay na natanggal ang logo" + immediate_removal_warning: "ang logo ay tatanggalin agad pagkatapos mong magkumpirma." + remove_promo_image: + remove: "alisin ang larawan" + removed_successfully: "ang promo na larawan ay matagumpay na natanggal" + immediate_removal_warning: "ang promo na larawan ay tatanggalin agad pagkatapos mong magkumpirma." + welcome: + welcome_title: Welcome sa Open Food Network! + welcome_text: matagumpay na nagawa ang + next_step: sunod na hakbang + choose_starting_point: 'pumili ng package:' + profile: 'profile' + producer_profile: 'Profile ng Prodyuser' + invite_manager: + user_already_exists: "ang user ay rehistrado na" + error: "may nangyaring mali" + order_cycles: + loading_flash: + loading_order_cycles: NILO-LOAD ANG MGA ORDER CYCLE + loading: NILO-LOAD... + new: + create: "gumawa" + cancel: "i-cancel" + back_to_list: "bumalik sa listahan" + edit: + advanced_settings: "Advanced settings" + save: "i-save" + save_and_next: "i-save at sunod" + next: "sunod" + cancel: "i-cancel" + back_to_list: "bumalik sa listahan" + save_and_back_to_list: "i-save at bumalik sa listahan" + choose_products_from: "pumili sa mga produkto mula sa:" + incoming: + save: "i-save" + save_and_next: "i-save at sunod" + next: "sunod" + cancel: "i-cancel" + back_to_list: "bumalik sa listahan" + outgoing: + outgoing: "papalabas" + distributor: "Distributor" + products: "mga produkto" + tags: "tags" + delivery_details: "detalye ng pag-deliver" + fees: "mga bayarin" + previous: "nauna" + save: "i-save" + save_and_back_to_list: "i-save at bumalik sa listahan" + cancel: "i-cancel" + back_to_list: "bumalik sa listahan" + wizard_progress: + edit: "1. Pangkalahatang Setting" + incoming: "2. Papasok na mga produkto" + outgoing: "3. Palabas na mga produkto" + exchange_form: + pickup_time_tip: kapag ang mga order mula sa OC ay handa na para sa customer + pickup_instructions_placeholder: "mga panuto sa pagpick-up" + pickup_instructions_tip: ang mga panuto na ito ay ipapakita sa mga customer pagkatapos nilang makumpleto ang pag-order + pickup_time_placeholder: "handa na para sa (hal. Date / Time)" + receival_instructions_placeholder: "panuto sa pagtanggap" + add_fee: 'idagdag ang bayad' + remove: 'tanggalin' + selected: 'napili' + add_exchange_form: + add_supplier: 'magdagdag ng supplier' + add_distributor: 'magdagdag ng tagapamahagi' + advanced_settings: + title: Advanced settings + choose_product_tip: maaring limitahan ang mga produktong pumapasok at lumalabas sa imbentaryo lamang ng%{inventory} + preferred_product_selection_from_coordinator_inventory_only_here: imbentaryo lamang ng coordinator + preferred_product_selection_from_coordinator_inventory_only_all: lahat ng produkto + save_reload: i-save at i-reload ang pahina + coordinator_fees: + add: idagdag ang bayad sa coordinator + filters: + search_by_order_cycle_name: "hanapin gamit ang pangalan ng order cycle..." + involving: "kinasangkot" + any_enterprise: "kahit anong enterprise" + any_schedule: "kahit anong petsa" + form: + general_settings: "Pangkalahatang Setting" + incoming: papasok + supplier: tagapagtustos + receival_details: detalye ng pagtanggap + fees: mga bayarin + outgoing: papalabas + distributor: Distributor + products: mga produkto + tags: tags + add_a_tag: magdagdag ng tag + delivery_details: detalye ng pick-up/pagdeliver + index: + schedule: iskedyul + schedules: iskedyul + new_schedule: bagong iskedyul + name_and_timing_form: + name: Pangalan + orders_open: ang mga order ay magbubukas sa + coordinator: coordinator + orders_close: sarado ang mga order + row: + suppliers: mga supplier + distributors: mga tagapamahala + variants: mga uri + simple_form: + ready_for: handa para sa + ready_for_placeholder: petsa/ oras + customer_instructions: panuto ng Customer + customer_instructions_placeholder: tala para sa pag-pick-up o pagdeliver + products: mga produkto + fees: mga bayarin + destroy_errors: + orders_present: ang order cycle na ito ay napili na ng isang customer at hindi na maaaring tanggalin. upang maiwasan na ma-access muli, isarado muna ito. + schedule_present: ang order cycle na ito ay naka-link sa isang iskedyul at hindi maaaring tanggalin. maaaring tanggalin muna ang link o tanggalin muna ang iskedyul. + bulk_update: + no_data: may nangyaring mali. walang mahanap na order cycle. + date_warning: + msg: ang order cycle na ito ay naka-link sa %{n}na bukas na subscription order. ang pagpapalit ng petsa ay hindi maaapektuhan ang iba pang order na nagawa na, ngunit kung maaaring iwasan ay huwag na muling gawin. Gusto bang magpatuloy? + cancel: i-cancel + proceed: magpatuloy + producer_properties: + index: + title: mga katangian ng producer + proxy_orders: + cancel: + could_not_cancel_the_order: hindi ma-cancel ang order + resume: + could_not_resume_the_order: hindi maituloy ang order + shared: + user_guide_link: + user_guide: gabay sa gumagamit + enterprises_hubs_tabs: + has_no_payment_methods: "%{enterprise}ay walang paraan ng pagbabayad" + has_no_shipping_methods: "%{enterprise}ay walang paraan ng pagpapadala" + has_no_enterprise_fees: "%{enterprise}ay walang mga bayarin sa enterpise" + enterprise_issues: + create_new: gumawa ng bago + resend_email: ipadala muli ang email + has_no_payment_methods: "%{enterprise}ay kasakuluyang walang mga paraan ng pagbabayad" + has_no_shipping_methods: "%{enterprise}ay kasalukuyang walang mga paraan ng pagpapadala" + email_confirmation: "ang kumpirmasyon ng email ay nakabinbin pa. kami ay nagpadala ng kumpirmasyon ng email sa %{email}." + not_visible: "%{enterprise}ay hindi nakikita kaya hindi matagpuan sa mapa o sa kahit saang paghahanap" + reports: + hidden: NAKATAGO + unitsize: LAKI KADA YUNIT + total: KABUUAN + total_items: KABUUAN NG MGA ITEM + supplier_totals: kabuuang order cycle ng mga supplier + supplier_totals_by_distributor: kabuuang order cycle ng mga supplier ng tagapamahala + totals_by_supplier: kabuuang order cycle ng tagapamahala ng Supplier + customer_totals: kabuuang order cycle ng customer + all_products: lahat ng produkto + inventory: Imbentaryo (on hand) + lettuce_share: LettuceShare + mailing_list: Listahan ng mga pagpapadalahan + addresses: Mga address + payment_methods: ulat ng mga paraan ng pagbabayad + delivery: ulat ukol sa pagdeliver + tax_types: uri ng buwis + tax_rates: rate ng mga buwis + pack_by_customer: binalot ng Customer + pack_by_supplier: binalot ng Supplier + orders_and_distributors: + name: mga order at tagapamahagi + description: mga order na may detalye ng tagapamahagi + bulk_coop: + name: Bultuhang Co-Op + description: ulat para sa mga order ng Bultuhang Co-Op + payments: + name: ulat ng mga bayad + description: ulat para sa mga bayad + orders_and_fulfillment: + name: ulat ng mga order at fulfillment + customers: + name: mga customer + products_and_inventory: + name: mga produkto at imbentaryo + users_and_enterprises: + name: mga gumagamit at enterprise + description: pag-aari ng enterprise at katayuan + order_cycle_management: + name: pamamahala sa order cycle + sales_tax: + name: buwis ng mga benta + xero_invoices: + name: mga invoice ng Xero + description: mga invoice na ililipat sa Xero + packing: + name: ulat sa pagbabalot + enterprise_fee_summary: + name: "buod ng bayad sa enterprise" + description: "buod ng mga nakolektang bayad sa enterprise" + subscriptions: + subscriptions: mga subscription + new: bagong subscription + create: gumawa ng subscription + edit: ayusin ang subscription + table: + edit_subscription: ayusin ang subsciption + pause_subscription: ihinto saglit ang subscription + unpause_subscription: ituloy ang subscription + cancel_subscription: itigil ang subscription + filters: + query_placeholder: "hanapin gamit ang email..." + setup_explanation: + just_a_few_more_steps: 'ilang hakbang na lamang bago ka makapagsimula:' + enable_subscriptions: "paganahin ang subscription sa kahit isa sa iyong mga shop" + enable_subscriptions_step_1_html: 1. pumunta sa%{enterprises_link}pahina, hanapin ang iyong shop at pindutin ang "pamahalaan" + enable_subscriptions_step_2: 2. sa ilalim ng "shop preference", paganahin ang Subscriptions sa pagpipilian + set_up_shipping_and_payment_methods_html: iset-up ang %{shipping_link}at%{payment_link} na pagbabayad + set_up_shipping_and_payment_methods_note_html: tandaan na Cash at Stripe na pamamaraan ang maaaring
gamitin sa mga subscription + ensure_at_least_one_customer_html: siguraduhing mayroong kahit isang%{customer_link}na nakikita + create_at_least_one_schedule: gumawa ng kahit isang iskedyul + create_at_least_one_schedule_step_1_html: 1. pumunta sa %{order_cycles_link}pahina + create_at_least_one_schedule_step_2: 2. gumawa ng order cycle kung hindi pa ito nagagawa + create_at_least_one_schedule_step_3: 3. pindutin ang '+ bagong iskedyul' at sagutan ang form + once_you_are_done_you_can_html: kapag natapos na ito, maaari kang%{reload_this_page_link} + reload_this_page: i-reload ang pahina na ito + steps: + details: 1. pangunahing detalye + address: 2. tirahan + products: 3. magdagdag ng mga produkto + review: 4. suriin at i-save + subscription_line_items: + this_is_an_estimate: | + ang mga nakasulat na presyo ay tantiya lamang at kinalkula sa panahon na binago ang subscription. + kung magpapalit ng presyo o bayarin, maa-update ang mga order ngunit ang subscription ay ipapakita pa rin ang dating mga halaga. + not_in_open_and_upcoming_order_cycles_warning: "walang bukas o paparating na mga order cycle para sa produkto na ito." + autocomplete: + name_or_sku: "PANGALAN O SKU" + quantity: "dami" + add: "idagdag" + details: + details: detalye + invalid_error: sagutan ang mga kailangang detalte... + allowed_payment_method_types_tip: Cash at pamamaraang Stripe lamang ang maaaring gamitin sa kasalukuyan. + credit_card: Credit Card + charges_not_allowed: ang paniningil ay hindi pinapayagan ng customer na ito + no_default_card: ang customer ay walang mga card na maaaring singilin + card_ok: ang customer ay may card na maaaring singilin + begins_at_placeholder: "pumili ng petsa" + ends_at_placeholder: "opsyonal" + loading_flash: + loading: NILOLOAD ANG MGA SUBSCRIPTION + review: + details: detalye + address: tirahan + products: mga produkto + no_open_or_upcoming_order_cycle: "walang paparating na order cycle" + products_panel: + save: "I-SAVE" + saving: "SINESAVE" + saved: "NA-SAVE NA" + product_already_in_order: ang produkto na ito ay naidagdag na sa order. ayusin ng direkta ang dami. + stock: + insufficient_stock: "walang sapat na stock" + out_of_stock: "Walang stock" + orders: + number: bilang + confirm_edit: sigurado ka bang nais mo ayusin ang order na ito? maaaring magdulot ito ng mas mahirap na awtomatikong pagsasaayos ng mga subscription sa hinaharap. + confirm_cancel_msg: "sigurado ka bang nais mong itigil ang subscription na ito? hindi na ito maaring ibalik kapag napalitan na." + cancel_failure_msg: "paumahin ngunit hindi naging matagumpay ang pagcancel!" + confirm_pause_msg: "sigurado ka bang nais mong pansamantalang itigil ang subscription na ito?" + pause_failure_msg: "paumanhin ngunit hindi matagumpay ang pansamantalang pagtigil" + confirm_unpause_msg: "kung ikaw ay may bukas na order cycle sa iskedyul ng subscription na ito, isang order ang gagawin para sa customer. sigurado ka bang nais mong ipagpatuloy ang subscription?" + unpause_failure_msg: "paumanhin ngunit hindi naging matagumpay ang pagpatuloy!" + confirm_cancel_open_orders_msg: "ang ibang order sa subscription na ito ay kasalukuyang nakabukas. ang customer ay nasabihan nang ang order ay magpapatuloy. nais mo bang itigil ang order(mga order) o ipagpatuloy ito?" + resume_canceled_orders_msg: "ang ibang order sa subsciption na ito ay maaaring ituloy. maaari mo itong ituloy sa dropdown ng mga order." + yes_cancel_them: wag ituloy + no_keep_them: ituloy + yes_i_am_sure: sigurado ako + order_update_issues_msg: ang ibang mga order ay hindi awtomatikong ma-update, sapagkat ito ay manwal na inayos. Tignan ang mga isyu na nakalista sa baba at gawin ang nararapat na pag-aayos sa bawat order kung kinakailangan. + no_results: + no_subscriptions: wala pang mga subscription.... + why_dont_you_add_one: nais mo bang magdagdag ng isa? :) + no_matching_subscriptions: walang nahanap na katugmang subscription + schedules: + destroy: + associated_subscriptions_error: ang iskedyul na ito ay hindi maialis sapagkat ito ay nauugnay sa ibang mga subscription. + controllers: + enterprises: + stripe_connect_cancelled: "ang pagkonekta sa Stripe ay kinansel" + stripe_connect_success: "matagumpay na nakonekta ang stripe account" + stripe_connect_fail: paumanhin, ang konekyson ng inyong Stripe account ay hindi nagtagumpay + stripe_connect_settings: + resource: pagsasaayos ng pagkonekta sa Stripe + api: + enterprise_logo: + destroy_attachment_does_not_exist: "ang Logo ay hindi matagpuan" + enterprise_promo_image: + destroy_attachment_does_not_exist: "ang promo na larawan ay hindi matagpuan" + orders: + failed_to_update: "hindi nagtagumpay na i-update ang order" + checkout: + already_ordered: + cart: "cart" + message_html: "mayroon ka ng order para sa order cycle na ito. tignan ang%{cart}para makita ang mga item na dating inorder. maaari mo ring i-cancel ang mga item habang ang order cycle ay bukas pa." + failed: "hindi matagumpay ang pag-check out. ipaalam sa amin upang maproseso ang inyong order." + shops: + hubs: + show_closed_shops: "ipakita ang mga saradong shop" + hide_closed_shops: "itago ang mga saradong shop" + show_on_map: "ipakita lahat sa mapa" + shared: + menu: + cart: + cart: "Cart" + signed_in: + profile: "profile" + mobile_menu: + cart: "Cart" + joyride: + checkout: "mag-checkout ngayon" + already_ordered_products: "na-order na sa order cycle na ito" + register_call: + selling_on_ofn: "interesado maging parte ng Open Food Network?" + register: "mag-rehistro dito" + footer: + footer_secure: "ligtas at mapagkakatiwalaan." + footer_secure_text: "ang Open Food Network ay gumagamit ng SSL encryption (2048 bit RSA) para mapanatiling pribado ang inyong pamimili at pagbababayad. Ang aming mga server ay hindi nagse-save ng mga detalye ng inyong credit card at ang inyong pagbabayad ay pinoproseso ng mga serbisyong PCI-compliant." + footer_contact_headline: "makipag-ugnayan" + footer_contact_email: "i-email kami" + footer_nav_headline: "Navigate" + footer_join_headline: "sumali sa amin" + footer_join_body: "gumawa ng listahan, Shop o group directory sa Open Food Network." + footer_join_cta: "sabihin pa sa akin ang iba pa!" + footer_legal_call: "basahin ang aming" + footer_legal_tos: "mga tuntunin at kondisyon" + footer_legal_visit: "Hanapin kami sa" + footer_legal_text_html: "ang Open Food Network ay isang libre at bukas ang pinagkukuhanang platform. ang mga nilalaman nito ay lisensiyado ng%{content_license}at ang aming mga code ng %{code_license}." + footer_data_text_with_privacy_policy_html: "Pinangangalagaan namin ang inyong impormasyon. Tignan ang aming%{privacy_policy}at%{cookies_policy}" + footer_data_text_without_privacy_policy_html: "Pinangangalagaan namin ang inyong impormasyon. Tignan ang aming%{cookies_policy}" + footer_data_privacy_policy: "patakaran ng privacy" + footer_data_cookies_policy: "patakaran ng cookies" + shop: + messages: + login: "mag-log-in" + signup: "mag-sign-up" + contact: "makipag-ugnay" + require_customer_login: "ang mga inaprubahang customer lamang ang maaaring gumamit ng shop na ito." + require_login_html: "Kung ikaw ay naaprubahang customer na, %{login} o %{signup}upang magpatuloy. Nais mamili dito? %{contact}%{enterprise}at magtanong kung paano sumali." + require_customer_html: "kung nais mong magsimulang mamili dito, maaaring%{contact}%{enterprise} at magtanong kung paano sumali." + card_could_not_be_updated: hindi ma-update ang card + card_could_not_be_saved: hindi ma-save ang card + spree_gateway_error_flash_for_checkout: "mayroong problema sa inyong ibinigay na impormasyon ng pagbabayad:%{error}" + invoice_billing_address: "Billing Address:" + invoice_column_tax: "GST" + invoice_column_price: "presyo" + invoice_column_item: "Item" + invoice_column_qty: "Dami:" + invoice_column_unit_price_with_taxes: "Presyo kada yunit (kasama ang tax)" + invoice_column_unit_price_without_taxes: "Presyo kada yunit (hindi kasama ang tax)" + invoice_column_price_with_taxes: "Kabuuang Presyo (kasama ang tax)" + invoice_column_price_without_taxes: "Kabuuang Presyo (hindi kasama ang tax)" + invoice_column_tax_rate: "rate ng buwis" + invoice_tax_total: "kabuuang GST:" + tax_invoice: "TAX INVOICE" + tax_total: "Kabuuang Buwis (%{rate}):" + total_excl_tax: "Kabuuan (Hindi kasama ang tax):" + total_incl_tax: "Kabuuan (Kasama ang tax):" + abn: "ABN:" + acn: "ACN:" + invoice_issued_on: "inilabas ang invoice noong:" + order_number: "numero ng invoice" + date_of_transaction: "Petsa ng Transaksiyon:" + ticket_column_qty: "Dami:" + ticket_column_item: "Item" + ticket_column_unit_price: "Presyo kada Yunit" + ticket_column_total_price: "Kabuuang Presyo" + menu_1_title: "mga shop" + menu_1_url: "/mga shop" + menu_2_title: "mapa" + menu_2_url: "/mapa" + menu_3_title: "Producers" + menu_3_url: "/mga producer" + menu_4_title: "mga grupo" + menu_4_url: "/mga grupo" + menu_5_title: "tungkol sa" + menu_5_url: "https://about.openfoodnetwork.org.ph/" + menu_6_title: "kumonekta" + menu_6_url: "https://openfoodnetwork.org/au/connect/" + menu_7_title: "matuto" + menu_7_url: "https://openfoodnetwork.org/au/learn/" + logo: "Logo (640x130)" + logo_mobile: "Mobile logo (75x26)" + logo_mobile_svg: "Mobile logo (SVG)" + home_hero: "Hero image" + home_show_stats: "ipakita ang statistics" + footer_logo: "Logo (220x76)" + footer_facebook_url: "Facebook URL" + footer_twitter_url: "Twitter URL" + footer_instagram_url: "Instagram URL" + footer_linkedin_url: "LinkedIn URL" + footer_googleplus_url: "Google Plus URL" + footer_pinterest_url: "Pinterest URL" + footer_email: "email" + footer_links_md: "mga link" + footer_about_url: "tungkol sa URL" + user_guide_link: "Link ng Gabay sa Paggamit" + name: pangalan + first_name: Pangalan + last_name: Apelyido + email: email + phone: telepono + next: sunod + address: tirahan + address_placeholder: eg. 123 High Street + address2: Tirahan (pinagpatuloy) + city: Lungsod + city_placeholder: hal. Northcote + postcode: Postcode + postcode_placeholder: hal. 3070 + suburb: labas ng lungsod + state: kalagayan + country: Bansa + unauthorized: hindi awtorisado + terms_of_service: "mga palatuntunan ng serbisyo" + on_demand: on demand + none: wala + not_allowed: hindi pinapayagan + no_shipping: walang mga paraan ng pagpapadala + no_payment: walang mga paraan ng pagbabayad + no_shipping_or_payment: walang mga paraan ng pagpapadala o pagbabayad + unconfirmed: hindi kumpirmado + days: mga araw + authorization_failure: "hindi nagtagumpay ang pagpahintulot" + label_shop: "Shop" + label_shops: "mga shop" + label_map: "mapa" + label_producer: "Prodyuser" + label_producers: "Producers" + label_groups: "mga grupo" + label_about: "tungkol sa" + label_connect: "kumonekta" + label_learn: "matuto" + label_blog: "Blog" + label_support: "Suporta" + label_shopping: "Pamimili" + label_login: "Login" + label_logout: "mag-log-out" + label_signup: "Mag-sign-up" + label_administration: "administrasyon" + label_admin: "admin" + label_account: "Account" + label_more: "ipakita lahat" + label_less: "ipakita ang mas kaunti" + label_notices: "mga abiso" + cart_items: "mga item" + cart_headline: "ang iyong cart sa pamimili" + total: "kabuuan" + cart_updating: "ina-update ang cart" + cart_empty: "walang laman ang cart" + cart_edit: "ayusin ang cart" + card_number: numero ng card + card_securitycode: "Security code" + card_expiry_date: petsa ng pag-expire + card_masked_digit: "X" + card_expiry_abbreviation: "Exp" + new_credit_card: "bagong credit card" + my_credit_cards: ang aking mga credit card + add_new_credit_card: magdagdag ng bagong credit card + saved_cards: i-save ang mga card + add_a_card: magdagdag ng card + add_card: idagdag ang card + you_have_no_saved_cards: wala ka pang nai-save na card. + saving_credit_card: sine-save ang credit card... + card_has_been_removed: "ang iyong card ay tinanggal na (numero:%{number})" + card_could_not_be_removed: paumanhin, hindi maalis ang card + invalid_credit_card: "hindi valid ang credit card" + ie_warning_headline: "ang iyong browser ay luma na :-(" + ie_warning_text: "para sa pinakamagandang karanasan sa Open Food Network, mariin naming nirerekomenda ang pag-upgrade ng inyong browser:" + ie_warning_chrome: i-download ang Chrome + ie_warning_firefox: i-download ang Firefox + ie_warning_ie: i-upgrade ang Internet Explorer + ie_warning_other: "Hindi ma-upgrade ang browser? Subukan ang Open Food Network sa inyong smartphone :-)" + legal: + cookies_policy: + header: "paano kami gumagamit ng cookies" + desc_part_1: "ang mga cookies ay maliliit na text files na naiimbak sa iyong computer kapag bumibisita ka sa mga website" + desc_part_2: "sa OFN, mahigpit naming pinahahalagahan ang inyong privacy. gumagamit lamang kami ng cookies na kinakailangan para makapagbigay sa inyo ng serbisyo sa pagbebenta/pamimili ng pagkain sa internet. Hindi namin pagkakakitaan ang inyong impormasyon. maaaring imungkahi namin sa hinaharap ang pagbahagi ng ilang impormasyon para makabuo ng isang bagong pangkaraniwang serbisyo na maaaring makatulong sa sistema ng pagkain( tulad ng mga proseso at serbisyo para sa maliliit na kalakalan ng pagkain) ngunit wala pa tayo sa hakbang na iyon sa ngayon at sisiguraduhin naming hindi namin ito gagawin ng wala ang inyong permiso." + desc_part_3: "ang pangunahing dahilan sa paggamit ng cookies ay para matandaan kung sino ka kapag ikaw ay naglog-in sa serbisyo at upang panatilihin ang mga item na nilagay mo sa iyong cart habang ikaw ay hindi pa nakalog-in. kung ikaw ay gumagamit ng website ng hindi pinipindot ang \"tanggapin ang cookies\", ipapalagay namin na binibigyan mo kami ng pahintulot na i-save ang mga cookies na lubhang mahalaga sa maayos na paggamit ng website. narito ang listahan ng mga cookies na aming ginagamit!" + essential_cookies: "mahahalagang mga cookies" + essential_cookies_desc: "ang mga sumusunod na cookies ay lubhang kailangan para sa operasyon ng ating website." + essential_cookies_note: "karamihan sa mga cookies ay naglalaman lamang ng natatanging pagkakakilanlan at wala ng iba, kung kaya ang iyong email address at password halimbawa ay hindi kailanman mai-se-save at maipapalam sa iba." + cookie_domain: "Sinet ng:" + cookie_session_desc: "ginagamit upang payagan ang website na matandaan ang mga gumagamit kapag dumadalaw sa pahina, halimbawa, alalahanin ang mga item na nasa cart." + cookie_consent_desc: "ginagamit upang mapanatili ang katayuan ng niilalaman ng gumagamit sa pag-store ng cookies" + cookie_remember_me_desc: "ginagamit kapag ang user ay humingi ng pahintulot na maalala siya. ang cookie na ito ay awtomatikong nabubura makalipas ang 12 araw. kung bilang gumagamit ay nais mong mabura ang cookie, kailangan mo lamang maglog-out. kung hindi mo nais na mailagay ang cookie sa iyong computer, hindi mo dapat lagyan ng check ang \"alalahanin ako\" na kahon kapag nagla-log-in." + cookie_openstreemap_desc: "ay ginagamit ng tagapagbigay sa atin ng serbisyo ukol sa open source mapping(OpennStreetMap) para masiguradong hindi ito makakatanggap ng maraming request sa tinakdang oras, at upang maiwasan na din ang pag-abuso sa kanilang serbisyo." + cookie_stripe_desc: "Mga data na nakolekta ng Stripe, ang tagaproseso para sa bayad, upang magamit sa pag-detect ng fraud https://stripe.com/cookies-policy/legal. hindi lahat ng shop ay gumagamit ng Stripe bilang paraan ng pagbabayad ngunit iminumungkahi namin itong gamitin sa lahat ng pahina upang maiwasan ang fraud at ilegal na pagkuha ng iyong impormasyon." + statistics_cookies: "katayuan ng cookies" + statistics_cookies_desc: "ang mga sumusunod ay hindi mahigpit na kinakailangan, ngunit nakakatulong upang mabigyan namin kayo ng mga pinakamagandang serbisyo sa pamamagitan ng pagpayag na suriin namin ang kilos ng mga gumagamit, alamin ang mga features na madalas gamitin o hindi ginagamit, at intindihin ang ang problemang kinaharap ng gumagamit, at iba pa." + statistics_cookies_analytics_desc_html: "upang kolektahin at suriin ang data sa paggamit ng platform, ginagamit namin ang Google Analytics, bilang ito ang orihinal na serbisyo na ginagamit ng Spree (ang e-commerce open source software kung saan kami nagsimula) ngunit ang aming layunin ay makalipat sa Matomo(halimbawa ay Piwik, open source analytics tool na sumusunos sa GDPR at pinangangalagaan angn inyong privacy) sa lalong madaling panahon." + statistics_cookies_matomo_desc_html: "para makolekta at masuri ang mga data na ginagamit, gumagamit kami ngMatomo(halimbawa ay Piwik), isang open source analytics na tool na sumusunod sa GDPR at pinangangalagaan ang inyong privacy." + statistics_cookies_matomo_optout: "nais mo bang gamitin ang Matomo Analytics? hindi kami kumukolekta ng kahit anong personal na imprormasyon, at tinutulungan kami ng Matomo na pag-igihin ang aming serbisyo, ngunit mas pinapahalagahan namin ang inyong desisyon :-)" + cookie_analytics_utma_desc: "ginagamit upang pag-ibahin ang mga gumagamit at mga sesyon. Ang cookie ay nabubuo kapag ang javascript library ay naisagawa at walang __utma cookies. ang cookie na ito ay ina-update sa tuwing may ipinapadala na data sa Google Analytics." + cookie_analytics_utmt_desc: "ginagamit upang makontrol ang bilis ng pagpasok ng mga request." + cookie_analytics_utmb_desc: "ginagamit upang matukoy ang mga bagong sesyon/bisita. ang cookie ay nabubuo kapag ang javascript library ay naisagawa at walang __utma cookies. ang cookie na ito ay ina-update sa tuwing may ipinapadala na data sa Google Analytics." + cookie_analytics_utmc_desc: "hindi ginagamit sa ga.js. i-set para sa interoperability sa urchin.js. Kahit sa nakaraan, ang cookie na ito ay ginagamit kasama ang the __utmb cookie para matukoy kung ang gumagamit ay nasa bagong sesyon/bisita." + cookie_analytics_utmz_desc: "sine-save ang traffic source o campaign na nagpapaliwanag kung paano napunta ang gumagamit sa inyong site. ang cookie ay nagagawa kapag ang javascript library ay nagamit at na-update sa tuwing may ipinapadalang data sa Google Analytics." + cookie_matomo_basics_desc: "mga cookies ng Matomo first party para mangolekta ng istatistika." + cookie_matomo_heatmap_desc: "cookies para sa Matomo Heatmap & Session Recording." + cookie_matomo_ignore_desc: "Cookie na ginagamit upang hindi maisama ang gumagamit sa pag-track." + disabling_cookies_header: "Babala sa hindi pagpapagana ng cookies" + disabling_cookies_desc: "ang gumagamit ay maaaring payagan, i-block o burahin ang Open Food Network o ang kahit anong website cookies kahit kailan nila naisin sa pamamagitan ng setting control ng browser na ginagamit. bawat browser ay may iba't ibang proseso. eto ang mga link:" + disabling_cookies_firefox_link: "https://support.mozilla.org/en-US/kb/enable-and-disable-cookies-website-preferences" + disabling_cookies_chrome_link: "https://support.google.com/chrome/answer/95647" + disabling_cookies_ie_link: "https://support.microsoft.com/en-us/help/17442/windows-internet-explorer-delete-manage-cookies" + disabling_cookies_safari_link: "https://www.apple.com/legal/privacy/en-ww/cookies/" + disabling_cookies_note: "ngunit dapat malaman na kapag binura o binago ang mahahalagang cookies na ginagamit ng Open Food Network, ang website ay hindi gagana at hindi ka maaring makapaglagay sa iyong cart upang makapagcheckout halimbawa." + cookies_banner: + cookies_usage: "ang site na ito ay gumagamit ng mga cookies upang maging mas ligtas at madali ang paggamit ng site. nakakatulong din ito sa amin upang maintindihan kung paano ang inyong paggamit para mas maging maayos ang serbisyong aming ibibigay sa inyo." + cookies_definition: "ang mga cookies ay maliliit na text files na naiimbak sa iyong computer kapag bumibisita ka sa mga website" + cookies_desc: "ginagamit lang namin ang mga cookies na kinakailangan para sa pagbibigay ng serbisyo ng pagbebenta/pamimili ng pagkain gamit ang internet. Hindi namin gagamitin ang inyong data para kumita. ang pangunahing dahilan sa paggamit ng cookies ay para matandaan kung sino ka kapag ikaw ay naglog-in sa serbisyo at upang panatilihin ang mga item na nilagay mo sa iyong cart habang ikaw ay hindi pa nakalog-in. kung ikaw ay gumagamit ng website ng hindi pinipindot ang \"tanggapin ang cookies\", ipapalagay namin na binibigyan mo kami ng pahintulot na i-save ang mga cookies na lubhang mahalaga sa maayos na paggamit ng website." + cookies_policy_link_desc: "para sa karagdagangn impormasyon, tignan ang" + cookies_policy_link: "patakaran ng cookies" + cookies_accept_button: "tanggapin ang cookies" + home_shop: mamili ngayon + brandstory_headline: "Pagkain, hindi pinagsama" + brandstory_intro: "minsan ang pinakamadaling paraan para pagsamahin ang mga sistema ay magsimulang bumuo ulit ng bago.." + brandstory_part1: "Kami ay nagsimula sa pinakaibaba pataas. Kasama ang mga magsasaka at tagatanim na may ipagmamalaki at handang ibahagi ang kanilang mga kuwento. Kasama rin namin ang mga tagapamahaging patas at tapat na handang makipag-usap sa mga taong may produkto. At mga mamimili na naniniwala na ang mabusising lingguhang pamimili ay magdudulot ng malaking pagbabago sa mundo." + brandstory_part2: "kaya kinailangan naming gumawa ng paraan para gawing totoo ang lahat. isang paraan para bigyan ng kapangyarihan ang lahat ng mga tao na nagtatanim, nagsasaka, nagbebenta at bumibili ng pagkain. isang paraan upang mabigyan ng boses ang lahat at malaman ang kanilang kuwento, matulungan sa pagsasaayos ng mga proseso. isang paraang upang ang mga transaksyon ay gawing pagbabago araw araw." + brandstory_part3: "ito ang dahilan kaya kami ay nagtayo ng online na pamilihan na kalebel na kung ano ang nasa katotohanan. ito ay transparent kaya bumubuo ito ng totoong mga relasyon. ito ay bukas ang pinagkukunan, kaya pag-aari ito ng lahat. ito ay sinusubukan na rin ng iba't ibang rehiyon at nasyon, dahilan kaya ang mga tao ay unti unting nagsisimulang gumawa ng sariling bersyon nito sa iba't ibang panig ng mundo." + brandstory_part4: "ito ay gumagana sa lahat ng lugar. kaya nitong baguhin ang lahat." + brandstory_part5_strong: "tinatawag namin itong Open Food Network." + brandstory_part6: "lahat tayo ay mahilig kumain. ngayon ay maaari narin nating mahalin ang sistema ng pagkain." + learn_body: "galugarin ang mga modelo, mga kuwento at pinagkukuhanan para ikaw ay matulungan sa pagbuo ng sarili mong negosyo o organisayon. Humanap ng mga pagsasanay, kaganapan at iba pang mga oportunidad para matuto sa iba." + learn_cta: "makakuha ng inspirasyon" + connect_body: "tumingin sa aming directory ng mga producer, hub at mga grupo upang makahanap ng patas na mangangalakal ng pagkain na pinakamalapit sa iyo. Ilagay ang iyong negosyo o organisasyon sa OFN para kayo'y makita ng mga mamimili. Sumali sa aming komunidad para makakuha ng mga payo ay makapagtulungan sa paglutas ng mga problema." + connect_cta: "halilka na at ma-explore" + system_headline: "pamimili - ganito siya gumagana." + system_step1: "1. humanap" + system_step1_text: "humanap sa iba't ibang mga shop ng lokal na napapanahong pagkain. humanap sa pamamagitan ng malapit na lokasyon o kategorya ng pagkain, o kung mas nais mo ang pick-up kesa sa delivery." + system_step2: "2. Mamili" + system_step2_text: "baguhin ang paraan ng pakikipagtransaksyon sa pagbili ng mga lokal ng pagkain mula sa iba't ibang producer at hubs. malaman ang mga kwento sa likod ng mga pagkain at sa mga gumagawa nito." + system_step3: "3. Pick-up / Delivery" + system_step3_text: "hintayin ang inyong pagkain o bisitahin ang producer o hub para sa mas personal na koneksyon sa inyong pagkain at pinanggagalingan nito." + cta_headline: "paraan ng pamimili na kayang gawing mas madali at maayos ang mundong ito." + cta_label: "handa na ako" + stats_headline: "kami ay bumubuo ng bagong sistema ng pagkain." + stats_producers: "producer ng pagkain" + stats_shops: "mga tindahan ng pagkain" + stats_shoppers: "mga mamimili ng pagkain" + stats_orders: "mga order ng pagkain" + checkout_title: checkout + checkout_now: mag-checkout ngayon + checkout_order_ready: ang order ay handa na para sa + checkout_hide: itago + checkout_expand: palawigin + checkout_headline: "ok, handa na ba magcheckout?" + checkout_as_guest: "mag-checkout bilang bisita" + checkout_details: "ang inyong detalye" + checkout_billing: "impormasyon sa paniningil" + checkout_default_bill_address: "i-save bilang default na address para sa paniningil" + checkout_shipping: impormasyon sa pagpapadala + checkout_default_ship_address: "i-save bilang default na address para sa pagpapadalahan" + checkout_method_free: libre + checkout_address_same: address ng pagpapadalahan pareho sa address ng paniningil? + checkout_ready_for: "handa na para sa :" + checkout_instructions: "komento o dagdag na tagubilin?" + checkout_payment: kabayaran + checkout_send: i-place ang order ngayon + checkout_your_order: ang iyong order + checkout_cart_total: kabuuan na laman ng cart + checkout_shipping_price: pagpapadala + checkout_total_price: kabuuan + checkout_back_to_cart: "bumalik sa cart" + cost_currency: "halaga ng pera" + order_paid: BAYAD NA + order_not_paid: HINDI PA BAYAD + order_total: kabuuang order + order_payment: "magbabayad sa pamamagitan ng:" + order_billing_address: address na pagsisingilan + order_delivery_on: petsa ng delivery + order_delivery_address: address kung saan ide-deliver + order_delivery_time: oras ng pagde-deliver + order_special_instructions: "ang iyong mga tala" + order_pickup_time: handa na para sa koleksyon + order_pickup_instructions: tagubilin sa pagkolekta + order_produce: produkto + order_total_price: kabuuan + order_includes_tax: (kasama ang buwis) + order_payment_paypal_successful: ang iyong bayad gamit ang PayPal ay matagumpay na naproseso. + order_hub_info: impormasyon ng Hub + order_back_to_store: bumalik sa pamillihan + order_back_to_cart: bumalik sa Cart + bom_tip: "gamitin ang pahina na ito para baguhin ang dami ng mga produkto sa maramihang mga order. maaari ding magtanggal ng mga produkto mula sa order kung kinakailangan." + unsaved_changes_warning: "may mga pagbabagong hindi pa na-save at maaaring mawala kung magpapatuloy." + unsaved_changes_error: "ang mga guhit na may pulang border ay may mga error" + products: "mga produkto" + products_in: "sa%{oc}" + products_at: "nasa%{distributor}" + products_elsewhere: "ang mga produkto ay hindi dito natagpuan" + email_confirmed: "Salamat sa pagkumpirma ng inyong email address." + email_confirmation_activate_account: "Bago natin ma-activate ang inyong account, kailangan munang kumpirmahin ang iyong email address." + email_confirmation_greeting: "magandang araw, %{contact}!" + email_confirmation_profile_created: "ang profile para kay/sa %{name}ay matagumpay na nagawa! para i-activate ang inyong profile, kailangan naming kumpirmahin ang email address na ito." + email_confirmation_click_link: "pindutin ang link sa ibaba para kumpirmahin ang iyong email address at upang maipagpatuloy ang pagset-up ng inyong profile." + email_confirmation_link_label: "kumpirmahin ang email address na ito »" + email_confirmation_help_html: "pagkatapos makumpirma ang iyong email, maaari mo na i-access ang iyong administration account para sa enterprise na ito. tignan ang%{link}upang lalong mas maunawaan ang%{sitename}at masimulan na ang paggamit ng inyong profile o online na tindahan." + email_confirmation_notice_unexpected: "natanggap mo ang mensahe na ito sapagkat ikaw ay nagsign-up sa%{sitename}, or ay inimbitahan para magsign-up ng isang tao na maaring kilala mo. kung hindi maintindihan kung bakit ka nakakatanggap ng ganitong email, maaring sumulat sa%{contact}." + email_social: "kumonekta sa amin:" + email_contact: "i-email kami:" + email_signoff: "Mabuhay," + email_signature: "%{sitename} Team" + email_confirm_customer_greeting: "Magandang araw%{name}," + email_confirm_customer_intro_html: "salamat sa pamimili sa%{distributor}!" + email_confirm_customer_number_html: "kumpirmasyon ng order#%{number}" + email_confirm_customer_details_html: "narito ang mga detalye ng niyong order mula sa%{distributor}:" + email_confirm_customer_signoff: "Lubos na gumagalang," + email_confirm_shop_greeting: "Magandang araw%{name}," + email_confirm_shop_order_html: "binabati kita! may bago kang order para sa%{distributor}!" + email_confirm_shop_number_html: "kumpirmasyon ng order#%{number}" + email_order_summary_item: "Item" + email_order_summary_quantity: "Dami:" + email_order_summary_sku: "SKU" + email_order_summary_price: "presyo" + email_order_summary_subtotal: "Subtotal:" + email_order_summary_total: "Kabuuan:" + email_order_summary_includes_tax: "(kasama ang tax):" + email_payment_paid: BAYAD NA + email_payment_not_paid: HINDI PA BAYAD + email_payment_summary: buod ng kabayaran + email_payment_method: "magbabayad sa pamamagitan ng:" + email_so_placement_intro_html: "mayroon kang bagong order sa%{distributor}" + email_so_placement_details_html: "narito ang mga detalye ng iyong order para sa %{distributor}:" + email_so_placement_changes: "sa kasamaang palad, hindi lahat ng produkto na iyong isinama ay available. ang orihinal na dami ng mga isinamang produkto ay naka-ekis sa baba." + email_so_payment_success_intro_html: "ang awtomatikong pagbabayad ay naproseso para sa iyong order mula sa%{distributor}." + email_so_placement_explainer_html: "ang order na ito ay awtomatikong binuo para sa iyo." + email_so_edit_true_html: "maaari kang gumawa ng mga pagbabago hanggang magsara ang iyong mga order sa%{orders_close_at}." + email_so_edit_false_html: "maari mong tignan ang mga detalye ng order na itokahit kailan." + email_so_contact_distributor_html: "kung ikaw ay may mga katanungan, maaring makipagugnayan sa%{distributor} sa pamamagitan ng%{email}." + email_so_contact_distributor_to_change_order_html: "ang order na ito ay awtomatikong binuo para sa iyo. maaari kang gumawa ng mga pagbabago hanggang magsara ang mga order sa%{orders_close_at} sa pamamagitan ng pakikipagugnayan%{distributor} sa pamamagitan ng%{email}.." + email_so_confirmation_intro_html: "ang iyong order kasama ang%{distributor} ay kumpirmado na." + email_so_confirmation_explainer_html: "ang order na ito ay awtomatikong na-place para sa iyo at ngayon ay pinalisa na." + email_so_confirmation_details_html: "ang lahat ng kailangan mong malaman tungkol sa iyong order mula sa%{distributor} ay narito:" + email_so_empty_intro_html: "sinubukan naming mag-place ng bagong order sa%{distributor}, ngunit nagkaroon ng ilang problema..." + email_so_empty_explainer_html: "sa kasamaang palad, wala sa mga produkto na inyong inorder ay available sa ngayon kaya walang na-place na order. ang orihinal na dami na inyong inilagay ay naka-ekis sa ilalim." + email_so_empty_details_html: "narito ang mga detalye ng hindi na-place na order para sa%{distributor}:" + email_so_failed_payment_intro_html: "sinubukan naming iproseso ang isang bayarin ngunit nagkaroon ng mga problema.." + email_so_failed_payment_explainer_html: "ang iyong bayad para sa subscription sa%{distributor} ay hindi nagpatuloy dahil sa problema sa inyong credit card.%{distributor} ay sinabihan ukol sa bayad na ito." + email_so_failed_payment_details_html: "ito ang mga detalye sa kung bakit hindi nagpatuloy ang bayad na ibinigay ng gateway para sa pagbabayad:" + email_shipping_delivery_details: detalye ng pag-deliver + email_shipping_delivery_time: "pagdeliver sa :" + email_shipping_delivery_address: "address ng pagdadalahan:" + email_shipping_collection_details: detalye ng pangongolekta + email_shipping_collection_time: "handa para sa koleksyon:" + email_shipping_collection_instructions: "tagubilin sa pangongolekta:" + email_special_instructions: "ang iyong mga tala" + email_signup_greeting: Magandang araw! + email_signup_welcome: "Welcome sa%{sitename}!" + email_signup_confirmed_email: "salamat sa pagkumpirma ng iyong email." + email_signup_shop_html: "maaari ka ng maglog-in sa%{link}." + email_signup_text: "maraming salamat sa pagsali sa network na ito. kung ikaw ay isang customer, kami ay nagagalak na ipakilala kayo sa aming mga magsasaka, mga Hub at masasarap na pagkain! kung ikaw ang isang producer o enterprise ng pagkain, kami ay nasasabik na maging parte kayo ng aming network." + email_signup_help_html: "para sa inyong mga katanungan at suhestiyon: maaaring gamitin ang Magpadala ng feedback na pindutan sa site o mag-email sa amin sa %{email}" + invite_email: + greeting: "Magandang araw!" + invited_to_manage: "ikaw ay naanyayahan para pamahalaan ang%{enterprise}sa%{instance}." + confirm_your_email: "Maaaring natanggap mo na o matatanggap pa lamang ang email na may link ng kumpirmasyon. hindi mo mapupuntahan ang profile ng%{enterprise}hanggang hindi pa nakukumpirma ang inyong email." + set_a_password: "pagtapos ay dapat kang magset ng password bago mapamahalaan ang enterprise." + mistakenly_sent: "Hindi sigurado kung bakit natanggap ang email na ito? makipagugnayan sa%{owner_email} para sa mas karagdagang impormasyon." + producer_mail_greeting: "Minamahal" + producer_mail_text_before: "ngayon nasa atin na ang lahat ng order ng mga mamimili para sa susunod na pag-drop ng order." + producer_mail_order_text: "narito ang buod ng mga order para inyong mga produkto:" + producer_mail_delivery_instructions: "tagubilin sa Stock pickup/delivery:" + producer_mail_signoff: "Maraming salamat!" + shopping_oc_closed: sarado na ang mga order + shopping_oc_closed_description: "maaaring maghintay sa susunod na pagbukas ng cycle( o makipaguganayan sa amin ng direkta upang malaman kung maaari pa kaming tumanggap ng huling mga order)" + shopping_oc_last_closed: "ang huling cycle ay nagsara%{distance_of_time}ang lumipas" + shopping_oc_next_open: "ang susunod na cycle ay magbubukas sa loob ng%{distance_of_time}" + shopping_oc_select: "pumili..." + shopping_tabs_home: "Home" + shopping_tabs_shop: "Shop" + shopping_tabs_about: "tungkol sa" + shopping_tabs_contact: "makipag-ugnayan" + shopping_contact_address: "tirahan" + shopping_contact_web: "makipag-ugnayan" + shopping_contact_social: "sumunod" + shopping_groups_part_of: "ay parte ng:" + shopping_producers_of_hub: "mga producer ng%{hub}:" + enterprises_next_closing: "susunod na order na magsasara" + enterprises_ready_for: "handa para sa" + enterprises_choose: "pumili kung kailan nais umorder:" + maps_open: "bukas" + maps_closed: "sarado" + hubs_buy: "mamili para sa/kay:" + hubs_shopping_here: "namimili rito" + hubs_orders_closed: "sarado na ang mga order" + hubs_profile_only: "Profile lamang" + hubs_delivery_options: "mga pagpipilian sa pagdeliver" + hubs_pickup: "Pickup" + hubs_delivery: "pagdeliver" + hubs_producers: "ang aming mga producer" + hubs_filter_by: "i-filter gamit ang" + hubs_filter_type: "uri" + hubs_filter_delivery: "pagdeliver" + hubs_filter_property: "ari-arian" + hubs_matches: "ang ibig mo bang sabihin" + hubs_intro: mamili sa iyong lokal na lugar + hubs_distance: pinakamalapit sa + hubs_distance_filter: "ipakita ang mga shop malapit sa%{location}" + shop_changeable_orders_alert_html: + one: ang iyong order sa%{shop}/%{order} ay maaaring tignan. maaaring gumawa ng pagbabago hanggang%{oc_close}. + other: ikaw ay mayroong%{count} na order sa%{shop} na maaari ngayong tignan. maaaring gumawa ng mga pagbabago hanggang%{oc_close}. + orders_changeable_orders_alert_html: ang order na ito ay nakumpirma na ngunit maaari pang gumawa ng mga pagbabago hanggang%{oc_close}. + products_clear_all: alisin lahat + products_showing: "pinapakita:" + products_or: "O" + products_with: kasama ang + products_search: "hanapin gamit ang produkto o producer" + products_loading: "nilo-load ang mga produkto..." + products_updating_cart: "ina-update ang cart" + products_cart_empty: "walang laman ang cart" + products_edit_cart: "ayusin ang cart" + products_from: mula sa + products_change: "walang pagbabago na isesave" + products_update_error: "hindi nagpatuloy ang pag-save dahil sa mga sumusunod na error(s):" + products_update_error_msg: "hindi nagpatuloy ang pag-save." + products_update_error_data: "hindi nagpatuloy ang pag-save dahil sa hindi valid na data:" + products_changes_saved: "nai-save ang mga pagbabago" + search_no_results_html: "paumahin, walang resultang nahanap para sa%{query}. sumubok ng isa pang paghahanap?" + components_profiles_popover: "ang mga profile ay walang Shopfront sa Open Food Network, ngunit maaaring mayroong sariling pisikal o online na shop sa ibang lugar" + components_profiles_show: "ipakita ang mga profile" + components_filters_nofilters: "walang mga filter" + components_filters_clearfilters: "alisin lahat ng mga filter" + groups_title: mga grupo + groups_headline: Grupo/ Mga Rehiyon + groups_text: "Bawat producer ay natatangi. Bawat negosyo ay may iba't ibang bagay na inaalok. ang aming grupo ay samahan ng mga producer, mga hub, at tagapamahagi na may mga pagkakapareho tulad ng lokasyon, pamilihan at pilosopiya. mas mapapadali nito ang iyong pamimili. kaya halina't subukan ang aming grupo at hayaan mo kaming tulungan ka sa iyong paghahanap." + groups_search: "hanapin ang pangalan o keyword" + groups_no_groups: "Walang mahanap na mga grupo" + groups_about: "tungkol sa amin" + groups_producers: "ang aming mga producer" + groups_hubs: "ang aming mga hub" + groups_contact_web: makipag-ugnayan + groups_contact_social: sumunod + groups_contact_address: tirahan + groups_contact_email: i-email kami + groups_contact_website: bisitahin ang aming website + groups_contact_facebook: sundan kami sa Facebook + groups_signup_title: mag-sign up bilang grupo + groups_signup_headline: Sign up ng grupo + groups_signup_intro: "kami ay isang kamanghamanghang plataporma para sa nagtutulungang kalakalan, ang pinakamadaling paraan para sa inyong mga miyembro at namumuhunan na makakonekta sa mga bagong pamilihan. Kami ay hindi tumutubo, abot-kaya at simple lamang." + groups_signup_email: i-email kami + groups_signup_motivation1: patas naming binabago ang sistema ng pagkain. + groups_signup_motivation2: at iyon ang dahilan kung bakit kami bumabangon araw araw. kami ay pandaigdigan ngunit hindi tumutubo base sa bukas na code ng pinagkukuhanan. kami ay lagi mong mapagkakatiwalaan. + groups_signup_motivation3: alam naming mayroon kayong magagandang ideya at nais namin kayong tulungan. Ibabahagi namin sa inyo ang aming kaalaman, mga network pati na ang pinagkukuhanan. alam naming ang pagsasarili ay hindi makabubuo ng pagbabago, kaya kami ay makikipagtulungan sa inyo. + groups_signup_motivation4: magsisimula tayo kung saan kayo nagmula. + groups_signup_motivation5: maaari kang may ka-alyansang mga hub ng pagkain, mga producer, mga tagapamahagi, kinatawan ng isang industriya o lokal na gobyerno. + groups_signup_motivation6: kung ano man ang iyong parte sa inyong lokal na sistema ng pagkain, handa kaming tumulong sa inyo. maaaring nagtatakaka kung ano ang Open Food Network at kung ano ang ginagawa nito, maaari tayong mag usap tungkol dito. + groups_signup_motivation7: ginagawa naming mas makabuluhan ang daloy ng proseso ng kalakalan ng pagkain. + groups_signup_motivation8: kailangan mong i-activate at paganahin ang iyong mga koneksyon, naririto ang aming plataporma para sa pagkilos at komunikasyon. Ang kailangan mo ay aktwal na pakikipag-ugnayan. tutulungan ka naming makausap ang mga tao sa industriya na ito, mga namumuhunan, lahat ng mga sektor. + groups_signup_motivation9: kailangan mo ng magpagkukunan. Ibibigay namin ang lahat ng tulong at karanasan na mayroon kami. kailangan mo ng kooperasyon. gagabayan ka namin sa pagkonekta sa pandaigdigang mga samahan. + groups_signup_pricing: Account ng grupo + groups_signup_studies: pag-aaral ng kaso + groups_signup_contact: handa na makipagtalakayan? + groups_signup_contact_text: "makipag-ugnayan upang malaman kung paano ka matutulungan ng OFN:" + groups_signup_detail: "ito ang mga detalye:" + login_invalid: "hindi valid ang email o password" + modal_hubs: "Mga Hub ng pagkain" + modal_hubs_abstract: ang mga Hub ng pagkain ang namamagitan sa iyo at sa mga gumagawa ng inyong pagkain! + modal_hubs_content1: maaari kang humanap ng pinakamalapit na Hub gamit ang lokasyon o pangalan. Ang ibang Hub ay may maraming mga lugar kung saan maaari mong kunin ang iyong pinamili habang ang iba ay bibigyan ka rin ng iba pang opsyon kung paano mo makukuha ang iyong order. Bawat Food Hub ay may iba ibang paraan ng operasyon at proseso kaya asahan ang kaibahan sa mga binibigay na serbisyo. + modal_hubs_content2: maaari ka lamang mamili sa isang hub ng pagkain sa isang pagkakataon. + modal_groups: "Mga Grupo / Mga Rehiyon" + modal_groups_content1: ito ang mga organisasyon at mga relasyon na namamagitan sa mga Hub na bumubuo sa Open Food Network. + modal_groups_content2: ang ibang grupo ay pinagsasama sama depende sa lokasyon o lupon, at ang iba ay sa hindi pangheograpiyang pagkakapareho. + modal_how: "Paano it gumagana" + modal_how_shop: mamili sa Open Food Network + modal_how_shop_explained: maghanap ng hub ng pagkain na pinakamalapit sa iyo para makapagsimulang makapamili. maaring palawakin ng bawat hub upang makita kung anong uri ng pagkain ang inaalok nila at pindutin ng tuluyan para magsimula mamili. (maaari lamang mamili sa isang hub sa isang pagkakataon.) + modal_how_pickup: Singil sa Pick-up, pag-deliver at pagdadala + modal_how_pickup_explained: ang ibang food hub ay magde-deliver mismo sa inyong tirahan, habang ang iba ay kakailanganin kang kunin ng personal ang inyong mga order. Mababasa sa homepage ang mga opsyon, at piliin ang mga produkto na nais sa pahina ng pamimili at checkout. Ang pagpapa-deliver ay mas mahal at ang halagang babayaran ay nakadepende sa iba't ibang food hub. Bawat Food Hub ay may iba't ibang paraan ng operasyon at proseso kaya dapat asahan ang kaibahan sa mga binibigay na serbisyo. + modal_how_more: dagdagan ang kaalaman + modal_how_more_explained: "kung nais mong mas maintindihan ang Open Food Network, kung paano ito gumagana at paano makasali dito, tignan ito:" + modal_producers: "Producers" + modal_producers_explained: "ang aming mga producer ay gumagawa ng masasarap na pagkain na maaari mong mabili sa Open Food Network." + producers_about: Tungkol sa amin + producers_buy: 'mamili para sa ' + producers_contact: makipag-ugnayan + producers_contact_phone: Tumawag + producers_contact_social: sumunod + producers_buy_at_html: "mamili para sa%{enterprise}na mga produkto sa:" + producers_filter: i-filter gamit ang + producers_filter_type: uri + producers_filter_property: ari-arian + producers_title: Producers + producers_headline: humanap ng lokal na mga producer + producers_signup_title: magsign-up bilang producer + producers_signup_headline: Producer ng pagkain, mas pinalakas. + producers_signup_motivation: Ibenta ang inyong pagkain at magkipagugnayan sa mga iba't ibang pamilihan. makatipid ng oras at pera. Pagbabago ng walang kaakibat na peligro. ginawang patas para sa lahat ang kalakaran. + producers_signup_send: sumali ngayon + producers_signup_enterprise: mga account ng enterprise + producers_signup_studies: mga kwento mula sa ating mga producer + producers_signup_cta_headline: sumali ngayon! + producers_signup_cta_action: sumali ngayon + producers_signup_detail: 'ito ang mga detalye:' + products_item: Item + products_description: paglalarawan + products_variant: Uri + products_quantity: dami + products_available: Mayroong stock? + products_producer: "Prodyuser" + products_price: "presyo" + name_or_sku: "PANGALAN O SKU" + register_title: magrehistro + sell_title: "magrehistro" + sell_headline: "pumunta sa Open Food Network!" + sell_motivation: "ipagmalaki ang iyong masasarap na pagkain!" + sell_producers: "Producers" + sell_hubs: "Hubs" + sell_groups: "mga grupo" + sell_producers_detail: "magset-up ng profile para sa inyong negosyo sa OFN sa loob lamang ng ilang minuto. maaari mong i-upgrade ang inyong profile upang maging online store at magbenta ng iyong mga produkto direkta sa mga customer." + sell_hubs_detail: "magset-up ng profile para sa inyong Food enterprise o organisasyon sa OFN. maaari mong i-upgrade ang inyong profile upang maging multi-producer na shop kahit kailan mo naisin." + sell_groups_detail: "magset-up ng directory ng mga enterprise (mga producer at iba pang enterprise ng pagkain) para sa iyong rehiyon o organisasyon." + sell_user_guide: "marami pang maaring malaman sa aming Gabay sa Paggamit" + sell_listing_price: "ang pagpapalista sa OFN ay libre. ang pagbubukas at pagpapatakbo ng shop ay libre hanggang sa $500 na buwanang benta. kung makakabenta ka ng mas marami, maaari kang mamili ng kontribusyon sa komunidad sa pagitan ng 1% at 3% ng kita. para sa karagdagang detalye ukol sa pagpepresyo, maaaring bisitahin ang seksyon ng Software Platform sa pamamagitan ng About link sa taas na menu." + sell_embed: "maari rin naming ilagay ang OFN sa inyong sariling website o magtayo ng sariling lokal na Food Network website sa inyong rehiyon." + sell_ask_services: "magtanong tungkol sa mga serbiyong binibigay ng OFN" + shops_title: mga shop + shops_headline: pamimili, binago. + shops_text: ang pagtatanim at paggawa ng pagkain ay isang cycle, ang mga magsasaka ay umaani sa isang cycle at nag-o-order tayo ng pagkain sa isang cycle. kung makikitang sarado ang isang cycle, maaaring bumalik sa ibang pagkakataon. + shops_signup_title: magsign-up bilang Hub + shops_signup_headline: Mga Food Hub, walang limitadong pagpipilian. + shops_signup_motivation: kung ano man ang iyong modelo, susuportahan ka namin. ano mang pagbabago na nais gawin, kasama mo kami. kami ay non-profit, malaya at bukas sa lahat ng impormasyon. kami ang kaibigan at kasangga na matagal mo nang pinapangarap. + shops_signup_action: sumali ngayon + shops_signup_pricing: mga account ng enterprise + shops_signup_stories: mga kwento mula sa aming mga Hub. + shops_signup_help: handa kaming tumulong. + shops_signup_help_text: kailangan mo ng mas malaking kita. kailangan mo ng bagong mga mamimili at mga katulong sa operasyon. kailangang malaman ng lahat ang tungkol sa iyong produkto. + shops_signup_detail: 'ito ang mga detalye:' + orders: mga order + orders_fees: Mga bayarin... + orders_edit_title: Cart para sa pamimili + orders_edit_headline: ang iyong cart sa pamimili + orders_edit_time: ang order ay handa na para sa + orders_edit_continue: magpatuloy sa pamimili + orders_edit_checkout: checkout + orders_form_empty_cart: "alisin ang laman ng cart" + orders_form_subtotal: bahagyang kabuuan ng mga produkto + orders_form_admin: Admin & Handling + orders_form_total: kabuuan + orders_oc_expired_headline: ang mga order ay nagsara na para sa order cycle na ito. + orders_oc_expired_text: "paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong%{time}! direktang makipag ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order." + orders_oc_expired_text_others_html: "paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong %{time}! direktang makipag ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order%{link}." + orders_oc_expired_text_link: "o tignan ang iba pang order cycle mula sa hub na ito." + orders_oc_expired_email: "Email:" + orders_oc_expired_phone: "Telepono:" + orders_show_title: Kumpirmasyon ng order + orders_show_time: 'ang order ay handa na sa:' + orders_show_order_number: "Order #%{number}" + orders_show_cancelled: Kinansela + orders_show_confirmed: Kumpirmado + orders_your_order_has_been_cancelled: "ang inyong order ay nakansela" + orders_could_not_cancel: "paumanhin sapagkat hindi makansela ang inyong order" + orders_cannot_remove_the_final_item: "hindi matanggal ang huling item mula sa isang order, maaaring kanselahin na lamang ang order." + orders_bought_items_notice: + one: "isang karagdagang item ang nakumpirma na para sa order cycle na ito" + other: "%{count}karagdagang mga item ang nakumpirma para sa order cycle na ito" + orders_bought_edit_button: ayusin ang kumpirmadong mga item + orders_bought_already_confirmed: "* kumpirmado na" + orders_confirm_cancel: sigurado ka bang nais mo na kanselahin ang order na ito? + order_processed_successfully: "ang inyong order ay matagumpay na nakumpirma" + products_cart_distributor_choice: "tagapamahagi ng inyong order:" + products_cart_distributor_change: "ang tagapamahagi para sa order na ito ay mapapalitan ng%{name} kung idadagdag ang produktong ito sa inyong cart." + products_cart_distributor_is: "ang tagapamahagi para sa order na ito ay%{name}." + products_distributor_error: "kumpletuhin ang inyong order sa%{link} bago mamili sa ibang tagapamahagi." + products_oc: "order cycle para sa iyong order:" + products_oc_change: "ang iyong order cycle para sa order na ito ay papalitan ng%{name} kung idadagdag mo ang produktong ito sa inyong cart." + products_oc_is: "ang order cycle para sa order na ito ay%{name}." + products_oc_error: "kumpletuhin ang inyong order mula sa %{link} bago mamili sa ibang order cycle." + products_oc_current: "ang iyong kasalukuyang order cycle" + products_max_quantity: sagad na dami + products_distributor: Distributor + products_distributor_info: kapag pumili ng tagapamahagi para sa inyong order, ang kanilang address at oras ng pickup ay makikita dito. + password: Password + remember_me: tandaan ako + are_you_sure: "Sigurado ka ba?" + orders_open: bukas ang mga order + closing: "sinasara" + going_back_to_home_page: "binabalik ka sa homepage" + creating: ginagawa + updating: ina-update + failed_to_create_enterprise: "hindi nagtagumpay sa paggawa ng iyong enterprise" + failed_to_create_enterprise_unknown: "hindi nagtagumpay sa paggawa ng iyong enterprise.\nsiguraduhing ang lahat ng patlang ay nasagutan." + failed_to_update_enterprise_unknown: "hindi nagtagumpay sa pag-update ng iyong enterprise.\nsiguraduhing ang lahat ng patlang ay nasagutan." + enterprise_confirm_delete_message: "mabubura rin ang%{product}na sinusuplay ng enterprise na ito. sigurado ka bang nais mo magpatuloy?" + order_not_saved_yet: "ang order mo ay hindi pa na-save. bigyan kami ng ilang segundo para tapusin ito." + filter_by: "i-filter gamit ang" + hide_filters: "itago ang mga filter" + one_filter_applied: "1 filter ang inilapat" + x_filters_applied: "inilapat ang mga filter" + submitting_order: "sinusimite ang iyong order: maghintay sandali" + confirm_hub_change: "sigurado ka ba? mapapalitan nito ang pinili mong hub at tatanggalin ang mga item sa iyong cart." + confirm_oc_change: "sigurado ka ba? mapapalitan nito ang pinili mong order cycle at tatanggalin ang mga item sa iyong cart." + location_placeholder: "mag-type ng lokasyon..." + error_required: "hindi maaaring iwanang blanko" + error_number: "ay dapat numero" + error_email: "ay dapat email address" + error_not_found_in_database: "%{name}ay hindi mahanap sa database" + error_not_primary_producer: "%{name}ay hindi isang producer" + error_no_permission_for_enterprise: "\"%{name}\": wala kang permiso para pamahalaan ang mga produkto ng enterprise na ito." + item_handling_fees: "bayad sa paghawak ng item (kasama sa kabuuan ng item)" + january: "Enero" + february: "Pebrero" + march: "Marso" + april: "Abril" + may: "Mayo" + june: "Hunyo" + july: "Hulyo" + august: "Agosto" + september: "Setyembre" + october: "Oktubre" + november: "Nobyembre" + december: "Disyembre" + email_not_found: "hindi mahanap ang email address" + email_unconfirmed: "kailangang kumpirmahin muna ang email address bago ma-reset ang password." + email_required: "kailangang magbigay ng email address" + logging_in: "maghintay sandali, ikaw ay nila-log in na namin." + signup_email: "ang iyong email" + choose_password: "pumili ng pasword" + confirm_password: "kumpirmahin ang password" + action_signup: "magsign-up ngayon" + forgot_password: "nakalimutan ang password?" + password_reset_sent: "ang email na may panuto kung paano papalitan ang inyong password ay napadala na!" + reset_password: "palitan ang password" + update_and_recalculate_fees: "i-update at kwentahin muli ang mga bayarin" + registration: + steps: + introduction: + registration_greeting: "Kumusta?" + registration_intro: "maaari ka ng gumawa ng profile para sa inyong Producer o Hub" + registration_checklist: "ano ang kailangan ko gawin?" + registration_time: "5-10 minuto" + registration_enterprise_address: "Address ng enterprise" + registration_contact_details: "pangunahing detalye ng contact" + registration_logo: "ang image ng iyong logo" + registration_promo_image: "ang pahigang imahe para sa inyong profile" + registration_about_us: "'Tungkol sa Amin' na teksto" + registration_outcome_headline: "ano ang makukuha ko?" + registration_outcome1_html: "ang iyong profile ang makakatulong sa mga taona hanapinatkontakin ka sa Open Food Network." + registration_outcome2: "gamitin ang espasyo na ito upang ipakilala ang iyong enterprise, para na rin sa pagpapalawig ng iyong koneksyon sa internet." + registration_outcome3: "ito rin ay unang hakbang para makipagkalakalan sa Open Food Network, o pagbubukas ng sariling tindahan sa internet." + registration_action: "Magsimula na tayo!" + details: + title: "detalye" + headline: "magsimula na tayo" + enterprise: "una sa lahat ay kailangan naming mas makilala ang iyong enterprise:" + producer: "una sa lahat ay kailangan naming mas makilala ang iyong bukid:" + enterprise_name_field: "pangalan ng enterprise:" + producer_name_field: "pangalan ng bukid:" + producer_name_field_placeholder: "hal. Charlie's Awesome Farm" + producer_name_field_error: "pumili ng natatanging pangalan para sa inyong enterprise" + address1_field: "linya ng address 1 :" + address1_field_placeholder: "hal. 123 Cranberry Drive" + address1_field_error: "isulat ang address" + address2_field: "linya ng address 2 :" + suburb_field: "suburb:" + suburb_field_placeholder: "hal. Northcote" + suburb_field_error: "isulat ang suburb" + postcode_field: "Postcode:" + postcode_field_placeholder: "hal. 3070" + postcode_field_error: "kailangang ilagay ang postcode" + state_field: "State:" + state_field_error: "kailangang sagutan ang state" + country_field: "Bansa:" + country_field_error: "pumili ng bansa" + contact: + title: "makipag-ugnayan" + who_is_managing_enterprise: "sino ang responsable sa pamamahala ng%{enterprise}?" + contact_field: "Pangunahing contact" + contact_field_placeholder: "Contact name" + contact_field_required: "kailangang maglagay ng pangunahing contact" + phone_field: "telepono" + phone_field_placeholder: "hal. (03) 1234 5678" + type: + title: "uri" + headline: "huling hakbang para maidagdag ang%{enterprise}!" + question: "isa ka bang producer?" + yes_producer: "oo, ako ay isang producer" + no_producer: "hindi ako producer" + producer_field_error: "pumili ng isa. ikaw ba ay isang producer?" + yes_producer_help: "Ang mga producer ay gumagawa ng masasarap na bagay na maaaring makain o mainom. Ikaw ay isang producer kung itinatanim mo ito, pinapalaki, binuburo, niluluto, hinuhurno, ginagatasan o hinuhulma." + no_producer_help: "kung hindi ka isang producer, malamang ikaw ay nagbebenta at namamahagi ng mga pagkain. maaaring ikaw ay isang Hub, coop, grupo ng mamimili, nagtitingi, namamakyaw o iba pa." + create_profile: "gumawa ng profile" + about: + title: "tungkol sa" + headline: "binabati kita!" + message: "ngayon ay ilagay na natin ang mga detalye tungkol sa" + success: "tagumpay!%{enterprise}ay naidagdag na sa Open Food Network." + registration_exit_message: "kung ikaw ay lalabas sa wizard na ito sa kahit anong yugto, maaari kang magpatuloy sa paggawa ng profile sa pamamagitan ng pagpunta sa interface ng admin." + enterprise_description: "maikling paglalarawan" + enterprise_description_placeholder: "isang maikling pangungusap na naglalarawan ng iyong enterprise." + enterprise_long_desc: "mahabang paglalarawan" + enterprise_long_desc_placeholder: "ito ang inyong pagkakataon upang ipakilala ang iyong enterprise-kung ano ang kaibahan mo sa iba at paano ka nakahihigit? iminumungkahi namin na gumamit ng 600 na letra o mas mababa pa o 150 salita sa pagbibigay ng paglalarawan." + enterprise_long_desc_length: "%{num}na mga letra/ hanggang 600 ang iminumungkahi" + enterprise_abn: "ABN" + enterprise_abn_placeholder: "hal. 99 123 456 789" + enterprise_acn: "ACN" + enterprise_acn_placeholder: "hal. 123 456 789" + enterprise_tax_required: "kailangang gumawa ng pagpipilian." + images: + title: "larawan" + headline: "maraming salamat!" + description: "tayo na at mag-upload ng mga larawan upang maging maganda ang iyong profile! :-)" + uploading: "ina-upload...." + continue: "Magpatuloy" + back: "bumalik" + logo: + select_logo: "hakbang 1, pumili ng imahe ng Logo" + logo_tip: "Tip: pinakamaganda ang mga parisukat na imahe, mas mabuti kung ito ay 300x300px" + logo_label: "pumili ng imahe ng logo" + logo_drag: "hilahin at ilagay ang logo dito" + review_logo: "hakbang 2. suriin ang iyong logo" + review_logo_tip: "Tip: para sa mas maayos na resulta, ang logo ay dapat matakpan ang lahat ng espasyo" + logo_placeholder: "ang iyong logo ay makikita dito para masuri kapag na-upload na" + promo: + select_promo_image: "hakbang 3. pumili ng imahe ng promo" + promo_image_tip: "Tip: ipapakita bilang banner, ang mas mabuting laki ay 1200x260px" + promo_image_label: "pumil ng imahe ng promo" + promo_image_drag: "hilahin at ilagay ang promo dito" + review_promo_image: "hakbang 4. suriin ang iyong banner ng promo" + review_promo_image_tip: "Payo: para sa pinakamagandang resulta, ang iyong promo na imahe ay dapat masakop ang lahat ng espasyo" + promo_image_placeholder: "ang iyong logo ay makikita dito para masuri kapag na-upload na" + social: + title: "Social" + enterprise_final_step: "Huling hakbang!" + enterprise_social_text: "paano mahahanap ng mga tao ang%{enterprise}sa internet?" + website: "website" + website_placeholder: "hal. openfoodnetwork.org.au" + facebook: "Facebook" + facebook_placeholder: "hal. www.facebook.com/pangalanngpahina" + linkedin: "LinkedIn" + linkedin_placeholder: "hal. www.linkedin.com/YourNameHere" + twitter: "Twitter" + twitter_placeholder: "hal. @twitter_handle" + instagram: "Instagram" + instagram_placeholder: "hal. @instagram_handle" + limit_reached: + headline: "Oh Hindi!" + message: "Naabot mo na ang limit!" + text: "naabot mo na ang limit na dami ng mga enterprise na iyong pag-aari sa" + action: "bumalik sa homepage" + finished: + headline: "Tapos na!" + thanks: "maraming salamat sa pagbigay ng mga detalye para sa%{enterprise}." + login: "maaari mong palitan o i-update ang iyong enterprise sa pamamagitan ng paglog-in sa Open Food Network at puntahan ang Admin." + action: "pumunta sa dashboard ng Enterprise" + back: "bumalik" + continue: "Magpatuloy" + action_or: "O" + enterprise_limit: Limitasyon ng enterprise + shipping_method_destroy_error: "ang paraan ng pagpapadala ay hindi maaaring burahin sapagkat ito ay nakasangguni na sa isang order:%{number}." + fees: "mga bayarin" + item_cost: "halaga ng item" + bulk: "Bulto" + shop_variant_quantity_min: "pinakakaunti" + shop_variant_quantity_max: "pinakamarami" + follow: "sumunod" + shop_for_products_html: "mamili ng%{enterprise}na mga produkto sa:" + change_shop: "palitan ang shop ng:" + shop_at: "mamili ngayon sa:" + price_breakdown: "ibaba ang listahan ng presyo" + admin_fee: "bayad sa admin" + sales_fee: "bayad sa pagbebenta" + packing_fee: "bayad sa pagbabalot" + transport_fee: "bayad sa pagdadala" + fundraising_fee: "bayad sa pangangalap ng pondo" + price_graph: "graph ng presyo" + included_tax: "kasamang buwis" + balance: "Balanse" + transaction: "transaksyon" + transaction_date: "petsa" + payment_state: "katayuan ng bayad" + shipping_state: "katayuan ng pagpapadala" + value: "halaga" + balance_due: "balanseng kelangan bayaran" + credit: "utang" + Paid: "bayad na" + Ready: "handa" + ok: OK + not_visible: hindi nakikita + you_have_no_orders_yet: "wala ka pang mga order" + show_only_complete_orders: "ipakita lamang ang mga kumpletong order" + successfully_created: '%{resource}ay matagumpay na nagawa!' + successfully_removed: '%{resource}ay matagumpay na natanggal!' + successfully_updated: '%{resource}ay matagumpay na na-update' + running_balance: "tumatakbong balanse" + outstanding_balance: "natitirang balanse" + admin_enterprise_relationships: "mga permiso ng enterprise" + admin_enterprise_relationships_everything: "lahat" + admin_enterprise_relationships_permits: "mga permit" + admin_enterprise_relationships_seach_placeholder: "hanapin" + admin_enterprise_relationships_button_create: "gumawa" + admin_enterprise_groups: "mga grupo ng enterprise" + admin_enterprise_groups_name: "pangalan" + admin_enterprise_groups_owner: "may-ari" + admin_enterprise_groups_on_front_page: "sa harapang pahina?" + admin_enterprise_groups_enterprise: "enterprises" + admin_enterprise_groups_data_powertip: "ang pangunahing gumagamit na responsable sa grupo na ito" + admin_enterprise_groups_data_powertip_logo: "ito ang logo ng inyong grupo" + admin_enterprise_groups_data_powertip_promo_image: "ang imahe na ito ay makikita sa taas ng profile ng grupo" + admin_enterprise_groups_contact: "makipag-ugnayan" + admin_enterprise_groups_contact_phone_placeholder: "hal. 98 7654 3210" + admin_enterprise_groups_contact_address1_placeholder: "eg. 123 High Street" + admin_enterprise_groups_contact_city: "labas ng lungsod" + admin_enterprise_groups_contact_city_placeholder: "hal. Northcote" + admin_enterprise_groups_contact_zipcode: "Postcode" + admin_enterprise_groups_contact_zipcode_placeholder: "hal. 3070" + admin_enterprise_groups_contact_state_id: "kalagayan" + admin_enterprise_groups_contact_country_id: "Bansa" + admin_enterprise_groups_web: "mga pinagkukuhanan ng Web" + admin_enterprise_groups_web_twitter: "hal. @the_prof" + admin_enterprise_groups_web_website_placeholder: "hal. www.truffles.com" + admin_order_cycles: "mga order cycle ng Admin" + open: "bukas" + close: "isara" + create: "gumawa" + search: "hanapin" + supplier: "tagapagtustos" + product_name: "pangalan ng produkto" + product_description: "paglalarawan ng produkto" + units: "laki kada yunit" + coordinator: "coordinator" + distributor: "Distributor" + enterprise_fees: "bayad para sa enterprise" + process_my_order: "iproseso ang aking order" + delivery_instructions: mga panuto sa pagdeliver + delivery_method: paraan ng pagdeliver + fee_type: "uri ng kabayaran" + tax_category: "kategorya ng buwis" + calculator: "calculator" + calculator_values: "mga halaga sa calculator" + calculator_settings_warning: "kung papalitan ang uri ng calculator, dapat ay i-save muna bago maiayos ang setting ng calculator" + flat_percent_per_item: "Flat percent (kada item)" + flat_rate_per_item: "Flat Rate (kada item)" + flat_rate_per_order: "Flat rate (kada order)" + flexible_rate: "nababagong rate" + price_sack: "Price Sack" + new_order_cycles: "bagong mga order cycle" + new_order_cycle: "bagong order cycle" + select_a_coordinator_for_your_order_cycle: "pumili ng coordinator para sa iyong order cycle" + notify_producers: 'ipagbigay-alam sa mga producer' + edit_order_cycle: "i-edit ang order cycle" + roles: "mga tungkulin" + update: "i-update" + delete: tanggalin + add_producer_property: "magdagdag ng pag-aari ng producer" + in_progress: "nasa proseso" + started_at: "nagsimula sa" + queued: "nakapila" + scheduled_for: "naka-iskedyul para sa" + customers: "mga customer" + please_select_hub: "pumili ng Hub" + loading_customers: "naglo-load ng mga Customer" + no_customers_found: "walang nahanap ng mga customer" + go: "Sige" + hub: "Hub" + producer: "Prodyuser" + product: "produkto" + price: "presyo" + on_hand: "on hand" + review: "suriin" + save_changes: "i-save ang mga pagbabago" + order_saved: "ang order ay na-save na" + no_products: walang mga produkto + spree_admin_overview_enterprises_header: "ang aking mga enterprise" + spree_admin_overview_enterprises_footer: "PAMAHALAAN ANG AKING MGA ENTERPRISE" + spree_admin_enterprises_hubs_name: "pangalan" + spree_admin_enterprises_create_new: "GUMAWA NG BAGO" + spree_admin_enterprises_shipping_methods: "mga paraan ng pagpapadala" + spree_admin_enterprises_fees: "bayad para sa enterprise" + spree_admin_enterprises_none_create_a_new_enterprise: "GUMAWA NG BAGONG ENTERPRISE" + spree_admin_enterprises_none_text: "wala ka pang mga enterprise" + spree_admin_enterprises_tabs_hubs: "MGA HUB" + spree_admin_enterprises_producers_manage_products: "PAMAHALAAN ANG MGA PRODUKTO" + spree_admin_enterprises_create_new_product: "GUMAWA NG BAGONG PRODUKTO" + spree_admin_single_enterprise_alert_mail_confirmation: "kumpirmahin ang email address para sa/kay" + spree_admin_single_enterprise_alert_mail_sent: "naipadala na ang email sa" + spree_admin_overview_action_required: "kinakailangan ng aksyon" + spree_admin_overview_check_your_inbox: "tignan ang iyong inbox para sa karagdagang panuto. maraming salamat!" + spree_admin_unit_value: halaga kada yunit + spree_admin_unit_description: paglalarawan sa bawat yunit + spree_admin_variant_unit: Variant unit + spree_admin_variant_unit_scale: sukat ng Variant unit + spree_admin_supplier: tagapagtustos + spree_admin_product_category: kategorya ng produkto + spree_admin_variant_unit_name: pangalan ng variant unit + unit_name: "pangalan ng yunit" + change_package: "palitan ang package" + spree_admin_single_enterprise_hint: "payo: para mahanap ka ng mga tao, i-turn on ang visibility sa ilalim ng" + spree_admin_eg_pickup_from_school: "hal. 'Pick-up from Primary School'" + spree_admin_eg_collect_your_order: "hal. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" + spree_classification_primary_taxon_error: "ang Taxon%{taxon}ay ang pangunahing taxon ng %{product}at hindi maaaring tanggalin" + spree_order_availability_error: "ang tagapamahagi o ang order cycle ay hindi kayang ibigay ang mga produkto sa inyong cart" + spree_order_populator_error: "ang tagapamahagi o order cycle na iyan ay hindi kayang ibigay lahat ng mga produkto sa inyong cart. pumili ng isa pa." + spree_order_populator_availability_error: "ang produktong iyan ay hindi ngayon available mula sa napiling tagapamahagi o order cycle." + spree_distributors_error: "pumili ng kahit isa sa mga Hub" + spree_user_enterprise_limit_error: "^%{email}ay walang permiso na mag-ari ng karagdagang mga enterprise (ang limitasyon ay%{enterprise_limit})." + spree_variant_product_error: ay dapat mayroong kahit isang uri + your_profil_live: "ang iyong live na profile" + on_ofn_map: "sa Open Food Network map" + see: "Tignan" + live: "live" + manage: "pamahalaan" + resend: "ipadala muli" + add_and_manage_products: "magdagdag at pamahalaan ang mga produkto" + add_and_manage_order_cycles: "magdagdag at pamahalaan ang mga order cycle" + manage_order_cycles: "pamahalaan ang mga order cycle" + manage_products: "pamahalaan ang mga produkto" + edit_profile_details: "ayusin ang mga detalye ng profile" + edit_profile_details_etc: "palitan ang paglalarawan, imahe at iba pa ng iyong profile" + order_cycle: "order cycle" + order_cycles: "order cycles" + enterprise_relationships: "mga permiso ng enterprise" + remove_tax: "alisin ang tax" + first_name_begins_with: "ang pangalan ay nagsisimula sa" + last_name_begins_with: "ang apelyido ay nagsisimula sa" + enterprise_tos_link: "Link para sa palatuntunan ng serbisyo ng Enterprise" + enterprise_tos_message: "nais naming makiisa sa mga taong kapareho ng aming layunin at adhikain. Dahil dito, hinihiling namin sa mga bagong enterprise na sumang-ayon sa aming" + enterprise_tos_link_text: "Palatuntunan ng serbisyo." + enterprise_tos_agree: "ako ay sumasang-ayon sa palatuntunan ng serbisyo na nasa itaas." + tax_settings: "settings ng buwis" + products_require_tax_category: "ang mga produkto ay kailangang may kategorya ng buwis" + admin_shared_address_1: "tirahan" + admin_shared_address_2: "address (pagpapatuloy)" + admin_share_city: "Lungsod" + admin_share_zipcode: "Postcode" + admin_share_country: "Bansa" + admin_share_state: "kalagayan" + hub_sidebar_hubs: "Hubs" + hub_sidebar_none_available: "walang available" + hub_sidebar_manage: "pamahalaan" + hub_sidebar_at_least: "pumili ng kahit isa sa mga Hub" + hub_sidebar_blue: "bughaw" + hub_sidebar_red: "pula" + report_customers_distributor: "Distributor" + report_customers_supplier: "tagapagtustos" + report_customers_cycle: "order cycle" + report_customers_type: "uri ng ulat" + report_customers_csv: "i-download bilang csv" + report_producers: "mga producer:" + report_type: "uri ng ulat:" + report_hubs: "mga Hub:" + report_payment: "mga uri ng pagbabayad:" + report_distributor: "tagapamahagi:" + report_payment_by: 'pagbabayad kada uri' + report_itemised_payment: 'kabuuan ng mga in-itemise na bayad' + report_payment_totals: 'kabuuan ng bayad' + report_all: 'lahat' + report_order_cycle: "Order Cycle:" + report_enterprises: "mga Enterprise:" + report_users: "mga gumagamit:" + report_tax_rates: mga rate ng buwis + report_tax_types: mga uri ng buwis + report_header_order_cycle: order cycle + report_header_user: User + report_header_email: email + report_header_status: katayuan + report_header_comments: mga puna + report_header_first_name: Pangalan + report_header_last_name: Apelyido + report_header_phone: telepono + report_header_suburb: labas ng lungsod + report_header_address: tirahan + report_header_billing_address: Billing Address + report_header_relationship: relasyon + report_header_hub: Hub + report_header_hub_address: address ng Hub + report_header_to_hub: sa Hub + report_header_hub_code: code ng Hub + report_header_code: Code + report_header_paid: bayad na? + report_header_delivery: dini-deliver? + report_header_shipping: pagpapadala + report_header_shipping_method: paraan ng pagpapadala + report_header_shipping_instructions: panuto sa pagpapadala + report_header_ship_street: kalsada na pagpapadalahan + report_header_ship_street_2: kalsada na pagpapadalahan 2 + report_header_ship_city: lungsod na pagpapadalahan + report_header_ship_postcode: postcode ng pagpapadalahan + report_header_ship_state: estado ng pagpapadalahan + report_header_billing_street: address na papadalahan ng bayarin + report_header_billing_street_2: address na papadalahan ng bayarin 2 + report_header_billing_street_3: address na papadalahan ng bayarin 3 + report_header_billing_street_4: address na papadalahan ng bayarin 4 + report_header_billing_city: lungsod na papadalahan ng bayarin + report_header_billing_postcode: postcode ng papadalahan ng bayarin + report_header_billing_state: estado ng papadalahan ng bayarin + report_header_incoming_transport: papasok na sasakyan + report_header_special_instructions: espesyal na mga panuto + report_header_order_number: numero ng order + report_header_date: petsa + report_header_confirmation_date: petsa ng kumpirmasyon + report_header_tags: tags + report_header_items: mga item + report_header_items_total: "kabuuan ng mga item%{currency_symbol}" + report_header_taxable_items_total: "kabuuan ng mga item na binubuwisan (%{currency_symbol})" + report_header_sales_tax: "buwis sa mga nabenta (%{currency_symbol})" + report_header_delivery_charge: "bayad sa pag-deliver(%{currency_symbol})" + report_header_tax_on_delivery: "buwis sa pagdeliver (%{currency_symbol})" + report_header_tax_on_fees: "buwis sa mga bayarin (%{currency_symbol})" + report_header_total_tax: "kabuuang buwis(%{currency_symbol})" + report_header_enterprise: Enterprise + report_header_customer: customer + report_header_customer_code: Code ng Customer + report_header_product: produkto + report_header_product_properties: mga katangian ng produkto + report_header_quantity: dami + report_header_max_quantity: Pinakamarami + report_header_variant: Uri + report_header_variant_value: Halaga ng Variant + report_header_variant_unit: Yunit ng variant + report_header_total_available: Kabuuan na mayroon + report_header_unallocated: hindi pinapamahalaan + report_header_max_quantity_excess: Sumobra sa limit na pinakamarami + report_header_taxons: Taxons + report_header_supplier: tagapagtustos + report_header_producer: Prodyuser + report_header_producer_suburb: Suburb ng Producer + report_header_unit: yunit + report_header_group_buy_unit_quantity: Dami ng yunit para sa Maramihang pagbili + report_header_cost: gastos + report_header_shipping_cost: gastos sa pagpapadala + report_header_curr_cost_per_unit: kasalukuyang gastos kada yunit + report_header_total_shipping_cost: 'kabuuang gastos sa pagpapadala ' + report_header_payment_method: paraan ng pagbayad + report_header_sells: nagbebenta + report_header_visible: nakikita + report_header_price: presyo + report_header_unit_size: laki kada yunit + report_header_distributor: Distributor + report_header_distributor_address: Address ng Distributor + report_header_distributor_city: Lungsod ng Distributor + report_header_distributor_postcode: Postcode ng Distributor + report_header_delivery_address: address kung saan ide-deliver + report_header_delivery_postcode: postcode kung saan ide-deliver + report_header_bulk_unit_size: laki ng bawat bultuhang yunit + report_header_weight: timbang + report_header_sum_total: Kabuuan + report_header_date_of_order: Petsa ng Order + report_header_amount_owing: halaga ng utang + report_header_amount_paid: Halagang Nabayaran + report_header_units_required: mga kailangang yunit + report_header_remainder: Natitira + report_header_order_date: Petsa ng order + report_header_order_id: Order Id + report_header_item_name: Pangalan ng Item + report_header_temp_controlled_items: Temp ng mga kontroladong mga item? + report_header_customer_name: Pangalan ng Customer + report_header_customer_email: Email ng Customer + report_header_customer_phone: Telepono ng Customer + report_header_customer_city: Lungsod ng Customer + report_header_payment_state: estado ng pagbabayad + report_header_payment_type: uri ng pagbabayad + report_header_item_price: "item(%{currency})" + report_header_item_fees_price: "item + bayad (%{currency})" + report_header_admin_handling_fees: "Admin at paghawak (%{currency})" + report_header_ship_price: "pagdala (%{currency})" + report_header_pay_fee_price: "Bayad sa pagbabayad (%{currency})" + report_header_total_price: "Kabuuan (%{currency})" + report_header_product_total_price: "Kabuuang Produkto (%{currency})" + report_header_shipping_total_price: "kabuuang pagpapadala (%{currency})" + report_header_outstanding_balance_price: "Kasalukuyang balanse (%{currency})" + report_header_eft_price: "EFT (%{currency})" + report_header_paypal_price: "Paypal (%{currency})" + report_header_sku: SKU + report_header_amount: halaga + report_header_balance: Balanse + report_header_total_cost: "Kabuuang Gastos" + report_header_total_ordered: Kabuuang na-order + report_header_total_max: kabuuang pinakamataas na limit + report_header_total_units: kabuuang yunit + report_header_sum_max_total: "kabuuan" + report_header_total_excl_vat: "Kabuuang buwis na hindi kasama (%{currency_symbol})" + report_header_total_incl_vat: "Kabuuang buwis na kasama (%{currency_symbol})" + report_header_temp_controlled: TempControlled? + report_header_is_producer: Producer? + report_header_not_confirmed: hindi kumpirmado + report_header_gst_on_income: GST sa Kinikita + report_header_gst_free_income: GST sa Libreng Kinikita + report_header_total_untaxable_produce: kabuuang produkto na hindi binubuwisan (walang buwis) + report_header_total_taxable_produce: kabuuang produkto na binubuwisan (may kasamang buwis) + report_header_total_untaxable_fees: kabuuang bayarin na hindi binubuwisan (walang buwis) + report_header_total_taxable_fees: kabuuang bayarin na binubuwisan (may kasamang buwis) + report_header_delivery_shipping_cost: Singil sa pagdeliver ng pinapadala (kasama ang buwis) + report_header_transaction_fee: Bayad sa Transaksyon (walang buwis) + report_header_total_untaxable_admin: kabuuang hindi binubuwisang pagsasaayos ng admin (walang tax) + report_header_total_taxable_admin: kabuuang hindi binubuwisang pagsasaayos ng admin (kasama ang tax) + initial_invoice_number: "paunang numero ng invoice:" + invoice_date: "Petsa ng Invoice:" + due_date: "Due Date:" + account_code: "code ng Account:" + equals: "katumbas" + contains: "naglalaman" + discount: "Diskwento" + filter_products: "i-filter ang mga produkto" + delete_product_variant: "ang huling mga variant ay hindi matanggal!" + progress: "progreso" + saving: "sine-save.." + success: "tagumpay" + failure: "pagkabigo" + unsaved_changes_confirmation: "ang mga hindi na-save na pagbabago ay mawawala. magpatuloy pa rin?" + one_product_unsaved: "ang mga pagbabagong ginawa sa isang produkto ay hindi pa nase-save." + products_unsaved: "ang mga pagbabagong ginawa sa%{n} produkto ay hindi pa nase-save." + is_already_manager: "ay isa nang tagapamahala" + no_change_to_save: "walang pagbabagong ise-save" + user_invited: "%{email}ay naimbitahan na para pamahalaan ang enterprise na ito." + add_manager: "magdagdag ng gumagamit" + users: "mga gumagamit" + about: "tungkol sa" + images: "larawan" + web: "Web" + primary_details: "pangunahing detalye" + adrdress: "tirahan" + contact: "makipag-ugnayan" + social: "Social" + business_details: "detalye ng negosyo" + properties: "mga katangian" + shipping: "pagpapadala" + shipping_methods: "mga paraan ng pagpapadala" + payment_methods: "Mga Paraan ng Pagbabayad" + payment_method_fee: "bayad sa transaksyon" + payment_processing_failed: "hindi maproseso ang bayad, maaaring suriin ang mga detalyeng inilagay" + payment_method_not_supported: "ang piniling paraan ng pagbabayad ay hindi suportado. pumili ng isa pa" + payment_updated: "na-update na ang bayad" + inventory_settings: "mga setting para sa imbentaryo" + tag_rules: "panuntunan sa pag-tag" + shop_preferences: "mga kagustuhan sa shop" + enterprise_fee_whole_order: Buong order + enterprise_fee_by: "%{type}na bayad ng%{role}%{enterprise_name}" + validation_msg_relationship_already_established: "^ang relasyon ay naitatag na" + validation_msg_at_least_one_hub: "^kailangang kahit isang Hub ay piliin" + validation_msg_tax_category_cant_be_blank: "^ang kategorya ng buwis ay hindi maaaring walang sagot" + validation_msg_is_associated_with_an_exising_customer: "ay nauugnay na sa isang customer" + content_configuration_pricing_table: "(DAPATGAWIN: TALAAN NG PRESYO)" + content_configuration_case_studies: "(DAPATGAWIN: mga pag-aaral ng kaso)" + content_configuration_detail: "(DAPATGAWIN: detalye)" + enterprise_name_error: "ay nagamit na. kung ito ay iyong enterprise at nais mong kunin ang pagmaymay-ari, o kung nais mong makipagkalakalan sa enterprise na ito, makipag-ugnayan sa kasalukuyang tagapamahala ng profile na ito sa %{email}." + enterprise_owner_error: "^%{email}ay walang permiso na mag-ari ng karagdagang mga enterprise (ang limitasyon ay%{enterprise_limit})." + enterprise_role_uniqueness_error: "^ang tungkulin na iyon ay may nagmamay-ari na" + inventory_item_visibility_error: ay dapat totoo o hindi totoo + product_importer_file_error: "error: walang file na na-upload" + product_importer_spreadsheet_error: "hindi maproseso ang file: invalid na uri ng file" + product_importer_products_save_error: hindi matagumpay na na-save ang mga produkto + product_import_file_not_found_notice: 'ang file ay hindi mahanap o mabuksan ' + product_import_no_data_in_spreadsheet_notice: 'walang data na mahanap sa spreadsheet' + order_choosing_hub_notice: ang iyong Hub ay napili + order_cycle_selecting_notice: ang iyong order cycle ay napili + adjustments_tax_rate_error: "^siguraduhing ang rate ng buwis para sa adjustment na ito ay tama." + active_distributors_not_ready_for_checkout_message_singular: >- + ang Hub na%{distributor_names}ay kasamang nakalista sa isang aktibong order + cyle ngunit walang valid na shipping at payment method. Hanggang hindi pa naisasaayos + ang pagset-up, hindi makakapamili ang mga customer sa hub na ito. + active_distributors_not_ready_for_checkout_message_plural: >- + ang mga Hub na %{distributor_names}ay kasamang nakalista sa isang aktibong order + cycle ngunit walang valid na shipping at payment method. Hanggang hindi pa naisasaayos + ang pagset-up, hindi makakapamili ang mga customer sa mga hub na ito. + enterprise_fees_update_notice: ang mga bayarin ng inyong enterprise ay na-update na + enterprise_register_package_error: "pumili ng package" + enterprise_register_error: "hindi makumpleto ang rehistrasyon para sa%{enterprise}" + enterprise_register_success_notice: "maligayang pagbati! ang rehistrasyon para sa%{enterprise}ay kumpleto na!" + enterprise_bulk_update_success_notice: "ang mga enterprise ay matagumpay na na-update" + enterprise_bulk_update_error: 'hindi matagumpay ang pag-update' + enterprise_shop_show_error: "ang shop na hinahanap mo ay wala o hindi aktibo sa OFN. Maaaring tignan ang ibang shops." + order_cycles_create_notice: 'ang iyong order cycle ay nagawa na.' + order_cycles_update_notice: 'ang iyong order cycle ay na-update na' + order_cycles_bulk_update_notice: 'ang mga order cycle ay na-update na' + order_cycles_clone_notice: "ang iyong order cyle %{name}ay kinopya." + order_cycles_email_to_producers_notice: 'ang mga email na ipapadala sa mga producer ay naghihintay na maipadala.' + order_cycles_no_permission_to_coordinate_error: "wala sa inyong mga enterprise ay may pahintulot na magsa-ayos ng order cycle" + order_cycles_no_permission_to_create_error: "wala kang pahintulot na gumawa ng order cycle na isinaayos ng enterprise na iyon." + back_to_orders_list: "bumalik sa listahan ng order" + no_orders_found: "walang mahanap na mga order" + order_information: "impormasyon tungkol sa order" + date_completed: "petsa kung kailan na kumpleto" + amount: "halaga" + state_names: + ready: handa + pending: nakabinbin + shipped: na-ship na + js: + saving: 'sine-save...' + changes_saved: 'nai-save ang mga pagbabago' + save_changes_first: i-save muna ang mga pagbabago + all_changes_saved: lahat ng pagbabago ay na-save na + unsaved_changes: may mga hindi na-save na pagbabago + all_changes_saved_successfully: lahat ng pagbabago ay matagumpay na na-save + oh_no: "paumanin! hindi ko na-save ang mga pagbabagong ginawa mo." + unauthorized: "ikaw ay hindi awtorisadong i-access ang pahina na ito." + error: pagkakamali + unavailable: hindi available + profile: profile + hub: Hub + shop: Shop + choose: pumili + resolve_errors: paki-ayos ang mga sumusunod na pagkakamali + more_items: "+%{count}iba pa" + default_card_updated: na-update ang card + admin: + enterprise_limit_reached: "naabot mo na ang karaniwang lmitasyon ng dami ng bilang ng mga enterprise sa bawat account. makipag-ugnayan sa%{contact_email}kung kailangan mo itong dagdagan." + modals: + got_it: nakuha na + close: "isara" + invite: "mag-imbita" + invite_title: "mag-imbita ng hindi rehistradong user" + tag_rule_help: + title: panuntunan sa pag-tag + overview: pangkalahatang ideya + overview_text: > + ang panuntunan sa tag na nagbibigay ng paraan upang maisalarawan kung + anong mga item ang nakikita at kung sa kaninong mga customer dapat ito + maipakita. Ang mga item ay maaaring paraan ng pagpapadala, paraang ng + pagbabayad, mga produkto at mga order cycle. + by_default_rules: "'By Default...' mga tuntunin" + by_default_rules_text: > + ang orihinal na mga tuntunin ay papayagan ka na magtago ng mga item + para hindi ito makita. ang gawaing ito ay maaaring saklawan ng ibang + tuntunin para sa mga customer na may tag. + customer_tagged_rules: "'Mga Customer na naka-tag...' mga tuntunin" + customer_tagged_rules_text: > + sa pamamagitan ng paggawa ng mga tuntunin na may kinalaman sa isang + partikular na customer na naka-tag, maaari mong saklawan ang kinagawiang + gawain(sa pagpapakita man o pagtago ng mga item) para sa mga customer + na may tag. + panels: + save: I-SAVE + saved: NA-SAVE NA + saving: SINESAVE + enterprise_package: + hub_profile: profile ng hub + hub_profile_cost: "HALAGANG BABAYARAN: PALAGING LIBRE" + hub_profile_text1: > + Maaari kayong mahanap at makausap ng mga tao sa Open Food Network. ang + inyong enterprise ay makikita sa mapa at maaaring ma-search sa listahan. + hub_profile_text2: > + ang pagkakaroon ng profile at paggawa ng koneksyon sa mga lokal na sistema + ng pagkain gamit ang Open Food Network ay palaging walang bayad. + hub_shop: Hub Shop + hub_shop_text1: > + ang iyong enterprise ang saligan ng iyong lokal na sistema ng pagkain. + pinagsasama sama mo ang mga produkto mula sa ibang mga enterprise at + maaari mo itong ibenta sa pamamagitang ng iyong shop sa Open Food Network. + hub_shop_text2: > + ang mga hub ay maaring co-op ng pagkain, grupo ng mamimili, isang programang + veggie-box o isang lokal na grocery store. + hub_shop_text3: > + kung nais mo ring ibenta ang inyong sariling mga produkto, kailangang + palitan ang enterprise na ito upang maging producer. + choose_package: Pumili ng package + choose_package_text1: > + ang inyong enterprise ay hindi maa-activate hanggang hindi pumipili + ng package mula sa pagpipilian sa kaliwa + choose_package_text2: > + Pumindot sa kahit anong pagpipilian para makita ang detalyadong impormasyon + tungkol sa bawat package. Pindutin ang pulang SAVE na button kapag tapos + na! + profile_only: Profile lamang + profile_only_cost: "HALAGANG BABAYARAN: PALAGING LIBRE" + profile_only_text1: > + maaari kang makita at makausap ng iba sa pamamagitan ng profile at paraan + din ito upang maisalaysay ang inyong kwento. + profile_only_text2: > + kung mas nais mong magpokus sa paggawa ng pagkain at ipaubaya sa iba + ang pagbebenta nito, hindi kailangan ang shop sa Open Food Network. + profile_only_text3: > + idagdag ang inyong produkto sa Open Food Network, upang mabigyan ng + permiso ang mga hub na ilagay ang inyong produkto sa kanilang mga tindahan. + producer_shop: Producer Shop + producer_shop_text1: > + Direktang ibenta ang inyong produkto sa mga customer sa pamamagitan + ng iyong sariling Open Food Network shopfront. + producer_shop_text2: > + ang shop ng Producer ay para lamang sa iyong mga produkto, kung nais + mong magtinda ng mga produkto na itinanim/ginawa sa labas ng site, piliin + ang 'Hub ng producer'. + producer_hub: Producer Hub + producer_hub_text1: > + ang iyong enterprise ang saligan ng iyong lokal na sistema ng pagkain. + maaari mong ibenta ang sarili mong produkto pati na rin ang mga produktong + pinagsama sama mula sa ibang enterprise sa pamamagitan ng iyong shopfront + sa Open Food Network. + producer_hub_text2: > + ang mga hub ng producer ay maaring may iba't ibang anyo tulad ng CSA, + isang programang veggie-box o isang co-op ng pagkain na may hardin sa + rooftop. + producer_hub_text3: > + ang layunin ng Open Food Network ay sumuporta sa mga modelo ng hub gaano + man ito karami, kaya ano man ang inyong sitwasyon, nais naming ibigay + ang lahat ng inyong kakailanganin para mapatakbo ng maayos ang inyong + organisasyon o lokal na negosyo ng pagkain. + get_listing: kumuha ng listahan + always_free: PALAGING LIBRE + sell_produce_others: magbenta ng produkto mula sa iba + sell_own_produce: magbenta ng sariling produkto + sell_both: magbenta ng produkto mula sa sarili at sa iba + enterprise_producer: + producer: Prodyuser + producer_text1: > + Ang mga producer ay gumagawa ng masasarap na bagay na maaaring makain + o mainom. Ikaw ay isang producer kung itinatanim mo ito, pinapalaki, + binuburo, niluluto, hinuhurno, ginagatasan o hinuhulma. + producer_text2: > + ang mga producer ay maaari ring gawin ang ibang tungkulin tulad ng pagsasama-sama + ng pagkain mula sa ibang mga enterprise at pagbebenta nito sa isang + shop sa Open Food Network. + non_producer: Hindi producer + non_producer_text1: > + ang mga hindi producer ay hindi gumagawa ng sarili nilang pagkain, nangangahulgang + wala silang kakayahang gumawa ng sariling mga produkto na maibebenta + sa Open Food Network. + non_producer_text2: > + sa halip, ang mga hindi producer ay dalubhasa sa pag-uugnay ng mga + producer sa mga mamili, maaaring sa pamamagitan ng pagsasama sama, pagmamarka, + pagbabalot, pagbebenta o pagde-deliver ng pagkain. + producer_desc: mga gumagawa ng pagkain + producer_example: hal. NAGPAPATUBO, PANADERO, MANGANGALAKAL, YUMAYARI + non_producer_desc: Iba pang mga enterprise ng pagkain + non_producer_example: hal. Grocery, Food co-ops, Buying groups + enterprise_status: + status_title: "%{name}ay naset-up na at maaari na gamitin!" + severity: kalubhaan + description: paglalarawan + resolve: lutasin + exchange_products: + load_more_variants: "mag-load ng iba pang uri" + load_all_variants: "i-load ang lahat ng uri" + select_all_variants: "piliin lahat%{total_number_of_variants}Variants" + variants_loaded: "%{num_of_variants_loaded}ng%{total_number_of_variants}Variants ay na-load" + loading_variants: "nilo-load ang Variants" + tag_rules: + shipping_method_tagged_top: "naka-tag ng mga paraan ng pagpapadala" + shipping_method_tagged_bottom: "ay:" + payment_method_tagged_top: "naka-tag na paraan ng pagbabayad" + payment_method_tagged_bottom: "ay:" + order_cycle_tagged_top: "naka-tag na mga Order Cycle" + order_cycle_tagged_bottom: "ay:" + inventory_tagged_top: "nakatag- na mga uri ng imbentaryo" + inventory_tagged_bottom: "ay:" + new_tag_rule_dialog: + select_rule_type: "pumili ng uri ng panuntunan:" + add_rule: "magdagdag ng panuntunan" + enterprise_fees: + inherit_from_product: "gayahin mula sa produkto" + orders: + index: + per_page: "%{results}kada pahina" + view_file: "tignan ang file" + compiling_invoices: "tipunin ang mga invoice" + bulk_invoice_created: "nagawa ang maramihang invoice" + bulk_invoice_failed: "hindi nagtagumpay na gumawa ng maramihang invoice" + please_wait: "hintayin na maihanda ang PDF bago isara ang modal na ito." + order_state: + address: "tirahan" + adjustments: "mga pagsasaayos" + awaiting_return: "naghihintay ng pagbalik" + canceled: "na-cancel" + cart: "cart" + complete: "kumpleto" + confirm: "kumpirmahin" + delivery: "pagdeliver" + paused: "nakahinto" + payment: "pagbabayad" + pending: "nakabinbin" + resumed: "nagpatuloy" + returned: "binalik" + skrill: "Skrill" + shipment_states: + backorder: "backorder" + partial: "bahagi" + pending: "nakabinbin" + ready: "handa na" + shipped: "nai-ship na" + canceled: "na-cancel" + payment_states: + balance_due: "balanse" + completed: "nakumpleto na" + checkout: "checkout" + credit_owed: "Utang na Credit" + failed: "hindi nagtagumpay" + paid: "bayad na" + pending: "nakabinbin" + processing: "pinoproseso" + void: "walang bisa" + invalid: "invalid" + resend_user_email_confirmation: + resend: "ipadala muli" + sending: "ipadala muli..." + done: "tapos na ipadala muli ✓" + failed: "hindi matagumpay ang muling pagpapadala ✗" + order_cycles: + schedules: + adding_a_new_schedule: "Pagdadagdag ng Bagong Iskedyul" + updating_a_schedule: "pag-update sa iskedyul" + create_schedule: "Gumawa ng iskedyul" + update_schedule: "i-update ang iskedyul" + delete_schedule: "burahin ang iskedyul" + schedule_name_placeholder: "pangalan ng iskedyul" + created_schedule: "nakagawa ng iskedyul" + updated_schedule: "na-update na iskedyul" + deleted_schedule: "binurang iskedyul" + name_required_error: "Maglagay ng name para sa iskedyul na ito" + no_order_cycles_error: "pumili kahit isang order cycle (i-drag at i-drop)" + available: "Available" + selected: "napili" + customers: + index: + add_customer: "magdagdag ng Customer" + add_a_new_customer_for: "magdadag ng customer para sa%{shop_name}" + customer_placeholder: "customer@example.org" + valid_email_error: "maglagay ng valid na email address" + subscriptions: + error_saving: "error sa pag-save ng subscription" + new: + please_select_a_shop: "Pumili ng shop" + insufficient_stock: "Hindi sapat ang stock, mayroon na lamang%{on_hand} na natitira" + out_of_stock: + reduced_stock_available: binawasan ang stock na magagamit + out_of_stock_text: > + habang ikaw ay namimili, ang lebel ng stock para sa isa o higit pang mga + produkto sa inyong cart ay nabawasan. ito ang nagbago: + now_out_of_stock: ay out of stock na ngayon + only_n_remainging: "ngayon ay may%{num}na natitira" + variants: + on_demand: + 'yes': "on demand" + variant_overrides: + on_demand: + use_producer_settings: "gamitin ang setting ng producer stock" + 'yes': "oo" + 'no': "hindi" + inventory_products: "mga produktong naka-imbentaryo" + hidden_products: "mga nakatagong pprodukto" + new_products: "bagong produkto" + reset_stock_levels: i-reset ang lebel ng stock sa orihinal + changes_to: mga pagbabago sa + one_override: isang override + overrides: mga override + remain_unsaved: nananatiling hindi naka-save. + no_changes_to_save: walang pagbabago na ise-save + no_authorisation: "hindi ko makuha ang awtorisasyon para i-save ang mga pagbabago kaya mananatili ang mga ito na hindi naka-save." + some_trouble: "nagkaroon ako ng problema sa pagse-save: %{errors}" + changing_on_hand_stock: pagbabago sa lebel ng hand stock + stock_reset: ni-reset sa orihinal ang mga stock + tag_rules: + show_hide_variants: 'ipakita o itago ang mga variant sa aking Shopfront' + show_hide_shipping: 'ipakita o itago ang mga paraan ng pagpapadala sa checkout' + show_hide_payment: 'ipakita o itago ang mga paraan ng pagbabayad sa checkout' + show_hide_order_cycles: 'ipakita o itago ang mga order cycle sa aking shopfront' + visible: NAKIKITA + not_visible: HINDI NAKIKITA + services: + unsaved_changes_message: may mga hindi pa nase-save na pagbabago, i-save na ngayon o balewalain? + save: I-SAVE + ignore: HUWAG PANSININ + add_to_order_cycle: "idagdag sa order cycle" + manage_products: "pamahalaan ang mga produkto" + edit_profile: "i-edit ang profile" + add_products_to_inventory: "magdagdag ng mga produkto sa imbentaryo" + resources: + could_not_delete_customer: 'hindi matanggal ang customer' + product_import: + confirmation: | + ise-set nito ang lebel ng stock sa zero para sa lahat ng mga produkto para dito + enterprise na hindi makikita sa inupload na file. + order_cycles: + create_failure: "hindi nagtagumpay sa paggawa ng order cycle" + update_success: 'ang iyong order cycle ay na-update na' + update_failure: "hindi nagtagumpay sa pag-update ng order cycle" + no_distributors: walang distributor sa order cycle na ito. ang order cycle ay hindi makikita ng mga customer hanggang hindi kayo naglalagay ng distributor. Nais mo bang magpatuloy i-save ang order cycle? + enterprises: + producer: "Prodyuser" + non_producer: "hindi producer" + customers: + select_shop: 'pumili muna ng shop' + could_not_create: hindi makagawa + subscriptions: + closes: nagsasara + closed: sarado + close_date_not_set: hindi pa nai-set ang close date + spree: + users: + order: "order" + registration: + welcome_to_ofn: "Welcome sa Open Food Network!" + signup_or_login: "magsimula sa pamamagitan ng pag-sign-up (o pag-log-in)" + have_an_account: "Mayroon ka na bang account?" + action_login: "Maglog-in na ngayon." + inflections: + each: + one: "bawat" + other: "bawat" + bunch: + one: "kumpol" + other: "mga kumpol" + pack: + one: "balot" + other: "mga balot" + box: + one: "mga bote" + other: "mga karton" + bottle: + one: "mga bote" + other: "mga bote" + jar: + one: "mga garapon" + other: "mga garapon" + head: + one: "ulo" + other: "mga ulo" + bag: + one: "supot" + other: "mga supot" + loaf: + one: "tinapay" + other: "mga tinapay" + single: + one: "isahan" + other: "mga isahan" + tub: + one: "batya" + other: "mga batya" + punnet: + one: "punnet" + other: "mga punnet" + packet: + one: "pakete" + other: "mga pakete" + item: + one: "item" + other: "mga item" + dozen: + one: "dosena" + other: "mga dosena" + unit: + one: "yunit" + other: "mga yunit" + serve: + one: "serve" + other: "mga serve" + tray: + one: "tray" + other: "mga tray" + piece: + one: "piraso" + other: "mga piraso" + pot: + one: "paso" + other: "mga paso" + bundle: + one: "bigkis" + other: "mga bigkis" + flask: + one: "prasko" + other: "mga prasko" + basket: + one: "basket" + other: "mga basket" + sack: + one: "sako" + other: "mga sako" + producers: + signup: + start_free_profile: "Magsimula sa libreng profile at palawakin kapag handa ka na!" + order_management: + reports: + enterprise_fee_summary: + date_end_before_start_error: "ay dapat pagkatapos magsimula" + parameter_not_allowed_error: "ikaw ay hindi awtorisadong gumamit ng isa o higit pa na mga filter para sa ulat na ito." + fee_calculated_on_transfer_through_all: "lahat" + fee_calculated_on_transfer_through_entire_orders: "ang buong order sa pamamagitan ng%{distributor}" + tax_category_various: "iba iba" + fee_type: + payment_method: "transaksyon ng bayad" + shipping_method: "kargamento" + fee_placements: + supplier: "papasok" + distributor: "papalabas" + coordinator: "coordinator" + tax_category_name: + shipping_instance_rate: "rate ng platform" + formats: + csv: + header: + fee_type: "uri ng kabayaran" + enterprise_name: "may-ari ng enterprise" + fee_name: "pangalan ng bayarin" + customer_name: "customer" + fee_placement: "paglilipat ng bayad" + fee_calculated_on_transfer_through_name: "Fee Calc sa Transfer Through" + tax_category_name: "kategorya ng buwis" + total_amount: "$$ KABUUAN" + html: + header: + fee_type: "uri ng kabayaran" + enterprise_name: "may-ari ng enterprise" + fee_name: "pangalan ng bayarin" + customer_name: "customer" + fee_placement: "paglilipat ng bayad" + fee_calculated_on_transfer_through_name: "Fee Calc sa Transfer Through" + tax_category_name: "kategorya ng buwis" + total_amount: "$$ KABUUAN" + invalid_filter_parameters: "ang mga filter na pinili para sa ulat na ito ay hindi valid." + order: "order" + distribution: "pamamahagi" + order_details: "detalye ng order" + customer_details: "detalye ng customer" + adjustments: "mga pagsasa-ayos" + payments: "mga bayad" + payment: "kabayaran" + payment_method: "paraan ng pagbayad" + shipment: "kargamento" + shipment_inc_vat: "kargamento kasama ang VAT" + shipping_tax_rate: "rate ng buwis para sa pagdadala" + category: "kategorya" + delivery: "pagdeliver" + temperature_controlled: "kontrolado ang temperatura" + new_product: "bagong produkto" + administration: "administrasyon" + logged_in_as: "maglog-in bilang" + account: "Account" + logout: "mag-log-out" + date_range: "saklaw na petsa" + status: "katayuan" + new: "Bago" + start: "simula" + end: "katapusan" + stop: "Hinto" + first: "Una" + previous: "nauna" + last: "huli" + spree: + your_order_is_empty_add_product: "ang iyong order ay walang laman, humanap at magdagdag ng produkto sa itaas." + add_product: "magdagdag ng produkto" + name_or_sku: "Pangalan o SKU (ipasok ang 4 na letra sa pangalan ng produkto)" + resend: ipadala muli + back_to_orders_list: bumalik sa listahan ng mga order + return_authorizations: mga awtorisasyon sa pagbabalik + cannot_create_returns: hindi makagawa ng pagbalik sa kadahilanang ang order na ito ay walang shipped na yunit. + select_stock: "Pumili ng stock" + location: "Lokasyon" + count_on_hand: "bilangin ang on hand" + quantity: "dami" + package_from: "package mula sa" + item_description: "Paglalarawan ng item" + price: "presyo" + total: "kabuuan" + edit: "i-edit" + split: "paghiwalayin" + delete: "tanggalin" + cannot_set_shipping_method_without_address: "hindi ma-set ang paraan ng pagdadala hanggang hindi binibigay ang detalye ng customer." + no_tracking_present: "walang detalye ng tracking na ibinigay." + order_total: "kabuuan ng order" + customer_details: "detalye ng customer" + customer_search: "paghanap ng customer" + choose_a_customer: "pumili ng customer" + account: "Account" + billing_address: "Billing Address" + shipping_address: "Shipping Address" + first_name: "Pangalan" + last_name: "apelyido" + street_address: "address ng kalye" + street_address_2: "address ng kalye (pinagpatuloy)" + city: "Lungsod" + zip: "Zip" + country: "Bansa" + state: "kalagayan" + phone: "telepono" + update: "i-update" + use_billing_address: "gamitin ang address para sa paniningil" + adjustments: "mga pagsasa-ayos" + continue: "Magpatuloy" + fill_in_customer_info: "sagutan ang impormasyon tungkol sa customer" + new_payment: "Bagong Pagbabayad" + capture: "kunan" + void: "walang bisa" + configurations: "mga pagsasaayos" + general_settings: "Pangkalahatang Setting" + site_name: "Pangalan ng site" + site_url: "URL ng site" + default_seo_title: "default Seo Title" + default_meta_description: "Default na paglalarawan ng Meta" + default_meta_keywords: "Default Meta Keywords" + security_settings: "mga setting para sa seguridad" + allow_ssl_in_development_and_test: "payagan na gamitin ang SSL kapag nasa moda ng pagpapaunlad at pagsubok.." + allow_ssl_in_production: "payagan na gamitin ang SSL sa moda ng produksiyon" + allow_ssl_in_staging: "payagan ang SSL sa moda ng staging" + currency_decimal_mark: "marka para sa currency decimal" + currency_settings: "mga setting para sa currency" + currency_symbol_position: ilagay ang "simbolo ng salapi bago o pagtapos ng halaga ng piso?" + currency_thousands_separator: "tagapaghiwalay ng Currency thousands" + hide_cents: "itago ang sentimo" + display_currency: "ipakita ang currency" + choose_currency: "pumili ng currency" + mail_method_settings: "mga setting para sa Mail Method" + general: "pangkalahatan" + enable_mail_delivery: "paganahin ang pagdedeliver ng sulat" + send_mails_as: "ipadala ang sulat bilang" + smtp_send_all_emails_as_from_following_address: "ipadala lahat ng mga sulat bilang galing sa mga sumusunod na address." + send_copy_of_all_mails_to: "magpadala ng kopya ng lahat ng sulat sa" + smtp_send_copy_to_this_addresses: "nagpapadala ng kopya ng lahat ng lumalabas na mga sulat sa address na ito, para sa maraming address, paghiwalayin gamit ang kuwit." + intercept_email_address: "harangin ang email address" + intercept_email_instructions: "pawalang halaga ang tatanggap ng email at palitan ng address na ito" + smtp: "SMTP" + smtp_domain: "SMTP Domain" + smtp_mail_host: "SMTP Mail Host" + smtp_port: "SMTP Port" + secure_connection_type: "Secure Connection Type" + smtp_authentication_type: "SMTP Authentication Type" + smtp_username: "SMTP username" + smtp_password: "SMTP password" + image_settings: "mga setting ng imahe" + image_settings_warning: "kinakailangang gumawa muli ng mga thumbnail kung ia-update ang mga estilo ng paperclip. gumamit ng rake paperclip:refresh:thumbnails CLASS=Spree::Image para gawin ito." + attachment_default_style: estilo ng mga attachment + attachment_default_url: "Default URL ng mga attachment" + attachment_path: "landas ng mga attachment" + attachment_styles: "estilo ng Paperclips" + attachment_url: "URL ng mga attachment" + add_new_style: "magdagdag ng bagong estilo" + image_settings_updated: "matagumpay na na-update ang settings ng imahe" + tax_categories: "kategorya ng buwis" + listing_tax_categories: "kategorya ng nakalistang buwis" + back_to_tax_categories_list: "bumalik sa listahan ng kategorya ng buwis" + tax rate: "rate ng mga buwis" + new_tax_rate: "bagong rate ng buwis" + tax_category: "kategorya ng buwis" + rate: "rate" + tax_rate_amount_explanation: "ang mga rate ng buwis ay mga halagang may decimal na makakatulong sa pagkukwenta, (hal. kung ang rate ng buwis ay 5% ang ilalagay ay 0.05)" + included_in_price: "nakasama sa presyo" + show_rate_in_label: "ipakita ang rate sa tatak" + back_to_tax_rates_list: "bumalik sa listahan ng rate ng buwis" + tax_settings: "Settings ng buwis" + zones: "mga sona" + new_zone: "bagong sona" + default_tax: "default na buwis" + default_tax_zone: "default na sona ng buwis" + country_based: "Country Based" + state_based: "nakabase sa estado" + countries: "Mga Bansa" + listing_countries: "Listahan ng mga Bansa" + iso_name: "pangalan ng ISO" + states_required: "kailangang may estado" + editing_country: "pag-edit ng bansa" + back_to_countries_list: "bumalik sa listahan ng mga bansa" + states: "Estado" + abbreviation: "Pinaikli" + new_state: "Bagong estado" + payment_methods: "Mga Paraan ng Pagbabayad" + new_payment_method: "Bagong Paraan ng pagbabayad" + provider: "tagapagbigay ng serbisyo" + taxonomies: "taxomies" + new_taxonomy: "bagong taxonomy" + back_to_taxonomies_list: "bumalik sa listahan ng mga taxonomy" + shipping_methods: "mga paraan ng pagpapadala" + shipping_categories: "mga kategorya ng pagpapadala" + new_shipping_category: "bagong kategorya ng pagpapadala" + back_to_shipping_categories: "bumalik sa kategorya ng pagpapadala" + analytics_trackers: "mga tracker ng analytic" + no_trackers_found: "walang natagpuang tracker" + new_tracker: "bagong tracker" + add_one: "Magdagdag ng isa" + google_analytics_id: "Analytics ID" + back_to_trackers_list: "bumalik sa listahan ng tracker" + name: "pangalan" + description: "paglalarawan" + type: "uri" + default: "default" + calculator: "calculator" + zone: "sona" + display: "ipakita" + environment: "kapaligiran" + active: "aktibo" + nore: "Iba pa" + no_results: "walang resulta" + create: "gumawa" + loading: "naglo-load" + flat_percent: "Patag na porsiyento" + per_kg: "kada Kg" + amount: "halaga" + currency: "Currency" + first_item: "halaga ng unang item" + additional_item: "halaga ng karagdagang item" + max_items: "sagad na mga item" + minimal_amount: "pinakamaliit na halaga" + normal_amount: "normal na halaga" + discount_amount: "halaga na may diskuwento" + no_images_found: "walang mahanap na larawan" + new_image: "bagong larawan" + filename: "pangalan ng file" + alt_text: "alternatibong teksto" + thumbnail: "thumbnail" + back_to_images_list: "balik sa listahan ng mga larawan" + email: email + account_updated: "na-update na ang Account" + email_updated: "ang account ay maa-update kapag ang bagong email ay nakumpirma na" + my_account: "ang aking account" + date: "petsa" + time: "oras" + inventory_error_flash_for_insufficient_quantity: "ang isang item sa inyong cart ay hindi na available." + inventory: imbentaryo + zipcode: Postcode + weight: timbang (per kg) + error_user_destroy_with_orders: "ang mga gumagamit na may kumpletong order ay hindi maaaring tanggalin" + cannot_create_payment_without_payment_methods: "hindi maaaring magbayad para sa isang order na walang nakasaad na paraan ng pagbabayad." + please_define_payment_methods: "isaad muna ang paraan ng pagbabayad" + options: "pagpipilian" + actions: + update: "i-update" + errors: + messages: + blank: "hindi maaaring iwanang blanko" + layouts: + admin: + header: + store: tindahan + admin: + tab: + dashboard: "Dashboard" + orders: "mga order" + bulk_order_management: "Pamamahala sa pangmaramihang order" + subscriptions: "mga subscription" + products: "mga produkto" + option_types: "mga uri ng pagpipilian" + properties: "mga katangian" + variant_overrides: "imbentaryo" + reports: "mga ulat" + configuration: "pagbabago" + users: "mga gumagamit" + roles: "mga tungkulin" + order_cycles: "order cycles" + enterprises: "enterprises" + enterprise_relationships: "mga pahintulot" + customers: "mga customer" + groups: "mga grupo" + product_properties: + index: + inherits_properties_checkbox_hint: "kopyahin ang mga katangian mula sa%{supplier}? (maliban kung napatungan ang nasa itaas)" + add_product_properties: "magdagdag ng katangian ng produkto" + select_from_prototype: "pumili mula sa prototype" + properties: + index: + properties: "mga katangian" + new_property: "bagong katangian" + name: "pangalan" + presentation: "presentasyon" + new: + new_property: "bagong katangian" + edit: + editing_property: "ayusin ang katangian" + back_to_properties_list: "bumalik sa listahan ng katangian" + form: + name: "pangalan" + presentation: "presentasyon" + return_authorizations: + index: + new_return_authorization: "bagong awtorisasyon sa pagbabalik" + return_authorizations: "mga awtorisasyon sa pagbabalik" + back_to_orders_list: "bumalik sa listahan ng mga order" + rma_number: "numbero ng RMA" + status: "katayuan" + amount: "halaga" + cannot_create_returns: "hindi makagawa ng pagbalik sa kadahilanang ang order na ito ay walang shipped na yunit." + continue: "Magpatuloy" + new: + new_return_authorization: "bagong awtorisasyon sa pagbabalik" + back_to_return_authorizations_list: "bumalik sa listahan ng awtorisasyon sa pagbabalik" + continue: "Magpatuloy" + edit: + receive: "tumanggap" + are_you_sure: "Sigurado ka ba?" + return_authorization: "awtorisasyon sa pagbabalik" + form: + product: "produkto" + quantity_shipped: "Dami ng naipadala" + quantity_returned: "dami ng ibinalik" + return_quantity: "binalik na dami" + amount: "halaga" + rma_value: "RMA Value" + reason: "Dahilan" + stock_location: "Lokasyon ng stock" + states: + authorized: "pinayagan" + received: "natanggap" + canceled: "na-cancel" + orders: + index: + listing_orders: "listahan ng mga order" + new_order: "bagong order" + capture: "kunan" + ship: "ship" + edit: "i-edit" + order_not_updated: "hindi ma-update ang order" + note: "tala" + first: "Una" + last: "huli" + previous: "nauna" + next: "sunod" + loading: "naglo-load" + no_orders_found: "walang mahanap na mga order" + results_found: "%{number}natagpuang resulta." + viewing: "makikita ang%{start} hanggang%{end}." + print_invoices: "i-print ang mga invoice" + sortable_header: + payment_state: "estado ng pagbabayad" + shipment_state: "kalagayan ng kargamento" + completed_at: "Natapos sa" + number: "bilang" + state: "kalagayan" + email: "Email ng Kustomer" + invoice: + issued_on: "inilabas noong" + tax_invoice: "TAX INVOICE" + code: "Code" + from: "mula" + to: "singilin sa" + shipping: "pagpapadala" + form: + distribution_fields: + title: "pamamahagi" + distributor: "Distributor:" + order_cycle: "Order Cycle:" + line_item_adjustments: "mga pagsasaayos sa linya ng item" + order_adjustments: "mga pagsasaayos sa order" + order_total: "kabuuan ng order" + overview: + enterprises_header: + ofn_with_tip: ang mga enterprise ay mga producer at/o mga Hub na siyang pangunahing yunit ng organisasyon sa loob ng Open Food Network. + products: + active_products: + zero: "wala kang aktibong mga produkto" + one: "Mayroon kang isang aktibong produkto" + other: "mayroon kang%{count}aktibong produkto." + order_cycles: + order_cycles: "order cycles" + order_cycles_tip: "ang mga order cycle ang tumutukoy kung kailan at saan may mga produkto para sa mga customer." + you_have_active: + zero: "wala kang mga aktibong order cycle" + one: "mayroon kang isang aktibong order cycle" + other: "mayroon kang%{count}aktibong order cycle." + manage_order_cycles: "PAMAHALAAN ANG MGA ORDER CYCLE" + shipping_methods: + index: + shipping_methods: "mga paraan ng pagpapadala" + new_shipping_method: "bagong paraan ng pagpapadala" + name: "pangalan" + products_distributor: "Distributor" + zone: "sona" + calculator: "calculator" + display: "ipakita" + both: "pareho" + front_end: "harapan" + back_end: "Likuran" + no_shipping_methods_found: "walang mahanap na mga paraan ng pagpapadala" + new: + new_shipping_method: "bagong paraan ng pagpapadala" + back_to_shipping_methods_list: "bumalik sa listahan ng mga paraan ng pagpapadala" + edit: + editing_shipping_method: "iayos ang paraan ng pagpapadala" + new: "Bago" + back_to_shipping_methods_list: "bumalik sa listahan ng mga paraan ng pagpapadala" + form: + categories: "mga kategorya" + zones: "mga sona" + both: "pareho" + front_end: "harapan" + back_end: "Likuran" + payment_methods: + new: + new_payment_method: "Bagong Paraan ng pagbabayad" + back_to_payment_methods_list: "bumalik sa listahan ng mga paraan ng pagbabayad" + edit: + editing_payment_method: "iayos ang paraan ng pagbabayad" + back_to_payment_methods_list: "bumalik sa listahan ng mga paraan ng pagbabayad" + stripe_connect: + enterprise_select_placeholder: pumili + loading_account_information_msg: nilo-load ang impormasyon ng account mula sa Stripe, maghintay lamang... + stripe_disabled_msg: ang pagbabayad gamit ang Stripe ay hindi pinagana ng system administrator. + request_failed_msg: Paumahin, may nangyaring mali habang sinusubukang patunayan ang mga detalye ng account sa Stripe + account_missing_msg: walang Stripe account para sa enterprise na ito + connect_one: Connect One + access_revoked_msg: ang access sa Stripe account na ito ay pinawalang bisa, ikonekta muli ang account. + status: katayuan + connected: konektado + account_id: Account ID + business_name: pangalan ng negosyo + charges_enabled: pinagana ang paniningil + payments: + source_forms: + stripe: + error_saving_payment: error sa pag-save ng bayad + submitting_payment: sinusumite ang bayad... + products: + image_upload_error: "ang imahe ng produkto ay hindi makilala. mag-upload ng imahe sa format na PNG o JPG." + new: + title: "bagong produkto" + new_product: "bagong produkto" + supplier: "tagapagtustos" + product_name: "pangalan ng produkto" + units: "laki kada yunit" + value: "halaga" + unit_name: "pangalan ng yunit" + price: "presyo" + on_hand: "on hand" + on_demand: "on demand" + product_description: "paglalarawan ng produkto" + image: "imahe" + or: "o" + unit_name_placeholder: 'hal. mga kumpol' + index: + header: + title: maramihang pag-edit ng mga produkto + indicators: + title: nilo-load ang mga produkto + no_products: "wala pang produkto. nais mo bang magdagdag?" + no_results: "Walang tugmang resulta" + products_head: + name: pangalan + unit: yunit + display_as: ipakita bilang + category: kategorya + tax_category: kategorya ng buwis + inherits_properties?: minana ang mga katangian? + available_on: Magagamit Nakabukas + av_on: "Av On" + import_date: "petsa ng pag-import" + products_variant: + variant_has_n_overrides: "ang uri ay may%{n}(mga)pagpapalit" + new_variant: "bagong uri" + product_name: pangalan ng produkto + primary_taxon_form: + product_category: kategorya ng produkto + group_buy_form: + group_buy: "grupong pamimili?" + bulk_unit_size: laki ng bultuhang yunit + display_as: + display_as: ipakita bilang + reports: + table: + select_and_search: "pumili ng mga filter at pindutin ang%{option} para ma-access ang inyong data." + bulk_coop: + bulk_coop_supplier_report: 'bultuhang Co-Op - kabuuan galing sa Supplier' + bulk_coop_allocation: 'bultuhang Co-Op - Alokasyon' + bulk_coop_packing_sheets: 'bultuhang Co-Op - piraso ng pagbabalot' + bulk_coop_customer_payments: 'bultuhang Co-Op - mga bayad ng customer' + enterprise_fee_summaries: + filters: + date_range: "saklaw na petsa" + report_format_csv: "i-download bilang CSV" + generate_report: "Bumuo ng ulat" + report: + none: "wala" + select_and_search: "pumili ng mga filter at pindutin ang GUMAWA NG REPORT para ma-access ang inyong data." + users: + index: + listing_users: "Nililista ang mga User" + new_user: "Bagong User" + user: "User" + enterprise_limit: "Limitasyon ng enterprise" + search: "hanapin" + email: "email" + edit: + editing_user: "pag-edit ng User" + back_to_users_list: "Bumalik sa listahan ng mga User" + general_settings: "Pangkalahatang Setting" + form: + email: "email" + roles: "mga tungkulin" + enterprise_limit: "Limitasyon ng enterprise" + confirm_password: "Kumpirmahin ang password" + password: "Password" + email_confirmation: + confirmation_pending: "ang pagkumpirma ng email ay hindi pa nagagawa. ipinadala namin ang email ng kumpirmasyon sa %{address}." + variants: + index: + sku: "SKU" + price: "presyo" + options: "pagpipilian" + no_results: "walang resulta" + to_add_variants_you_must_first_define: "para makapagdagdag ng mga variant, tukuyin muna ang" + option_types: "mga uri ng pagpipilian" + option_values: "Mga halaga ng pagpipilian" + and: "at" + new_variant: "bagong variant" + show_active: "ipakita ang aktibo" + show_deleted: "ipakita ang tinanggal" + new: + new_variant: "bagong variant" + form: + cost_price: "halaga ng gastos" + sku: "SKU" + price: "presyo" + display_as: "ipakita bilang" + display_name: "Pangalan na nakikita" + autocomplete: + producer_name: "Prodyuser" + unit: "yunit" + general_settings: + edit: + legal_settings: "Legal Settings" + cookies_consent_banner_toggle: "ipakita ang banner ng pagpayag sa cookies" + privacy_policy_url: "Patakaran sa privacy URL" + enterprises_require_tos: "ang mga enterprise ay dapat tanggapin ang Termino ng serbisyo." + cookies_policy_matomo_section: "ipakita ang seksyon ng Matomo sa pahina ng patakaran sa cookies" + cookies_policy_ga_section: "ipakita ang seksyon ng Google Analytics sa pahina ng patakaran sa cookies" + footer_tos_url: "URL ng Termino ng Serbisyo" + checkout: + payment: + stripe: + choose_one: pumili ng isa + enter_new_card: ipasok ang detalye para sa bagong card + used_saved_card: "gumamit ng naka-save na card:" + or_enter_new_card: "o ipasok ang detalye para sa bagong card:" + remember_this_card: Naaalala ba ang card na ito? + stripe_sca: + choose_one: pumili ng isa + enter_new_card: ipasok ang detalye para sa bagong card + used_saved_card: "gumamit ng naka-save na card:" + or_enter_new_card: "o ipasok ang detalye para sa bagong card:" + remember_this_card: Naaalala ba ang card na ito? + date_picker: + format: '%Y-%m-%d' + js_format: 'yy-mm-dd' + orders: + error_flash_for_unavailable_items: "ang isang item sa inyong cart ay hindi na available." + edit: + login_to_view_order: "Maglog-in para makita ang inyong order." + bought: + item: "na-order na sa order cycle na ito" + line_item: + insufficient_stock: "Hindi sapat ang stock, mayroon na lamang%{on_hand} na natitira" + out_of_stock: "Walang stock" + unavailable_item: "kasalulkuyang hindi available" + shipment_states: + backorder: backorder + partial: bahagi + pending: nakabinbin + ready: handa na + shipped: nai-ship na + payment_states: + balance_due: balanse + completed: nakumpleto na + checkout: checkout + credit_owed: Utang na Credit + failed: hindi nagtagumpay + paid: bayad na + pending: nakabinbin + processing: pinoproseso + void: walang bisa + invalid: invalid + order_mailer: + cancel_email: + customer_greeting: "hi %{name}!" + instructions: "ang iyong order ay NA-CANCEL. Panatilihin ang impormasyon na ito ng kanselasyon para sa inyong talaan." + order_summary_canceled: "Buod ng order [NA-CANCEL]" + subject: "Pag-cancel ng order" + confirm_email: + subject: "Kumpirmasyon ng order" + invoice_email: + hi: "Hi %{name}" + invoice_attached_text: 'tignan ang nakalakip na invoice para sa pinakabagong order mula sa ' + order_state: + address: tirahan + adjustments: mga pagsasaayos + awaiting_return: naghihintay ng pagbalik + canceled: na-cancel + cart: cart + complete: kumpleto + confirm: kumpirmahin + delivery: pagdeliver + paused: nakahinto + payment: pagbabayad + pending: nakabinbin + resumed: nagpatuloy + returned: binalik + skrill: Skrill + subscription_state: + active: aktibo + pending: nakabinbin + ended: natapos na + paused: nakahinto + canceled: na-cancel + user_mailer: + reset_password_instructions: + request_sent_text: | + may ginawang request para i-reset ang inyong password. + kung hindi ikaw ang gumawa nito, huwag pansinin ang email na ito. + link_text: > + kung ikaw ang gumawa ng request na ito, pindutin ang link sa ilalim: + issue_text: | + kung ang URL sa itaas ay hindi gumagana, subukang kopyahin at i-paste ito sa inyong browser. + kung patuloy na magkakaroon ng mga problema, huwag mag-atubiling makipag-ugnayan sa amin. + confirmation_instructions: + subject: kumpirmahin ang inyong OFN account + users: + form: + account_settings: Setting ng Account + show: + tabs: + orders: mga order + cards: Credit cards + transactions: Mga transaksyon + settings: Setting ng Account + unconfirmed_email: "Nakabinbin na kumpirmasyon ng email para sa:%{unconfirmed_email}. ang iyong email address ay maa-update kapag ang bagong email ay nakumpirma." + orders: + open_orders: mga bukas na order + past_orders: mga nakaraang order + transactions: + transaction_history: kasaysayan ng mga transaksyon + open_orders: + order: order + shop: Shop + changes_allowed_until: ang mga pagbabago ay papayagan hanggang + items: mga item + total: kabuuan + edit: i-edit + cancel: i-cancel + closed: sarado + until: hanggang + past_orders: + order: order + shop: Shop + completed_at: Natapos sa + items: mga item + total: kabuuan + paid?: bayad na? + view: tignan + saved_cards: + default?: Default? + delete?: tanggalin? + cards: + authorised_shops: awtorisadong mga shop + authorised_shops_popover: ito ang listahan ng mga shop na may permisong singilin ang iyong default na credit card para sa kahit anong subscription (hal.nauulit na mga order) na mayroon ka. Ang mga detalye ng iyong card ay pananatilihing ligtas at hindi ipapaalam sa mga may-ari ng shop. Ikaw ay aabisuhan kapag ikaw ay nasingil na. + saved_cards_popover: ito ang listahan ng mga card na pinili mong i-save para magamit sa hinaharap. ang iyong 'default' ay awtomatikong mapipili kapag ikaw ay nagcheckout ng order, at maaari ring singilin ng mga shop na binigyan mo ng permiso (tignan sa kanan). + authorised_shops: + shop_name: "pangalan ng shop" + allow_charges?: "pumayag na masingil?" + localized_number: + invalid_format: ay may hindi valid na format. mag.pasok ng numero + api: + invalid_api_key: "hindi valid na API key (%{key}) na tinutukoy." + unauthorized: "ikaw ay hindi awtorisado na gawin ang kilos na iyon." + invalid_resource: "hindi valid na pinagkuhanan. ayusin ang error at subukan muli." + resource_not_found: "ang pinagkukuhan ay hindi mahanap." + access: "API Access" + key: "Key" + clear_key: "burahin ang key" + regenerate_key: "gumawa muli ng key" + no_key: "walang key" + generate_key: "gumawa ng API key" + key_generated: "nagawa na ang key" + key_cleared: "binura ang key" + shipment: + cannot_ready: "hindi maihanda ang kargamento" + invalid_taxonomy_id: "hindi valid na taxonomy id." From b6753a259368d9f07caa629ab2ec6cd8320fb98d Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Tue, 7 Apr 2020 16:03:57 +1000 Subject: [PATCH 061/166] Updating translations for config/locales/fil_PH.yml --- config/locales/fil_PH.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 73c43a25e4..d6ae17f48a 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -250,7 +250,7 @@ fil_PH: blocked_cookies_alert: " ang iyong browser ay maaaring hinaharang ang cookies na kailangan upang magamit ang shopfront na ito. Pindutin sa ibaba upang payagan ang mga cookies at i-reload ang pahina." allow_cookies: "Payagan ang cookies" notes: mga tala - error: pagkakamali + error: error processing_payment: "pinoproseso ang bayad" no_pending_payments: "walang nakabinbin na mga bayarin" invalid_payment_state: "hindi valid na estado ng pagbabayad" From e6cd33ee57465db13e46d7a52d935e6abdd72bef Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Mon, 6 Apr 2020 17:05:36 +0800 Subject: [PATCH 062/166] Increase max characters for locale in spree_users There are many locales that have six (6) characters. --- ...85833_increase_characters_of_locale_in_spree_users.rb | 9 +++++++++ db/schema.rb | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb diff --git a/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb b/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb new file mode 100644 index 0000000000..5cac7dab5b --- /dev/null +++ b/db/migrate/20200406085833_increase_characters_of_locale_in_spree_users.rb @@ -0,0 +1,9 @@ +class IncreaseCharactersOfLocaleInSpreeUsers < ActiveRecord::Migration + def up + change_column :spree_users, :locale, :string, limit: 6 + end + + def down + change_column :spree_users, :locale, :string, limit: 5 + end +end diff --git a/db/schema.rb b/db/schema.rb index 40badc11bf..a1f2124d59 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20200327105910) do +ActiveRecord::Schema.define(:version => 20200406085833) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -1045,7 +1045,7 @@ ActiveRecord::Schema.define(:version => 20200327105910) do t.datetime "reset_password_sent_at" t.string "api_key", :limit => 40 t.integer "enterprise_limit", :default => 5, :null => false - t.string "locale", :limit => 5 + t.string "locale", :limit => 6 t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" From 94f8ea2f93a1168591d2bdd1b45aa0c7bd1a27ce Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 10:19:12 +0200 Subject: [PATCH 063/166] Fix flicker effect showing 3 buttons when clicking "Show Closed Shops" button --- app/views/shops/_hubs.html.haml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/shops/_hubs.html.haml b/app/views/shops/_hubs.html.haml index 3d83d28923..a44ae17f8d 100644 --- a/app/views/shops/_hubs.html.haml +++ b/app/views/shops/_hubs.html.haml @@ -26,8 +26,10 @@ %a{href: "", "ng-click" => "showDistanceMatches()"} = t :hubs_distance_filter, location: "{{ nameMatchesFiltered[0].name }}" .more-controls - %a.button{href: "", ng: {click: "showClosedShops()", show: "!show_closed"}} - = t '.show_closed_shops' - %a.button{href: "", ng: {click: "hideClosedShops()", show: "show_closed"}} - = t '.hide_closed_shops' + %div{ng: {if: "!show_closed", cloak: true}} + %a.button{href: "", ng: {click: "showClosedShops()"}} + = t '.show_closed_shops' + %div{ng: {if: "show_closed", cloak: true}} + %a.button{href: "", ng: {click: "hideClosedShops()"}} + = t '.hide_closed_shops' %a.button{href: main_app.map_path}= t '.show_on_map' From 003341ef7af37499c68544e18f1bd8a9d9ced4b7 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 10:40:49 +0200 Subject: [PATCH 064/166] Add loading indicator when showing closed shops --- .../darkswarm/controllers/enterprises_controller.js.coffee | 3 +++ app/assets/stylesheets/darkswarm/hubs.css.scss | 5 +++++ app/views/shops/_hubs.html.haml | 5 +++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee index 280e584562..0bc5c3a460 100644 --- a/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/enterprises_controller.js.coffee @@ -9,6 +9,7 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location $scope.show_closed = false $scope.filtersActive = false $scope.distanceMatchesShown = false + $scope.closed_shops_loading = false $scope.closed_shops_loaded = false $scope.$watch "query", (query)-> @@ -23,6 +24,7 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location $timeout -> Enterprises.calculateDistance query, $scope.firstNameMatch() $rootScope.$broadcast 'enterprisesChanged' + $scope.closed_shops_loading = false $timeout -> if $location.search()['show_closed']? @@ -78,6 +80,7 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location $scope.showClosedShops = -> unless $scope.closed_shops_loaded + $scope.closed_shops_loading = true $scope.closed_shops_loaded = true Enterprises.loadClosedEnterprises().then -> $scope.resetSearch($scope.query) diff --git a/app/assets/stylesheets/darkswarm/hubs.css.scss b/app/assets/stylesheets/darkswarm/hubs.css.scss index 9845ce9ad8..253266eba4 100644 --- a/app/assets/stylesheets/darkswarm/hubs.css.scss +++ b/app/assets/stylesheets/darkswarm/hubs.css.scss @@ -14,5 +14,10 @@ .more-controls { text-align: center; + + .spinner { + height: 2.25em; + margin-right: 0.5em; + } } } diff --git a/app/views/shops/_hubs.html.haml b/app/views/shops/_hubs.html.haml index a44ae17f8d..6c05561da0 100644 --- a/app/views/shops/_hubs.html.haml +++ b/app/views/shops/_hubs.html.haml @@ -26,10 +26,11 @@ %a{href: "", "ng-click" => "showDistanceMatches()"} = t :hubs_distance_filter, location: "{{ nameMatchesFiltered[0].name }}" .more-controls - %div{ng: {if: "!show_closed", cloak: true}} + %img.spinner.text-center{ng: {show: "closed_shops_loading"}, src: "/assets/spinning-circles.svg" } + %span{ng: {if: "!show_closed", cloak: true}} %a.button{href: "", ng: {click: "showClosedShops()"}} = t '.show_closed_shops' - %div{ng: {if: "show_closed", cloak: true}} + %span{ng: {if: "show_closed", cloak: true}} %a.button{href: "", ng: {click: "hideClosedShops()"}} = t '.hide_closed_shops' %a.button{href: main_app.map_path}= t '.show_on_map' From 64c66ddedcc9a3eedecd80b7fce0312cc210044a Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:21:09 +0200 Subject: [PATCH 065/166] Eager-load variant data for overridable products Cuts query count and page load time in half for this endpoint. --- app/controllers/api/products_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb index a45e9a8aea..c0a46aca05 100644 --- a/app/controllers/api/products_controller.rb +++ b/app/controllers/api/products_controller.rb @@ -121,6 +121,7 @@ module Api def paged_products_for_producers(producers) Spree::Product.scoped. merge(product_scope). + includes(variants: [:product, :default_price, :stock_items]). where(supplier_id: producers). by_producer.by_name. ransack(params[:q]).result. From 9c421e146eb390bbeccbfdfe2c8300d36ba72a11 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 8 Apr 2020 10:23:18 +0200 Subject: [PATCH 066/166] Remove arrows from cart and checkout buttons --- app/views/checkout/_summary.html.haml | 1 - app/views/spree/orders/form/_cart_links.html.haml | 2 -- app/views/spree/orders/form/_update_buttons.html.haml | 2 -- 3 files changed, 5 deletions(-) diff --git a/app/views/checkout/_summary.html.haml b/app/views/checkout/_summary.html.haml index 0ca86fcb2e..fa3bd6f4ed 100644 --- a/app/views/checkout/_summary.html.haml +++ b/app/views/checkout/_summary.html.haml @@ -31,5 +31,4 @@ //= f.submit "Purchase", class: "button", "ofn-focus" => "accordion['payment']" %a.button.secondary{href: main_app.cart_url} - %i.ofn-i_008-caret-left = t :checkout_back_to_cart diff --git a/app/views/spree/orders/form/_cart_links.html.haml b/app/views/spree/orders/form/_cart_links.html.haml index d787b9c50f..24b5b50b27 100644 --- a/app/views/spree/orders/form/_cart_links.html.haml +++ b/app/views/spree/orders/form/_cart_links.html.haml @@ -1,9 +1,7 @@ .row.links{'data-hook' => "cart_buttons"} .columns.large-8{"data-hook" => ""} %a.button.large.secondary{href: current_shop_products_path} - %i.ofn-i_008-caret-left = t :orders_edit_continue .columns.large-4.text-right %a#checkout-link.button.large.primary{href: main_app.checkout_path} = t :orders_edit_checkout - %i.ofn-i_007-caret-right diff --git a/app/views/spree/orders/form/_update_buttons.html.haml b/app/views/spree/orders/form/_update_buttons.html.haml index 22ede28e57..5757d1742f 100644 --- a/app/views/spree/orders/form/_update_buttons.html.haml +++ b/app/views/spree/orders/form/_update_buttons.html.haml @@ -3,11 +3,9 @@ - if current_order.nil? || current_order.distributor.nil? || current_order.distributor == @order.distributor - if current_order&.line_items.present? = link_to main_app.cart_path, :class => "button expand" do - %i.ofn-i_008-caret-left = t(:order_back_to_cart) - else = link_to "#{main_app.enterprise_shop_path(@order.distributor)}#/shop", class: "button expand" do - %i.ofn-i_008-caret-left = t(:order_back_to_store) - else   From 0414f4984dd7ddb0d5c6480ada75bb004b676dbd Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 8 Apr 2020 10:55:55 +0200 Subject: [PATCH 067/166] Align buttons left and right on cart page --- app/views/spree/orders/form/_cart_links.html.haml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/views/spree/orders/form/_cart_links.html.haml b/app/views/spree/orders/form/_cart_links.html.haml index 24b5b50b27..8da012cd78 100644 --- a/app/views/spree/orders/form/_cart_links.html.haml +++ b/app/views/spree/orders/form/_cart_links.html.haml @@ -1,7 +1,5 @@ .row.links{'data-hook' => "cart_buttons"} - .columns.large-8{"data-hook" => ""} - %a.button.large.secondary{href: current_shop_products_path} - = t :orders_edit_continue - .columns.large-4.text-right - %a#checkout-link.button.large.primary{href: main_app.checkout_path} - = t :orders_edit_checkout + %a.button.large.secondary{href: current_shop_products_path} + = t :orders_edit_continue + %a#checkout-link.button.large.primary.right{href: main_app.checkout_path} + = t :orders_edit_checkout From 1ddbabd841eb1b6f9e20fc5b0e139ecdee90e1fe Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 8 Apr 2020 10:57:33 +0200 Subject: [PATCH 068/166] Adjust colours of primary buttons to use (bright) orange instead of (warning) red --- app/assets/stylesheets/darkswarm/branding.css.scss | 1 + app/assets/stylesheets/darkswarm/ui.css.scss | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/branding.css.scss b/app/assets/stylesheets/darkswarm/branding.css.scss index b8ab72349c..ca75eaa227 100644 --- a/app/assets/stylesheets/darkswarm/branding.css.scss +++ b/app/assets/stylesheets/darkswarm/branding.css.scss @@ -54,6 +54,7 @@ $teal-400: #4cb5c5; $teal-500: #0096ad; $orange-400: #ff9466; +$orange-450: #f4704c; $orange-500: #f27052; $orange-600: #d7583a; diff --git a/app/assets/stylesheets/darkswarm/ui.css.scss b/app/assets/stylesheets/darkswarm/ui.css.scss index 6dc4d95d3b..4a50c4a1a0 100644 --- a/app/assets/stylesheets/darkswarm/ui.css.scss +++ b/app/assets/stylesheets/darkswarm/ui.css.scss @@ -64,13 +64,13 @@ .button.primary, button.primary { font-family: $body-font; - background: $clr-brick; + background: $orange-450; color: white; } .button.primary:hover, .button.primary:active, .button.primary:focus, button.primary:hover, button.primary:active, button.primary:focus { - background: $clr-brick-bright; - text-shadow: 0 1px 0 $clr-brick; + background: $orange-400; + text-shadow: 0 1px 0 $orange-450; } button.success, .button.success { From 538e4e54d2811133796fb007825e73667c76fc8f Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 8 Apr 2020 11:07:06 +0200 Subject: [PATCH 069/166] Set cart buttons to fixed width and expand when screen is too small --- .../stylesheets/darkswarm/shopping-cart.css.scss | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss index 9a1a2efe8d..bd4a5019c8 100644 --- a/app/assets/stylesheets/darkswarm/shopping-cart.css.scss +++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.scss @@ -115,3 +115,14 @@ height: 36px; } } + +.links { + .button { + padding: 1.125rem 0 1.1875rem; + width: 210px; + + @media all and (max-width: 480px) { + width: 100%; + } + } +} From 3aff7f62e37187d8d2f6112cabda50ad3a6fdd65 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 3 Apr 2020 13:09:07 +0200 Subject: [PATCH 070/166] Don't query distributed properties on enterprises that aren't active distributors Cuts page load on /shops by ~75% (with production data) and removes ~300 expensive and superfluous queries. --- app/serializers/api/cached_enterprise_serializer.rb | 6 ++++++ spec/features/consumer/groups_spec.rb | 4 ++-- .../api/cached_enterprise_serializer_spec.rb | 12 ++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/serializers/api/cached_enterprise_serializer.rb b/app/serializers/api/cached_enterprise_serializer.rb index 05677720db..8a6726e503 100644 --- a/app/serializers/api/cached_enterprise_serializer.rb +++ b/app/serializers/api/cached_enterprise_serializer.rb @@ -73,12 +73,16 @@ module Api # This results in 3 queries per enterprise def distributed_properties + return [] unless active + (distributed_product_properties + distributed_producer_properties).uniq do |property_object| property_object.property.presentation end end def distributed_product_properties + return [] unless active + properties = Spree::Property .joins(products: { variants: { exchanges: :order_cycle } }) .merge(Exchange.outgoing) @@ -91,6 +95,8 @@ module Api end def distributed_producer_properties + return [] unless active + properties = Spree::Property .joins( producer_properties: { diff --git a/spec/features/consumer/groups_spec.rb b/spec/features/consumer/groups_spec.rb index c59835c344..dc9a3e4b75 100644 --- a/spec/features/consumer/groups_spec.rb +++ b/spec/features/consumer/groups_spec.rb @@ -60,8 +60,8 @@ feature 'Groups', js: true do let!(:group) { create(:enterprise_group, enterprises: [d1, d2], on_front_page: true) } let!(:order_cycle) { create(:simple_order_cycle, distributors: [d1, d2], coordinator: create(:distributor_enterprise)) } let(:producer) { create(:supplier_enterprise) } - let(:d1) { create(:distributor_enterprise) } - let(:d2) { create(:distributor_enterprise) } + let(:d1) { create(:distributor_enterprise, with_payment_and_shipping: true) } + let(:d2) { create(:distributor_enterprise, with_payment_and_shipping: true) } let(:p1) { create(:simple_product, supplier: producer) } let(:p2) { create(:simple_product, supplier: create(:supplier_enterprise)) } let(:ex_d1) { order_cycle.exchanges.outgoing.where(receiver_id: d1).first } diff --git a/spec/serializers/api/cached_enterprise_serializer_spec.rb b/spec/serializers/api/cached_enterprise_serializer_spec.rb index c4e5624fa8..6bcaeffdc3 100644 --- a/spec/serializers/api/cached_enterprise_serializer_spec.rb +++ b/spec/serializers/api/cached_enterprise_serializer_spec.rb @@ -53,17 +53,9 @@ describe Api::CachedEnterpriseSerializer do instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributor_ids: []) end - it 'does not duplicate properties' do + it 'does not serialize distributed properties' do properties = cached_enterprise_serializer.distributed_properties - expect(properties.map(&:presentation)).to eq([property.presentation]) - end - - it 'fetches producer properties' do - distributed_producer_properties = cached_enterprise_serializer - .distributed_producer_properties - - expect(distributed_producer_properties.map(&:presentation)) - .to eq(producer.producer_properties.map(&:property).map(&:presentation)) + expect(properties).to eq [] end end From d31b24786aead9aa8321a366f18b30dacf322a3e Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 9 Apr 2020 16:16:24 +1000 Subject: [PATCH 071/166] Updating translations for config/locales/en_NZ.yml --- config/locales/en_NZ.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index 15ad362a51..65eb93ef25 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -31,6 +31,10 @@ en_NZ: taken: "There's already an account for this email. Please login or reset your password." spree/order: no_card: There are no authorised credit cards available to charge + spree/credit_card: + attributes: + base: + card_expired: "has expired" order_cycle: attributes: orders_close_at: @@ -55,7 +59,7 @@ en_NZ: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" @@ -867,6 +871,7 @@ en_NZ: distributor: "Distributor" products: "Products" tags: "Tags" + delivery_details: "Delivery Details" fees: "Fees" previous: "Previous" save: "Save" From 1b7ac1a252f2a06f6ee8b45814899b90587c5d8e Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:30:02 +0200 Subject: [PATCH 072/166] Don't re-use fat serializers when thin ones are needed. This cuts the pageload and query count in half, again. --- app/controllers/api/products_controller.rb | 6 ++--- .../api/admin/product_simple_serializer.rb | 16 +++++++++++ .../api/admin/variant_simple_serializer.rb | 27 +++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 app/serializers/api/admin/product_simple_serializer.rb create mode 100644 app/serializers/api/admin/variant_simple_serializer.rb diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb index c0a46aca05..3182c79044 100644 --- a/app/controllers/api/products_controller.rb +++ b/app/controllers/api/products_controller.rb @@ -74,7 +74,7 @@ module Api @products = paged_products_for_producers producers - render_paged_products @products + render_paged_products @products, ::Api::Admin::ProductSimpleSerializer end # POST /api/products/:product_id/clone @@ -128,10 +128,10 @@ module Api page(params[:page]).per(params[:per_page]) end - def render_paged_products(products) + def render_paged_products(products, product_serializer = ::Api::Admin::ProductSerializer) serializer = ActiveModel::ArraySerializer.new( products, - each_serializer: ::Api::Admin::ProductSerializer + each_serializer: product_serializer ) render text: { diff --git a/app/serializers/api/admin/product_simple_serializer.rb b/app/serializers/api/admin/product_simple_serializer.rb new file mode 100644 index 0000000000..181bb33f54 --- /dev/null +++ b/app/serializers/api/admin/product_simple_serializer.rb @@ -0,0 +1,16 @@ +class Api::Admin::ProductSimpleSerializer < ActiveModel::Serializer + attributes :id, :name + + has_one :supplier, key: :producer_id, embed: :id + has_many :variants, key: :variants, serializer: Api::Admin::VariantSimpleSerializer + + def on_hand + return 0 if object.on_hand.nil? + + object.on_hand + end + + def price + object.price.nil? ? '0.0' : object.price + end +end diff --git a/app/serializers/api/admin/variant_simple_serializer.rb b/app/serializers/api/admin/variant_simple_serializer.rb new file mode 100644 index 0000000000..64aa6e433d --- /dev/null +++ b/app/serializers/api/admin/variant_simple_serializer.rb @@ -0,0 +1,27 @@ +class Api::Admin::VariantSimpleSerializer < ActiveModel::Serializer + attributes :id, :name, :import_date, + :options_text, :unit_value, :unit_description, :unit_to_display, + :display_as, :display_name, :name_to_display, + :price, :on_demand, :on_hand + + has_many :variant_overrides + + def name + if object.full_name.present? + "#{object.name} - #{object.full_name}" + else + object.name + end + end + + def on_hand + return 0 if object.on_hand.nil? + + object.on_hand + end + + def price + # Decimals are passed to json as strings, we need to run parseFloat.toFixed(2) on the client. + object.price.nil? ? 0.to_f : object.price + end +end From ececbce596a33bcd97f0902636a67eaddbe28fd3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:43:42 +0200 Subject: [PATCH 073/166] Only select id in producers query --- app/controllers/api/products_controller.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb index 3182c79044..854d820a47 100644 --- a/app/controllers/api/products_controller.rb +++ b/app/controllers/api/products_controller.rb @@ -69,10 +69,10 @@ module Api end def overridable - producers = OpenFoodNetwork::Permissions.new(current_api_user). - variant_override_producers.by_name + producer_ids = OpenFoodNetwork::Permissions.new(current_api_user). + variant_override_producers.by_name.select('enterprises.id') - @products = paged_products_for_producers producers + @products = paged_products_for_producers producer_ids render_paged_products @products, ::Api::Admin::ProductSimpleSerializer end @@ -118,11 +118,11 @@ module Api ] end - def paged_products_for_producers(producers) + def paged_products_for_producers(producer_ids) Spree::Product.scoped. merge(product_scope). includes(variants: [:product, :default_price, :stock_items]). - where(supplier_id: producers). + where(supplier_id: producer_ids). by_producer.by_name. ransack(params[:q]).result. page(params[:page]).per(params[:per_page]) From f9cf826f1c190894083338c3f2b9c53786eead68 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:53:26 +0200 Subject: [PATCH 074/166] Bring Spree::Stock::Quantifier in to OFN This is the original unmodified Class from Spree. Modifications added in subsequent commits. --- app/models/spree/stock/quantifier.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 app/models/spree/stock/quantifier.rb diff --git a/app/models/spree/stock/quantifier.rb b/app/models/spree/stock/quantifier.rb new file mode 100644 index 0000000000..6b1c11de62 --- /dev/null +++ b/app/models/spree/stock/quantifier.rb @@ -0,0 +1,28 @@ +module Spree + module Stock + class Quantifier + attr_reader :stock_items + + def initialize(variant) + @variant = variant + @stock_items = Spree::StockItem.joins(:stock_location).where(:variant_id => @variant, Spree::StockLocation.table_name =>{ :active => true}) + end + + def total_on_hand + if Spree::Config.track_inventory_levels + stock_items.sum(&:count_on_hand) + else + Float::INFINITY + end + end + + def backorderable? + stock_items.any?(&:backorderable) + end + + def can_supply?(required) + total_on_hand >= required || backorderable? + end + end + end +end From f959e632eaeddfc450401509f5c3028e9b6ca2f3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:15:25 +0200 Subject: [PATCH 075/166] Modify Spree::Stock::Quantifier to not re-fetch stock items if they are already eager-loaded This helps to remove a big N+1 here, and will also be very helpful elsewhere in the app --- app/models/spree/stock/quantifier.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/spree/stock/quantifier.rb b/app/models/spree/stock/quantifier.rb index 6b1c11de62..806fdf33dd 100644 --- a/app/models/spree/stock/quantifier.rb +++ b/app/models/spree/stock/quantifier.rb @@ -5,7 +5,7 @@ module Spree def initialize(variant) @variant = variant - @stock_items = Spree::StockItem.joins(:stock_location).where(:variant_id => @variant, Spree::StockLocation.table_name =>{ :active => true}) + @stock_items = fetch_stock_items end def total_on_hand @@ -23,6 +23,16 @@ module Spree def can_supply?(required) total_on_hand >= required || backorderable? end + + private + + def fetch_stock_items + # Don't re-fetch associated stock items from the DB if we've already eager-loaded them + return @variant.stock_items.to_a if @variant.stock_items.loaded? + + Spree::StockItem.joins(:stock_location). + where(:variant_id => @variant, Spree::StockLocation.table_name => { active: true }) + end end end end From b0a7497f2ae8778ae265aaf6facc7a5f17c1789a Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:22:00 +0200 Subject: [PATCH 076/166] Remove another N+1 in product serialization --- app/serializers/api/admin/product_simple_serializer.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/serializers/api/admin/product_simple_serializer.rb b/app/serializers/api/admin/product_simple_serializer.rb index 181bb33f54..b5af292e81 100644 --- a/app/serializers/api/admin/product_simple_serializer.rb +++ b/app/serializers/api/admin/product_simple_serializer.rb @@ -1,9 +1,12 @@ class Api::Admin::ProductSimpleSerializer < ActiveModel::Serializer - attributes :id, :name + attributes :id, :name, :producer_id - has_one :supplier, key: :producer_id, embed: :id has_many :variants, key: :variants, serializer: Api::Admin::VariantSimpleSerializer + def producer_id + object.supplier_id + end + def on_hand return 0 if object.on_hand.nil? From b3c968856bdf99123c173065ea85918f5b7e9212 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:57:26 +0200 Subject: [PATCH 077/166] Fix some rubocop issues --- app/models/spree/stock/quantifier.rb | 2 + .../api/admin/product_simple_serializer.rb | 30 +++++++----- .../api/admin/variant_simple_serializer.rb | 49 ++++++++++--------- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/app/models/spree/stock/quantifier.rb b/app/models/spree/stock/quantifier.rb index 806fdf33dd..b046dc2b17 100644 --- a/app/models/spree/stock/quantifier.rb +++ b/app/models/spree/stock/quantifier.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Spree module Stock class Quantifier diff --git a/app/serializers/api/admin/product_simple_serializer.rb b/app/serializers/api/admin/product_simple_serializer.rb index b5af292e81..ad7ad16ba1 100644 --- a/app/serializers/api/admin/product_simple_serializer.rb +++ b/app/serializers/api/admin/product_simple_serializer.rb @@ -1,19 +1,25 @@ -class Api::Admin::ProductSimpleSerializer < ActiveModel::Serializer - attributes :id, :name, :producer_id +# frozen_string_literal: true - has_many :variants, key: :variants, serializer: Api::Admin::VariantSimpleSerializer +module Api + module Admin + class ProductSimpleSerializer < ActiveModel::Serializer + attributes :id, :name, :producer_id - def producer_id - object.supplier_id - end + has_many :variants, key: :variants, serializer: Api::Admin::VariantSimpleSerializer - def on_hand - return 0 if object.on_hand.nil? + def producer_id + object.supplier_id + end - object.on_hand - end + def on_hand + return 0 if object.on_hand.nil? - def price - object.price.nil? ? '0.0' : object.price + object.on_hand + end + + def price + object.price.nil? ? '0.0' : object.price + end + end end end diff --git a/app/serializers/api/admin/variant_simple_serializer.rb b/app/serializers/api/admin/variant_simple_serializer.rb index 64aa6e433d..d94421321f 100644 --- a/app/serializers/api/admin/variant_simple_serializer.rb +++ b/app/serializers/api/admin/variant_simple_serializer.rb @@ -1,27 +1,32 @@ -class Api::Admin::VariantSimpleSerializer < ActiveModel::Serializer - attributes :id, :name, :import_date, - :options_text, :unit_value, :unit_description, :unit_to_display, - :display_as, :display_name, :name_to_display, - :price, :on_demand, :on_hand +# frozen_string_literal: true - has_many :variant_overrides +module Api + module Admin + class VariantSimpleSerializer < ActiveModel::Serializer + attributes :id, :name, :import_date, + :options_text, :unit_value, :unit_description, :unit_to_display, + :display_as, :display_name, :name_to_display, + :price, :on_demand, :on_hand - def name - if object.full_name.present? - "#{object.name} - #{object.full_name}" - else - object.name + has_many :variant_overrides + + def name + if object.full_name.present? + "#{object.name} - #{object.full_name}" + else + object.name + end + end + + def on_hand + return 0 if object.on_hand.nil? + + object.on_hand + end + + def price + object.price.nil? ? 0.to_f : object.price + end end end - - def on_hand - return 0 if object.on_hand.nil? - - object.on_hand - end - - def price - # Decimals are passed to json as strings, we need to run parseFloat.toFixed(2) on the client. - object.price.nil? ? 0.to_f : object.price - end end From 5bb2614f9d4bac48b927183036604217149afe0c Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Tue, 7 Apr 2020 17:58:37 +0200 Subject: [PATCH 078/166] Refactor PagedFetcher so it makes one request at a time --- .../services/paged_fetcher.js.coffee | 29 +++++++++++-------- .../variant_overrides_controller.js.coffee | 9 +++--- ...ariant_overrides_controller_spec.js.coffee | 4 +-- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee b/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee index 82487996ae..96836ef9cc 100644 --- a/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee @@ -2,19 +2,24 @@ angular.module("admin.indexUtils").factory "PagedFetcher", (dataFetcher) -> new class PagedFetcher # Given a URL like http://example.com/foo?page=::page::&per_page=20 # And the response includes an attribute pages with the number of pages to fetch - # Fetch each page async, and call the processData callback with the resulting data - fetch: (url, processData, onLastPageComplete) -> - dataFetcher(@urlForPage(url, 1)).then (data) => - processData data + # Fetch each page async, and call the pageCallback callback with the resulting data + # Developer note: this class should not be re-used! + page: 1 + last_page: 1 - if data.pages > 1 - for page in [2..data.pages] - lastPromise = dataFetcher(@urlForPage(url, page)).then (data) -> - processData data - onLastPageComplete && lastPromise.then onLastPageComplete - return - else - onLastPageComplete && onLastPageComplete() + fetch: (url, pageCallback) -> + @fetchPages(url, @page, pageCallback) urlForPage: (url, page) -> url.replace("::page::", page) + + fetchPages: (url, page, pageCallback) -> + dataFetcher(@urlForPage(url, page)).then (data) => + @page++ + @last_page = data.pages + + pageCallback(data) if pageCallback + + if @page <= @last_page + @fetchPages(url, @page, pageCallback) + diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index c37ba72071..b890d2ffd5 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -43,12 +43,11 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.fetchProducts = -> url = "/api/products/overridable?page=::page::;per_page=100" - PagedFetcher.fetch url, (data) => $scope.addProducts data.products + PagedFetcher.fetch url, $scope.addProducts - - $scope.addProducts = (products) -> - $scope.products = $scope.products.concat products - VariantOverrides.ensureDataFor hubs, products + $scope.addProducts = (data) -> + $scope.products = $scope.products.concat data.products + VariantOverrides.ensureDataFor hubs, data.products $scope.displayDirty = -> if DirtyVariantOverrides.count() > 0 diff --git a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee index 5724fe1353..1c860e8e91 100644 --- a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee @@ -51,9 +51,9 @@ describe "VariantOverridesCtrl", -> it "adds products", -> spyOn(VariantOverrides, "ensureDataFor") expect(scope.products).toEqual [] - scope.addProducts ['a', 'b'] + scope.addProducts { products: ['a', 'b'] } expect(scope.products).toEqual ['a', 'b'] - scope.addProducts ['c', 'd'] + scope.addProducts { products: ['c', 'd'] } expect(scope.products).toEqual ['a', 'b', 'c', 'd'] expect(VariantOverrides.ensureDataFor).toHaveBeenCalled() From 6afda141a18e4664d4a194a7086244bfedafd382 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 09:18:28 +0200 Subject: [PATCH 079/166] Remove track_inventory_levels conditional This value is always true in OFN --- app/models/spree/stock/quantifier.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/models/spree/stock/quantifier.rb b/app/models/spree/stock/quantifier.rb index b046dc2b17..8c437dc580 100644 --- a/app/models/spree/stock/quantifier.rb +++ b/app/models/spree/stock/quantifier.rb @@ -11,11 +11,7 @@ module Spree end def total_on_hand - if Spree::Config.track_inventory_levels - stock_items.sum(&:count_on_hand) - else - Float::INFINITY - end + stock_items.sum(&:count_on_hand) end def backorderable? From 47ac6c14916f2418a476db6011bae4356bcaad3b Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 09:51:32 +0200 Subject: [PATCH 080/166] Remove unused methods from ProductSimpleSerializer --- app/serializers/api/admin/product_simple_serializer.rb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/serializers/api/admin/product_simple_serializer.rb b/app/serializers/api/admin/product_simple_serializer.rb index ad7ad16ba1..6b968ab8d3 100644 --- a/app/serializers/api/admin/product_simple_serializer.rb +++ b/app/serializers/api/admin/product_simple_serializer.rb @@ -10,16 +10,6 @@ module Api def producer_id object.supplier_id end - - def on_hand - return 0 if object.on_hand.nil? - - object.on_hand - end - - def price - object.price.nil? ? '0.0' : object.price - end end end end From e3de71668af044c9466e7c401da24747cb8a009b Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 7 Apr 2020 13:15:48 +0100 Subject: [PATCH 081/166] Depend on a spree version in which spree_core doesnt depend on deface AND remove deface from list of dependencies --- Gemfile | 1 - Gemfile.lock | 14 +++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index b01600d0d3..30def03b30 100644 --- a/Gemfile +++ b/Gemfile @@ -70,7 +70,6 @@ gem 'angularjs-file-upload-rails', '~> 2.4.1' gem 'blockenspiel' gem 'custom_error_message', github: 'jeremydurham/custom-err-msg' gem 'dalli' -gem 'deface', '1.0.2' gem 'diffy' gem 'figaro' gem 'geocoder' diff --git a/Gemfile.lock b/Gemfile.lock index 1cf17a8cd4..9698de0377 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,7 +23,7 @@ GIT GIT remote: https://github.com/openfoodfoundation/spree.git - revision: 8a8585a43cd04d1a50dc65227f337a91b18d66d5 + revision: e10ca1f689b1658040b081939b7523f6fb68895a branch: 2-0-4-stable specs: spree_core (2.0.4) @@ -32,14 +32,13 @@ GIT awesome_nested_set (= 2.1.5) aws-sdk (~> 1.11.1) cancan (~> 1.6.10) - deface (>= 0.9.1) ffaker (~> 1.16) highline (= 1.6.18) httparty (~> 0.11) json (>= 1.7.7) kaminari (~> 0.14.1) money (= 5.1.1) - paperclip (~> 3.0) + paperclip (~> 3.4.1) paranoia (~> 1.3) rails (~> 3.2.14) ransack (= 0.7.2) @@ -167,7 +166,6 @@ GEM coffee-script-source execjs coffee-script-source (1.10.0) - colorize (0.8.1) combine_pdf (1.0.16) ruby-rc4 (>= 0.1.5) compass (1.0.3) @@ -201,11 +199,6 @@ GEM ddtrace (0.34.1) msgpack debugger-linecache (1.2.0) - deface (1.0.2) - colorize (>= 0.5.8) - nokogiri (~> 1.6.0) - polyglot - rails (>= 3.1) delayed_job (4.1.8) activesupport (>= 3.0, < 6.1) delayed_job_active_record (4.1.4) @@ -238,7 +231,7 @@ GEM railties (>= 3.0.0) faraday (1.0.0) multipart-post (>= 1.2, < 3) - ffaker (1.22.1) + ffaker (1.32.1) ffi (1.12.2) figaro (1.1.1) thor (~> 0.14) @@ -715,7 +708,6 @@ DEPENDENCIES db2fog ddtrace debugger-linecache - deface (= 1.0.2) delayed_job_active_record delayed_job_web devise (~> 2.2.5) From 71ffa6b17841fb2556a818c6dda8670d018d1583 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 7 Apr 2020 13:20:49 +0100 Subject: [PATCH 082/166] Upgrade nokogiri as much as possible (it's not an explicit dependency of OFN and we dont need to control the version now, so I remove it from Gemfile) --- Gemfile | 2 -- Gemfile.lock | 7 +++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 30def03b30..f3b6d8220d 100644 --- a/Gemfile +++ b/Gemfile @@ -9,8 +9,6 @@ gem 'rails-i18n', '~> 3.0.0' gem 'rails_safe_tasks', '~> 1.0' gem "activerecord-import" -# Patched version. See http://rubysec.com/advisories/CVE-2015-5312/. -gem 'nokogiri', '>= 1.6.7.1' gem "catalog", path: "./engines/catalog" gem "order_management", path: "./engines/order_management" diff --git a/Gemfile.lock b/Gemfile.lock index 9698de0377..a52fb38d06 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -442,7 +442,7 @@ GEM method_source (0.9.2) mime-types (1.25.1) mini_mime (1.0.1) - mini_portile2 (2.1.0) + mini_portile2 (2.4.0) mini_racer (0.2.9) libv8 (>= 6.9.411) momentjs-rails (2.20.1) @@ -454,8 +454,8 @@ GEM multi_xml (0.6.0) multipart-post (2.1.1) newrelic_rpm (3.18.1.330) - nokogiri (1.6.8.1) - mini_portile2 (~> 2.1.0) + nokogiri (1.10.9) + mini_portile2 (~> 2.4.0) oauth2 (1.4.4) faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) @@ -737,7 +737,6 @@ DEPENDENCIES mini_racer (= 0.2.9) momentjs-rails newrelic_rpm (~> 3.0) - nokogiri (>= 1.6.7.1) oauth2 (~> 1.4.4) ofn-qz! oj From 4aad80c134e7ad23293a18c2204f4f65e40c9bff Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 7 Apr 2020 15:36:14 +0100 Subject: [PATCH 083/166] Update message for capybara with new upgrade blocker --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index f3b6d8220d..983493975e 100644 --- a/Gemfile +++ b/Gemfile @@ -122,7 +122,7 @@ group :test, :development do # Pretty printed test output gem 'atomic' gem 'awesome_print' - gem 'capybara', '>= 2.18.0' # 3.0 requires nokogiri 1.8 + gem 'capybara', '>= 2.18.0' # 3.0 requires rack 1.6 that only works with Rails 4.2 gem 'database_cleaner', '0.7.1', require: false gem "factory_bot_rails", require: false gem 'fuubar', '~> 2.5.0' From 2ff8356c63ebf316a04fa0eac8b4b897d0ebbf04 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 9 Apr 2020 16:33:17 +0100 Subject: [PATCH 084/166] Delete dead code from products helper --- app/controllers/base_controller.rb | 4 ---- app/helpers/spree/products_helper.rb | 13 ++++++++++ .../spree/products_helper_decorator.rb | 23 ------------------ spec/helpers/products_helper_spec.rb | 24 ------------------- 4 files changed, 13 insertions(+), 51 deletions(-) create mode 100644 app/helpers/spree/products_helper.rb delete mode 100644 app/helpers/spree/products_helper_decorator.rb delete mode 100644 spec/helpers/products_helper_spec.rb diff --git a/app/controllers/base_controller.rb b/app/controllers/base_controller.rb index dab3eb6752..fdbe51634d 100644 --- a/app/controllers/base_controller.rb +++ b/app/controllers/base_controller.rb @@ -14,10 +14,6 @@ class BaseController < ApplicationController helper 'spree/base' - # Spree::Core::ControllerHelpers declares helper_method get_taxonomies, so we need to - # include Spree::ProductsHelper so that method is available on the controller - include Spree::ProductsHelper - before_filter :set_locale before_filter :check_order_cycle_expiry diff --git a/app/helpers/spree/products_helper.rb b/app/helpers/spree/products_helper.rb new file mode 100644 index 0000000000..9e367fb010 --- /dev/null +++ b/app/helpers/spree/products_helper.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Spree + module ProductsHelper + def product_has_variant_unit_option_type?(product) + product.option_types.any? { |option_type| variant_unit_option_type? option_type } + end + + def variant_unit_option_type?(option_type) + Spree::Product.all_variant_unit_option_types.include? option_type + end + end +end diff --git a/app/helpers/spree/products_helper_decorator.rb b/app/helpers/spree/products_helper_decorator.rb deleted file mode 100644 index ac31d260b9..0000000000 --- a/app/helpers/spree/products_helper_decorator.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Spree - ProductsHelper.class_eval do - # Return the price of the variant, overriding sprees price diff capability. - # This will allways return the variant price as if the show_variant_full_price is set. - def variant_price_diff(variant) - "(#{Spree::Money.new(variant.price)})" - end - - def product_has_variant_unit_option_type?(product) - product.option_types.any? { |option_type| variant_unit_option_type? option_type } - end - - def variant_unit_option_type?(option_type) - Spree::Product.all_variant_unit_option_types.include? option_type - end - - def product_variant_unit_options - [[I18n.t(:weight), 'weight'], - [I18n.t(:volume), 'volume'], - [I18n.t(:items), 'items']] - end - end -end diff --git a/spec/helpers/products_helper_spec.rb b/spec/helpers/products_helper_spec.rb deleted file mode 100644 index 876c263eed..0000000000 --- a/spec/helpers/products_helper_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' - -module Spree - describe ProductsHelper, type: :helper do - it "displays variant price differences as absolute, not relative values" do - variant = make_variant_stub(10.00, 10.00) - expect(helper.variant_price_diff(variant)).to eq("(#{with_currency(10.00)})") - - variant = make_variant_stub(10.00, 15.55) - expect(helper.variant_price_diff(variant)).to eq("(#{with_currency(15.55)})") - - variant = make_variant_stub(10.00, 5.55) - expect(helper.variant_price_diff(variant)).to eq("(#{with_currency(5.55)})") - end - - private - - def make_variant_stub(product_price, variant_price) - product = double(:product, price: product_price) - variant = double(:variant, product: product, price: variant_price) - variant - end - end -end From cf712e947878416d3f11d2fe67408cdefa9e5945 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 13:57:24 +0200 Subject: [PATCH 085/166] Select only enterprise id --- app/controllers/admin/customers_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index a2109c3fca..902b458dab 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -64,8 +64,10 @@ module Admin def collection return Customer.where("1=0") unless json_request? && params[:enterprise_id].present? - enterprise = Enterprise.managed_by(spree_current_user).find_by_id(params[:enterprise_id]) - Customer.of(enterprise) + enterprise_id = Enterprise.managed_by(spree_current_user). + select('enterprises.id').find_by_id(params[:enterprise_id]) + + Customer.of(enterprise_id) end def load_managed_shops From 59f56cb0f66f7f019700871f30c065194d193809 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 9 Apr 2020 17:32:28 +0100 Subject: [PATCH 086/166] Remove before delivery method in checkout controller, this differentiator is never used in OFN, only in Spree frontend code --- app/controllers/checkout_controller.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 26c566e9a6..78aca3479c 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -133,13 +133,6 @@ class CheckoutController < Spree::StoreController @order.ship_address = finder.ship_address end - def before_delivery - return if params[:order].present? - - packages = @order.shipments.map(&:to_package) - @differentiator = Spree::Stock::Differentiator.new(@order, packages) - end - def before_payment current_order.payments.destroy_all if request.put? end From 0ca87580e83fe861dfb2856f8c88c39aa6333a8b Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 19:48:13 +0200 Subject: [PATCH 087/166] Load variants in cart in one query Avoids an N+1 --- app/services/variants_stock_levels.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/services/variants_stock_levels.rb b/app/services/variants_stock_levels.rb index 73f6e68278..5763996752 100644 --- a/app/services/variants_stock_levels.rb +++ b/app/services/variants_stock_levels.rb @@ -8,10 +8,12 @@ class VariantsStockLevels variant_stock_levels = variant_stock_levels(order.line_items) order_variant_ids = variant_stock_levels.keys - missing_variant_ids = requested_variant_ids - order_variant_ids - missing_variant_ids.each do |variant_id| - variant = scoped_variant(order.distributor, Spree::Variant.find(variant_id)) - variant_stock_levels[variant_id] = { quantity: 0, max_quantity: 0, on_hand: variant.on_hand, on_demand: variant.on_demand } + missing_variants = Spree::Variant.where(id: (requested_variant_ids - order_variant_ids)) + + missing_variants.each do |missing_variant| + variant = scoped_variant(order.distributor, missing_variant) + variant_stock_levels[variant.id] = + { quantity: 0, max_quantity: 0, on_hand: variant.on_hand, on_demand: variant.on_demand } end variant_stock_levels From 57d87a804264f3d138d34050792d799cc643cfde Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 19:48:50 +0200 Subject: [PATCH 088/166] Eager-load variant stock items Avoids another N+1 --- app/services/variants_stock_levels.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/variants_stock_levels.rb b/app/services/variants_stock_levels.rb index 5763996752..f06002db19 100644 --- a/app/services/variants_stock_levels.rb +++ b/app/services/variants_stock_levels.rb @@ -8,7 +8,8 @@ class VariantsStockLevels variant_stock_levels = variant_stock_levels(order.line_items) order_variant_ids = variant_stock_levels.keys - missing_variants = Spree::Variant.where(id: (requested_variant_ids - order_variant_ids)) + missing_variants = Spree::Variant.includes(:stock_items). + where(id: (requested_variant_ids - order_variant_ids)) missing_variants.each do |missing_variant| variant = scoped_variant(order.distributor, missing_variant) From 0d5c08c363ec751696f39aecb3b89a2134987f4d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 9 Apr 2020 19:06:05 +0100 Subject: [PATCH 089/166] Remove dead code, there's no Spree::Money in app/models/spree and the Spree::Money in lib/spree already has a class_eval with this function --- app/models/spree/money_decorator.rb | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 app/models/spree/money_decorator.rb diff --git a/app/models/spree/money_decorator.rb b/app/models/spree/money_decorator.rb deleted file mode 100644 index ae4ca7e497..0000000000 --- a/app/models/spree/money_decorator.rb +++ /dev/null @@ -1,6 +0,0 @@ -Spree::Money.class_eval do - # return the currency symbol (on it's own) for the current default currency - def self.currency_symbol - Money.new(0, Spree::Config[:currency]).symbol - end -end From 314fed063d38896f54ae09637948bafa6d41459d Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 9 Apr 2020 19:09:22 +0100 Subject: [PATCH 090/166] Merge property with property_decorator both in our codebase --- app/models/spree/property.rb | 23 ++++++++++++++++++++++ app/models/spree/property_decorator.rb | 27 -------------------------- 2 files changed, 23 insertions(+), 27 deletions(-) delete mode 100644 app/models/spree/property_decorator.rb diff --git a/app/models/spree/property.rb b/app/models/spree/property.rb index 514de54313..792b39e5b5 100644 --- a/app/models/spree/property.rb +++ b/app/models/spree/property.rb @@ -2,11 +2,34 @@ module Spree class Property < ActiveRecord::Base has_many :product_properties, dependent: :destroy has_many :products, through: :product_properties + has_many :producer_properties attr_accessible :name, :presentation validates :name, :presentation, presence: true scope :sorted, -> { order(:name) } + + scope :applied_by, ->(enterprise) { + select('DISTINCT spree_properties.*'). + joins(:product_properties). + where('spree_product_properties.product_id IN (?)', enterprise.supplied_product_ids) + } + + scope :ever_sold_by, ->(shop) { + joins(products: { variants: { exchanges: :order_cycle } }). + merge(Exchange.outgoing). + merge(Exchange.to_enterprise(shop)). + select('DISTINCT spree_properties.*') + } + + scope :currently_sold_by, ->(shop) { + ever_sold_by(shop). + merge(OrderCycle.active) + } + + def property + self + end end end diff --git a/app/models/spree/property_decorator.rb b/app/models/spree/property_decorator.rb deleted file mode 100644 index aeeb607af9..0000000000 --- a/app/models/spree/property_decorator.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Spree - Property.class_eval do - has_many :producer_properties - - scope :applied_by, ->(enterprise) { - select('DISTINCT spree_properties.*'). - joins(:product_properties). - where('spree_product_properties.product_id IN (?)', enterprise.supplied_product_ids) - } - - scope :ever_sold_by, ->(shop) { - joins(products: { variants: { exchanges: :order_cycle } }). - merge(Exchange.outgoing). - merge(Exchange.to_enterprise(shop)). - select('DISTINCT spree_properties.*') - } - - scope :currently_sold_by, ->(shop) { - ever_sold_by(shop). - merge(OrderCycle.active) - } - - def property - self - end - end -end From e97a16cb40483b2a3d33548da887fe2fa876d9e8 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Fri, 10 Apr 2020 04:14:21 +1000 Subject: [PATCH 091/166] Updating translations for config/locales/ca.yml --- config/locales/ca.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 35a2a9657a..684076b91b 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -31,6 +31,10 @@ ca: taken: "Ja hi ha un compte per a aquest correu electrònic. Si us plau, inicia sessió o restableix la contrasenya." spree/order: no_card: No hi ha targetes de crèdit autoritzades disponibles per carregar + spree/credit_card: + attributes: + base: + card_expired: "Ha expirat" order_cycle: attributes: orders_close_at: @@ -55,7 +59,7 @@ ca: messages: inclusion: "no està inclòs a la llista" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Afegiu com a mínim un producte" From 0fabde88494baddc62f4ff6ac561949d1132437a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2020 19:21:30 +0000 Subject: [PATCH 092/166] Bump rubocop-rails from 2.5.1 to 2.5.2 Bumps [rubocop-rails](https://github.com/rubocop-hq/rubocop-rails) from 2.5.1 to 2.5.2. - [Release notes](https://github.com/rubocop-hq/rubocop-rails/releases) - [Changelog](https://github.com/rubocop-hq/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop-hq/rubocop-rails/compare/v2.5.1...v2.5.2) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1cf17a8cd4..cb46f056db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -483,7 +483,7 @@ GEM parallel (1.19.1) paranoia (1.3.4) activerecord (~> 3.1) - parser (2.7.0.5) + parser (2.7.1.0) ast (~> 2.4.0) paypal-sdk-core (0.2.10) multi_json (~> 1.0) @@ -596,7 +596,7 @@ GEM rexml ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-rails (2.5.1) + rubocop-rails (2.5.2) activesupport rack (>= 1.1) rubocop (>= 0.72.0) From 31a54e49c5c95281df019cfbe1593232886eaeaa Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 14:06:18 +0200 Subject: [PATCH 093/166] Allow User#default_card to work with eager-loading --- app/models/spree/user.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index 135e54d306..63d51f657c 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -125,7 +125,12 @@ module Spree end def default_card - credit_cards.where(is_default: true).first + # Don't re-fetch associated cards from the DB if they're already eager-loaded + if credit_cards.loaded? + credit_cards.to_a.find(&:is_default) + else + credit_cards.where(is_default: true).first + end end # Checks whether the specified user is a superadmin, with full control of the From 2a8809e6e8fed014ed7be093f4e7d99be5f73a42 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 14:06:49 +0200 Subject: [PATCH 094/166] Eager-load default card in customer serializer --- app/controllers/admin/customers_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 902b458dab..8143df7ee2 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -67,7 +67,7 @@ module Admin enterprise_id = Enterprise.managed_by(spree_current_user). select('enterprises.id').find_by_id(params[:enterprise_id]) - Customer.of(enterprise_id) + Customer.of(enterprise_id).includes(user: :credit_cards) end def load_managed_shops From e53f733966ab51560b3db513d2e343bf38be8258 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 14:48:00 +0200 Subject: [PATCH 095/166] Eager-load addresses in customer serializer --- app/controllers/admin/customers_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 8143df7ee2..680248e94f 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -67,7 +67,7 @@ module Admin enterprise_id = Enterprise.managed_by(spree_current_user). select('enterprises.id').find_by_id(params[:enterprise_id]) - Customer.of(enterprise_id).includes(user: :credit_cards) + Customer.of(enterprise_id).includes(:bill_address, :ship_address, user: :credit_cards) end def load_managed_shops From 4c41c84cc1688670e6dde958d366eb39e28d9139 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 9 Apr 2020 16:28:12 +0200 Subject: [PATCH 096/166] Refactor tag rules loading for customers Fixes N+1 queries on customer tags --- app/controllers/admin/customers_controller.rb | 32 ++++++++++++++++--- .../api/admin/customer_serializer.rb | 12 +++++-- .../api/admin/customer_serializer_spec.rb | 15 +++++++-- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 680248e94f..91eda7d4a7 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -17,8 +17,9 @@ module Admin respond_to do |format| format.html format.json do - tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: params[:enterprise_id])) - render_as_json @collection, tag_rule_mapping: tag_rule_mapping + render_as_json @collection, + tag_rule_mapping: tag_rule_mapping, + customer_tags: customer_tags_by_id end end end @@ -64,10 +65,13 @@ module Admin def collection return Customer.where("1=0") unless json_request? && params[:enterprise_id].present? - enterprise_id = Enterprise.managed_by(spree_current_user). - select('enterprises.id').find_by_id(params[:enterprise_id]) + Customer.of(managed_enterprise_id). + includes(:bill_address, :ship_address, user: :credit_cards) + end - Customer.of(enterprise_id).includes(:bill_address, :ship_address, user: :credit_cards) + def managed_enterprise_id + @managed_enterprise_id ||= Enterprise.managed_by(spree_current_user). + select('enterprises.id').find_by_id(params[:enterprise_id]) end def load_managed_shops @@ -82,5 +86,23 @@ module Admin def ams_prefix_whitelist [:subscription] end + + def tag_rule_mapping + TagRule.mapping_for(Enterprise.where(id: managed_enterprise_id)) + end + + # Fetches tags for all customers of the enterprise and returns a hash indexed by customer_id + def customer_tags_by_id + customer_tags = ::ActsAsTaggableOn::Tag. + joins(:taggings). + includes(:taggings). + where(taggings: { taggable_id: Customer.of(managed_enterprise_id), context: 'tags' }) + + customer_tags.each_with_object({}) do |tag, indexed_hash| + customer_id = tag.taggings.first.taggable_id + indexed_hash[customer_id] ||= [] + indexed_hash[customer_id] << tag.name + end + end end end diff --git a/app/serializers/api/admin/customer_serializer.rb b/app/serializers/api/admin/customer_serializer.rb index 070e7927da..7648104600 100644 --- a/app/serializers/api/admin/customer_serializer.rb +++ b/app/serializers/api/admin/customer_serializer.rb @@ -6,7 +6,7 @@ class Api::Admin::CustomerSerializer < ActiveModel::Serializer has_one :bill_address, serializer: Api::AddressSerializer def tag_list - object.tag_list.join(",") + customer_tag_list.join(",") end def name @@ -14,7 +14,7 @@ class Api::Admin::CustomerSerializer < ActiveModel::Serializer end def tags - object.tag_list.map do |tag| + customer_tag_list.map do |tag| tag_rule_map = options[:tag_rule_mapping].andand[tag] tag_rule_map || { text: tag, rules: nil } end @@ -25,4 +25,12 @@ class Api::Admin::CustomerSerializer < ActiveModel::Serializer object.user.default_card.present? end + + private + + def customer_tag_list + return object.tag_list unless options[:customer_tags] + + options[:customer_tags].andand[object.id] || [] + end end diff --git a/spec/serializers/api/admin/customer_serializer_spec.rb b/spec/serializers/api/admin/customer_serializer_spec.rb index 02c97e3948..0d9b1625d9 100644 --- a/spec/serializers/api/admin/customer_serializer_spec.rb +++ b/spec/serializers/api/admin/customer_serializer_spec.rb @@ -1,12 +1,16 @@ require 'spec_helper' describe Api::Admin::CustomerSerializer do - let(:customer) { create(:customer, tag_list: "one, two, three") } + let(:tag_list) { ["one", "two", "three"] } + let(:customer) { create(:customer, tag_list: tag_list) } let!(:tag_rule) { create(:tag_rule, enterprise: customer.enterprise, preferred_customer_tags: "two") } it "serializes a customer with tags" do tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: customer.enterprise_id)) - serializer = Api::Admin::CustomerSerializer.new customer, tag_rule_mapping: tag_rule_mapping + customer_tag_list = { customer.id => tag_list } + serializer = Api::Admin::CustomerSerializer.new customer, + tag_rule_mapping: tag_rule_mapping, + customer_tags: customer_tag_list result = JSON.parse(serializer.to_json) expect(result['email']).to eq customer.email tags = result['tags'] @@ -27,4 +31,11 @@ describe Api::Admin::CustomerSerializer do expect(tag['rules']).to be nil end end + + it 'serializes a customer without customer_tags' do + serializer = Api::Admin::CustomerSerializer.new customer + result = JSON.parse(serializer.to_json) + + expect(result['tags'].first['text']).to eq tag_list.first + end end From eafffa2c231d2baadb70e5a39604c68a26c0d3b1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 10 Apr 2020 13:08:11 +0100 Subject: [PATCH 097/166] Update all locales with the latest Transifex translations --- config/locales/ar.yml | 2 +- config/locales/en_AU.yml | 2 +- config/locales/en_BE.yml | 2 +- config/locales/en_CA.yml | 2 +- config/locales/en_DE.yml | 2 +- config/locales/en_PH.yml | 6 +- config/locales/en_US.yml | 2 +- config/locales/en_ZA.yml | 2 +- config/locales/es.yml | 2 +- config/locales/fil_PH.yml | 620 +++++++++++++++++++------------------- config/locales/fr.yml | 4 +- config/locales/fr_BE.yml | 2 +- config/locales/fr_CA.yml | 2 +- config/locales/it.yml | 2 +- config/locales/nb.yml | 2 +- config/locales/nl_BE.yml | 2 +- config/locales/pt.yml | 2 +- config/locales/pt_BR.yml | 2 +- config/locales/tr.yml | 2 +- 19 files changed, 332 insertions(+), 330 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index b7c5a59b6c..d0aa90278c 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -55,7 +55,7 @@ ar: messages: inclusion: "غير مدرجة في القائمة" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^ الرجاء إضافة منتج واحد على الأقل" diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index ecc81b40ce..2c658de1aa 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -53,7 +53,7 @@ en_AU: payment_method_ids: "Payment Methods" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index 7f6c05a7c3..348dbbbc9a 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -53,7 +53,7 @@ en_BE: payment_method_ids: "Payment Methods" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 193b756e57..6c33563ca2 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -55,7 +55,7 @@ en_CA: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index 8c81c87986..2f7d28557a 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -53,7 +53,7 @@ en_DE: payment_method_ids: "Payment Methods" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index d5cd28c690..97ae33afaf 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -59,7 +59,7 @@ en_PH: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" @@ -1203,8 +1203,8 @@ en_PH: menu_2_url: "/map" menu_3_title: "Producers" menu_3_url: "/producers" - menu_4_title: "Groups" - menu_4_url: "/groups" + menu_4_title: "Fees" + menu_4_url: "/sell" menu_5_title: "About" menu_5_url: "https://www.openfoodnetwork.org/about-us/" menu_6_title: "Connect" diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index 1e04a29f90..93c675a0d1 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -55,7 +55,7 @@ en_US: messages: inclusion: "is not included in the list" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 71e4279ab3..74ecc774dc 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -53,7 +53,7 @@ en_ZA: payment_method_ids: "Payment Methods" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Please add at least one product" diff --git a/config/locales/es.yml b/config/locales/es.yml index ab12b1328f..b7d30e1b8f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -53,7 +53,7 @@ es: payment_method_ids: "Métodos de Pago" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Por favor agrega al menos un producto" diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index d6ae17f48a..1db31edec6 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -3,11 +3,11 @@ fil_PH: activerecord: attributes: enterprise_fee: - fee_type: uri ng bayarin + fee_type: Uri ng Bayarin spree/order: payment_state: Status ng Pagbabayad - shipment_state: kalagayan ng kargamento - completed_at: Natapos sa + shipment_state: status ng kargamento + completed_at: Nakumpleto number: Bilang state: Status email: Email ng Parokyano @@ -15,7 +15,7 @@ fil_PH: amount: Halaga spree/product: primary_taxon: "Kategorya ng Produkto" - supplier: "Suplayer" + supplier: "Supplier" shipping_category_id: "Kategorya ng Pagpapadala" variant_unit: "Yunit ng variant" variant_unit_name: "pangalan ng yunit ng variant" @@ -30,7 +30,7 @@ fil_PH: email: taken: "Mayroon ng account para sa email na ito. Maglog-in o i-reset ang inyong password." spree/order: - no_card: walang mga awtorisadong credit card na maaaring i-charge + no_card: Walang mga awtorisadong credit card na maaaring i-charge spree/credit_card: attributes: base: @@ -43,12 +43,12 @@ fil_PH: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "ay dapat blanko sapagkat ginagamit ang stock settings ng producer" on_demand_but_count_on_hand_set: "ay dapat blanko kung on demand" - limited_stock_but_no_count_on_hand: "ay dapat matukoy sapagkat pinupuwersa ang limitadong stock" + limited_stock_but_no_count_on_hand: "ay dapat matukoy sapagkat ipipilit ang limitadong stock" activemodel: attributes: order_management/reports/enterprise_fee_summary/parameters: - start_at: "simula" - end_at: "katapusan" + start_at: "Simula" + end_at: "Hanggang" distributor_ids: "Hubs" producer_ids: "Producers" order_cycle_ids: "Order Cycles" @@ -71,10 +71,10 @@ fil_PH: schedule: not_coordinated_by_shop: "ay hindi coordinated ng%{shop}" payment_method: - not_available_to_shop: "ay hindi magagamit para%{shop}" + not_available_to_shop: "ay hindi magagamit para sa%{shop}" invalid_type: "ay dapat pamamaraang Cash o Stripe" charges_not_allowed: "^ang paniningil gamit ang Credit card ay hindi pinahihintulutan ng Customer na ito" - no_default_card: "^walang card na maaring gamitin para sa Customer na ito" + no_default_card: "^Walang default card na maaaring gamitin para sa customer na ito" shipping_method: not_available_to_shop: "ay hindi magagamit para%{shop}" devise: @@ -98,7 +98,7 @@ fil_PH: hindi valid ang email o password. isa ka bang Guest dati? marahil ay kailangang gumawa ng account o i-reset ang inyong password. unconfirmed: "Kailangang kumpirmahin ang inyong account bago magpatuloy." - already_registered: "ang email address ay nakaregister na. Maglog-in upang makapagpatuloy o bumalik at gumamit ng ibang email address" + already_registered: "Ang email address na ito ay nakarehistro na. Maglog-in upang makapagpatuloy o bumalik at gumamit ng ibang email address." success: logged_in_succesfully: "Matagumpay na nakapaglog-in." user_passwords: @@ -122,9 +122,9 @@ fil_PH: welcome: subject: "%{enterprise}ay nasa %{sitename}na ngayon" email_welcome: "Maligayang pagdating" - email_registered: "ay kabilang na ng/sa" - email_userguide_html: "ang user guide na may detalyadong suporta para sa pagset-up ng iyong Producer o Hub ay narito: %{link}" - userguide: "Open Food Network Gabay sa Gumagamit" + email_registered: "ay miyembro na ng" + email_userguide_html: "Narito ang Gabay sa Paggamit na may detalyadong suporta para sa pagset-up ng iyong Producer o Hub: %{link}" + userguide: "Gabay sa Paggamit ng Open Food Network" email_admin_html: "maaaring pamahalaan ang iyong account sa pamamagitan ng paglog-in sa%{link}o sa pagpindot sa cog sa pinakataas na kanang bahagi ng homepage at pagpili sa Administration." admin_panel: "Admin Panel" email_community_html: "Kami ay mayroon ding online forum para sa talakayang pangkomunidad na may kinalaman sa OFN software at sa mga natatanging hamon sa pagpapatakbo ng enterprise ng pagkain. Kayo ay hinihikayat namin na sumali rito. Kami ay patuloy na nagbabago para makapagbigay ng mas mabuting serbisyo, at ang inyong suhestiyon sa forum ay makakatulong para mga susunod na pagbabago.%{link}" @@ -171,7 +171,7 @@ fil_PH: explainer: ang mga order na ito ay namarkahan na kumpleto at hindi na babaguhin processing: title: May Error na Kinaharap (%{count}na order) - explainer: ang awtomatikong pagproseso ng mga order na ito ay hindi nagtagumpay dahil sa isang error. ang error ay nailista upang mabusisi kung saan posibleng nagsimula. + explainer: ang awtomatikong pagproseso ng mga order na ito ay hindi nagtagumpay dahil sa isang error. ang error ay nailista na upang mabusisi kung saan posibleng nagsimula. failed_payment: title: Hindi Nagtagumpay Ang Pagbayad (%{count}na order) explainer: ang awtomatikong pagproseso ng bayad para sa mga order na ito ay hindi nagtagumpay dahil sa isang error. ang error ay nailista upang mabusisi kung saan posibleng nagsimula. @@ -181,9 +181,9 @@ fil_PH: home: "OFN" title: Open Food Network welcome_to: 'Maligayang Pagdating sa' - site_meta_description: "Kami ay nagsimula sa pinakaibaba pataas. Kasama ang mga magsasaka at tagatanim na may ipagmamalaki at handang ibahagi ang kanilang mga kuwento. Kasama rin namin ang mga tagapamahaging patas at tapat na handang makipag-usap sa mga taong may produkto. At mga mamimili na naniniwala na ang mabusising lingguhang pamimili ay..." - search_by_name: Hanapin gamit ang pangalan o lungsod - producers_join: ang mga Pilipinong producers ay inaanyayahang sumali sa Open Food Network. + site_meta_description: "Kami ay nagsimula sa pinakaibaba pataas. Kasama ang mga magsasaka at tagatanim na handang ibahagi at ipagmalaki ang kanilang mga kuwento. May mga tapat at patas na Distributors na handang makipag-usap sa mga gumagawa ng produkto. At mga mamimili na naniniwala na ang mabusising lingguhang pamimili ay..." + search_by_name: Hanapin gamit ang pangalan o lungsod... + producers_join: Ang mga Pilipinong producers ay inaanyayahang naming sumali sa Open Food Network. charges_sales_tax: Charges GST? print_invoice: "i-print ang invoice" print_ticket: "i-print ang ticket" @@ -194,16 +194,16 @@ fil_PH: edit_order: "i-edit ang order" ship_order: "i-ship ang order" cancel_order: "i-cancel ang order" - confirm_send_invoice: "ang invoice para sa order na ito ay ipapadala sa customer. gusto mo bang magpatuloy?" + confirm_send_invoice: "ang invoice para sa order na ito ay ipapadala sa customer. nais mo bang magpatuloy?" confirm_resend_order_confirmation: "nais mo bang ipadala muli ang order confirmation email?" must_have_valid_business_number: "%{enterprise_name}ay dapat may valid na ABN bago makapagpadala ng mga invoice" invoice: "invoice" - more: "Iba pa" - say_no: "hindi" - say_yes: "oo" + more: "Karagdagang Impormasyon" + say_no: "Hindi" + say_yes: "Oo" ongoing: Nagaganap bill_address: Billing Address - ship_address: Shipping Address + ship_address: Address kung saan ipapadala sort_order_cycles_on_shopfront_by: "Uriin ang mga order cycle sa shopfront gamit ang" required_fields: ang mga kailangang may sagot ay may nakalagay na asterisk select_continue: pumili at magpatuloy @@ -211,19 +211,19 @@ fil_PH: or: o collapse_all: Itago lahat expand_all: Ipakita lahat - loading: naglo-load... + loading: Naglo-load... show_more: Ipakita lahat show_all: Ipakita lahat - show_all_with_more: "ipakita lahat (%{num}iba pa)" + show_all_with_more: "Ipakita lahat (%{num}pa)" cancel: i-cancel edit: i-edit clone: Clone - distributors: mga tagapamahagi + distributors: Mga Distributor bulk_order_management: Pamamahala sa pangmaramihang order - enterprises: enterprises + enterprises: Mga Enterprise enterprise_groups: Mga grupo reports: mga ulat - variant_overrides: imbentaryo + variant_overrides: Imbentaryo import: i-import spree_products: mga produktong Spree all: Lahat @@ -231,10 +231,10 @@ fil_PH: available: Available dashboard: Dashboard undefined: hindi matukoy - unused: hindi nagamit + unused: Hindi nagamit admin_and_handling: Admin & Handling - profile: profile - supplier_only: Supplier lamang + profile: Profile + supplier_only: Supplier Lamang has_shopfront: May Shopfront weight: timbang volume: dami @@ -242,25 +242,25 @@ fil_PH: summary: Buod detailed: detalyado updated: na-update - 'yes': "oo" - 'no': "hindi" + 'yes': "Oo" + 'no': "Hindi" y: 'Y' n: 'N' powered_by: Powered by blocked_cookies_alert: " ang iyong browser ay maaaring hinaharang ang cookies na kailangan upang magamit ang shopfront na ito. Pindutin sa ibaba upang payagan ang mga cookies at i-reload ang pahina." allow_cookies: "Payagan ang cookies" notes: mga tala - error: error - processing_payment: "pinoproseso ang bayad" + error: Error + processing_payment: "Pinoproseso ang bayad..." no_pending_payments: "walang nakabinbin na mga bayarin" - invalid_payment_state: "hindi valid na estado ng pagbabayad" - filter_results: i-filter ang mga resulta - quantity: dami + invalid_payment_state: "hindi valid na status ng pagbabayad" + filter_results: I-filter ang mga resulta + quantity: Dami pick_up: kunin - copy: kopyahin - change_my_password: "palitan ang aking password" + copy: Kopyahin + change_my_password: "Palitan ang aking password" update_password: "i-update ang password" - password_confirmation: kumpirmasyon ng password + password_confirmation: Kumpirmasyon ng password reset_password_token: i-reset ang password token expired: ay expired na, magrequest ng bago back_to_payments_list: "ibalik sa listahan ng mga bayad" @@ -269,43 +269,43 @@ fil_PH: on hand: "on hand" ship: "ship" actions: - create_and_add_another: "gumawa at magdagdag ng isa pa" + create_and_add_another: "Gumawa at magdagdag ng isa pa" create: "gumawa" cancel: "i-cancel" save: "i-save" edit: "i-edit" update: "i-update" - delete: "tanggalin" + delete: "Tanggalin" admin: begins_at: nagsimula sa begins_on: nagsisimula sa - customer: customer - date: petsa - email: email + customer: Customer + date: Petsa + email: Email ends_at: nagtatapos sa ends_on: natapos sa - name: pangalan + name: Pangalan on_hand: on hand on_demand: on demand on_demand?: on demand? - order_cycle: order cycle + order_cycle: Order Cycle payment: kabayaran - payment_method: paraan ng pagbayad - phone: telepono - price: presyo - producer: Prodyuser - image: imahe - product: produkto - quantity: dami + payment_method: Paraan ng pagbayad + phone: Telepono + price: Presyo + producer: Producer + image: larawan + product: Produkto + quantity: Dami schedule: iskedyul shipping: pagpapadala shipping_method: paraan ng pagpapadala shop: Shop sku: SKU - status_state: kalagayan + status_state: Status tags: tags variant: Uri - weight: timbang + weight: Timbang volume: dami items: mga item select_all: piliin ang lahat @@ -313,26 +313,26 @@ fil_PH: clear_all: alisin lahat start_date: "Petsa na nagsimula" end_date: "Petsa na natapos" - form_invalid: "ang form ay may nawawala o hindi valid na sagutan" + form_invalid: "ang form ay may nawawala o hindi valid na sagot sa mga patlang" clear_filters: alisin ang mga filter clear: alisin save: i-save cancel: i-cancel back: bumalik - show_more: ipakita lahat - show_n_more: ipakita%{num}iba pa - choose: "pumili" + show_more: Ipakita lahat + show_n_more: Ipakita%{num}pa + choose: "pumili..." please_select: pumili columns: hanay actions: mga kilos - viewing: "tinitignan: %{current_view_name}" + viewing: "Tinitignan: %{current_view_name}" description: paglalarawan - whats_this: ano ito? - tag_has_rules: "mga umiiral na patakaran para sa tag na ito: %{num}" + whats_this: Ano ito? + tag_has_rules: "mga umiiral na panuntunan para sa tag na ito: %{num}" has_one_rule: "may isang panuntunan" has_n_rules: "ay may%{num}na panuntunan" unsaved_confirm_leave: "may mga hindi naka-save na pagbabago sa pahina na ito. Magpatuloy ng hindi sine-save?" - unsaved_changes: "may mga hindi na-save na pagbabago" + unsaved_changes: "May mga pagbabago na hindi na-save" shopfront_settings: embedded_shopfront_settings: "Embedded Shopfront Settings" enable_embedded_shopfronts: "Enable Embedded Shopfronts" @@ -344,7 +344,7 @@ fil_PH: edit: title: "settings para sa invoice" enable_invoices?: "paganahin ang mga invoice?" - invoice_style2?: "gamitin ang alternatibong modelo ng invoice na kinabibilangan ng kabuuang breakdown ng buwis bawat rate at impormasyon ng rate ng buwis kada item (hindi pa akma para sa mga bansang nagpapakita na presyo na hindi kasama ang tax)" + invoice_style2?: "gamitin ang alternatibong modelo ng invoice na kinabibilangan ng kabuuang breakdown ng tax bawat rate at impormasyon ng rate ng tax kada item (hindi pa akma para sa mga bansang nagpapakita na presyo na hindi kasama ang tax)" enable_receipt_printing?: "ipakita ang mga pagpipilian sa pag-print ng mga resibo gamit ang thermal printers sa dropdown ng order." stripe_connect_settings: edit: @@ -353,11 +353,11 @@ fil_PH: stripe_connect_enabled: paganahin ang pagtanggap ng mga bayad gamit ang Stripe Connect sa mga Shop? no_api_key_msg: walang Stripe account para sa enterprise na ito configuration_explanation_html: para sa detalyadong panuto sa pag-configure ng pagsasama ng Stripe Connect, maaari lamang nakumonsulta sa gabay. - status: katayuan - ok: ok + status: Status + ok: Ok instance_secret_key: Instance Secret Key account_id: Account ID - business_name: pangalan ng negosyo + business_name: Pangalan ng negosyo charges_enabled: pinagana ang paniningil charges_enabled_warning: "Babala: Ang paniningil ay hindi pa napapagana sa iyong account" auth_fail_error: ang API key na inyong binigay ay invalid @@ -375,14 +375,14 @@ fil_PH: code: Code duplicate_code: "ang code na ito ay nagamit na" bill_address: "Billing Address" - ship_address: "Shipping Address" + ship_address: "Address kung saan ipapadala" update_address_success: 'matagumpay na na-update ang address' update_address_error: 'pakisagutan lahat ng kailangang impormasyon' edit_bill_address: 'i-edit ang Billing Address' - edit_ship_address: 'i-edit ang shipping address' + edit_ship_address: 'i-edit ang address kung saan ipapadala' required_fileds: 'ang mga kailangang may sagot ay may nakalagay na asterisk' select_country: 'Piliin ang bansa' - select_state: 'pumili ng estado' + select_state: 'pumili ng status' edit: 'i-edit' update_address: 'i-update ang address' confirm_delete: 'siguradong tatanggalin?' @@ -408,7 +408,7 @@ fil_PH: enterprise: "Enterprise" fee_type: "uri ng bayad" name: "pangalan" - tax_category: "kategorya ng buwis" + tax_category: "kategorya ng tax" calculator: "calculator" calculator_values: "calculator values" search: "hanapin" @@ -427,7 +427,7 @@ fil_PH: unit: yunit display_as: ipakita bilang category: kategorya - tax_category: kategorya ng buwis + tax_category: kategorya ng tax inherits_properties?: minana ang mga katangian? available_on: Magagamit Nakabukas av_on: "Av On" @@ -468,14 +468,14 @@ fil_PH: not_updatable: ay hindi maaring i-update sa mga umiiral na produkto gamit ang paglilipat ng produkto blank: hindi maaaring iwanang blanko products_no_permission: walang permiso na pamahalaan ang mga produkto para sa enterprise na ito - inventory_no_permission: walang permiso na gumawa ng imbentaryo para sa producer na ito + inventory_no_permission: Wala kang permiso na gumawa ng imbentaryo para sa producer na ito none_saved: hindi matagumpay na na-save ang mga produkto line_number: "linya%{number}:" encoding_error: "Paki-check ang language setting ng inyong source file at siguraduhing ito ay naka-save gamit ang UTF-8 encoding" unexpected_error: "ang paglilipat ng produkto ay may kinaharap na error habang binubuksan ang file: %{error_message}" index: notice: "Paalala" - beta_notice: "ang feature na ito ay nasa beta pa rin: maari kang makaranas ng mga error habang ginagamit ito. huwag mag-atubiling kumontak sa suporta." + beta_notice: "ang feature na ito ay nasa beta pa: maari kang makaranas ng mga error habang ginagamit ito. huwag mag-atubiling kumontak sa suporta." select_file: pumili ng spreadsheet na i-a-upload spreadsheet: spreadsheet choose_import_type: pumili ng uri ng paglilipat @@ -489,13 +489,13 @@ fil_PH: inventory_template: i-download ang Inventory template category_values: mga available na halaga ng kategorya product_categories: kategorya ng produkto - tax_categories: kategorya ng buwis + tax_categories: kategorya ng tax shipping_categories: mga kategorya ng pagpapadala import: review: suriin import: i-import save: i-save - results: mga resulta + results: Mga Resulta save_imported: i-save ang inilipat na mga produkto no_valid_entries: walang nahanap na mga valid na entry none_to_save: Walang mga entry na maaaring i-save @@ -504,7 +504,7 @@ fil_PH: save_valid?: i-save ang mga valid na entry at hayaan ang iba? no_errors: walang error na nakita! save_all_imported?: i-save lahat ng mga nilipat na produkto? - options_and_defaults: mga pagpipiliaan sa paglilipat at mga default + options_and_defaults: mga pagpipilian sa paglilipat at mga default no_permission: walang permiso na pamahalaan ang enterprise na ito not_found: hindi mahanap ang enterprise sa database no_name: walang pangalan @@ -514,7 +514,7 @@ fil_PH: overwrite_all: sulatan lahat overwrite_empty: sulatan kung walang nakalagay default_stock: i-set ang lebel ng stock - default_tax_cat: i-set ang kategorya ng buwis + default_tax_cat: i-set ang kategorya ng tax default_shipping_cat: i-set ang kategorya ng pagpapadala default_available_date: i-set ang available na petsa validation_overview: pagtingin sa pagpapatunay ng paglipat @@ -594,7 +594,7 @@ fil_PH: max_qtt_ordered: "sagad na dami ng na-order" current_fulfilled_units: "kasalukuyang tapos na mga yunit" max_fulfilled_units: "sagad na natapos na yunit" - order_error: "ang ibang error ay dapat munang ayusin bago makapag-update ng mga order.\nang mga linya na may pulang border ay may mga error." + order_error: "ang ibang error ay dapat munang ayusin bago makapag-update ng mga order.\nang mga patlang na may pulang border ay may mga error." variants_without_unit_value: "BABALA: Ang ibang variant ay walang halaga ang yunit" select_variant: "pumili ng variant" enterprise: @@ -605,7 +605,7 @@ fil_PH: new_enterprise: bagong enterprise producer?: "Producer?" package: Package - status: katayuan + status: Status manage: pamahalaan form: about_us: @@ -647,10 +647,10 @@ fil_PH: inventory: imbentaryo text2: > kung ikaw ay gumagamit ng tool para sa imbentaryo, piliin na ang mga - bagong produktong dinagdag ng inyong suplayer ay kailangan munang idagdag - sa inyong imbentaryo bago ito mai-stock. kung hindi ka naman gumagamit - ng imbentaryo para pamahalaan ang inyong produkto, piliin ang "nirerekomenda" - sa pagpipilian sa baba: + bagong produktong dinagdag ng inyong mga supplier ay kailangan munang + idagdag sa inyong imbentaryo bago ito mai-stock. kung hindi ka naman + gumagamit ng imbentaryo para pamahalaan ang inyong produkto, piliin + ang "nirerekomenda" sa pagpipilian sa baba: preferred_product_selection_from_inventory_only_yes: mga bagong produkto ay maaaring ilagay sa aking shopfront (nirerekomenda) preferred_product_selection_from_inventory_only_no: ang mga bagong produkto ay dapat idagdag muna sa aking imbentaryo bago mailagay sa aking shopfront. payment_methods: @@ -666,7 +666,7 @@ fil_PH: groups: mga grupo groups_tip: pumili ng grupo o rehiyon kung saan ka kabilang. makakatulong ito sa mga customer sa paghahanap ng inyong enterprise. groups_placeholder: magsimulang magsulat para maghanap ng mga grupo... - primary_producer: pangunahing prodyuser + primary_producer: pangunahing producer primary_producer_tip: piliin ang "Producer" kung ikaw ay pangunahing producer ng pagkain. producer: Producer any: kahit ano @@ -746,8 +746,8 @@ fil_PH: tag_rules: default_rules: by_default: bilang default - no_rules_yet: wala pang panuntunan na ginagamit - add_new_button: '+ magdagdag ng bagong panuntunan' + no_rules_yet: wala pang default na panuntunan na ginagamit + add_new_button: '+ magdagdag ng bagong default na panuntunan' no_tags_yet: walang pang tag na magagamit sa enterprise na ito no_rules_yet: wala pang panuntunan na magagamit sa tag na ito for_customers_tagged: 'Para sa mga customer na naka-tag:' @@ -757,7 +757,7 @@ fil_PH: email_confirmation_notice_html: "ang kumpirmasyon ng email ay nakabinbin pa. kami ay nagpadala ng kumpirmasyon ng email sa %{email}." resend: Ipadala muli owner: 'May-ari' - contact: "makipag-ugnayan" + contact: "Makipag-usap" contact_tip: "ang tagapamahala na makakatanggap ng enterprise emails at notipikasyon. kailangang may kumpirmadong email address." owner_tip: ang pangunahing gumagamit na responsable sa enterprise na ito. notifications: notipikasyon @@ -801,7 +801,7 @@ fil_PH: producer_hub_description_text: ang iyong enterprise ang saligan ng iyong lokal na sistema ng pagkain. maaari mong ibenta ang sarili mong produkto pati na rin ang mga produktong pinagsama sama mula sa ibang enterprise gamit ang iyong shop sa Open Food Network. profile: Profile lamang get_listing: kumuha ng listahan - profile_description_text: maaari kang mahanap ng mga tao at makipag-ugnayan sa kanila sa Open Food Network. Ang iyong enterprise ay makikita sa mapa at mahahanap sa mga listahan. + profile_description_text: Maaari kang mahanap ng mga tao sa Open Food Network. Ang iyong enterprise ay makikita sa mapa, at maaaring mahanap sa mga listahan. hub_shop: Hub Shop hub_shop_text: magbenta ng produkto mula sa iba hub_shop_description_text: ang iyong enterprise ang saligan ng iyong lokal na sistema ng pagkain. maaari mong pagsama samahin ang mga produkto mula sa ibang enterprise at ibenta ito gamit ang iyong shop sa Open Food Network. @@ -815,7 +815,7 @@ fil_PH: manage_link: settings producer?: "Producer?" package: "Package" - status: "katayuan" + status: "Status" new_form: owner: may-ari owner_tip: ang pangunahing gumagamit na responsable sa enterprise na ito. @@ -841,7 +841,7 @@ fil_PH: next_step: sunod na hakbang choose_starting_point: 'pumili ng package:' profile: 'profile' - producer_profile: 'Profile ng Prodyuser' + producer_profile: 'Profile ng Producer' invite_manager: user_already_exists: "ang user ay rehistrado na" error: "may nangyaring mali" @@ -895,7 +895,7 @@ fil_PH: selected: 'napili' add_exchange_form: add_supplier: 'magdagdag ng supplier' - add_distributor: 'magdagdag ng tagapamahagi' + add_distributor: 'magdagdag ng distributor' advanced_settings: title: Advanced settings choose_product_tip: maaring limitahan ang mga produktong pumapasok at lumalabas sa imbentaryo lamang ng%{inventory} @@ -912,7 +912,7 @@ fil_PH: form: general_settings: "Pangkalahatang Setting" incoming: papasok - supplier: tagapagtustos + supplier: Supplier receival_details: detalye ng pagtanggap fees: mga bayarin outgoing: papalabas @@ -932,7 +932,7 @@ fil_PH: orders_close: sarado ang mga order row: suppliers: mga supplier - distributors: mga tagapamahala + distributors: mga distributor variants: mga uri simple_form: ready_for: handa para sa @@ -978,8 +978,8 @@ fil_PH: total: KABUUAN total_items: KABUUAN NG MGA ITEM supplier_totals: kabuuang order cycle ng mga supplier - supplier_totals_by_distributor: kabuuang order cycle ng mga supplier ng tagapamahala - totals_by_supplier: kabuuang order cycle ng tagapamahala ng Supplier + supplier_totals_by_distributor: kabuuang order cycle ng mga supplier ng Distributor + totals_by_supplier: kabuuang order cycle ng Distributor ng Supplier customer_totals: kabuuang order cycle ng customer all_products: lahat ng produkto inventory: Imbentaryo (on hand) @@ -988,13 +988,13 @@ fil_PH: addresses: Mga address payment_methods: ulat ng mga paraan ng pagbabayad delivery: ulat ukol sa pagdeliver - tax_types: uri ng buwis - tax_rates: rate ng mga buwis + tax_types: uri ng tax + tax_rates: rate ng mga tax pack_by_customer: binalot ng Customer pack_by_supplier: binalot ng Supplier orders_and_distributors: - name: mga order at tagapamahagi - description: mga order na may detalye ng tagapamahagi + name: mga order at Distributor + description: mga order na may detalye ng Distributor bulk_coop: name: Bultuhang Co-Op description: ulat para sa mga order ng Bultuhang Co-Op @@ -1009,11 +1009,11 @@ fil_PH: name: mga produkto at imbentaryo users_and_enterprises: name: mga gumagamit at enterprise - description: pag-aari ng enterprise at katayuan + description: pag-aari ng enterprise at status order_cycle_management: name: pamamahala sa order cycle sales_tax: - name: buwis ng mga benta + name: tax ng mga benta xero_invoices: name: mga invoice ng Xero description: mga invoice na ililipat sa Xero @@ -1055,8 +1055,8 @@ fil_PH: review: 4. suriin at i-save subscription_line_items: this_is_an_estimate: | - ang mga nakasulat na presyo ay tantiya lamang at kinalkula sa panahon na binago ang subscription. - kung magpapalit ng presyo o bayarin, maa-update ang mga order ngunit ang subscription ay ipapakita pa rin ang dating mga halaga. + Ang mga nakalagay na presyo ay tantiya lamang at kinakalkula sa panahon na binago ang subscription. + Kung magpapalit ka ng presyo o bayarin, maa-update ang mga order ngunit ang subscription ay ipapakita pa rin ang dating mga halaga. not_in_open_and_upcoming_order_cycles_warning: "walang bukas o paparating na mga order cycle para sa produkto na ito." autocomplete: name_or_sku: "PANGALAN O SKU" @@ -1130,31 +1130,31 @@ fil_PH: failed: "hindi matagumpay ang pag-check out. ipaalam sa amin upang maproseso ang inyong order." shops: hubs: - show_closed_shops: "ipakita ang mga saradong shop" + show_closed_shops: "Ipakita ang mga saradong shop" hide_closed_shops: "itago ang mga saradong shop" - show_on_map: "ipakita lahat sa mapa" + show_on_map: "Ipakita lahat sa mapa" shared: menu: cart: cart: "Cart" signed_in: - profile: "profile" + profile: "Profile" mobile_menu: cart: "Cart" joyride: - checkout: "mag-checkout ngayon" - already_ordered_products: "na-order na sa order cycle na ito" + checkout: "Mag-checkout na" + already_ordered_products: "Naka-order na sa order cycle na ito" register_call: - selling_on_ofn: "interesado maging parte ng Open Food Network?" - register: "mag-rehistro dito" + selling_on_ofn: "Interesado ka ba maging parte ng Open Food Network?" + register: "Magrehistro dito" footer: - footer_secure: "ligtas at mapagkakatiwalaan." - footer_secure_text: "ang Open Food Network ay gumagamit ng SSL encryption (2048 bit RSA) para mapanatiling pribado ang inyong pamimili at pagbababayad. Ang aming mga server ay hindi nagse-save ng mga detalye ng inyong credit card at ang inyong pagbabayad ay pinoproseso ng mga serbisyong PCI-compliant." - footer_contact_headline: "makipag-ugnayan" + footer_secure: "Mapagkakatiwalaan." + footer_secure_text: "Ang Open Food Network ay gumagamit ng SSL encryption (2048 bit RSA) para mapanatiling pribado ang inyong pamimili at pagbababayad. Ang aming mga server ay hindi nagse-save ng mga detalye ng inyong credit card at ang inyong pagbabayad ay pinoproseso ng mga serbisyong PCI-compliant." + footer_contact_headline: "Makipag-ugnayan" footer_contact_email: "i-email kami" footer_nav_headline: "Navigate" - footer_join_headline: "sumali sa amin" - footer_join_body: "gumawa ng listahan, Shop o group directory sa Open Food Network." + footer_join_headline: "Sumali sa amin" + footer_join_body: "Gumawa ng profile, shop, o listahan ng grupo sa Open Food Network." footer_join_cta: "sabihin pa sa akin ang iba pa!" footer_legal_call: "basahin ang aming" footer_legal_tos: "mga tuntunin at kondisyon" @@ -1184,10 +1184,10 @@ fil_PH: invoice_column_unit_price_without_taxes: "Presyo kada yunit (hindi kasama ang tax)" invoice_column_price_with_taxes: "Kabuuang Presyo (kasama ang tax)" invoice_column_price_without_taxes: "Kabuuang Presyo (hindi kasama ang tax)" - invoice_column_tax_rate: "rate ng buwis" + invoice_column_tax_rate: "rate ng tax" invoice_tax_total: "kabuuang GST:" tax_invoice: "TAX INVOICE" - tax_total: "Kabuuang Buwis (%{rate}):" + tax_total: "Kabuuang Tax (%{rate}):" total_excl_tax: "Kabuuan (Hindi kasama ang tax):" total_incl_tax: "Kabuuan (Kasama ang tax):" abn: "ABN:" @@ -1199,19 +1199,19 @@ fil_PH: ticket_column_item: "Item" ticket_column_unit_price: "Presyo kada Yunit" ticket_column_total_price: "Kabuuang Presyo" - menu_1_title: "mga shop" - menu_1_url: "/mga shop" - menu_2_title: "mapa" - menu_2_url: "/mapa" - menu_3_title: "Producers" - menu_3_url: "/mga producer" - menu_4_title: "mga grupo" - menu_4_url: "/mga grupo" - menu_5_title: "tungkol sa" - menu_5_url: "https://about.openfoodnetwork.org.ph/" - menu_6_title: "kumonekta" + menu_1_title: "Mga Shop" + menu_1_url: "/shops" + menu_2_title: "Mapa" + menu_2_url: "/map" + menu_3_title: "Mga Producer" + menu_3_url: "/producers" + menu_4_title: "Mga Bayarin" + menu_4_url: "/sell" + menu_5_title: "Tungkol Sa OFN" + menu_5_url: "https://www.openfoodnetwork.org/" + menu_6_title: "Kumonekta" menu_6_url: "https://openfoodnetwork.org/au/connect/" - menu_7_title: "matuto" + menu_7_title: "Matuto" menu_7_url: "https://openfoodnetwork.org/au/learn/" logo: "Logo (640x130)" logo_mobile: "Mobile logo (75x26)" @@ -1242,8 +1242,8 @@ fil_PH: city_placeholder: hal. Northcote postcode: Postcode postcode_placeholder: hal. 3070 - suburb: labas ng lungsod - state: kalagayan + suburb: lungsod + state: status country: Bansa unauthorized: hindi awtorisado terms_of_service: "mga palatuntunan ng serbisyo" @@ -1259,7 +1259,7 @@ fil_PH: label_shop: "Shop" label_shops: "mga shop" label_map: "mapa" - label_producer: "Prodyuser" + label_producer: "Producer" label_producers: "Producers" label_groups: "mga grupo" label_about: "tungkol sa" @@ -1278,7 +1278,7 @@ fil_PH: label_less: "ipakita ang mas kaunti" label_notices: "mga abiso" cart_items: "mga item" - cart_headline: "ang iyong cart sa pamimili" + cart_headline: "Ang iyong shopping cart" total: "kabuuan" cart_updating: "ina-update ang cart" cart_empty: "walang laman ang cart" @@ -1309,22 +1309,22 @@ fil_PH: cookies_policy: header: "paano kami gumagamit ng cookies" desc_part_1: "ang mga cookies ay maliliit na text files na naiimbak sa iyong computer kapag bumibisita ka sa mga website" - desc_part_2: "sa OFN, mahigpit naming pinahahalagahan ang inyong privacy. gumagamit lamang kami ng cookies na kinakailangan para makapagbigay sa inyo ng serbisyo sa pagbebenta/pamimili ng pagkain sa internet. Hindi namin pagkakakitaan ang inyong impormasyon. maaaring imungkahi namin sa hinaharap ang pagbahagi ng ilang impormasyon para makabuo ng isang bagong pangkaraniwang serbisyo na maaaring makatulong sa sistema ng pagkain( tulad ng mga proseso at serbisyo para sa maliliit na kalakalan ng pagkain) ngunit wala pa tayo sa hakbang na iyon sa ngayon at sisiguraduhin naming hindi namin ito gagawin ng wala ang inyong permiso." + desc_part_2: "Sa OFN, mahigpit naming pinahahalagahan ang inyong privacy. Gumagamit lamang kami ng cookies na kinakailangan para makapagbigay sa inyo ng serbisyo sa pagbebenta/pamimili ng pagkain sa Internet. Hindi namin binebenta ang inyong impormasyon. Maaaring imungkahi namin sa hinaharap ang pagbahagi ng ilang impormasyon para makabuo ng isang bagong serbisyo na maaaring makatulong sa sistema ng pagkain (tulad ng mga proseso at serbisyo para sa maliliit na kalakalan ng pagkain) ngunit wala pa tayo sa hakbang na iyon sa ngayon, at sisiguraduhin naming hindi namin ito gagawin ng wala ang inyong permiso. :-)" desc_part_3: "ang pangunahing dahilan sa paggamit ng cookies ay para matandaan kung sino ka kapag ikaw ay naglog-in sa serbisyo at upang panatilihin ang mga item na nilagay mo sa iyong cart habang ikaw ay hindi pa nakalog-in. kung ikaw ay gumagamit ng website ng hindi pinipindot ang \"tanggapin ang cookies\", ipapalagay namin na binibigyan mo kami ng pahintulot na i-save ang mga cookies na lubhang mahalaga sa maayos na paggamit ng website. narito ang listahan ng mga cookies na aming ginagamit!" essential_cookies: "mahahalagang mga cookies" essential_cookies_desc: "ang mga sumusunod na cookies ay lubhang kailangan para sa operasyon ng ating website." essential_cookies_note: "karamihan sa mga cookies ay naglalaman lamang ng natatanging pagkakakilanlan at wala ng iba, kung kaya ang iyong email address at password halimbawa ay hindi kailanman mai-se-save at maipapalam sa iba." cookie_domain: "Sinet ng:" cookie_session_desc: "ginagamit upang payagan ang website na matandaan ang mga gumagamit kapag dumadalaw sa pahina, halimbawa, alalahanin ang mga item na nasa cart." - cookie_consent_desc: "ginagamit upang mapanatili ang katayuan ng niilalaman ng gumagamit sa pag-store ng cookies" - cookie_remember_me_desc: "ginagamit kapag ang user ay humingi ng pahintulot na maalala siya. ang cookie na ito ay awtomatikong nabubura makalipas ang 12 araw. kung bilang gumagamit ay nais mong mabura ang cookie, kailangan mo lamang maglog-out. kung hindi mo nais na mailagay ang cookie sa iyong computer, hindi mo dapat lagyan ng check ang \"alalahanin ako\" na kahon kapag nagla-log-in." + cookie_consent_desc: "ginagamit upang mapanatili ang status ng permiso ng gumagamit sa pag-store ng cookies" + cookie_remember_me_desc: "ginagamit kapag ang user ay humingi ng pahintulot na siya ay maalala. ang cookie na ito ay awtomatikong nabubura makalipas ang 12 araw. kung bilang gumagamit ay nais mong mabura ang cookie, kailangan mo lamang maglog-out. kung hindi mo nais na mailagay ang cookie sa iyong computer, hindi mo dapat lagyan ng check ang \"alalahanin ako\" na kahon kapag nagla-log-in." cookie_openstreemap_desc: "ay ginagamit ng tagapagbigay sa atin ng serbisyo ukol sa open source mapping(OpennStreetMap) para masiguradong hindi ito makakatanggap ng maraming request sa tinakdang oras, at upang maiwasan na din ang pag-abuso sa kanilang serbisyo." cookie_stripe_desc: "Mga data na nakolekta ng Stripe, ang tagaproseso para sa bayad, upang magamit sa pag-detect ng fraud https://stripe.com/cookies-policy/legal. hindi lahat ng shop ay gumagamit ng Stripe bilang paraan ng pagbabayad ngunit iminumungkahi namin itong gamitin sa lahat ng pahina upang maiwasan ang fraud at ilegal na pagkuha ng iyong impormasyon." statistics_cookies: "katayuan ng cookies" - statistics_cookies_desc: "ang mga sumusunod ay hindi mahigpit na kinakailangan, ngunit nakakatulong upang mabigyan namin kayo ng mga pinakamagandang serbisyo sa pamamagitan ng pagpayag na suriin namin ang kilos ng mga gumagamit, alamin ang mga features na madalas gamitin o hindi ginagamit, at intindihin ang ang problemang kinaharap ng gumagamit, at iba pa." - statistics_cookies_analytics_desc_html: "upang kolektahin at suriin ang data sa paggamit ng platform, ginagamit namin ang Google Analytics, bilang ito ang orihinal na serbisyo na ginagamit ng Spree (ang e-commerce open source software kung saan kami nagsimula) ngunit ang aming layunin ay makalipat sa Matomo(halimbawa ay Piwik, open source analytics tool na sumusunos sa GDPR at pinangangalagaan angn inyong privacy) sa lalong madaling panahon." + statistics_cookies_desc: "ang mga sumusunod ay hindi mahigpit na kinakailangan, ngunit nakakatulong upang mabigyan namin kayo ng mga pinakamagandang serbisyo sa pamamagitan ng pagpayag na suriin namin ang kilos ng mga gumagamit, alamin ang mga features na madalas gamitin o hindi ginagamit, intindihin ang mga problemang kinaharap ng gumagamit, at iba pa." + statistics_cookies_analytics_desc_html: "upang kolektahin at suriin ang data sa paggamit ng platform, ginagamit namin ang Google Analytics, bilang ito ang default na serbisyo na ginagamit ng Spree (ang e-commerce open source software kung saan kami nagsimula) ngunit ang aming layunin ay makalipat sa Matomo(halimbawa ay Piwik, open source analytics tool na sumusunod sa GDPR at pinangangalagaan ang inyong privacy) sa lalong madaling panahon." statistics_cookies_matomo_desc_html: "para makolekta at masuri ang mga data na ginagamit, gumagamit kami ngMatomo(halimbawa ay Piwik), isang open source analytics na tool na sumusunod sa GDPR at pinangangalagaan ang inyong privacy." - statistics_cookies_matomo_optout: "nais mo bang gamitin ang Matomo Analytics? hindi kami kumukolekta ng kahit anong personal na imprormasyon, at tinutulungan kami ng Matomo na pag-igihin ang aming serbisyo, ngunit mas pinapahalagahan namin ang inyong desisyon :-)" + statistics_cookies_matomo_optout: "nais mo bang gamitin ang Matomo Analytics? hindi kami kumukolekta ng kahit anong personal na impormasyon, at tinutulungan kami ng Matomo na pag-igihin ang aming serbisyo, ngunit mas pinapahalagahan namin ang inyong desisyon :-)" cookie_analytics_utma_desc: "ginagamit upang pag-ibahin ang mga gumagamit at mga sesyon. Ang cookie ay nabubuo kapag ang javascript library ay naisagawa at walang __utma cookies. ang cookie na ito ay ina-update sa tuwing may ipinapadala na data sa Google Analytics." cookie_analytics_utmt_desc: "ginagamit upang makontrol ang bilis ng pagpasok ng mga request." cookie_analytics_utmb_desc: "ginagamit upang matukoy ang mga bagong sesyon/bisita. ang cookie ay nabubuo kapag ang javascript library ay naisagawa at walang __utma cookies. ang cookie na ito ay ina-update sa tuwing may ipinapadala na data sa Google Analytics." @@ -1339,7 +1339,7 @@ fil_PH: disabling_cookies_chrome_link: "https://support.google.com/chrome/answer/95647" disabling_cookies_ie_link: "https://support.microsoft.com/en-us/help/17442/windows-internet-explorer-delete-manage-cookies" disabling_cookies_safari_link: "https://www.apple.com/legal/privacy/en-ww/cookies/" - disabling_cookies_note: "ngunit dapat malaman na kapag binura o binago ang mahahalagang cookies na ginagamit ng Open Food Network, ang website ay hindi gagana at hindi ka maaring makapaglagay sa iyong cart upang makapagcheckout halimbawa." + disabling_cookies_note: "Ngunit dapat mong malaman na kapag binura o binago mo ang kinakailangang cookies na ginagamit ng Open Food Network, ang website ay hindi gagana at, halimbawa, hindi ka maaring makapaglagay sa iyong cart upang makapagcheckout." cookies_banner: cookies_usage: "ang site na ito ay gumagamit ng mga cookies upang maging mas ligtas at madali ang paggamit ng site. nakakatulong din ito sa amin upang maintindihan kung paano ang inyong paggamit para mas maging maayos ang serbisyong aming ibibigay sa inyo." cookies_definition: "ang mga cookies ay maliliit na text files na naiimbak sa iyong computer kapag bumibisita ka sa mga website" @@ -1347,10 +1347,10 @@ fil_PH: cookies_policy_link_desc: "para sa karagdagangn impormasyon, tignan ang" cookies_policy_link: "patakaran ng cookies" cookies_accept_button: "tanggapin ang cookies" - home_shop: mamili ngayon - brandstory_headline: "Pagkain, hindi pinagsama" - brandstory_intro: "minsan ang pinakamadaling paraan para pagsamahin ang mga sistema ay magsimulang bumuo ulit ng bago.." - brandstory_part1: "Kami ay nagsimula sa pinakaibaba pataas. Kasama ang mga magsasaka at tagatanim na may ipagmamalaki at handang ibahagi ang kanilang mga kuwento. Kasama rin namin ang mga tagapamahaging patas at tapat na handang makipag-usap sa mga taong may produkto. At mga mamimili na naniniwala na ang mabusising lingguhang pamimili ay magdudulot ng malaking pagbabago sa mundo." + home_shop: Mamili Ngayon + brandstory_headline: "Etikal na pagkain." + brandstory_intro: "Minsan ang pinakamabuting paraan para ayusin ang sistema ay ang pagbuo ulit ng bago..." + brandstory_part1: "Kami ay nagsimula sa pinakaibaba pataas. Kasama ang mga magsasaka at tagatanim na handang ibahagi at ipagmalaki ang kanilang mga kuwento. May mga tapat at patas na Distributors na handang makipag-usap sa mga gumagawa ng produkto. At mga mamimili na naniniwala na ang mabusising lingguhang pamimili ay magdudulot ng malaking pagbabago sa mundo." brandstory_part2: "kaya kinailangan naming gumawa ng paraan para gawing totoo ang lahat. isang paraan para bigyan ng kapangyarihan ang lahat ng mga tao na nagtatanim, nagsasaka, nagbebenta at bumibili ng pagkain. isang paraan upang mabigyan ng boses ang lahat at malaman ang kanilang kuwento, matulungan sa pagsasaayos ng mga proseso. isang paraang upang ang mga transaksyon ay gawing pagbabago araw araw." brandstory_part3: "ito ang dahilan kaya kami ay nagtayo ng online na pamilihan na kalebel na kung ano ang nasa katotohanan. ito ay transparent kaya bumubuo ito ng totoong mga relasyon. ito ay bukas ang pinagkukunan, kaya pag-aari ito ng lahat. ito ay sinusubukan na rin ng iba't ibang rehiyon at nasyon, dahilan kaya ang mga tao ay unti unting nagsisimulang gumawa ng sariling bersyon nito sa iba't ibang panig ng mundo." brandstory_part4: "ito ay gumagana sa lahat ng lugar. kaya nitong baguhin ang lahat." @@ -1360,7 +1360,7 @@ fil_PH: learn_cta: "makakuha ng inspirasyon" connect_body: "tumingin sa aming directory ng mga producer, hub at mga grupo upang makahanap ng patas na mangangalakal ng pagkain na pinakamalapit sa iyo. Ilagay ang iyong negosyo o organisasyon sa OFN para kayo'y makita ng mga mamimili. Sumali sa aming komunidad para makakuha ng mga payo ay makapagtulungan sa paglutas ng mga problema." connect_cta: "halilka na at ma-explore" - system_headline: "pamimili - ganito siya gumagana." + system_headline: "Pamimili - ganito ang paraan." system_step1: "1. humanap" system_step1_text: "humanap sa iba't ibang mga shop ng lokal na napapanahong pagkain. humanap sa pamamagitan ng malapit na lokasyon o kategorya ng pagkain, o kung mas nais mo ang pick-up kesa sa delivery." system_step2: "2. Mamili" @@ -1411,14 +1411,14 @@ fil_PH: order_pickup_instructions: tagubilin sa pagkolekta order_produce: produkto order_total_price: kabuuan - order_includes_tax: (kasama ang buwis) + order_includes_tax: (kasama ang tax) order_payment_paypal_successful: ang iyong bayad gamit ang PayPal ay matagumpay na naproseso. order_hub_info: impormasyon ng Hub order_back_to_store: bumalik sa pamillihan order_back_to_cart: bumalik sa Cart bom_tip: "gamitin ang pahina na ito para baguhin ang dami ng mga produkto sa maramihang mga order. maaari ding magtanggal ng mga produkto mula sa order kung kinakailangan." unsaved_changes_warning: "may mga pagbabagong hindi pa na-save at maaaring mawala kung magpapatuloy." - unsaved_changes_error: "ang mga guhit na may pulang border ay may mga error" + unsaved_changes_error: "ang mga patlang na may pulang border ay may mga error" products: "mga produkto" products_in: "sa%{oc}" products_at: "nasa%{distributor}" @@ -1430,7 +1430,7 @@ fil_PH: email_confirmation_click_link: "pindutin ang link sa ibaba para kumpirmahin ang iyong email address at upang maipagpatuloy ang pagset-up ng inyong profile." email_confirmation_link_label: "kumpirmahin ang email address na ito »" email_confirmation_help_html: "pagkatapos makumpirma ang iyong email, maaari mo na i-access ang iyong administration account para sa enterprise na ito. tignan ang%{link}upang lalong mas maunawaan ang%{sitename}at masimulan na ang paggamit ng inyong profile o online na tindahan." - email_confirmation_notice_unexpected: "natanggap mo ang mensahe na ito sapagkat ikaw ay nagsign-up sa%{sitename}, or ay inimbitahan para magsign-up ng isang tao na maaring kilala mo. kung hindi maintindihan kung bakit ka nakakatanggap ng ganitong email, maaring sumulat sa%{contact}." + email_confirmation_notice_unexpected: "natanggap mo ang mensahe na ito sapagkat ikaw ay nagsign-up sa%{sitename}, o inimbitahan para magsign-up ng isang tao na maaring kilala mo. kung hindi maintindihan kung bakit ka nakakatanggap ng ganitong email, maaring sumulat sa%{contact}." email_social: "kumonekta sa amin:" email_contact: "i-email kami:" email_signoff: "Mabuhay," @@ -1461,8 +1461,8 @@ fil_PH: email_so_placement_explainer_html: "ang order na ito ay awtomatikong binuo para sa iyo." email_so_edit_true_html: "maaari kang gumawa ng mga pagbabago hanggang magsara ang iyong mga order sa%{orders_close_at}." email_so_edit_false_html: "maari mong tignan ang mga detalye ng order na itokahit kailan." - email_so_contact_distributor_html: "kung ikaw ay may mga katanungan, maaring makipagugnayan sa%{distributor} sa pamamagitan ng%{email}." - email_so_contact_distributor_to_change_order_html: "ang order na ito ay awtomatikong binuo para sa iyo. maaari kang gumawa ng mga pagbabago hanggang magsara ang mga order sa%{orders_close_at} sa pamamagitan ng pakikipagugnayan%{distributor} sa pamamagitan ng%{email}.." + email_so_contact_distributor_html: "Kung ikaw ay may mga katanungan, maaring makipag-ugnayan sa%{distributor} sa%{email}." + email_so_contact_distributor_to_change_order_html: "Ang order na ito ay awtomatikong binuo para sa iyo. Maaari kang gumawa ng mga pagbabago hanggang magsara ang mga order sa%{orders_close_at} sa pamamagitan ng pakikipagugnayan sa%{distributor} sa%{email}." email_so_confirmation_intro_html: "ang iyong order kasama ang%{distributor} ay kumpirmado na." email_so_confirmation_explainer_html: "ang order na ito ay awtomatikong na-place para sa iyo at ngayon ay pinalisa na." email_so_confirmation_details_html: "ang lahat ng kailangan mong malaman tungkol sa iyong order mula sa%{distributor} ay narito:" @@ -1490,7 +1490,7 @@ fil_PH: invited_to_manage: "ikaw ay naanyayahan para pamahalaan ang%{enterprise}sa%{instance}." confirm_your_email: "Maaaring natanggap mo na o matatanggap pa lamang ang email na may link ng kumpirmasyon. hindi mo mapupuntahan ang profile ng%{enterprise}hanggang hindi pa nakukumpirma ang inyong email." set_a_password: "pagtapos ay dapat kang magset ng password bago mapamahalaan ang enterprise." - mistakenly_sent: "Hindi sigurado kung bakit natanggap ang email na ito? makipagugnayan sa%{owner_email} para sa mas karagdagang impormasyon." + mistakenly_sent: "Hindi sigurado kung bakit ka nakatanggap ang email na ito? Makipagugnayan sa%{owner_email} para sa karagdagang impormasyon." producer_mail_greeting: "Minamahal" producer_mail_text_before: "ngayon nasa atin na ang lahat ng order ng mga mamimili para sa susunod na pag-drop ng order." producer_mail_order_text: "narito ang buod ng mga order para inyong mga produkto:" @@ -1504,9 +1504,9 @@ fil_PH: shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "tungkol sa" - shopping_tabs_contact: "makipag-ugnayan" + shopping_tabs_contact: "Makipag-ugnayan" shopping_contact_address: "tirahan" - shopping_contact_web: "makipag-ugnayan" + shopping_contact_web: "Makipag-ugnayan" shopping_contact_social: "sumunod" shopping_groups_part_of: "ay parte ng:" shopping_producers_of_hub: "mga producer ng%{hub}:" @@ -1515,7 +1515,7 @@ fil_PH: enterprises_choose: "pumili kung kailan nais umorder:" maps_open: "bukas" maps_closed: "sarado" - hubs_buy: "mamili para sa/kay:" + hubs_buy: "Mamili para sa/kay:" hubs_shopping_here: "namimili rito" hubs_orders_closed: "sarado na ang mga order" hubs_profile_only: "Profile lamang" @@ -1528,7 +1528,7 @@ fil_PH: hubs_filter_delivery: "pagdeliver" hubs_filter_property: "ari-arian" hubs_matches: "ang ibig mo bang sabihin" - hubs_intro: mamili sa iyong lokal na lugar + hubs_intro: Mamili sa iyong komunidad hubs_distance: pinakamalapit sa hubs_distance_filter: "ipakita ang mga shop malapit sa%{location}" shop_changeable_orders_alert_html: @@ -1550,20 +1550,20 @@ fil_PH: products_update_error_msg: "hindi nagpatuloy ang pag-save." products_update_error_data: "hindi nagpatuloy ang pag-save dahil sa hindi valid na data:" products_changes_saved: "nai-save ang mga pagbabago" - search_no_results_html: "paumahin, walang resultang nahanap para sa%{query}. sumubok ng isa pang paghahanap?" + search_no_results_html: "Paumahin, walang resultang nahanap para sa%{query}. Maaari kang sumubok ng isa pang keyword." components_profiles_popover: "ang mga profile ay walang Shopfront sa Open Food Network, ngunit maaaring mayroong sariling pisikal o online na shop sa ibang lugar" - components_profiles_show: "ipakita ang mga profile" + components_profiles_show: "Ipakita ang mga profile" components_filters_nofilters: "walang mga filter" components_filters_clearfilters: "alisin lahat ng mga filter" groups_title: mga grupo groups_headline: Grupo/ Mga Rehiyon - groups_text: "Bawat producer ay natatangi. Bawat negosyo ay may iba't ibang bagay na inaalok. ang aming grupo ay samahan ng mga producer, mga hub, at tagapamahagi na may mga pagkakapareho tulad ng lokasyon, pamilihan at pilosopiya. mas mapapadali nito ang iyong pamimili. kaya halina't subukan ang aming grupo at hayaan mo kaming tulungan ka sa iyong paghahanap." + groups_text: "Bawat producer ay natatangi. Bawat negosyo ay may iba't ibang bagay na inaalok. ang aming grupo ay samahan ng mga producer, mga hub, at mga distributor na may mga pagkakapareho tulad ng lokasyon, pamilihan at pilosopiya. mas mapapadali nito ang iyong pamimili. kaya halina't subukan ang aming grupo at hayaan mo kaming tulungan ka sa iyong paghahanap at pamimili." groups_search: "hanapin ang pangalan o keyword" groups_no_groups: "Walang mahanap na mga grupo" groups_about: "tungkol sa amin" groups_producers: "ang aming mga producer" groups_hubs: "ang aming mga hub" - groups_contact_web: makipag-ugnayan + groups_contact_web: Makipag-ugnayan groups_contact_social: sumunod groups_contact_address: tirahan groups_contact_email: i-email kami @@ -1577,36 +1577,36 @@ fil_PH: groups_signup_motivation2: at iyon ang dahilan kung bakit kami bumabangon araw araw. kami ay pandaigdigan ngunit hindi tumutubo base sa bukas na code ng pinagkukuhanan. kami ay lagi mong mapagkakatiwalaan. groups_signup_motivation3: alam naming mayroon kayong magagandang ideya at nais namin kayong tulungan. Ibabahagi namin sa inyo ang aming kaalaman, mga network pati na ang pinagkukuhanan. alam naming ang pagsasarili ay hindi makabubuo ng pagbabago, kaya kami ay makikipagtulungan sa inyo. groups_signup_motivation4: magsisimula tayo kung saan kayo nagmula. - groups_signup_motivation5: maaari kang may ka-alyansang mga hub ng pagkain, mga producer, mga tagapamahagi, kinatawan ng isang industriya o lokal na gobyerno. - groups_signup_motivation6: kung ano man ang iyong parte sa inyong lokal na sistema ng pagkain, handa kaming tumulong sa inyo. maaaring nagtatakaka kung ano ang Open Food Network at kung ano ang ginagawa nito, maaari tayong mag usap tungkol dito. + groups_signup_motivation5: maaaring kayo ay samahan ng mga hub ng pagkain, mga producer, mga distributor, kinatawan ng isang industriya o lokal na gobyerno. + groups_signup_motivation6: kung ano man ang iyong parte sa inyong lokal na sistema ng pagkain, handa kaming tumulong sa inyo. maaaring nagtataka ka kung ano ang Open Food Network at kung ano ang ginagawa nito, maaari tayong mag usap tungkol dito. groups_signup_motivation7: ginagawa naming mas makabuluhan ang daloy ng proseso ng kalakalan ng pagkain. groups_signup_motivation8: kailangan mong i-activate at paganahin ang iyong mga koneksyon, naririto ang aming plataporma para sa pagkilos at komunikasyon. Ang kailangan mo ay aktwal na pakikipag-ugnayan. tutulungan ka naming makausap ang mga tao sa industriya na ito, mga namumuhunan, lahat ng mga sektor. groups_signup_motivation9: kailangan mo ng magpagkukunan. Ibibigay namin ang lahat ng tulong at karanasan na mayroon kami. kailangan mo ng kooperasyon. gagabayan ka namin sa pagkonekta sa pandaigdigang mga samahan. groups_signup_pricing: Account ng grupo groups_signup_studies: pag-aaral ng kaso groups_signup_contact: handa na makipagtalakayan? - groups_signup_contact_text: "makipag-ugnayan upang malaman kung paano ka matutulungan ng OFN:" + groups_signup_contact_text: "Makipag-ugnayan upang malaman kung paano ka matutulungan ng OFN:" groups_signup_detail: "ito ang mga detalye:" login_invalid: "hindi valid ang email o password" modal_hubs: "Mga Hub ng pagkain" modal_hubs_abstract: ang mga Hub ng pagkain ang namamagitan sa iyo at sa mga gumagawa ng inyong pagkain! modal_hubs_content1: maaari kang humanap ng pinakamalapit na Hub gamit ang lokasyon o pangalan. Ang ibang Hub ay may maraming mga lugar kung saan maaari mong kunin ang iyong pinamili habang ang iba ay bibigyan ka rin ng iba pang opsyon kung paano mo makukuha ang iyong order. Bawat Food Hub ay may iba ibang paraan ng operasyon at proseso kaya asahan ang kaibahan sa mga binibigay na serbisyo. - modal_hubs_content2: maaari ka lamang mamili sa isang hub ng pagkain sa isang pagkakataon. + modal_hubs_content2: Maaari ka lamang mamili sa isang hub ng pagkain sa bawat pagkakataon. modal_groups: "Mga Grupo / Mga Rehiyon" modal_groups_content1: ito ang mga organisasyon at mga relasyon na namamagitan sa mga Hub na bumubuo sa Open Food Network. modal_groups_content2: ang ibang grupo ay pinagsasama sama depende sa lokasyon o lupon, at ang iba ay sa hindi pangheograpiyang pagkakapareho. modal_how: "Paano it gumagana" - modal_how_shop: mamili sa Open Food Network + modal_how_shop: Mamili sa Open Food Network modal_how_shop_explained: maghanap ng hub ng pagkain na pinakamalapit sa iyo para makapagsimulang makapamili. maaring palawakin ng bawat hub upang makita kung anong uri ng pagkain ang inaalok nila at pindutin ng tuluyan para magsimula mamili. (maaari lamang mamili sa isang hub sa isang pagkakataon.) - modal_how_pickup: Singil sa Pick-up, pag-deliver at pagdadala - modal_how_pickup_explained: ang ibang food hub ay magde-deliver mismo sa inyong tirahan, habang ang iba ay kakailanganin kang kunin ng personal ang inyong mga order. Mababasa sa homepage ang mga opsyon, at piliin ang mga produkto na nais sa pahina ng pamimili at checkout. Ang pagpapa-deliver ay mas mahal at ang halagang babayaran ay nakadepende sa iba't ibang food hub. Bawat Food Hub ay may iba't ibang paraan ng operasyon at proseso kaya dapat asahan ang kaibahan sa mga binibigay na serbisyo. + modal_how_pickup: Singil sa Pick-up, pag-deliver at pagpapadala + modal_how_pickup_explained: ang ibang food hub ay magde-deliver mismo sa inyong tirahan, habang ang iba ay kakailanganin kang kunin ng personal sa kanila ang inyong mga order. Mababasa sa homepage ang mga opsyon, at piliin ang mga produkto na nais sa pahina ng pamimili at checkout. Ang pagpapa-deliver ay mas mahal at ang halagang babayaran ay nakadepende sa iba't ibang food hub. Bawat Food Hub ay may iba't ibang paraan ng operasyon at proseso kaya dapat asahan ang kaibahan sa mga binibigay na serbisyo. modal_how_more: dagdagan ang kaalaman modal_how_more_explained: "kung nais mong mas maintindihan ang Open Food Network, kung paano ito gumagana at paano makasali dito, tignan ito:" modal_producers: "Producers" modal_producers_explained: "ang aming mga producer ay gumagawa ng masasarap na pagkain na maaari mong mabili sa Open Food Network." producers_about: Tungkol sa amin producers_buy: 'mamili para sa ' - producers_contact: makipag-ugnayan + producers_contact: Makipag-ugnayan producers_contact_phone: Tumawag producers_contact_social: sumunod producers_buy_at_html: "mamili para sa%{enterprise}na mga produkto sa:" @@ -1629,11 +1629,11 @@ fil_PH: products_variant: Uri products_quantity: dami products_available: Mayroong stock? - products_producer: "Prodyuser" + products_producer: "Producer" products_price: "presyo" name_or_sku: "PANGALAN O SKU" - register_title: magrehistro - sell_title: "magrehistro" + register_title: Magrehistro + sell_title: "Magrehistro" sell_headline: "pumunta sa Open Food Network!" sell_motivation: "ipagmalaki ang iyong masasarap na pagkain!" sell_producers: "Producers" @@ -1647,8 +1647,8 @@ fil_PH: sell_embed: "maari rin naming ilagay ang OFN sa inyong sariling website o magtayo ng sariling lokal na Food Network website sa inyong rehiyon." sell_ask_services: "magtanong tungkol sa mga serbiyong binibigay ng OFN" shops_title: mga shop - shops_headline: pamimili, binago. - shops_text: ang pagtatanim at paggawa ng pagkain ay isang cycle, ang mga magsasaka ay umaani sa isang cycle at nag-o-order tayo ng pagkain sa isang cycle. kung makikitang sarado ang isang cycle, maaaring bumalik sa ibang pagkakataon. + shops_headline: Pamimili, binago. + shops_text: Ang pagtatanim at paggawa ng pagkain ay nasa mga cycle, ang mga magsasaka ay umaani sa mga cycle, at nag-o-order tayo ng pagkain sa mga cycle. Kung makikita mong sarado ang isang order cycle, maaaring kang bumalik sa ibang pagkakataon. shops_signup_title: magsign-up bilang Hub shops_signup_headline: Mga Food Hub, walang limitadong pagpipilian. shops_signup_motivation: kung ano man ang iyong modelo, susuportahan ka namin. ano mang pagbabago na nais gawin, kasama mo kami. kami ay non-profit, malaya at bukas sa lahat ng impormasyon. kami ang kaibigan at kasangga na matagal mo nang pinapangarap. @@ -1670,7 +1670,7 @@ fil_PH: orders_form_admin: Admin & Handling orders_form_total: kabuuan orders_oc_expired_headline: ang mga order ay nagsara na para sa order cycle na ito. - orders_oc_expired_text: "paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong%{time}! direktang makipag ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order." + orders_oc_expired_text: "Paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong%{time}! Direktang makipag-ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order." orders_oc_expired_text_others_html: "paumanhin ngunit ang mga order para sa order cycle na ito ay sarado na mula noong %{time}! direktang makipag ugnayan sa inyong Hub upang malaman kung maaari pa silang tumanggap ng mga order%{link}." orders_oc_expired_text_link: "o tignan ang iba pang order cycle mula sa hub na ito." orders_oc_expired_email: "Email:" @@ -1690,10 +1690,10 @@ fil_PH: orders_bought_already_confirmed: "* kumpirmado na" orders_confirm_cancel: sigurado ka bang nais mo na kanselahin ang order na ito? order_processed_successfully: "ang inyong order ay matagumpay na nakumpirma" - products_cart_distributor_choice: "tagapamahagi ng inyong order:" - products_cart_distributor_change: "ang tagapamahagi para sa order na ito ay mapapalitan ng%{name} kung idadagdag ang produktong ito sa inyong cart." - products_cart_distributor_is: "ang tagapamahagi para sa order na ito ay%{name}." - products_distributor_error: "kumpletuhin ang inyong order sa%{link} bago mamili sa ibang tagapamahagi." + products_cart_distributor_choice: "Distributor ng inyong order:" + products_cart_distributor_change: "ang distributor para sa order na ito ay mapapalitan ng%{name} kung idadagdag ang produktong ito sa inyong cart." + products_cart_distributor_is: "ang distributor para sa order na ito ay%{name}." + products_distributor_error: "kumpletuhin ang inyong order sa%{link} bago mamili sa ibang distributor." products_oc: "order cycle para sa iyong order:" products_oc_change: "ang iyong order cycle para sa order na ito ay papalitan ng%{name} kung idadagdag mo ang produktong ito sa inyong cart." products_oc_is: "ang order cycle para sa order na ito ay%{name}." @@ -1701,7 +1701,7 @@ fil_PH: products_oc_current: "ang iyong kasalukuyang order cycle" products_max_quantity: sagad na dami products_distributor: Distributor - products_distributor_info: kapag pumili ng tagapamahagi para sa inyong order, ang kanilang address at oras ng pickup ay makikita dito. + products_distributor_info: kapag pumili ng distributor para sa inyong order, ang kanilang address at oras ng pickup ay makikita dito. password: Password remember_me: tandaan ako are_you_sure: "Sigurado ka ba?" @@ -1763,8 +1763,8 @@ fil_PH: registration_time: "5-10 minuto" registration_enterprise_address: "Address ng enterprise" registration_contact_details: "pangunahing detalye ng contact" - registration_logo: "ang image ng iyong logo" - registration_promo_image: "ang pahigang imahe para sa inyong profile" + registration_logo: "ang larawan ng iyong logo" + registration_promo_image: "ang pahigang larawan para sa inyong profile" registration_about_us: "'Tungkol sa Amin' na teksto" registration_outcome_headline: "ano ang makukuha ko?" registration_outcome1_html: "ang iyong profile ang makakatulong sa mga taona hanapinatkontakin ka sa Open Food Network." @@ -1784,18 +1784,18 @@ fil_PH: address1_field_placeholder: "hal. 123 Cranberry Drive" address1_field_error: "isulat ang address" address2_field: "linya ng address 2 :" - suburb_field: "suburb:" + suburb_field: "lungsod:" suburb_field_placeholder: "hal. Northcote" - suburb_field_error: "isulat ang suburb" + suburb_field_error: "isulat ang lungsod" postcode_field: "Postcode:" postcode_field_placeholder: "hal. 3070" postcode_field_error: "kailangang ilagay ang postcode" - state_field: "State:" - state_field_error: "kailangang sagutan ang state" + state_field: "Probinsiya:" + state_field_error: "Kailangang ang probinsiya" country_field: "Bansa:" country_field_error: "pumili ng bansa" contact: - title: "makipag-ugnayan" + title: "Makipag-ugnayan" who_is_managing_enterprise: "sino ang responsable sa pamamahala ng%{enterprise}?" contact_field: "Pangunahing contact" contact_field_placeholder: "Contact name" @@ -1836,20 +1836,20 @@ fil_PH: continue: "Magpatuloy" back: "bumalik" logo: - select_logo: "hakbang 1, pumili ng imahe ng Logo" - logo_tip: "Tip: pinakamaganda ang mga parisukat na imahe, mas mabuti kung ito ay 300x300px" - logo_label: "pumili ng imahe ng logo" + select_logo: "hakbang 1, pumili ng larawan ng Logo" + logo_tip: "Tip: pinakamaganda ang mga parisukat na larawan, mas mabuti kung ito ay 300x300px" + logo_label: "pumili ng larawan ng logo" logo_drag: "hilahin at ilagay ang logo dito" review_logo: "hakbang 2. suriin ang iyong logo" review_logo_tip: "Tip: para sa mas maayos na resulta, ang logo ay dapat matakpan ang lahat ng espasyo" logo_placeholder: "ang iyong logo ay makikita dito para masuri kapag na-upload na" promo: - select_promo_image: "hakbang 3. pumili ng imahe ng promo" + select_promo_image: "hakbang 3. pumili ng larawan ng promo" promo_image_tip: "Tip: ipapakita bilang banner, ang mas mabuting laki ay 1200x260px" - promo_image_label: "pumil ng imahe ng promo" + promo_image_label: "pumili ng larawan ng promo" promo_image_drag: "hilahin at ilagay ang promo dito" review_promo_image: "hakbang 4. suriin ang iyong banner ng promo" - review_promo_image_tip: "Payo: para sa pinakamagandang resulta, ang iyong promo na imahe ay dapat masakop ang lahat ng espasyo" + review_promo_image_tip: "Tip: para sa pinakamagandang resulta, ang iyong promo na larawan ay dapat masakop ang lahat ng espasyo" promo_image_placeholder: "ang iyong logo ay makikita dito para masuri kapag na-upload na" social: title: "Social" @@ -1896,12 +1896,12 @@ fil_PH: transport_fee: "bayad sa pagdadala" fundraising_fee: "bayad sa pangangalap ng pondo" price_graph: "graph ng presyo" - included_tax: "kasamang buwis" + included_tax: "kasamang tax" balance: "Balanse" transaction: "transaksyon" transaction_date: "petsa" - payment_state: "katayuan ng bayad" - shipping_state: "katayuan ng pagpapadala" + payment_state: "status ng bayad" + shipping_state: "status ng pagpapadala" value: "halaga" balance_due: "balanseng kelangan bayaran" credit: "utang" @@ -1910,7 +1910,7 @@ fil_PH: ok: OK not_visible: hindi nakikita you_have_no_orders_yet: "wala ka pang mga order" - show_only_complete_orders: "ipakita lamang ang mga kumpletong order" + show_only_complete_orders: "Ipakita lamang ang mga nakumpletong order" successfully_created: '%{resource}ay matagumpay na nagawa!' successfully_removed: '%{resource}ay matagumpay na natanggal!' successfully_updated: '%{resource}ay matagumpay na na-update' @@ -1928,15 +1928,15 @@ fil_PH: admin_enterprise_groups_enterprise: "enterprises" admin_enterprise_groups_data_powertip: "ang pangunahing gumagamit na responsable sa grupo na ito" admin_enterprise_groups_data_powertip_logo: "ito ang logo ng inyong grupo" - admin_enterprise_groups_data_powertip_promo_image: "ang imahe na ito ay makikita sa taas ng profile ng grupo" - admin_enterprise_groups_contact: "makipag-ugnayan" + admin_enterprise_groups_data_powertip_promo_image: "ang larawan na ito ay makikita sa taas ng profile ng grupo" + admin_enterprise_groups_contact: "Makipag-ugnayan" admin_enterprise_groups_contact_phone_placeholder: "hal. 98 7654 3210" admin_enterprise_groups_contact_address1_placeholder: "eg. 123 High Street" - admin_enterprise_groups_contact_city: "labas ng lungsod" + admin_enterprise_groups_contact_city: "lungsod" admin_enterprise_groups_contact_city_placeholder: "hal. Northcote" admin_enterprise_groups_contact_zipcode: "Postcode" admin_enterprise_groups_contact_zipcode_placeholder: "hal. 3070" - admin_enterprise_groups_contact_state_id: "kalagayan" + admin_enterprise_groups_contact_state_id: "Probinsiya" admin_enterprise_groups_contact_country_id: "Bansa" admin_enterprise_groups_web: "mga pinagkukuhanan ng Web" admin_enterprise_groups_web_twitter: "hal. @the_prof" @@ -1946,7 +1946,7 @@ fil_PH: close: "isara" create: "gumawa" search: "hanapin" - supplier: "tagapagtustos" + supplier: "Supplier" product_name: "pangalan ng produkto" product_description: "paglalarawan ng produkto" units: "laki kada yunit" @@ -1957,7 +1957,7 @@ fil_PH: delivery_instructions: mga panuto sa pagdeliver delivery_method: paraan ng pagdeliver fee_type: "uri ng kabayaran" - tax_category: "kategorya ng buwis" + tax_category: "kategorya ng tax" calculator: "calculator" calculator_values: "mga halaga sa calculator" calculator_settings_warning: "kung papalitan ang uri ng calculator, dapat ay i-save muna bago maiayos ang setting ng calculator" @@ -1985,7 +1985,7 @@ fil_PH: no_customers_found: "walang nahanap ng mga customer" go: "Sige" hub: "Hub" - producer: "Prodyuser" + producer: "Producer" product: "produkto" price: "presyo" on_hand: "on hand" @@ -2012,7 +2012,7 @@ fil_PH: spree_admin_unit_description: paglalarawan sa bawat yunit spree_admin_variant_unit: Variant unit spree_admin_variant_unit_scale: sukat ng Variant unit - spree_admin_supplier: tagapagtustos + spree_admin_supplier: Supplier spree_admin_product_category: kategorya ng produkto spree_admin_variant_unit_name: pangalan ng variant unit unit_name: "pangalan ng yunit" @@ -2020,10 +2020,10 @@ fil_PH: spree_admin_single_enterprise_hint: "payo: para mahanap ka ng mga tao, i-turn on ang visibility sa ilalim ng" spree_admin_eg_pickup_from_school: "hal. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "hal. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" - spree_classification_primary_taxon_error: "ang Taxon%{taxon}ay ang pangunahing taxon ng %{product}at hindi maaaring tanggalin" - spree_order_availability_error: "ang tagapamahagi o ang order cycle ay hindi kayang ibigay ang mga produkto sa inyong cart" - spree_order_populator_error: "ang tagapamahagi o order cycle na iyan ay hindi kayang ibigay lahat ng mga produkto sa inyong cart. pumili ng isa pa." - spree_order_populator_availability_error: "ang produktong iyan ay hindi ngayon available mula sa napiling tagapamahagi o order cycle." + spree_classification_primary_taxon_error: "ang Tax sa%{taxon}ay ang pangunahing tax ng %{product}at hindi maaaring tanggalin" + spree_order_availability_error: "ang distributor o order cycle ay hindi kayang ibigay ang mga produkto sa inyong cart" + spree_order_populator_error: "ang distributor o order cycle na ito ay hindi kayang ibigay lahat ng mga produkto sa inyong cart. pumili ng iba." + spree_order_populator_availability_error: "ang produktong ito ay hindi ngayon available mula sa napiling distributor o order cycle." spree_distributors_error: "pumili ng kahit isa sa mga Hub" spree_user_enterprise_limit_error: "^%{email}ay walang permiso na mag-ari ng karagdagang mga enterprise (ang limitasyon ay%{enterprise_limit})." spree_variant_product_error: ay dapat mayroong kahit isang uri @@ -2038,7 +2038,7 @@ fil_PH: manage_order_cycles: "pamahalaan ang mga order cycle" manage_products: "pamahalaan ang mga produkto" edit_profile_details: "ayusin ang mga detalye ng profile" - edit_profile_details_etc: "palitan ang paglalarawan, imahe at iba pa ng iyong profile" + edit_profile_details_etc: "palitan ang paglalarawan, larawan at iba pa ng iyong profile" order_cycle: "order cycle" order_cycles: "order cycles" enterprise_relationships: "mga permiso ng enterprise" @@ -2049,14 +2049,14 @@ fil_PH: enterprise_tos_message: "nais naming makiisa sa mga taong kapareho ng aming layunin at adhikain. Dahil dito, hinihiling namin sa mga bagong enterprise na sumang-ayon sa aming" enterprise_tos_link_text: "Palatuntunan ng serbisyo." enterprise_tos_agree: "ako ay sumasang-ayon sa palatuntunan ng serbisyo na nasa itaas." - tax_settings: "settings ng buwis" - products_require_tax_category: "ang mga produkto ay kailangang may kategorya ng buwis" + tax_settings: "settings ng tax" + products_require_tax_category: "ang mga produkto ay kailangang may kategorya ng tax" admin_shared_address_1: "tirahan" admin_shared_address_2: "address (pagpapatuloy)" admin_share_city: "Lungsod" admin_share_zipcode: "Postcode" admin_share_country: "Bansa" - admin_share_state: "kalagayan" + admin_share_state: "Status" hub_sidebar_hubs: "Hubs" hub_sidebar_none_available: "walang available" hub_sidebar_manage: "pamahalaan" @@ -2064,7 +2064,7 @@ fil_PH: hub_sidebar_blue: "bughaw" hub_sidebar_red: "pula" report_customers_distributor: "Distributor" - report_customers_supplier: "tagapagtustos" + report_customers_supplier: "Suuplier" report_customers_cycle: "order cycle" report_customers_type: "uri ng ulat" report_customers_csv: "i-download bilang csv" @@ -2072,7 +2072,7 @@ fil_PH: report_type: "uri ng ulat:" report_hubs: "mga Hub:" report_payment: "mga uri ng pagbabayad:" - report_distributor: "tagapamahagi:" + report_distributor: "Distributor:" report_payment_by: 'pagbabayad kada uri' report_itemised_payment: 'kabuuan ng mga in-itemise na bayad' report_payment_totals: 'kabuuan ng bayad' @@ -2080,17 +2080,17 @@ fil_PH: report_order_cycle: "Order Cycle:" report_enterprises: "mga Enterprise:" report_users: "mga gumagamit:" - report_tax_rates: mga rate ng buwis - report_tax_types: mga uri ng buwis + report_tax_rates: mga rate ng tax + report_tax_types: mga uri ng tax report_header_order_cycle: order cycle report_header_user: User report_header_email: email - report_header_status: katayuan + report_header_status: Status report_header_comments: mga puna report_header_first_name: Pangalan report_header_last_name: Apelyido report_header_phone: telepono - report_header_suburb: labas ng lungsod + report_header_suburb: lungsod report_header_address: tirahan report_header_billing_address: Billing Address report_header_relationship: relasyon @@ -2108,14 +2108,14 @@ fil_PH: report_header_ship_street_2: kalsada na pagpapadalahan 2 report_header_ship_city: lungsod na pagpapadalahan report_header_ship_postcode: postcode ng pagpapadalahan - report_header_ship_state: estado ng pagpapadalahan + report_header_ship_state: status ng pagpapadala report_header_billing_street: address na papadalahan ng bayarin report_header_billing_street_2: address na papadalahan ng bayarin 2 report_header_billing_street_3: address na papadalahan ng bayarin 3 report_header_billing_street_4: address na papadalahan ng bayarin 4 report_header_billing_city: lungsod na papadalahan ng bayarin report_header_billing_postcode: postcode ng papadalahan ng bayarin - report_header_billing_state: estado ng papadalahan ng bayarin + report_header_billing_state: status ng papadalahan ng bayarin report_header_incoming_transport: papasok na sasakyan report_header_special_instructions: espesyal na mga panuto report_header_order_number: numero ng order @@ -2124,12 +2124,12 @@ fil_PH: report_header_tags: tags report_header_items: mga item report_header_items_total: "kabuuan ng mga item%{currency_symbol}" - report_header_taxable_items_total: "kabuuan ng mga item na binubuwisan (%{currency_symbol})" - report_header_sales_tax: "buwis sa mga nabenta (%{currency_symbol})" + report_header_taxable_items_total: "kabuuan ng mga item na taxable (%{currency_symbol})" + report_header_sales_tax: "tax sa mga nabenta (%{currency_symbol})" report_header_delivery_charge: "bayad sa pag-deliver(%{currency_symbol})" - report_header_tax_on_delivery: "buwis sa pagdeliver (%{currency_symbol})" - report_header_tax_on_fees: "buwis sa mga bayarin (%{currency_symbol})" - report_header_total_tax: "kabuuang buwis(%{currency_symbol})" + report_header_tax_on_delivery: "tax sa pagdeliver (%{currency_symbol})" + report_header_tax_on_fees: "tax sa mga bayarin (%{currency_symbol})" + report_header_total_tax: "kabuuang tax(%{currency_symbol})" report_header_enterprise: Enterprise report_header_customer: customer report_header_customer_code: Code ng Customer @@ -2144,9 +2144,9 @@ fil_PH: report_header_unallocated: hindi pinapamahalaan report_header_max_quantity_excess: Sumobra sa limit na pinakamarami report_header_taxons: Taxons - report_header_supplier: tagapagtustos - report_header_producer: Prodyuser - report_header_producer_suburb: Suburb ng Producer + report_header_supplier: Supplier + report_header_producer: Producer + report_header_producer_suburb: Lungsod ng Producer report_header_unit: yunit report_header_group_buy_unit_quantity: Dami ng yunit para sa Maramihang pagbili report_header_cost: gastos @@ -2180,7 +2180,7 @@ fil_PH: report_header_customer_email: Email ng Customer report_header_customer_phone: Telepono ng Customer report_header_customer_city: Lungsod ng Customer - report_header_payment_state: estado ng pagbabayad + report_header_payment_state: status ng pagbabayad report_header_payment_type: uri ng pagbabayad report_header_item_price: "item(%{currency})" report_header_item_fees_price: "item + bayad (%{currency})" @@ -2189,7 +2189,7 @@ fil_PH: report_header_pay_fee_price: "Bayad sa pagbabayad (%{currency})" report_header_total_price: "Kabuuan (%{currency})" report_header_product_total_price: "Kabuuang Produkto (%{currency})" - report_header_shipping_total_price: "kabuuang pagpapadala (%{currency})" + report_header_shipping_total_price: "kabuuan ng ipapadala (%{currency})" report_header_outstanding_balance_price: "Kasalukuyang balanse (%{currency})" report_header_eft_price: "EFT (%{currency})" report_header_paypal_price: "Paypal (%{currency})" @@ -2201,21 +2201,21 @@ fil_PH: report_header_total_max: kabuuang pinakamataas na limit report_header_total_units: kabuuang yunit report_header_sum_max_total: "kabuuan" - report_header_total_excl_vat: "Kabuuang buwis na hindi kasama (%{currency_symbol})" - report_header_total_incl_vat: "Kabuuang buwis na kasama (%{currency_symbol})" + report_header_total_excl_vat: "Kabuuang tax na hindi kasama (%{currency_symbol})" + report_header_total_incl_vat: "Kabuuang tax na kasama (%{currency_symbol})" report_header_temp_controlled: TempControlled? report_header_is_producer: Producer? report_header_not_confirmed: hindi kumpirmado report_header_gst_on_income: GST sa Kinikita report_header_gst_free_income: GST sa Libreng Kinikita - report_header_total_untaxable_produce: kabuuang produkto na hindi binubuwisan (walang buwis) - report_header_total_taxable_produce: kabuuang produkto na binubuwisan (may kasamang buwis) - report_header_total_untaxable_fees: kabuuang bayarin na hindi binubuwisan (walang buwis) - report_header_total_taxable_fees: kabuuang bayarin na binubuwisan (may kasamang buwis) - report_header_delivery_shipping_cost: Singil sa pagdeliver ng pinapadala (kasama ang buwis) - report_header_transaction_fee: Bayad sa Transaksyon (walang buwis) - report_header_total_untaxable_admin: kabuuang hindi binubuwisang pagsasaayos ng admin (walang tax) - report_header_total_taxable_admin: kabuuang hindi binubuwisang pagsasaayos ng admin (kasama ang tax) + report_header_total_untaxable_produce: kabuuang produkto na untaxable (walang tax) + report_header_total_taxable_produce: kabuuang produkto na taxable (may kasamang tax) + report_header_total_untaxable_fees: kabuuang bayarin na untaxable (walang tax) + report_header_total_taxable_fees: kabuuang bayarin na taxable (may kasamang tax) + report_header_delivery_shipping_cost: Singil sa pagdeliver ng pinapadala (kasama ang tax) + report_header_transaction_fee: Bayad sa Transaksyon (walang tax) + report_header_total_untaxable_admin: kabuuang untaxable na pagsasaayos ng admin (walang tax) + report_header_total_taxable_admin: kabuuang taxable na pagsasaayos ng admin (kasama ang tax) initial_invoice_number: "paunang numero ng invoice:" invoice_date: "Petsa ng Invoice:" due_date: "Due Date:" @@ -2242,7 +2242,7 @@ fil_PH: web: "Web" primary_details: "pangunahing detalye" adrdress: "tirahan" - contact: "makipag-ugnayan" + contact: "Makipag-ugnayan" social: "Social" business_details: "detalye ng negosyo" properties: "mga katangian" @@ -2260,7 +2260,7 @@ fil_PH: enterprise_fee_by: "%{type}na bayad ng%{role}%{enterprise_name}" validation_msg_relationship_already_established: "^ang relasyon ay naitatag na" validation_msg_at_least_one_hub: "^kailangang kahit isang Hub ay piliin" - validation_msg_tax_category_cant_be_blank: "^ang kategorya ng buwis ay hindi maaaring walang sagot" + validation_msg_tax_category_cant_be_blank: "^ang kategorya ng tax ay hindi maaaring walang sagot" validation_msg_is_associated_with_an_exising_customer: "ay nauugnay na sa isang customer" content_configuration_pricing_table: "(DAPATGAWIN: TALAAN NG PRESYO)" content_configuration_case_studies: "(DAPATGAWIN: mga pag-aaral ng kaso)" @@ -2276,15 +2276,17 @@ fil_PH: product_import_no_data_in_spreadsheet_notice: 'walang data na mahanap sa spreadsheet' order_choosing_hub_notice: ang iyong Hub ay napili order_cycle_selecting_notice: ang iyong order cycle ay napili - adjustments_tax_rate_error: "^siguraduhing ang rate ng buwis para sa adjustment na ito ay tama." + adjustments_tax_rate_error: "^siguraduhing ang rate ng tax para sa adjustment na ito ay tama." active_distributors_not_ready_for_checkout_message_singular: >- ang Hub na%{distributor_names}ay kasamang nakalista sa isang aktibong order - cyle ngunit walang valid na shipping at payment method. Hanggang hindi pa naisasaayos - ang pagset-up, hindi makakapamili ang mga customer sa hub na ito. + cyle ngunit walang valid na paraan ng pagbabayad at pagpapadala. Hanggang hindi + pa naisasaayos ang pagset-up, hindi makakapamili ang mga customer sa hub na + ito. active_distributors_not_ready_for_checkout_message_plural: >- ang mga Hub na %{distributor_names}ay kasamang nakalista sa isang aktibong order - cycle ngunit walang valid na shipping at payment method. Hanggang hindi pa naisasaayos - ang pagset-up, hindi makakapamili ang mga customer sa mga hub na ito. + cycle ngunit walang valid na paraan ng pagpapadala at pagbabayad. Hanggang hindi + pa naisasaayos ang pagset-up, hindi makakapamili ang mga customer sa mga hub + na ito. enterprise_fees_update_notice: ang mga bayarin ng inyong enterprise ay na-update na enterprise_register_package_error: "pumili ng package" enterprise_register_error: "hindi makumpleto ang rehistrasyon para sa%{enterprise}" @@ -2317,15 +2319,15 @@ fil_PH: all_changes_saved_successfully: lahat ng pagbabago ay matagumpay na na-save oh_no: "paumanin! hindi ko na-save ang mga pagbabagong ginawa mo." unauthorized: "ikaw ay hindi awtorisadong i-access ang pahina na ito." - error: pagkakamali + error: Error unavailable: hindi available profile: profile hub: Hub shop: Shop choose: pumili - resolve_errors: paki-ayos ang mga sumusunod na pagkakamali + resolve_errors: paki-ayos ang mga sumusunod na mga error more_items: "+%{count}iba pa" - default_card_updated: na-update ang card + default_card_updated: na-update ang default card admin: enterprise_limit_reached: "naabot mo na ang karaniwang lmitasyon ng dami ng bilang ng mga enterprise sa bawat account. makipag-ugnayan sa%{contact_email}kung kailangan mo itong dagdagan." modals: @@ -2339,16 +2341,16 @@ fil_PH: overview_text: > ang panuntunan sa tag na nagbibigay ng paraan upang maisalarawan kung anong mga item ang nakikita at kung sa kaninong mga customer dapat ito - maipakita. Ang mga item ay maaaring paraan ng pagpapadala, paraang ng + maipakita. Ang mga item ay maaaring paraan ng pagpapadala, paraan ng pagbabayad, mga produkto at mga order cycle. - by_default_rules: "'By Default...' mga tuntunin" + by_default_rules: "'By Default...' mga panuntunan" by_default_rules_text: > - ang orihinal na mga tuntunin ay papayagan ka na magtago ng mga item - para hindi ito makita. ang gawaing ito ay maaaring saklawan ng ibang - tuntunin para sa mga customer na may tag. - customer_tagged_rules: "'Mga Customer na naka-tag...' mga tuntunin" + ang default na mga panuntunan ay papayagan ka na magtago ng mga item + upang hindi ito makita. ang gawaing ito ay maaaring saklawan ng hindi + default na panuntunan para sa mga customer na may tag. + customer_tagged_rules: "'Mga Customer na naka-tag...' mga panuntunan" customer_tagged_rules_text: > - sa pamamagitan ng paggawa ng mga tuntunin na may kinalaman sa isang + sa pamamagitan ng paggawa ng mga panuntunan na may kinalaman sa isang partikular na customer na naka-tag, maaari mong saklawan ang kinagawiang gawain(sa pagpapakita man o pagtago ng mga item) para sa mga customer na may tag. @@ -2424,7 +2426,7 @@ fil_PH: sell_own_produce: magbenta ng sariling produkto sell_both: magbenta ng produkto mula sa sarili at sa iba enterprise_producer: - producer: Prodyuser + producer: Producer producer_text1: > Ang mga producer ay gumagawa ng masasarap na bagay na maaaring makain o mainom. Ikaw ay isang producer kung itinatanim mo ito, pinapalaki, @@ -2442,7 +2444,7 @@ fil_PH: sa halip, ang mga hindi producer ay dalubhasa sa pag-uugnay ng mga producer sa mga mamili, maaaring sa pamamagitan ng pagsasama sama, pagmamarka, pagbabalot, pagbebenta o pagde-deliver ng pagkain. - producer_desc: mga gumagawa ng pagkain + producer_desc: mga producer ng pagkain producer_example: hal. NAGPAPATUBO, PANADERO, MANGANGALAKAL, YUMAYARI non_producer_desc: Iba pang mga enterprise ng pagkain non_producer_example: hal. Grocery, Food co-ops, Buying groups @@ -2561,7 +2563,7 @@ fil_PH: inventory_products: "mga produktong naka-imbentaryo" hidden_products: "mga nakatagong pprodukto" new_products: "bagong produkto" - reset_stock_levels: i-reset ang lebel ng stock sa orihinal + reset_stock_levels: i-reset ang lebel ng stock sa default changes_to: mga pagbabago sa one_override: isang override overrides: mga override @@ -2570,7 +2572,7 @@ fil_PH: no_authorisation: "hindi ko makuha ang awtorisasyon para i-save ang mga pagbabago kaya mananatili ang mga ito na hindi naka-save." some_trouble: "nagkaroon ako ng problema sa pagse-save: %{errors}" changing_on_hand_stock: pagbabago sa lebel ng hand stock - stock_reset: ni-reset sa orihinal ang mga stock + stock_reset: ni-reset sa default ang mga stock tag_rules: show_hide_variants: 'ipakita o itago ang mga variant sa aking Shopfront' show_hide_shipping: 'ipakita o itago ang mga paraan ng pagpapadala sa checkout' @@ -2598,7 +2600,7 @@ fil_PH: update_failure: "hindi nagtagumpay sa pag-update ng order cycle" no_distributors: walang distributor sa order cycle na ito. ang order cycle ay hindi makikita ng mga customer hanggang hindi kayo naglalagay ng distributor. Nais mo bang magpatuloy i-save ang order cycle? enterprises: - producer: "Prodyuser" + producer: "Producer" non_producer: "hindi producer" customers: select_shop: 'pumili muna ng shop' @@ -2717,7 +2719,7 @@ fil_PH: customer_name: "customer" fee_placement: "paglilipat ng bayad" fee_calculated_on_transfer_through_name: "Fee Calc sa Transfer Through" - tax_category_name: "kategorya ng buwis" + tax_category_name: "kategorya ng tax" total_amount: "$$ KABUUAN" html: header: @@ -2727,7 +2729,7 @@ fil_PH: customer_name: "customer" fee_placement: "paglilipat ng bayad" fee_calculated_on_transfer_through_name: "Fee Calc sa Transfer Through" - tax_category_name: "kategorya ng buwis" + tax_category_name: "kategorya ng tax" total_amount: "$$ KABUUAN" invalid_filter_parameters: "ang mga filter na pinili para sa ulat na ito ay hindi valid." order: "order" @@ -2740,7 +2742,7 @@ fil_PH: payment_method: "paraan ng pagbayad" shipment: "kargamento" shipment_inc_vat: "kargamento kasama ang VAT" - shipping_tax_rate: "rate ng buwis para sa pagdadala" + shipping_tax_rate: "rate ng tax para sa pagpapadala" category: "kategorya" delivery: "pagdeliver" temperature_controlled: "kontrolado ang temperatura" @@ -2750,7 +2752,7 @@ fil_PH: account: "Account" logout: "mag-log-out" date_range: "saklaw na petsa" - status: "katayuan" + status: "status" new: "Bago" start: "simula" end: "katapusan" @@ -2785,7 +2787,7 @@ fil_PH: choose_a_customer: "pumili ng customer" account: "Account" billing_address: "Billing Address" - shipping_address: "Shipping Address" + shipping_address: "Address kung saan ipapadala" first_name: "Pangalan" last_name: "apelyido" street_address: "address ng kalye" @@ -2793,7 +2795,7 @@ fil_PH: city: "Lungsod" zip: "Zip" country: "Bansa" - state: "kalagayan" + state: "status" phone: "telepono" update: "i-update" use_billing_address: "gamitin ang address para sa paniningil" @@ -2838,7 +2840,7 @@ fil_PH: smtp_authentication_type: "SMTP Authentication Type" smtp_username: "SMTP username" smtp_password: "SMTP password" - image_settings: "mga setting ng imahe" + image_settings: "mga setting ng larawan" image_settings_warning: "kinakailangang gumawa muli ng mga thumbnail kung ia-update ang mga estilo ng paperclip. gumamit ng rake paperclip:refresh:thumbnails CLASS=Spree::Image para gawin ito." attachment_default_style: estilo ng mga attachment attachment_default_url: "Default URL ng mga attachment" @@ -2846,38 +2848,38 @@ fil_PH: attachment_styles: "estilo ng Paperclips" attachment_url: "URL ng mga attachment" add_new_style: "magdagdag ng bagong estilo" - image_settings_updated: "matagumpay na na-update ang settings ng imahe" - tax_categories: "kategorya ng buwis" - listing_tax_categories: "kategorya ng nakalistang buwis" - back_to_tax_categories_list: "bumalik sa listahan ng kategorya ng buwis" - tax rate: "rate ng mga buwis" - new_tax_rate: "bagong rate ng buwis" - tax_category: "kategorya ng buwis" + image_settings_updated: "matagumpay na na-update ang settings ng larawan" + tax_categories: "kategorya ng tax" + listing_tax_categories: "kategorya ng nakalistang tax" + back_to_tax_categories_list: "bumalik sa listahan ng kategorya ng tax" + tax rate: "rate ng mga tax" + new_tax_rate: "bagong rate ng tax" + tax_category: "kategorya ng tax" rate: "rate" - tax_rate_amount_explanation: "ang mga rate ng buwis ay mga halagang may decimal na makakatulong sa pagkukwenta, (hal. kung ang rate ng buwis ay 5% ang ilalagay ay 0.05)" + tax_rate_amount_explanation: "ang mga rate ng tax ay mga halagang may decimal na makakatulong sa pagkukuwenta, (hal. kung ang rate ng tax ay 5% ang ilalagay ay 0.05)" included_in_price: "nakasama sa presyo" show_rate_in_label: "ipakita ang rate sa tatak" - back_to_tax_rates_list: "bumalik sa listahan ng rate ng buwis" - tax_settings: "Settings ng buwis" + back_to_tax_rates_list: "bumalik sa listahan ng rate ng tax" + tax_settings: "Settings ng tax" zones: "mga sona" new_zone: "bagong sona" - default_tax: "default na buwis" - default_tax_zone: "default na sona ng buwis" + default_tax: "default na tax" + default_tax_zone: "default na sona ng tax" country_based: "Country Based" - state_based: "nakabase sa estado" + state_based: "Nakabase sa probinsiya" countries: "Mga Bansa" listing_countries: "Listahan ng mga Bansa" iso_name: "pangalan ng ISO" - states_required: "kailangang may estado" + states_required: "Kailangang may mga probinsiya" editing_country: "pag-edit ng bansa" back_to_countries_list: "bumalik sa listahan ng mga bansa" - states: "Estado" + states: "Mga probinsiya" abbreviation: "Pinaikli" - new_state: "Bagong estado" + new_state: "Bagong Probinsiya" payment_methods: "Mga Paraan ng Pagbabayad" new_payment_method: "Bagong Paraan ng pagbabayad" provider: "tagapagbigay ng serbisyo" - taxonomies: "taxomies" + taxonomies: "taxonomies" new_taxonomy: "bagong taxonomy" back_to_taxonomies_list: "bumalik sa listahan ng mga taxonomy" shipping_methods: "mga paraan ng pagpapadala" @@ -2896,11 +2898,11 @@ fil_PH: default: "default" calculator: "calculator" zone: "sona" - display: "ipakita" + display: "Ipakita" environment: "kapaligiran" active: "aktibo" nore: "Iba pa" - no_results: "walang resulta" + no_results: "Walang resulta" create: "gumawa" loading: "naglo-load" flat_percent: "Patag na porsiyento" @@ -2986,7 +2988,7 @@ fil_PH: return_authorizations: "mga awtorisasyon sa pagbabalik" back_to_orders_list: "bumalik sa listahan ng mga order" rma_number: "numbero ng RMA" - status: "katayuan" + status: "status" amount: "halaga" cannot_create_returns: "hindi makagawa ng pagbalik sa kadahilanang ang order na ito ay walang shipped na yunit." continue: "Magpatuloy" @@ -3026,15 +3028,15 @@ fil_PH: next: "sunod" loading: "naglo-load" no_orders_found: "walang mahanap na mga order" - results_found: "%{number}natagpuang resulta." + results_found: "%{number}Natagpuang resulta." viewing: "makikita ang%{start} hanggang%{end}." print_invoices: "i-print ang mga invoice" sortable_header: - payment_state: "estado ng pagbabayad" - shipment_state: "kalagayan ng kargamento" + payment_state: "status ng pagbabayad" + shipment_state: "status ng kargamento" completed_at: "Natapos sa" number: "bilang" - state: "kalagayan" + state: "status" email: "Email ng Kustomer" invoice: issued_on: "inilabas noong" @@ -3075,7 +3077,7 @@ fil_PH: products_distributor: "Distributor" zone: "sona" calculator: "calculator" - display: "ipakita" + display: "Ipakita" both: "pareho" front_end: "harapan" back_end: "Likuran" @@ -3108,7 +3110,7 @@ fil_PH: account_missing_msg: walang Stripe account para sa enterprise na ito connect_one: Connect One access_revoked_msg: ang access sa Stripe account na ito ay pinawalang bisa, ikonekta muli ang account. - status: katayuan + status: status connected: konektado account_id: Account ID business_name: pangalan ng negosyo @@ -3119,11 +3121,11 @@ fil_PH: error_saving_payment: error sa pag-save ng bayad submitting_payment: sinusumite ang bayad... products: - image_upload_error: "ang imahe ng produkto ay hindi makilala. mag-upload ng imahe sa format na PNG o JPG." + image_upload_error: "ang larawan ng produkto ay hindi makilala. mag-upload ng larawan sa format na PNG o JPG." new: title: "bagong produkto" new_product: "bagong produkto" - supplier: "tagapagtustos" + supplier: "Supplier" product_name: "pangalan ng produkto" units: "laki kada yunit" value: "halaga" @@ -3132,7 +3134,7 @@ fil_PH: on_hand: "on hand" on_demand: "on demand" product_description: "paglalarawan ng produkto" - image: "imahe" + image: "larawan" or: "o" unit_name_placeholder: 'hal. mga kumpol' index: @@ -3145,9 +3147,9 @@ fil_PH: products_head: name: pangalan unit: yunit - display_as: ipakita bilang + display_as: Ipakita Bilang category: kategorya - tax_category: kategorya ng buwis + tax_category: kategorya ng tax inherits_properties?: minana ang mga katangian? available_on: Magagamit Nakabukas av_on: "Av On" @@ -3162,7 +3164,7 @@ fil_PH: group_buy: "grupong pamimili?" bulk_unit_size: laki ng bultuhang yunit display_as: - display_as: ipakita bilang + display_as: Ipakita Bilang reports: table: select_and_search: "pumili ng mga filter at pindutin ang%{option} para ma-access ang inyong data." @@ -3204,24 +3206,24 @@ fil_PH: sku: "SKU" price: "presyo" options: "pagpipilian" - no_results: "walang resulta" + no_results: "Walang resulta" to_add_variants_you_must_first_define: "para makapagdagdag ng mga variant, tukuyin muna ang" option_types: "mga uri ng pagpipilian" option_values: "Mga halaga ng pagpipilian" and: "at" new_variant: "bagong variant" - show_active: "ipakita ang aktibo" - show_deleted: "ipakita ang tinanggal" + show_active: "Ipakita Ang Mga Aktibo" + show_deleted: "Ipakita Ang Mga Tinanggal" new: new_variant: "bagong variant" form: cost_price: "halaga ng gastos" sku: "SKU" price: "presyo" - display_as: "ipakita bilang" + display_as: "Ipakita Bilang" display_name: "Pangalan na nakikita" autocomplete: - producer_name: "Prodyuser" + producer_name: "Producer" unit: "yunit" general_settings: edit: @@ -3368,7 +3370,7 @@ fil_PH: api: invalid_api_key: "hindi valid na API key (%{key}) na tinutukoy." unauthorized: "ikaw ay hindi awtorisado na gawin ang kilos na iyon." - invalid_resource: "hindi valid na pinagkuhanan. ayusin ang error at subukan muli." + invalid_resource: "hindi valid na pinagkuhanan. ayusin ang mga error at subukan muli." resource_not_found: "ang pinagkukuhan ay hindi mahanap." access: "API Access" key: "Key" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 7566b07d58..422c67981d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -59,7 +59,7 @@ fr: messages: inclusion: "n'est pas inclus dans la liste" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Veuillez ajouter au moins un produit" @@ -1670,7 +1670,7 @@ fr: orders_form_admin: Admin & traitements orders_form_total: Total orders_oc_expired_headline: Les commandes ne sont plus possibles pour ce cycle de vente. - orders_oc_expired_text: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le hub pour voir s'il accepte les commandes tardives." + orders_oc_expired_text: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}!" orders_oc_expired_text_others_html: "Désolé, les commandes pour ce cycle de vente ont été clôturées il y a %{time}! Veuillez contacter directement le hub pour voir s'il accepte les commandes tardives %{link}." orders_oc_expired_text_link: "ou voir si d'autres cycles de vente sont ouverts pour ce hub" orders_oc_expired_email: "Email:" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index 8ca1872694..ff58ad6631 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -55,7 +55,7 @@ fr_BE: messages: inclusion: "N'est pas inclus dans la liste" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Veuillez ajouter au moins un produit" diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index cf300ce168..12f9a6a53b 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -55,7 +55,7 @@ fr_CA: messages: inclusion: "n'est pas inclus dans la liste" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "Veuillez ajouter au moins un produit" diff --git a/config/locales/it.yml b/config/locales/it.yml index 67f67b0a28..317c08bdd0 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -55,7 +55,7 @@ it: messages: inclusion: "non incluso nella lista" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Aggiungi almeno un prodotto" diff --git a/config/locales/nb.yml b/config/locales/nb.yml index 471207ccca..cf941afc92 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -55,7 +55,7 @@ nb: messages: inclusion: "er ikke inkludert i listen" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Vennligst legg til minst ett produkt" diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index d6d40e6fdc..3ce888b436 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -53,7 +53,7 @@ nl_BE: payment_method_ids: "Betaalmethodes" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Gelieve minstens één product toe te voegen" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index b5444331ec..d40a0f3ba9 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -51,7 +51,7 @@ pt: payment_method_ids: "Métodos de pagamento" errors: models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^Por favor adicione pelo menos um produto" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index d5dbc46d8d..158198a36d 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -53,7 +53,7 @@ pt_BR: messages: inclusion: "não está incluso na lista" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^ Por favor, adicione pelo menos um produto" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index b36a8da76b..6c5579977e 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -55,7 +55,7 @@ tr: messages: inclusion: "Listeye dahil değil" models: - subscription_validator: + order_management/subscriptions/validator: attributes: subscription_line_items: at_least_one_product: "^ Lütfen en az bir ürün ekleyin" From a6414b6dbed387aa0cb738ac6ffc4fb7a10b8fe0 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Fri, 10 Apr 2020 20:14:14 +0200 Subject: [PATCH 098/166] Make sure taggable_type is 'Customer' when querying customer tags --- app/controllers/admin/customers_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index 91eda7d4a7..dac3b209dc 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -96,7 +96,10 @@ module Admin customer_tags = ::ActsAsTaggableOn::Tag. joins(:taggings). includes(:taggings). - where(taggings: { taggable_id: Customer.of(managed_enterprise_id), context: 'tags' }) + where(taggings: + { taggable_type: 'Customer', + taggable_id: Customer.of(managed_enterprise_id), + context: 'tags' }) customer_tags.each_with_object({}) do |tag, indexed_hash| customer_id = tag.taggings.first.taggable_id From c3ee7b7c642189428ea8af74434097472a1fccc8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2020 19:19:13 +0000 Subject: [PATCH 099/166] Bump ddtrace from 0.34.1 to 0.34.2 Bumps [ddtrace](https://github.com/DataDog/dd-trace-rb) from 0.34.1 to 0.34.2. - [Release notes](https://github.com/DataDog/dd-trace-rb/releases) - [Changelog](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md) - [Commits](https://github.com/DataDog/dd-trace-rb/compare/v0.34.1...v0.34.2) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1cf17a8cd4..c09de59c97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -198,7 +198,7 @@ GEM activerecord (>= 3.2.0, < 5.0) fog (~> 1.0) rails (>= 3.2.0, < 5.0) - ddtrace (0.34.1) + ddtrace (0.34.2) msgpack debugger-linecache (1.2.0) deface (1.0.2) From 14cf168e3bf9eeaa12f9f9c6e43431bba29b5504 Mon Sep 17 00:00:00 2001 From: Rob H Date: Tue, 7 Apr 2020 23:57:08 +1000 Subject: [PATCH 100/166] Take sku overrides into account in customer totals report --- .../orders_and_fulfillments_report.rb | 15 +++++++++ .../customer_totals_report.rb | 8 ++++- .../reports/variant_overrides.rb | 30 +++++++++++++++++ .../customer_totals_report_spec.rb | 22 +++++++++++++ .../reports/variant_overrides_spec.rb | 32 +++++++++++++++++++ 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 lib/open_food_network/reports/variant_overrides.rb create mode 100644 spec/lib/open_food_network/reports/variant_overrides_spec.rb diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index 7c3780bb55..bf7be98cbd 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -1,4 +1,5 @@ require "open_food_network/reports/line_items" +require "open_food_network/reports/variant_overrides" require "open_food_network/orders_and_fulfillments_report/supplier_totals_report" require "open_food_network/orders_and_fulfillments_report/supplier_totals_by_distributor_report" require "open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report" @@ -18,6 +19,7 @@ module OpenFoodNetwork @options = options @report_type = options[:report_type] @render_table = render_table + @variant_scopers_by_distributor_id = {} end def search @@ -45,6 +47,14 @@ module OpenFoodNetwork proc { |line_items| line_items.first.variant.product.name } end + def variant_scoper_for(distributor_id) + @variant_scopers_by_distributor_id[distributor_id] ||= + OpenFoodNetwork::ScopeVariantToHub.new( + distributor_id, + report_variant_overrides[distributor_id] + ) + end + private def report @@ -89,5 +99,10 @@ module OpenFoodNetwork def report_line_items @report_line_items ||= Reports::LineItems.new(order_permissions, options) end + + def report_variant_overrides + @report_variant_overrides ||= + Reports::VariantOverrides.new(order_permissions.visible_line_items).indexed + end end end diff --git a/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb b/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb index 593933e157..8225d45eea 100644 --- a/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb @@ -7,9 +7,11 @@ module OpenFoodNetwork attr_reader :context delegate :line_item_name, to: :context + delegate :variant_scoper_for, to: :context def initialize(context) @context = context + @scopers_by_distributor_id = {} end # rubocop:disable Metrics/AbcSize @@ -159,7 +161,11 @@ module OpenFoodNetwork }, proc { |_line_items| "" }, - proc { |line_items| line_items.first.variant.sku }, + proc do |line_items| + line_item = line_items.first + variant_scoper_for(line_item.order.distributor_id).scope(line_item.variant) + line_item.variant.sku + end, proc { |line_items| line_items.first.order.order_cycle.andand.name }, proc { |line_items| diff --git a/lib/open_food_network/reports/variant_overrides.rb b/lib/open_food_network/reports/variant_overrides.rb new file mode 100644 index 0000000000..2b2a02845b --- /dev/null +++ b/lib/open_food_network/reports/variant_overrides.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module OpenFoodNetwork + module Reports + class VariantOverrides + def initialize(line_items) + @line_items = line_items + end + + def indexed + variant_overrides.each_with_object(hash_of_hashes) do |variant_override, indexed| + indexed[variant_override.hub_id][variant_override.variant] = variant_override + end + end + + private + + attr_reader :line_items + + def variant_overrides + VariantOverride.joins(:variant) + .where(spree_variants: { id: line_items.select(:variant_id) }) + end + + def hash_of_hashes + Hash.new { |h, k| h[k] = {} } + end + end + end +end diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb index 29064b63f8..eb2e2f3cc9 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb @@ -62,4 +62,26 @@ RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::CustomerTotalsRepor expect(shipping_method_name_field).to eq shipping_method2.name end end + + context 'when a variant override applies' do + let!(:order) do + create(:completed_order_with_totals, line_items_count: 1, user: customer.user, + customer: customer, distributor: distributor) + end + let(:overidden_sku) { 'magical_sku' } + + before do + create( + :variant_override, + hub: distributor, + variant: order.line_items.first.variant, + sku: overidden_sku + ) + end + + it 'uses the sku from the variant override' do + sku_field = report_table.first[23] + expect(sku_field).to eq overidden_sku + end + end end diff --git a/spec/lib/open_food_network/reports/variant_overrides_spec.rb b/spec/lib/open_food_network/reports/variant_overrides_spec.rb new file mode 100644 index 0000000000..684b79ae4e --- /dev/null +++ b/spec/lib/open_food_network/reports/variant_overrides_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' +require 'open_food_network/reports/variant_overrides' + +module OpenFoodNetwork::Reports + describe VariantOverrides do + subject(:variant_overrides) { described_class.new(order.line_items) } + + let(:distributor) { create(:distributor_enterprise) } + let(:order) do + create(:completed_order_with_totals, line_items_count: 1, + distributor: distributor) + end + let(:variant) { order.line_items.first.variant } + let!(:variant_override) do + create( + :variant_override, + hub: distributor, + variant: variant, + ) + end + + describe '#indexed' do + let(:result) { variant_overrides.indexed } + + it 'indexes variant override mappings by distributor id' do + expect(variant_overrides.indexed).to eq( + distributor.id => { variant => variant_override } + ) + end + end + end +end From 147654df4189abf30facf624e1a6e000ca5a9e5b Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Sun, 12 Apr 2020 07:05:59 +1000 Subject: [PATCH 101/166] Updating translations for config/locales/es_CR.yml --- config/locales/es_CR.yml | 3379 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 3379 insertions(+) create mode 100644 config/locales/es_CR.yml diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml new file mode 100644 index 0000000000..845b8838c2 --- /dev/null +++ b/config/locales/es_CR.yml @@ -0,0 +1,3379 @@ +es_CR: + language_name: "Español" + activerecord: + attributes: + enterprise_fee: + fee_type: Tipo de Comisión + spree/order: + payment_state: Estado del pago + shipment_state: Estado del envío + completed_at: Completado en + number: Número + state: Provincia + email: E-mail del consumidor + spree/payment: + amount: Cantidad + spree/product: + primary_taxon: "categoría del producto" + supplier: "Proveedora" + shipping_category_id: "Categoría de envío" + variant_unit: "Unidad Variante" + variant_unit_name: "Nombre de la unidad de la variante" + spree/credit_card: + base: "Tarjeta de crédito" + order_cycle: + orders_close_at: Fecha de cierre + errors: + models: + spree/user: + attributes: + email: + taken: "Ya existe una cuenta con este email. Inicie sesión o restablezca tu contraseña." + spree/order: + no_card: No hay tarjetas de crédito autorizadas disponibles para cargar + spree/credit_card: + attributes: + base: + card_expired: "ha expirado" + order_cycle: + attributes: + orders_close_at: + after_orders_open_at: debe ser después de la fecha de apertura + variant_override: + count_on_hand: + using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de estoc de la productora" + on_demand_but_count_on_hand_set: "debe estar en blanco si está bajo demanda" + limited_stock_but_no_count_on_hand: "se debe especificar porque se ha definido estoc limitado" + activemodel: + attributes: + order_management/reports/enterprise_fee_summary/parameters: + start_at: "Inicio" + end_at: "Final" + distributor_ids: "Hubs" + producer_ids: "Productoras" + order_cycle_ids: "Ciclos de Pedido" + enterprise_fee_ids: "Nombres de las comisiones" + shipping_method_ids: "Métodos de envío" + payment_method_ids: "Métodos de Pago" + errors: + messages: + inclusion: "no está incluido en la lista" + models: + order_management/subscriptions/validator: + attributes: + subscription_line_items: + at_least_one_product: "^Por favor agrega al menos un producto" + not_available: "^%{name} no está disponible en el programa seleccionado" + ends_at: + after_begins_at: "debe ser después comienza en" + customer: + does_not_belong_to_shop: "no pertenece a %{shop}" + schedule: + not_coordinated_by_shop: "no está coordinado por %{shop}" + payment_method: + not_available_to_shop: "no está disponible para %{shop}" + invalid_type: "El método debe ser Cash o Stripe" + charges_not_allowed: "^ Los cargos de la tarjeta de crédito no estan permitidos para esta consumidora" + no_default_card: "^ Ninguna tarjeta predeterminada disponible para esta consumidora" + shipping_method: + not_available_to_shop: "no está disponible para %{shop}" + devise: + confirmations: + send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + failed_to_send: "Se produjo un error al enviar su correo electrónico de confirmación." + resend_confirmation_email: "Reenviar el correo electrónico de confirmación." + confirmed: "¡Gracias por confirmar tu correo electrónico! Ahora puedes iniciar sesión." + not_confirmed: "Su dirección de correo electrónico no pudo ser confirmada. Tal vez ya has completado este paso?" + user_confirmations: + spree_user: + send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + confirmation_sent: "Se ha enviado un correo electrónico de confirmación" + confirmation_not_sent: "Error al enviar el correo electrónico de confirmación." + user_registrations: + spree_user: + signed_up_but_unconfirmed: "Se ha enviado un mensaje con un enlace de confirmación a tu dirección de correo electrónico. Abre el enlace para activar tu cuenta." + unknown_error: "Algo salió mal al crear tu cuenta. Comprueba tu dirección de correo electrónico y vuelve a intentarlo." + failure: + invalid: | + Correo o contraseña inválidos. + ¿Has sido invitada? Tal vez necesites crear una cuenta o recuperar tu contraseña. + unconfirmed: "Debes confirmar tu cuenta antes de continuar." + already_registered: "Esta dirección de correo electrónico ya está registrada. Inicie sesión para continuar, o vuelva atrás y use otra dirección de correo electrónico." + success: + logged_in_succesfully: "Sesión iniciada con éxito" + user_passwords: + spree_user: + updated_not_active: "Su contraseña ha sido restablecida, pero su correo electrónico aún no ha sido confirmado." + updated: "Su contraseña ha sido cambiada con éxito. Ya tienes la sesión iniciada." + send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + models: + order_cycle: + cloned_order_cycle_name: "COPIA DE %{order_cycle}" + validators: + date_time_string_validator: + not_string_error: "debe ser una cadena" + invalid_format_error: "debe ser válido" + integer_array_validator: + not_array_error: "debe ser una matriz" + invalid_element_error: "debe contener solo enteros válidos" + enterprise_mailer: + confirmation_instructions: + subject: "Confirma la dirección de correo electrónico de %{enterprise}" + welcome: + subject: "%{enterprise} está ahora en %{sitename}" + email_welcome: "Bienvenido" + email_registered: "ahora es parte de" + email_userguide_html: "La Guía de Usuario con soporte detallado para configurar su Productora o Grupo de Consumo está aquí: %{link}" + userguide: "Guía de usuario de Open Food Network" + email_admin_html: "Puede administrar su cuenta iniciando sesión en %{link} o haciendo clic en el engrane arriba a la derecha de la página de inicio, y seleccionando Administración." + admin_panel: "Panel de administración" + email_community_html: "También tenemos un foro en líea para la discusión comunal relacionada con el programa OFN y los retos únicos del funcionamiento de una organización de alimentación. Lo invitamos a unirse. Estamos evolucionando de forma constante y su aporte en este formo le dará forma a lo que pase luego. %{link}" + join_community: "Unirse a la comunidad" + invite_manager: + subject: "%{enterprise} te ha invitado a ser administrador" + producer_mailer: + order_cycle: + subject: "Informe Ciclo de Pedido para %{producer}" + shipment_mailer: + shipped_email: + dear_customer: "Estimada consumidora," + instructions: "Tu pedido ha sido enviado" + shipment_summary: "Resumen de envío" + subject: "Notificación de envío" + thanks: "Gracias por hacer negocios." + track_information: "Información de seguimiento: %{tracking}" + track_link: "Enlace de seguimiento: %{url}" + subscription_mailer: + placement_summary_email: + subject: Un resumen los pedidos de suscripción recientes + greeting: "Hola %{name}," + intro: "A continuación se muestra un resumen de los pedidos de suscripción que acaban de realizarse en %{shop}." + confirmation_summary_email: + subject: Un resumen de los pedidos de suscripción confirmadas recientemente + greeting: "Hola %{name}," + intro: "A continuación se muestra un resumen de los pedidos de suscripción que acaban de finalizar para %{shop}." + summary_overview: + total: Se marcaron un total de %{count} suscripciones para ser procesadas automáticamente. + success_zero: De estos, ninguno fue procesado. + success_some: De estos, %{count} se procesaron con éxito. + success_all: Todos fueron procesados ​​con éxito. + issues: Los detalles de los problemas encontrados se proporcionan a continuación. + summary_detail: + no_message_provided: No hay mensajes de error + changes: + title: Insufficient Stock (%{count} pedidos) + explainer: Estos pedidos se procesaron pero no se dispuso de existencias suficientes para algunos artículos solicitados + empty: + title: Sin stock (%{count} pedidos) + explainer: Estas órdenes no se pudieron procesar porque no había existencias disponibles para los artículos solicitados + complete: + title: Ya procesado (%{count} pedidos) + explainer: Estas órdenes ya estaban marcadas como completas y, por lo tanto, no se modificaron + processing: + title: Error encontrado (%{count} pedidos) + explainer: El procesamiento automático de estas órdenes falló debido a un error. El error será mostrado en los casos en que sea posible. + failed_payment: + title: Error en el pago (%{count} pedidos) + explainer: El procesamiento automático del pago de estos pedidos falló debido a un error. El error ha sido listado donde a sido posible. + other: + title: Otros fallos (%{count} pedidos) + explainer: El procesamiento automático de estas órdenes falló por un motivo desconocido. Esto no debería ocurrir, contáctanos si estás viendo esto. + home: "OFN" + title: Open Food Network + welcome_to: 'Bienvenido a ' + site_meta_description: "Nosotros empezamos desde abajo. Con granjeros y productoras listas para contar sus historias con orgullo y autenticidad. Con distribuidoras listas para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden..." + search_by_name: Buscar por nombre o municipio... + producers_join: Las productoras australianas ahora son bienvenidas a unirse a Open Food Network. + charges_sales_tax: ¿Cargos de IVA? + print_invoice: "Imprimir factura" + print_ticket: "Imprimir Ticket" + select_ticket_printer: "Seleccionar impresora para los tickets" + send_invoice: "Enviar factura" + resend_confirmation: "Reenviar confirmación" + view_order: "Ver pedido" + edit_order: "Editar pedido" + ship_order: "Enviar pedido" + cancel_order: "Cancelar pedido" + confirm_send_invoice: "Una factura para esta orde se envió al cliente. ¿Está seguro que quiere continuar?" + confirm_resend_order_confirmation: "¿Estás seguro que quieres reenviar el correo de confirmación del pedido?" + must_have_valid_business_number: "%{enterprise_name} debe tener un NIF válido antes de que las facturas se puedan enviar." + invoice: "Factura" + more: "Más" + say_no: "No" + say_yes: "Si" + ongoing: En marcha + bill_address: Dirección de facturación + ship_address: Dirección de envío + sort_order_cycles_on_shopfront_by: "Ordenar Ciclos de Pedidos en Tienda por" + required_fields: Los campos obligatorios se indican con un asterisco + select_continue: Selecciona y Continua + remove: Eliminar + or: o + collapse_all: Contraer todos + expand_all: Expandir todos + loading: Cargando... + show_more: Mostrar más + show_all: Mostrar todos + show_all_with_more: "Mostrar todo (%{num} Más)" + cancel: Cancelar + edit: Editar + clone: Duplicar + distributors: Distribuidores + bulk_order_management: Gestión de pedidos en bloque + enterprises: Organizaciones + enterprise_groups: Redes + reports: Informes + variant_overrides: Inventario + import: Importar + spree_products: Productos Spree + all: Todos + current: Actual + available: Disponible + dashboard: Panel de inicio + undefined: indefinido + unused: no se usa + admin_and_handling: Administración y Manejo + profile: Perfil + supplier_only: Sólo Proveedor + has_shopfront: Tiene tienda + weight: Peso + volume: Volumen + items: Elementos + summary: Resumen + detailed: Detallado + updated: Actualizado + 'yes': "Sí" + 'no': "No" + y: 'S' + n: 'N' + powered_by: Powered by + blocked_cookies_alert: "Es posible que su navegador esté bloqueando las cookies necesarias para utilizar esta tienda. Haga clic a continuación para permitir las cookies y vuelva a cargar la página." + allow_cookies: "Permitir cookies" + notes: Notas + error: Error + processing_payment: "Procesando el pago..." + no_pending_payments: "No tiene pagos pendientes" + invalid_payment_state: "Estado de pago no válido" + filter_results: Filtrar resultados + quantity: Cantidad + pick_up: Recogida + copy: Copia + change_my_password: "Cambiar mi contraseña" + update_password: "Actualizar contraseña" + password_confirmation: Confirmación de contraseña + reset_password_token: token de restablecimiento de contraseña + expired: ha expirado, por favor solicite una nueva + back_to_payments_list: "Volver a la lista de pagos" + maestro_or_solo_cards: "Tarjetas Maestro/Solo" + backordered: "Reabastecido" + on hand: "Disponibles" + ship: "Envío" + actions: + create_and_add_another: "Crear y agregar otro" + create: "Crear" + cancel: "Cancelar" + save: "Guardar" + edit: "Editar" + update: "Actualizar" + delete: "Borrar" + admin: + begins_at: Empieza en + begins_on: Comienza en + customer: Consumidora + date: Fecha + email: Email + ends_at: Termina en + ends_on: Finaliza + name: Nombre + on_hand: Disponibles + on_demand: Bajo demanda + on_demand?: Bajo demanda? + order_cycle: Ciclo de Pedido + payment: Pago + payment_method: Método de pago + phone: Teléfono + price: Precio + producer: Productora + image: Imagen + product: Producto + quantity: Cantidad + schedule: Programación + shipping: Envío + shipping_method: Método de envío + shop: Tienda + sku: número de referencia + status_state: Provincia + tags: Etiquetas + variant: Variedad + weight: Peso + volume: Volumen + items: Artículos + select_all: Seleccionar todo + quick_search: Búsqueda rápida + clear_all: Limpiar todo + start_date: "Fecha de inicio" + end_date: "Fecha de finalización" + form_invalid: "El formulario contiene campos vacíos o inválidos" + clear_filters: Limpiar filtros + clear: Limpiar + save: Guardar + cancel: Cancelar + back: Atrás + show_more: Mostrar más + show_n_more: Mostrar %{num} más + choose: "Escoger..." + please_select: Por favor selecciona ... + columns: Columnas + actions: Acciones + viewing: "Viendo: %{current_view_name}" + description: Descripción + whats_this: ¿Qué es esto? + tag_has_rules: "Reglas existentes para esta etiqueta: %{num}" + has_one_rule: "Tiene una regla" + has_n_rules: "Tiene %{num} reglas" + unsaved_confirm_leave: "Has cambios sin guardar en esta página ¿Continuar sin guardar?" + unsaved_changes: "Tienes cambios sin guardar" + shopfront_settings: + embedded_shopfront_settings: "Configuración de la tienda integrada" + enable_embedded_shopfronts: "Habilitar tiendas integradas" + embedded_shopfronts_whitelist: "Lista de dominios externos permitidos" + number_localization: + number_localization_settings: "Number Localization Settings" + enable_localized_number: "Usar la logica internacional separador miles/decimales" + invoice_settings: + edit: + title: "Configuración de Factura" + enable_invoices?: "Habilitar facturas?" + invoice_style2?: "Utiliza el modelo de factura alternativo que incluye el desglose fiscal total por tipo de interés y tasa de impuestos por artículo (todavía no es adecuado para países que muestran los precios sin impuestos)" + enable_receipt_printing?: "¿Mostrar opciones para imprimir recibos usando impresoras térmicas en el desplegable del pedido?" + stripe_connect_settings: + edit: + title: "Stripe Connect" + settings: "Configuración" + stripe_connect_enabled: ¿Permitir a las tiendas aceptar pagos mediante Stripe Connect? + no_api_key_msg: No existe una cuenta Stripe para esta organización. + configuration_explanation_html: Para obtener instrucciones detalladas sobre cómo configurar la integración con Stripe Connect, consulte esta guía . + status: Estado + ok: Ok + instance_secret_key: Clave secreta de instancia + account_id: Account ID + business_name: Nombre de la Organización + charges_enabled: Cargos habilitados + charges_enabled_warning: "Advertencia: los cargos no están habilitados para su cuenta" + auth_fail_error: La clave API que proporcionó no es válida. + empty_api_key_error_html: No se ha proporcionado ninguna clave API Stripe. Para configurar su clave API, siga estas instrucciones + matomo_settings: + edit: + title: "Configuración de Matomo" + matomo_url: "URL de Matomo" + matomo_site_id: "ID de sitio de Matomo" + info_html: "Matomo es un analizador web y móvil. Puede alojar Matomo en sus servidores o utilizar un servicio alojado en la nube. Consulte matomo.org para obtener más información." + config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." + customers: + index: + new_customer: "Nuevo Consumidor" + code: Código + duplicate_code: "Este código ya se ha usado." + bill_address: "Dirección de Facturación" + ship_address: "Dirección de Envío" + update_address_success: 'Dirección actualizada correctamente.' + update_address_error: 'Introduce todos los campos requeridos' + edit_bill_address: 'Edita la Dirección de Facturación' + edit_ship_address: 'Editar Dirección de Envío' + required_fileds: 'Los campos obligatorios se indican con un asterisco' + select_country: 'Selecciona país' + select_state: 'Selecciona Provincia' + edit: 'Editar' + update_address: 'Actualizar Dirección' + confirm_delete: '¿Confirmas que quieres borrar?' + search_by_email: "Buscar por email/código" + guest_label: 'Hacer pedido como invitado' + destroy: + has_associated_orders: 'Se ha producido un error en la eliminación: la consumidora tiene pedidos asociados en su tienda.' + contents: + edit: + title: Contenido + header: Encabezamiento + home_page: Página principal + producer_signup_page: Página de registro del productor + hub_signup_page: Página de registro del Grupo + group_signup_page: Página de registro de grupo + main_links: Enlaces al menú principal + footer_and_external_links: Pie de página y enlaces externos + your_content: Tu contenido + user_guide: Manual de Usuario + enterprise_fees: + index: + title: "Comisiones de la Organización" + enterprise: "Organización" + fee_type: "Tipo de Comisión" + name: "Nombre" + tax_category: "Categoría del impuesto" + calculator: "Calculadora" + calculator_values: "Valores de la Calculadora" + search: "Buscar" + name_placeholder: "por ejemplo, comision de embalaje" + enterprise_groups: + index: + new_button: Nuevo Grupo de Organizaciones + enterprise_roles: + form: + manages: Gestiona + enterprise_role: + manages: Gestionan + products: + unit_name_placeholder: 'ej. manojos' + index: + unit: Unidad + display_as: Mostrar como + category: Categoría + tax_category: Categoría de impuestos + inherits_properties?: ¿Hereda propiedades? + available_on: Disponible en + av_on: "Av. En" + import_date: Importado + upload_an_image: Subir una imagen + seo: + product_search_keywords: "Palabras clave de búsqueda de productos" + product_search_tip: "Escriba palabras para ayudar a buscar sus productos en las tiendas. Use espacio para separar cada palabra clave." + SEO_keywords: "Palabras clave de SEO" + seo_tip: "Escriba palabras para ayudar a buscar sus productos en la web. Use espacio para separar cada palabra clave." + search: "Buscar" + properties: + property_name: "Nombre de la Propiedad" + inherited_property: "Propiedad Heredada" + variants: + infinity: "infinito" + to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda." + back_to_products_list: "Volver a la lista de productos" + editing_product: "Editando producto" + tabs: + product_details: "Detalles del Producto" + group_buy_options: "Opciones de compra grupales" + images: "Imágenes" + variants: "variaciones" + product_properties: "Propiedades del producto" + product_import: + title: Importación de productos + file_not_found: Archivo no encontrado o no se pudo abrir + no_data: No se encontraron datos en la hoja de cálculo + confirm_reset: "Esto establecerá el nivel de stock en cero en todos los productos para esta\n organizacion que no están presentes en el archivo cargado" + model: + no_file: "Error: no se ha subido ningún archivo" + could_not_process: "No se pudo procesar el archivo: tipo de archivo inválido" + incorrect_value: valor incorrecto + conditional_blank: no puede estar en blanco si unit_type está en blanco + no_product: no coincide con ningún producto en la base de datos + not_found: no encontrado en la base de datos + not_updatable: No se puede actualizar sobre productos existentes a través de la importación de productos + blank: no puede estar vacío + products_no_permission: no tienes permiso para administrar productos para esta organización + inventory_no_permission: no tienes permiso para crear inventario para esta productora + none_saved: No se guardó ningún producto con éxito + line_number: "Línea %{number}:" + encoding_error: "Verifique la configuración de idioma de su archivo fuente y asegúrese de que esté guardado con la codificación UTF-8" + unexpected_error: "La importación de productos encontró un error inesperado al abrir el archivo: %{error_message}" + index: + notice: "aviso" + beta_notice: "Esta funcionalidad aún está en versión beta: puede experimentar algunos errores mientras la usa. Por favor no dude en ponerse en contacto con nosotros." + select_file: Selecciona una hoja de cálculo para subir + spreadsheet: Hoja de cálculo + choose_import_type: Seleccionar tipo de importación + import_into: Tipo de importación + product_list: Lista de productos + inventories: Inventarios + import: Importar + upload: Subir + csv_templates: Plantillas CSV + product_list_template: Descargar la plantilla de lista de productos + inventory_template: Descargar plantilla de inventario + category_values: Valores de categoría disponibles + product_categories: Categorías de Producto + tax_categories: Categorías de impuestos + shipping_categories: Categorías de envío + import: + review: Revisión + import: Importar + save: Guardar + results: Resultados + save_imported: Guardar productos importados + no_valid_entries: No se encontraron entradas válidas + none_to_save: No hay entradas que se puedan guardar + some_invalid_entries: El archivo importado contiene entradas no válidas + fix_before_import: Corrija estos errores e intente importar el archivo nuevamente + save_valid?: ¿Guardar entradas válidas por ahora y descartar las demás? + no_errors: ¡No se detectaron errores! + save_all_imported?: Guardar todos los productos importados? + options_and_defaults: Opciones de importación y valores predeterminados + no_permission: no tienes permiso para administrar esta organización + not_found: no se pudo encontrar la organización en la base de datos + no_name: Sin nombre + blank_enterprise: Algunos productos no tienen una organización definida. + reset_absent?: Restablecer productos ausentes + reset_absent_tip: Establezca el stock en cero para todos los productos existentes que no estén presentes en el archivo. + overwrite_all: Sobrescribir todo + overwrite_empty: Sobrescribir si está vacío + default_stock: Establecer nivel de existencias + default_tax_cat: Establecer categoría de impuestos + default_shipping_cat: Establecer categoría de envío + default_available_date: Establecer fecha disponible + validation_overview: Resumen de validación de importación + entries_found: Entradas encontradas en el archivo importado + entries_with_errors: Los artículos contienen errores y no se importarán + products_to_create: Los productos se crearán + products_to_update: Los productos se actualizarán + inventory_to_create: Se crearán Artículos de inventario + inventory_to_update: Los artículos de inventario se actualizarán + products_to_reset: Los productos existentes tendrán su stock restablecido a cero + inventory_to_reset: Los artículos de inventario existentes tendrán su stock restablecido a cero + line: Línea + item_line: Línea del artículo + import_review: + not_updatable_tip: "Los siguientes campos no se pueden actualizar mediante la importación masiva de productos existentes:" + fields_ignored: Estos campos se ignorarán cuando se guarden los productos importados. + entries_table: + not_updatable: Este campo no es actualizable mediante importación masiva en productos existentes + save_results: + final_results: Importar resultados finales + products_created: Productos creados + products_updated: Productos actualizados + inventory_created: Artículos de inventario creados + inventory_updated: Artículos de inventario actualizados + products_reset: Los productos tenían nivel de stock restablecido a cero + inventory_reset: Los artículos de inventario tenían el nivel de stock restablecido a cero + all_saved: "Todos los artículos guardados con éxito" + some_saved: "Artículos guardados con éxito" + save_errors: Guardar errores + import_again: Subir otro archivo + view_products: Ir a la página de productos + view_inventory: Ir a la página de inventario + variant_overrides: + loading_flash: + loading_inventory: CARGANDO INVENTARIO + index: + title: Inventario + description: Utilice esta página para administrar inventarios para sus organizaciones. Todos los detalles del producto establecidos aquí anularán los establecidos en la página de 'Productos' + enable_reset?: ¿Activar Reset del Stock? + default_stock: "Stock predeterminado" + inherit?: ¿Heredado? + add: Añadir + hide: Ocultar + import_date: Importado + select_a_shop: Selecciona una Tienda + review_now: Revisar ahora + new_products_alert_message: Hay %{new_product_count} nuevos productos disponibles para añadir a tu inventario. + currently_empty: Tu inventario está vacio + no_matching_products: No se encuentran productos que concuerden en tu inventario + no_hidden_products: No hay productos ocultados de tu inventario + no_matching_hidden_products: No se encuentran productos ocultos que concuerden + no_new_products: No hay nuevos productos disponibles para añadir a este inventario + no_matching_new_products: No hay nuevos productos que concuerden + inventory_powertip: Este es tu inventario de productos. Para añadir productos a tu inventario, selecciona "Nuevos Productos" en el menú desplegable. + hidden_powertip: Estos productos han sido ocultados de tu inventario y no están disponibles para añadir a tu tienda. Puedes hacer click en "Añadir" para añadir un producto a tu inventario. + new_powertip: Estos productos están disponibles para añadirlos a tu inventario. Haz clic en "Añadir" para añadir un producto a tu inventario o "Ocultar" para ocultarlo de la vista. Siempre puedes cambiar de idea! + controls: + back_to_my_inventory: Volver a mi inventario + orders: + invoice_email_sent: 'Se ha enviado correo electrónico con la factura.' + order_email_resent: 'El correo electrónico del pedido se ha reenviado' + bulk_management: + tip: "Usa esta página para alterar la cantidad del producto en varios pedidos a la vez. Los productos pueden ser eliminados de los pedidos si es necesario. " + shared: "¿Recurso compartido?" + order_no: "Pedido Nº" + order_date: "Completado en" + max: "Max" + product_unit: "Producto: Unidad" + weight_volume: "Peso/Volumen" + ask: "¿Pregunta?" + page_title: "Gestor de Multiples Pedidos" + actions_delete: "Borrar Seleccionados" + loading: "Cargando pedidos" + no_results: "No se encuentran pedidos." + group_buy_unit_size: "Unidad de Magnitud del Grupo de Consumo" + total_qtt_ordered: "Cantidad total del Pedido" + max_qtt_ordered: "Cantidad máxima del Pedido" + current_fulfilled_units: "Unidades Completadas" + max_fulfilled_units: "Max Unidades Completadas" + order_error: "Algunos errores deberán ser resueltos antes de que puedas actualizar los pedidos.\nTodos los campos con borde rojo contienen errores." + variants_without_unit_value: "CUIDADO: Algunas variedades no tienen un valor unitario " + select_variant: "Seleccione una variante" + enterprise: + select_outgoing_oc_products_from: Selecciona los productos OC que salgan de + enterprises: + index: + title: Organizaciones + new_enterprise: Nueva Organización + producer?: "Productora?" + package: Perfil + status: Estado + manage: Gestionar + form: + about_us: + desc_short: Descripción corta + desc_short_placeholder: Háblanos sobre tu organización en una o dos frases + desc_long: Sobre nosotras + desc_long_placeholder: Explica a las consumidoras quién eres. Esta información aparecerá en tu perfil público. + business_details: + abn: NIF + abn_placeholder: ej. 99 123 456 789 + acn: ACN + acn_placeholder: ej. 123 456 789 + display_invoice_logo: Mostrar logo en facturas + invoice_text: Añadir texto personalizado al final de las facturas + contact: + name: Nombre + name_placeholder: ej. Gustav Plum + email_address: Dirección de correo electrónico público + email_address_placeholder: p.ej. consultas@lacesta.com + email_address_tip: "Esta dirección de correo electrónico se mostrará en su perfil público" + phone: Teléfono + phone_placeholder: ej. 98 7654 3210 + website: Website + website_placeholder: ej. www.truffles.com + enterprise_fees: + name: Nombre + fee_type: Tipo de Comisión + manage_fees: Gestiona las comisiones de la Organización + no_fees_yet: No tienes comisiones para la organización. + create_button: Crear una ahora + images: + logo: Logo + promo_image_placeholder: 'Esta imagen aparece en "Sobre nosotras"' + promo_image_note1: 'ATENCIÓN:' + promo_image_note2: La imagen será recortada a 1200 x 260. + promo_image_note3: La imagen se mostrará en la parte superior del perfil de la organización y en pop-ups. + inventory_settings: + text1: Puedes optar por administrar los niveles de stock y los precios a través de tu + inventory: inventario + text2: > + Si estás utilizando la herramienta de inventario, puedes seleccionar + si los nuevos productos añadidos por las proveedoras deben añadirse + antes al inventario de ser almacenados. Si no estás utilizando tu inventario + para administrar tus productos, debes seleccionar la opción 'recomendada' + a continuación: + preferred_product_selection_from_inventory_only_yes: Los nuevos productos se pueden publicar en la tienda (recomendado) + preferred_product_selection_from_inventory_only_no: Los nuevos productos se deben agregar al inventario antes de que puedan ser puestos en la tienda + payment_methods: + name: Nombre + applies: ¿Aplicar? + manage: Gestionar los métodos de pago + no_method_yet: Todavía no tienes ningún método de pago. + create_button: Crear un nuevo método de pago + create_one_button: Crear una ahora + primary_details: + name: Nombre + name_placeholder: ej. Professor Plum's Biodynamic Truffles + groups: Redes + groups_tip: Seleccione las redes o zonas de los que es miembro. Esto ayudará a los consumidores a encontrar tu organización. + groups_placeholder: Escribe para buscar las redes disponibles... + primary_producer: Productora Principal? + primary_producer_tip: Seleciona "Productora" si eres la principal productora. + producer: Productora + any: Cualquiera + none: Ninguno + own: Propio + sells: Vende + sells_tip: "Ninguno - La organización no vende directamente a los consumidores.
Popios - La organización vende sus propios productos a los consumidores.
Cualquiera - La organización vende sus propios productos o de otros.
" + visible_in_search: ¿Visible en la búsqueda? + visible_in_search_tip: Determina qué organizaciones son visibles para los consumidores cuando buscan en el site. + visible: Visible + not_visible: No visible + permalink: Permalink (sin espacios) + permalink_tip: "Se usa para crear la URL de tu tienda: %{link}nombre-de-tu-tienda/shop" + link_to_front: Link a la tienda + link_to_front_tip: Enlace directo a tu tienda en Open Food Networks + ofn_uid: UID de OFN + ofn_uid_tip: La identificación única utilizada para identificar la organización en Open Food Network. + shipping_methods: + name: Nombre + applies: ¿Aplicar? + manage: Gestionar métodos de envío + create_button: Crear nuevo método de envío + create_one_button: Crear una ahora + no_method_yet: Todavía no tienes ningún método de envío. + shop_preferences: + shopfront_requires_login: "¿Quieres que la tienda sea visible y pública?" + shopfront_requires_login_tip: "Elije si los clientes deben iniciar sesión para ver la tienda o si es visible para todos." + shopfront_requires_login_false: "Pública" + shopfront_requires_login_true: "Visible solo para consumidores registrados" + recommend_require_login: "Recomendamos requerir a los usuarios que accedan cuando sus pedidos puedan cambiar." + allow_guest_orders: "Pedidos de invitados" + allow_guest_orders_tip: "Permitir pedidos como invitado o solo como usuarios registrados." + allow_guest_orders_false: "Se necesita hacer login para realizar un pedido" + allow_guest_orders_true: "Permitir pedidos a invitados" + allow_order_changes: "Cambiar pedidos" + allow_order_changes_tip: "Permitir a los clientes cambiar sus pedidos mientras que el ciclo de pedido siga abierto." + allow_order_changes_false: "Los pedidos efectuados no pueden ser cambiados / cancelados" + allow_order_changes_true: "Los clientes pueden cambiar / cancelar pedidos mientras el ciclo de pedido está abierto" + enable_subscriptions: "Suscripciones" + enable_subscriptions_tip: "¿Habilitar la funcionalidad de suscripciones?" + enable_subscriptions_false: "Deshabilitado" + enable_subscriptions_true: "Habilitado" + shopfront_message: "Mensaje de la Tienda" + shopfront_message_placeholder: > + Mensaje de bienvenida opcional para compradores, explica como comprar + en el sitio. si el texto se agrega en este campo, va a ser mostrado + en la pestaña de inicio cuando los clientes ingresen por primera vez + a la tienda. + shopfront_message_link_tooltip: "Insertar / editar enlace" + shopfront_message_link_prompt: "Por favor introduzca una URL para insertar" + shopfront_closed_message: "Mensaje de tienda cerrada" + shopfront_closed_message_placeholder: > + Un mensaje que proporciona una explicación más detallada sobre por qué + tu tienda está cerrada y/o cuándo se abrirá de nuevo. Esto se muestra + en tu tienda sólo cuando no tienes ciclos de pedidos activos (p.e. la + tienda está cerrada). + shopfront_category_ordering: "Orden de las categorías de la tienda" + open_date: "Fecha de Inicio" + close_date: "Fecha de Finalización" + social: + twitter_placeholder: "ej: the_prof" + instagram_placeholder: "p.ej. @mi_huerta" + facebook_placeholder: "eg. www.facebook.com/NombreDePáginaAquí" + linkedin_placeholder: "p.ej. www.linkedin.com/in/YourNameHere" + stripe_connect: + connect_with_stripe: "Conectar con Stripe" + stripe_connect_intro: "Para aceptar pagos con tarjeta de crédito, necesitarás conectar tu cuenta Stripe con Open Food Network. Usa el botón a la derecha para comenzar." + stripe_account_connected: "Cuenta de Stripe conectada." + disconnect: "Desconectar cuenta" + confirm_modal: + title: Conectar con Stripe + part1: Stripe es un servicio de pagos que permite a las tiendas aceptar pagos con tarjeta de crédito de las consumidoras. + part2: Para usar esta función, debes conectar tu cuenta Stripe con OFN. Al hacer clic en 'Acepto' a continuación, se redireccionará al sitio web de Stripe donde puedes conectar una cuenta de Stripe existente o crear una nueva si aún no la tienes. + part3: Esto permitirá que Open Food Network acepte pagos con tarjeta de crédito de los clientes en tu nombre. Ten en cuenta que deberás mantener tu propia cuenta de Stripe, pagar las tarifas de Stripe y gestionar los reembolsos y el servicio al cliente. + i_agree: Estoy de acuerdo + cancel: Cancelar + tag_rules: + default_rules: + by_default: Por Defecto + no_rules_yet: No hay reglas por defecto aplicadas + add_new_button: '+ Añadir una nueva regla por defecto' + no_tags_yet: No hay etiquetas para esta organización + no_rules_yet: Todavía no se aplican reglas a esta etiqueta + for_customers_tagged: 'Para los consumidores etiquetados:' + add_new_rule: '+ Añadir una nueva regla' + add_new_tag: '+ Añadir una nueva etiqueta' + users: + email_confirmation_notice_html: "Falta la confirmación del email. Te hemos enviado un correo de confirmación a %{email}." + resend: Reenviar + owner: 'Propietaria' + contact: "Contacto" + contact_tip: "El administrador que recibirá los correos electrónicos de la empresa para pedidos y notificaciones. Debe tener una dirección de correo electrónico confirmada." + owner_tip: La principal usaría responsable para esta organización. + notifications: Notificaciones + notifications_tip: Las Notificaciones sobre los pedidos se enviarán a esta dirección de correo. + notifications_placeholder: ej. gustav@truffles.com + notifications_note: 'Nota: Una nueva dirección de correo debe ser confirmada. ' + managers: Gestoras + managers_tip: Otras usuarias con permiso para gestionar esta organización. + invite_manager: "Invitar administrador" + invite_manager_tip: "Invite a un usuario no registrado a registrarse y convertirse en administrador de esta organización." + add_unregistered_user: "Agregar un usuario no registrado" + email_confirmed: "Correo electrónico confirmado" + email_not_confirmed: "Correo electrónico no confirmado" + actions: + edit_profile: Configuración + properties: Propiedades + payment_methods: Métodos de Pago + payment_methods_tip: Esta organización no tiene métodos de pago + shipping_methods: Métodos de envío + shipping_methods_tip: Esta organización tiene métodos de envío + enterprise_fees: Comisiones de la Organización + enterprise_fees_tip: Esta organización no tiene comisiones + admin_index: + name: Nombre + role: Rol + sells: Vende + visible: ¿Visible? + owner: Propietaria + producer: Productora + change_type_form: + producer_profile: Perfil Productora + connect_ofn: Conectar a través de OFN + always_free: SIEMPRE GRATIS + producer_description_text: Añade tus productos a Open Food Network, permitiendo a los Grupos de Consumo vender tus productos. + producer_shop: Tienda Productora + sell_your_produce: Vende tu propia producción + producer_shop_description_text: Venda sus productos directamente a los clientes a través de su propia tienda. + producer_shop_description_text2: Una tienda de productora es para vender sus productos solamente, si quiere vender productos de otros productores, seleccione "Grupo de Productoras" + producer_hub: Grupo + producer_hub_text: Vende tu propia producción y la de otros + producer_hub_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos tuyos o de otras organizaciones y véndelo a través de tu tienda en Open Food Network. + profile: Solo perfil + get_listing: Obtener un listado + profile_description_text: La gente podrá encontrarte y ponerse en contacto contigo en Open Food Network. Su organización será visible en el mapa y se podrá buscar en los listados. + hub_shop: Tienda + hub_shop_text: Vender la producción de otros + hub_shop_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos de otras organizaciones y véndelo a través de tu tienda en Open Food Network. + choose_option: Por favor, elija una de las opciones anteriores. + change_now: Cambiar + enterprise_user_index: + loading_enterprises: CARGANDO ORGANIZACIONES + no_enterprises_found: No se encuentran organizaciones. + search_placeholder: Buscar por Nombre + manage: Gestionar + manage_link: Configuración + producer?: "¿Productora?" + package: "Perfil" + status: "Estado" + new_form: + owner: Propietaria + owner_tip: La principal usaría responsable para esta organización. + i_am_producer: Soy una Productora + contact_name: Nombre de Contacto + edit: + editing: 'Configuración:' + back_link: Volver a la lista de organizaciones + new: + title: Nueva Organización + back_link: Volver a la lista de organizaciones + remove_logo: + remove: "Eliminar la imagen" + removed_successfully: "Logotipo eliminado con éxito" + immediate_removal_warning: "El logotipo se eliminará inmediatamente después de confirmar." + remove_promo_image: + remove: "Eliminar la imagen" + removed_successfully: "Imagen promocional eliminada con éxito" + immediate_removal_warning: "La imagen promocional se eliminará inmediatamente después de confirmar." + welcome: + welcome_title: Bienvenida a Open Food Network! + welcome_text: Has creado correctamente un + next_step: Siguiente paso + choose_starting_point: 'Selecciona tu perfil:' + profile: 'Perfil' + producer_profile: 'Perfil Productora' + invite_manager: + user_already_exists: "El usuario ya existe" + error: "Algo salió mal" + order_cycles: + loading_flash: + loading_order_cycles: Cargando ciclos de pedido + loading: Cargando... + new: + create: "Crear" + cancel: "Cancelar" + back_to_list: "Regresar a la lista" + edit: + advanced_settings: "Configuración Avanzada" + save: "Guardar" + save_and_next: "Salvar y continuar" + next: "Siguiente" + cancel: "Cancelar" + back_to_list: "Regresar a la lista" + save_and_back_to_list: "Salvar y volver a lista" + choose_products_from: "Escoger Productos desde:" + incoming: + save: "Guardar" + save_and_next: "Salvar y continuar" + next: "Siguiente" + cancel: "Cancelar" + back_to_list: "Regresar a la lista" + outgoing: + outgoing: "Saliente" + distributor: "Distribuidora" + products: "Productos" + tags: "Tags" + delivery_details: "Detalles de entrega" + fees: "Comisiones" + previous: "Anterior" + save: "Guardar" + save_and_back_to_list: "Salvar y volver a lista" + cancel: "Cancelar" + back_to_list: "Regresar a la lista" + wizard_progress: + edit: "1. Configuración general" + incoming: "2. Productos entrantes" + outgoing: "3. Productos salientes" + exchange_form: + pickup_time_tip: Cuando los pedidos de este ciclo de pedido estarán listos para la consumidora + pickup_instructions_placeholder: "Instrucciones de recogida" + pickup_instructions_tip: Estas instrucciones se muestran a las consumidoras después de completar un pedido. + pickup_time_placeholder: "Listo para ( Fecha / Hora)" + receival_instructions_placeholder: "Instrucciones de recepción" + add_fee: 'Añadir comisión' + remove: 'Eliminar' + selected: 'seleccionado' + add_exchange_form: + add_supplier: 'Añadir proveedora' + add_distributor: 'Añadir distribuidora' + advanced_settings: + title: Configuración Avanzada + choose_product_tip: Puede restringir los productos entrantes y salientes a solo el inventario de %{inventory}. + preferred_product_selection_from_coordinator_inventory_only_here: Solo el Inventario de la Coordinadora + preferred_product_selection_from_coordinator_inventory_only_all: Todos los productos disponibles + save_reload: Guardar y recargar la página + coordinator_fees: + add: Añadir comisión para el coordinador + filters: + search_by_order_cycle_name: "Buscar por nombre del Ciclo de Pedido..." + involving: "Involucrando" + any_enterprise: "Cualquier organización" + any_schedule: "Cualquier programación" + form: + general_settings: "Configuración general" + incoming: Entrante + supplier: Proveedora + receival_details: Detalles de la recepción + fees: Comisiones + outgoing: Saliente + distributor: Distribuidor + products: Productos + tags: Etiquetas + add_a_tag: Add a tag + delivery_details: Detalles de Recogida / Entrega + index: + schedule: Programación + schedules: Programación + new_schedule: Nueva programación + name_and_timing_form: + name: Nombre + orders_open: Pedidos abiertos a + coordinator: Coordinadora + orders_close: Cierre de Pedidos + row: + suppliers: proveedoras + distributors: distribuidoras + variants: variedades + simple_form: + ready_for: Listo para + ready_for_placeholder: Fecha / hora + customer_instructions: Instrucciones del Consumidor + customer_instructions_placeholder: Notas de la recogida o entrega + products: Productos + fees: Comisiones + destroy_errors: + orders_present: Ese ciclo de pedido ha sido seleccionado por un cliente y no puede ser eliminado. Para evitar que los clientes accedan a él, ciérrelo. + schedule_present: Ese ciclo de pedido está vinculado a una programación y no puede ser eliminado. Desvincula o elimina la programación primero. + bulk_update: + no_data: Hm, algo salió mal. No se encontraron datos de ciclo de pedido. + date_warning: + msg: Este ciclo de pedido está vinculado a %{n}pedidos de suscripción abiertos. Cambiar esta fecha ahora no afectará ningun pedido que ya se haya realizado pero se debe evitar si es posible. ¿Estás seguro que deseas continuar? + cancel: Cancelar + proceed: Proceder + producer_properties: + index: + title: Propiedades de la Productora + proxy_orders: + cancel: + could_not_cancel_the_order: No se pudo cancelar la orden + resume: + could_not_resume_the_order: No se pudo reanudar el pedido + shared: + user_guide_link: + user_guide: Manual de Usuario + enterprises_hubs_tabs: + has_no_payment_methods: "%{enterprise} no tiene formas de pago" + has_no_shipping_methods: "%{enterprise} no tiene ningún método de envío" + has_no_enterprise_fees: "%{enterprise} no tiene comisiones de organización" + enterprise_issues: + create_new: Crear nuevo + resend_email: Reenviar email + has_no_payment_methods: "%{enterprise} actualmente no tiene formas de pago" + has_no_shipping_methods: "%{enterprise} no tiene actualmente métodos de envío" + email_confirmation: "La confirmación de correo electrónico está pendiente. Hemos enviado un correo electrónico de confirmación a %{email}." + not_visible: "%{enterprise} no es visible y no se puede encontrar en el mapa o en búsquedas" + reports: + hidden: OCULTO + unitsize: UNIDAD DE MEDIDA + total: TOTAL + total_items: ARTÍCULOS TOTALES + supplier_totals: Totales de proveedores del Ciclo de Pedido + supplier_totals_by_distributor: Totales de proveedores por Distribuidor del Ciclo de pedidos + totals_by_supplier: Totales del distribuidor por proveedor del Ciclos de Pedido  + customer_totals: Totales de los consumidores del Ciclo de Pedido  + all_products: Todos los productos + inventory: Inventario (disponible) + lettuce_share: LettuceShare + mailing_list: Lista de correo + addresses: Direcciones + payment_methods: Informe de los métodos de pago + delivery: Informe de entrega + tax_types: Tipos de impuestos + tax_rates: '% Impuestos' + pack_by_customer: Pack por Consumidor + pack_by_supplier: Pack por proveedor + orders_and_distributors: + name: Pedidos y Distribuidores + description: Pedidos con detalles de distribuidor + bulk_coop: + name: Bulk Co-Op + description: Informes para pedidos de Bulk Co-Op + payments: + name: Informes de pago + description: Informes de pagos + orders_and_fulfillment: + name: Informes de Pedidos & Repartos + customers: + name: Consumidoras + products_and_inventory: + name: Productos & Inventario + users_and_enterprises: + name: Usuarias y Organizaciones + description: Propiedad y Estado de la Organización + order_cycle_management: + name: Gestión del Ciclo de Pedido + sales_tax: + name: Impuesto de venta + xero_invoices: + name: Facturas Xero + description: Facturas para la importación en Xero + packing: + name: Informes de empaquetado + enterprise_fee_summary: + name: "Resumen de las comisiones de la organización" + description: "Resumen de las comisiones de la organización recolectadas" + subscriptions: + subscriptions: Suscripciones + new: Nueva suscripción + create: Crear suscripción + edit: Editar suscripción + table: + edit_subscription: Editar suscripción + pause_subscription: Pausa Suscripción + unpause_subscription: Reanudar suscripción + cancel_subscription: Cancelar suscripción + filters: + query_placeholder: "Buscar por correo electrónico ..." + setup_explanation: + just_a_few_more_steps: 'Solo unos pocos pasos más antes de que pueda comenzar:' + enable_subscriptions: "Habilita suscripciones para al menos una de tus tiendas" + enable_subscriptions_step_1_html: 1. Vaya a la página %{enterprises_link}, encuentre su tienda y haga clic en "Administrar" + enable_subscriptions_step_2: 2. En "Preferencias de la tienda", habilite la opción Suscripciones + set_up_shipping_and_payment_methods_html: Configurar los métodos %{shipping_link} y %{payment_link} + set_up_shipping_and_payment_methods_note_html: Tenga en cuenta que solo se pueden usar
métodos de pago en efectivo y Stripe con las suscripciones + ensure_at_least_one_customer_html: Asegúrese de que exista al menos un %{customer_link} + create_at_least_one_schedule: Crear al menos una programación + create_at_least_one_schedule_step_1_html: 1. Vaya a la página %{order_cycles_link} + create_at_least_one_schedule_step_2: 2. Crea un ciclo de pedido si aún no lo has hecho + create_at_least_one_schedule_step_3: 3. Haga clic en '+ Nueva programación' y complete el formulario + once_you_are_done_you_can_html: Una vez que haya terminado, puede %{reload_this_page_link} + reload_this_page: recarga esta página + steps: + details: 1. Detalles básicos + address: 2. Dirección + products: 3. Agregue productos + review: 4. Revisar y guardar + subscription_line_items: + this_is_an_estimate: | + Los precios mostrados son solo una estimación y se calculan en el momento en que se cambia la suscripción. + Si cambias precios o comisiones, los pedidos se actualizarán pero la suscripción seguirá mostrando los valores anteriores. + not_in_open_and_upcoming_order_cycles_warning: "No hay ciclos de pedidos abiertos o próximos para este producto." + autocomplete: + name_or_sku: "NOMBRE O CÓDIGO SKU" + quantity: "Cantidad" + add: "Añadir" + details: + details: Detalles + invalid_error: Ups! Por favor complete todos los campos requeridos ... + allowed_payment_method_types_tip: Solo se pueden usar métodos de pago en efectivo y Stripe en este momento + credit_card: Tarjeta de crédito + charges_not_allowed: Los cargos no están permitidos para esta consumidora + no_default_card: La consumidora no tiene tarjetas disponibles para cargar + card_ok: La consumidora tiene una tarjeta disponible para cargar + begins_at_placeholder: "Seleccione una fecha" + ends_at_placeholder: "Opcional" + loading_flash: + loading: CARGANDO SUSCRIPCIONES + review: + details: Detalles + address: Dirección + products: Productos + no_open_or_upcoming_order_cycle: "No hay ciclo de pedido próximo" + products_panel: + save: "GUARDAR" + saving: "GUARDANDO" + saved: "GUARDADO" + product_already_in_order: Este producto ya ha sido agregado a la orden. Por favor edite la cantidad directamente. + stock: + insufficient_stock: "Stock disponible insuficiente" + out_of_stock: "Agotado" + orders: + number: Número + confirm_edit: ¿Seguro que quieres editar esta orden? Si lo hace, puede ser más difícil sincronizar automáticamente los cambios a la suscripción en el futuro. + confirm_cancel_msg: "¿Seguro que quieres cancelar esta suscripción? Esta acción no se puede deshacer." + cancel_failure_msg: "Lo sentimos, ¡la cancelación falló!" + confirm_pause_msg: "¿Seguro que quieres pausar esta suscripción?" + pause_failure_msg: "Lo sentimos, pausar falló!" + confirm_unpause_msg: "Si tiene un ciclo de pedido abierto en la programación de esta suscripción, se creará un pedido para esta consumidora. ¿Estás seguro de que deseas anular la pausa de esta suscripción?" + unpause_failure_msg: "Lo sentimos, ¡no se pudo reanudar!" + confirm_cancel_open_orders_msg: "Algunas órdenes para esta suscripción están actualmente abiertas. El cliente ya ha sido notificado de que se realizará el pedido. ¿Desea cancelar estos pedidos o conservarlos?" + resume_canceled_orders_msg: "Algunos pedidos de esta suscripción se pueden reanudar en este momento. Puede reanudarlos desde el menú desplegable de pedidos." + yes_cancel_them: Cancelarlos + no_keep_them: Guárdalos + yes_i_am_sure: Sí estoy seguro + order_update_issues_msg: Algunas órdenes no se pudieron actualizar automáticamente, esto es más probable porque se han editado manualmente. Revise los problemas que se detallan a continuación y realice los ajustes a los pedidos individuales si es necesario. + no_results: + no_subscriptions: Aún no hay suscripciones ... + why_dont_you_add_one: ¿Por qué no agregas una? :) + no_matching_subscriptions: No se encontraron suscripciones coincidentes + schedules: + destroy: + associated_subscriptions_error: Este horario no se puede eliminar porque tiene suscripciones asociadas + controllers: + enterprises: + stripe_connect_cancelled: "Se ha cancelado la conexión a Stripe" + stripe_connect_success: "La cuenta Stripe se ha conectado correctamente" + stripe_connect_fail: Lo sentimos, la conexión de tu cuenta Stripe ha fallado + stripe_connect_settings: + resource: Configuración de Stripe Connect + api: + enterprise_logo: + destroy_attachment_does_not_exist: "El logotipo no existe" + enterprise_promo_image: + destroy_attachment_does_not_exist: "La imagen promocional no existe" + orders: + failed_to_update: "Error al actualizar pedido" + checkout: + already_ordered: + cart: "carrito" + message_html: "Ya realizó un pedido para este ciclo de pedido. Compruebe el %{cart}para ver los artículos que pidió. También puede cancelar artículos mientras el ciclo de pedido siga abierto." + failed: "La finalización de compra falló, por favor comunicate con nosotros para procesar la orden." + shops: + hubs: + show_closed_shops: "Mostrar tiendas cerradas" + hide_closed_shops: "Ocultar tiendas cerradas" + show_on_map: "Ver todos en el mapa" + shared: + menu: + cart: + cart: "Carrito" + signed_in: + profile: "Perfil" + mobile_menu: + cart: "Carrito" + joyride: + checkout: "Validar el carrito ahora" + already_ordered_products: "Pedido en este ciclo de pedido" + register_call: + selling_on_ofn: "¿Estás interesada en entrar en Open Food Network?" + register: "Regístrate aquí" + footer: + footer_secure: "Seguro y de confianza." + footer_secure_text: "Open Food Network usa cifrado SSL (RSA de 2048 bit) en toda su plataforma para mantener privada la información de compras y pagos. Nuestros servidores no almacenan los detalles de tarjetas de créditos y los pagos son procesados por servicios que cumplen con PCI." + footer_contact_headline: "Mantenerse en contacto" + footer_contact_email: "Envíenos un correo electrónico" + footer_nav_headline: "Navegar" + footer_join_headline: "Unirse" + footer_join_body: "Crea un listado, una tienda o un directorio en Open Food Network." + footer_join_cta: "Cuentame más!" + footer_legal_call: "Leer nuestros" + footer_legal_tos: "Terminos y condiciones" + footer_legal_visit: "Encuéntrenos en" + footer_legal_text_html: "Open Food Network es una plataforma libre y de código abierto. Nuestro contenido tiene una licencia %{content_license} y nuestro código %{code_license}." + footer_data_text_with_privacy_policy_html: "Cuidamos bien tus datos. Consulta nuestra %{privacy_policy} y %{cookies_policy}" + footer_data_text_without_privacy_policy_html: "Cuidamos bien tus datos. Consulta nuestra %{cookies_policy}" + footer_data_privacy_policy: "política de privacidad" + footer_data_cookies_policy: "política de cookies" + shop: + messages: + login: "login" + signup: "Regístrate" + contact: "contactar" + require_customer_login: "Sólo las consumidoras aprobadas pueden acceder a esta tienda." + require_login_html: "Si ya eres una consumidora aprobado, %{login} o %{signup} para continuar. ¿Quieres empezar a comprar aquí? Por favor, %{contact} %{enterprise} y pide tu adhesión." + require_customer_html: "Si desea comenzar a comprar aquí, por favor %{contact} %{enterprise} para preguntar acerca de incorporación." + card_could_not_be_updated: La tarjeta no se pudo actualizar + card_could_not_be_saved: la tarjeta no se pudo guardar + spree_gateway_error_flash_for_checkout: "Hubo un problema con tu información de pago: %{error}" + invoice_billing_address: "Dirección de facturación:" + invoice_column_tax: "Impuesto sobre bienes y servicios" + invoice_column_price: "Precio" + invoice_column_item: "Artículo" + invoice_column_qty: "Cantidad" + invoice_column_unit_price_with_taxes: "Precio unidad (Impuestos incl.)" + invoice_column_unit_price_without_taxes: "Precio unidad (Sin Impuestos)" + invoice_column_price_with_taxes: "Precio total (Impuestos incl.)" + invoice_column_price_without_taxes: "Precio total (Sin Impuestos)" + invoice_column_tax_rate: "% Impuestos" + invoice_tax_total: "IVA Total:" + tax_invoice: "FACTURA DE IMPUESTOS" + tax_total: "Total impuestos (%{rate}):" + total_excl_tax: "Total (Sin Impuestos):" + total_incl_tax: "Total (Impuestos incl.)" + abn: "NIF:" + acn: "ACN:" + invoice_issued_on: "Factura emitida el:" + order_number: "Número de Factura:" + date_of_transaction: "Fecha de la transacción:" + ticket_column_qty: "Cantidad" + ticket_column_item: "Artículo" + ticket_column_unit_price: "Precio por unidad" + ticket_column_total_price: "Precio total" + menu_1_title: "Tiendas" + menu_1_url: "/shops" + menu_2_title: "Mapa" + menu_2_url: "/map" + menu_3_title: "Productoras" + menu_3_url: "/producers" + menu_4_title: "Redes" + menu_4_url: "/groups" + menu_5_title: "Acerca de" + menu_5_url: "http://katuma.org/" + menu_6_title: "Conectar" + menu_6_url: " " + menu_7_title: "Aprender" + menu_7_url: " " + logo: "Logo (640x130)" + logo_mobile: "Logo para móvil (75x26)" + logo_mobile_svg: "Logo para móvil (SVG)" + home_hero: "Hero image" + home_show_stats: "Mostrar estadísticas" + footer_logo: "Logo (220x76)" + footer_facebook_url: "URL de Facebook" + footer_twitter_url: "URL de Twitter" + footer_instagram_url: "URL de Instagram" + footer_linkedin_url: "URL de LinkedIn" + footer_googleplus_url: "URL de Google Plus" + footer_pinterest_url: "URL de Pinterest" + footer_email: "Correo electrónico" + footer_links_md: "Enlaces" + footer_about_url: "URL acerca de" + user_guide_link: "Enlace de la Guía de usuario" + name: Nombre + first_name: Nombre + last_name: Apellido + email: Correo electrónico + phone: Teléfono + next: Siguiente + address: Dirección + address_placeholder: ej. Carrer Torrent de l'Olla + address2: Dirección (cont.) + city: Ciudad + city_placeholder: ej. Barcelona + postcode: Código postal + postcode_placeholder: ej. 08025 + suburb: Barrio + state: Estado + country: País + unauthorized: No autorizado + terms_of_service: "Términos de servicio" + on_demand: Bajo demanda + none: Ninguno + not_allowed: No permitido + no_shipping: Sin métodos de envío + no_payment: Sin métodos de pago + no_shipping_or_payment: Sin envío ni métodos de pago + unconfirmed: sin confirmar + days: dias + authorization_failure: "Fallo de autorización" + label_shop: "Tienda" + label_shops: "Tiendas" + label_map: "Mapa" + label_producer: "Productora" + label_producers: "Productoras" + label_groups: "Redes" + label_about: "Acerca de" + label_connect: "Conectar" + label_learn: "Aprender" + label_blog: "Blog" + label_support: "Soporte" + label_shopping: "Tienda" + label_login: "Iniciar sesión" + label_logout: "Cerrar sesión" + label_signup: "Registrarse" + label_administration: "Administración" + label_admin: "Admin" + label_account: "Cuenta" + label_more: "Mostrar más" + label_less: "Mostrar menos" + label_notices: "Noticias" + cart_items: "elementos" + cart_headline: "Su carrito de compras" + total: "Total" + cart_updating: "Actualizando el carrito..." + cart_empty: "Carrito vacío" + cart_edit: "Editar carrito" + card_number: Número de tarjeta + card_securitycode: "Código de seguridad" + card_expiry_date: Fecha de expiración + card_masked_digit: "X" + card_expiry_abbreviation: "Exp" + new_credit_card: "Nueva tarjeta de crédito" + my_credit_cards: Mis tarjetas de credito + add_new_credit_card: Añadir nueva tarjeta de crédito + saved_cards: Tarjetas guardadas + add_a_card: Añade una tarjeta + add_card: Añadir tarjeta + you_have_no_saved_cards: Aún no has guardado ninguna tarjeta. + saving_credit_card: Guardando tarjeta de crédito... + card_has_been_removed: "Su tarjeta ha sido eliminada (número: %{number})" + card_could_not_be_removed: Lo sentimos, la tarjeta no se pudo quitar + invalid_credit_card: "Tarjeta de crédito inválida" + ie_warning_headline: "Su navegador está desactualizado :-(" + ie_warning_text: "Para la mejor esperiencia de Open Food Network, recomendamos actualizar su navegador:" + ie_warning_chrome: Descargar Chrome + ie_warning_firefox: Descargar Firefox + ie_warning_ie: Actualizar Internet Explorer + ie_warning_other: "¿No puede actualizar su navegador? Pruebe Open Food Network en su teléfono :-)" + legal: + cookies_policy: + header: "Cómo utilizamos las cookies" + desc_part_1: "Las cookies son archivos de texto muy pequeños que se almacenan en tu computadora cuando visitas algunos sitios web." + desc_part_2: "En OFN somos respetuosos con tu privacidad. Utilizamos solo las cookies que son necesarias para ofrecerte el servicio de compraventa de alimentos en línea. No vendemos ninguno de tus datos. Es posible que en el futuro te propongamos que compartas alguno de tus datos para crear nuevos servicios comunes que podrían ser útiles para el ecosistema (como los servicios logísticos para sistemas alimentarios cortos), pero aún no hemos llegado a ese punto y no lo haremos sin tu autorización :-)" + desc_part_3: "Usamos cookies principalmente para recordar quién eres si 'inicias sesión' o para poder recordar los artículos que colocas en tu carrito, incluso si no has iniciado sesión. Si continúas navegando en el sitio web sin hacer clic en \"Aceptar cookies\" suponemos que nos das tu consentimiento para almacenar las cookies que son esenciales para el funcionamiento del sitio web. ¡Aquí está la lista de cookies que usamos!" + essential_cookies: "Cookies esenciales" + essential_cookies_desc: "Las siguientes cookies son estrictamente necesarias para el funcionamiento de nuestro sitio web." + essential_cookies_note: "La mayoría de las cookies solo contienen un identificador único, pero no otros datos, por lo que su dirección de correo electrónico y contraseña, por ejemplo, nunca se incluyen ni se exponen." + cookie_domain: "Establecido por:" + cookie_session_desc: "Se usa para permitir que el sitio web recuerde a los usuarios entre las visitas a la página, por ejemplo, recordar los artículos en tu carrito." + cookie_consent_desc: "Se usa para mantener el estado del consentimiento del usuario para almacenar cookies" + cookie_remember_me_desc: "Se usa si el usuario ha solicitado que el sitio web lo recuerde. Esta cookie se elimina automáticamente después de 12 días. Si como usuario deseas que se elimine esa cookie, solo necesitas desconectarte. Si no deseas que la cookie se instale en tu computadora no debes marcar la casilla \"recordarme\" al iniciar sesión." + cookie_openstreemap_desc: "Utilizado por nuestro amigo proveedor de mapeo de código abierto (OpenStreetMap) para garantizar que no recibas demasiadas solicitudes durante un período de tiempo determinado, para evitar el abuso de sus servicios." + cookie_stripe_desc: "Datos recopilados por nuestro procesador de pagos Stripe para detectar fraudes https://stripe.com/cookies-policy/legal. No todas las tiendas usan Stripe como método de pago pero es una buena práctica evitar fraude aplicarlo a todas las páginas. Stripe probablemente crea una imagen de cuáles de nuestras páginas generalmente interactúan con su API y luego marca cualquier cosa inusual. Por lo tanto configurar la cookie Stripe tiene una función más amplia que la simple provisión de un método de pago a un usuario. Eliminarla podría afectar la seguridad del servicio en sí. Puede obtener más información acerca de Stripe y leer su política de privacidad en https://stripe.com/privacy." + statistics_cookies: "Cookies de estadísticas" + statistics_cookies_desc: "Las siguientes no son estrictamente necesarias, pero ayudan a proporcionarle una mejor experiencia de usuario al permitirnos analizar el comportamiento del usuario, identificar qué funciones usa más o no, comprender los problemas de la experiencia del usuario, etc." + statistics_cookies_analytics_desc_html: "Para recopilar y analizar los datos de uso de la plataforma utilizamos Google Analytics, ya que era el servicio predeterminado conectado con Spree (el software de código abierto de comercio electrónico en el que creamos) pero nuestra visión es cambiar a Matomo (ex Piwik, herramienta analítica de código abierto que cumple con GDPR y protege tu privacidad) tan pronto como podamos." + statistics_cookies_matomo_desc_html: "Para recopilar y analizar los datos de uso de la plataforma, utilizamos Matomo (ex Piwik), una herramienta analítica de código abierto que cumple con GDPR y protege tu privacidad" + statistics_cookies_matomo_optout: "¿Deseas excluirte de Matomo Analytics? No recopilamos ningún dato personal y Matomo nos ayuda a mejorar nuestro servicio, pero respetamos tu elección :-)" + cookie_analytics_utma_desc: "Se usa para distinguir usuarios y sesiones. La cookie se crea cuando la biblioteca javascript se ejecuta y no existe ninguna cookie __utma existente. La cookie se actualiza cada vez que se envían datos a Google Analytics." + cookie_analytics_utmt_desc: "Se usa para acelerar la tasa de solicitud." + cookie_analytics_utmb_desc: "Se utiliza para determinar nuevas sesiones / visitas. La cookie se crea cuando la librería javascript se ejecuta y no existe ninguna cookie __utmb existente. La cookie se actualiza cada vez que los datos se envían a Google Analytics." + cookie_analytics_utmc_desc: "No utilizado en ga.js. Establecer para la interoperabilidad con urchin.js. Históricamente, esta cookie funcionó junto con la cookie __utmb para determinar si el usuario estaba en una nueva sesión / visita." + cookie_analytics_utmz_desc: "Almacena la fuente de tráfico o la campaña que explica cómo el usuario llegó a su sitio. La cookie se crea cuando se ejecuta la librería javascript y se actualiza cada vez que se envían datos a Google Analytics." + cookie_matomo_basics_desc: "Matomo cookies de origen para recopilar estadísticas." + cookie_matomo_heatmap_desc: "Matomo Heatmap y sesión de grabación de cookies." + cookie_matomo_ignore_desc: "Cookie utilizada para excluir al usuario de ser rastreado." + disabling_cookies_header: "Advertencia sobre la desactivación de cookies" + disabling_cookies_desc: "Como usuario, siempre puede permitir, bloquear o eliminar las cookies de Open Food Network o cualquier otra página web cuando lo desee a través del control de configuración de su navegador. Cada navegador tiene una operativa diferente. Aquí están los enlaces:" + disabling_cookies_firefox_link: "https://support.mozilla.org/es/kb/habilitar-y-deshabilitar-cookies-sitios-web-rastrear-preferencias" + disabling_cookies_chrome_link: "https://support.google.com/chrome/answer/95647" + disabling_cookies_ie_link: "https://support.microsoft.com/es-es/help/17442/windows-internet-explorer-delete-manage-cookies" + disabling_cookies_safari_link: "https://www.apple.com/legal/privacy/es/cookies/" + disabling_cookies_note: "Pero tenga en cuenta que si elimina o modifica las cookies esenciales utilizadas por Open Food Network, el sitio web no funcionará, no podrá agregar nada a su carrito ni realizar pedidos, por ejemplo." + cookies_banner: + cookies_usage: "Este sitio utiliza cookies para que su navegación sea fluida y segura, y para ayudarnos a comprender cómo lo usa para mejorar las funciones que ofrecemos." + cookies_definition: "Las cookies son archivos de texto muy pequeños que se almacenan en tu ordenador cuando visitas algunos sitios web." + cookies_desc: "Utilizamos solo las cookies que son necesarias para ofrecerle el servicio de venta / compra de alimentos en línea. No vendemos ninguno de sus datos. Utilizamos cookies principalmente para recordar quién es usted si 'inicia sesión' en el servicio, o para poder recordar los artículos que puso en su carrito, incluso si no ha iniciado sesión. Si continúa navegando en el sitio web sin hacer clic en \"Aceptar cookies\", asumimos que nos da su consentimiento para almacenar las cookies que son esenciales para el funcionamiento del sitio web." + cookies_policy_link_desc: "Si desea obtener más información, consulte nuestro" + cookies_policy_link: "política de cookies" + cookies_accept_button: "Aceptar cookies" + home_shop: Comprar ahora + brandstory_headline: "Consume con valores." + brandstory_intro: "A veces la mejor forma de arreglar el sistema es empezar uno nuevo…" + brandstory_part1: "Nosotros empezamos desde abajo. Con granjeros y productoras listas para contar sus historias con orgullo y autenticidad. Con distribuidoras listas para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden seriamente cambiar el mundo." + brandstory_part2: "Luego necesitamos una forma de hacerlo real. Una forma de empoderar a todos los que producen, venden y compran comida. Una forma de contar todas las historias, de manejar todas las logísticas. Una forma de convertir transacción en transformación todos los días." + brandstory_part3: "Entonces contruímos un mercado que nivela el campo de juego. Es transparente, de forma que crea relaciones reales. Es de código abierto, de forma que todos son los dueños." + brandstory_part4: "Funciona en cualquier lugar. Lo cambia todo." + brandstory_part5_strong: "Le llamamos Open Food Network." + brandstory_part6: "Todos amamos la comida. Ahora podemos amar nuestro sistema de comida también." + learn_body: "Explora modelos, historias y recursos para ayudarte a desarrollar tu organización. Encuentra formación, eventos y otras oportunidades para aprender de tus compañeros." + learn_cta: "Inspírate" + connect_body: "Busca en nuestros directorios de productoras, grupos u otras organizaciones. Haz una lista de tu organización en OFN para que los consumidores puedan encontrarte. Únete a la comunidad para obtener consejos y resolver problemas juntos." + connect_cta: "Explorar" + system_headline: "Compras - cómo funcionan." + system_step1: "1. Buscar" + system_step1_text: "Busca comida local y de temporada en nuestras tiendas diversas e independientes. Busca por municipio y participa en un grupo de consumo." + system_step2: "2. Comprar" + system_step2_text: "Transforma tu consumo con comida local y asequible de diversas productoras ¡Conoce las historias detrás de tu comida y la gente que la hace!" + system_step3: "3. Recogida" + system_step3_text: "Visita tu Grupo de Consumo para un vínculo más directo con las productoras y tus vecinos, también puedes comprar directamente a algunas productoras o centrales de compras. Compra tu comida de una manera tan diversa como la naturaleza." + cta_headline: "Compras que hacen el mundo un mejor lugar." + cta_label: "Estoy lista" + stats_headline: "Entre todas creamos un nuevo sistema de producción, distribución y consumo." + stats_producers: "productoras" + stats_shops: "tiendas" + stats_shoppers: "consumidoras" + stats_orders: "pedidos" + checkout_title: Validar el carrito + checkout_now: Validar el carrito ahora + checkout_order_ready: Pedido preparado para + checkout_hide: Esconder + checkout_expand: Expandir + checkout_headline: "Esta bien, ¿listo para realizar el pedido?" + checkout_as_guest: "Hacer pedido como invitado" + checkout_details: "Sus detalles" + checkout_billing: "Información de cobro" + checkout_default_bill_address: "Guardar como dirección de facturación por defecto" + checkout_shipping: Información de envío + checkout_default_ship_address: "Guardar como dirección de envío por defecto" + checkout_method_free: Gratis + checkout_address_same: ¿Dirección de entrega igual a la dirección de cobro? + checkout_ready_for: "Listo para:" + checkout_instructions: "¿Algún comentario o intrucciones especiales?" + checkout_payment: Pago + checkout_send: Realizar pedido ahora + checkout_your_order: Tu pedido + checkout_cart_total: Total del carrito + checkout_shipping_price: Envío + checkout_total_price: Total + checkout_back_to_cart: "De vuelta al carrito" + cost_currency: "Moneda" + order_paid: PAGADO + order_not_paid: NO PAGADO + order_total: Pedido total + order_payment: "Pagando con:" + order_billing_address: Dirección de cobro + order_delivery_on: Entregar en + order_delivery_address: Dirección de entrega + order_delivery_time: Tiempo de entrega + order_special_instructions: "Sus notas:" + order_pickup_time: Listo para la recolección + order_pickup_instructions: Instrucciones de recolección + order_produce: Productos + order_total_price: Total + order_includes_tax: (incluye impuesto) + order_payment_paypal_successful: Su pago a través de PayPal ha sido procesado con éxito. + order_hub_info: Información del Grupo + order_back_to_store: Volver a la Tienda + order_back_to_cart: Volver al Carrito + bom_tip: "Usa esta página para alterar la cantidad del producto en varios pedidos a la vez. Los productos pueden ser eliminados de los pedidos si es necesario. " + unsaved_changes_warning: "Hay cambios no guardados, se perderán si continúas." + unsaved_changes_error: "Los campos con bordes rojos contienen errores." + products: "Productos" + products_in: "en %{oc}" + products_at: "en %{distributor}" + products_elsewhere: "Productos encontrados en otros lugares" + email_confirmed: "Gracias por confirmar la dirección de correo electrónico." + email_confirmation_activate_account: "Antes de que podamos activar su nueva cuenta, necesitamos confirmar su dirección de correo electrónico." + email_confirmation_greeting: "Hola, %{contact}!" + email_confirmation_profile_created: "¡Se creó un un perfil para %{name} con éxito! Para activar su Perfil necesitamos que confirme esta dirección de correos." + email_confirmation_click_link: "Por favor haga clic en el enlace de abajo para confirmar el correo electrónico y continuar configurando su perfil." + email_confirmation_link_label: "Confirmar este correo electrónico »" + email_confirmation_help_html: "Después de confirmar el correo electrónico puedes acceder a tu cuenta de administración para esta organización. Visita %{link} para encontrar más información sobre las características de %{sitename} y empieza a usar tu perfil o tienda online." + email_confirmation_notice_unexpected: "Recibes este mensaje porque te has registrado en %{sitename} o has sido invitado a inscribirte por alguien que probablemente conozcas. Si no entiendes por qué estás recibiendo este correo electrónico, escribe a %{contact}." + email_social: "Conecte con nosotros:" + email_contact: "Envíenos un correo electrónico:" + email_signoff: "Saludos," + email_signature: "El equipo de %{sitename}" + email_confirm_customer_greeting: "Hola %{name}," + email_confirm_customer_intro_html: "¡Gracias por comprar en %{distributor}!" + email_confirm_customer_number_html: "Confirmación del pedido #%{number}" + email_confirm_customer_details_html: "Aquí están los detalles de tu pedido de %{distributor}:" + email_confirm_customer_signoff: "Saludos cordiales," + email_confirm_shop_greeting: "Hola %{name}," + email_confirm_shop_order_html: "¡Bien! ¡Tiene un nuevo pedido en %{distributor}!" + email_confirm_shop_number_html: "Confirmación del pedido #%{number}" + email_order_summary_item: "Artículo" + email_order_summary_quantity: "Cantidad" + email_order_summary_sku: "SKU" + email_order_summary_price: "Precio" + email_order_summary_subtotal: "Subtotal:" + email_order_summary_total: "Total:" + email_order_summary_includes_tax: "(incluye impuestos):" + email_payment_paid: PAGADO + email_payment_not_paid: NO PAGADO + email_payment_summary: Resumen de pago + email_payment_method: "Pagando con:" + email_so_placement_intro_html: "Tiene un nuevo pedido con %{distributor} " + email_so_placement_details_html: "Aquí están los detalles de su pedido para %{distributor} :" + email_so_placement_changes: "Desafortunadamente, no todos los productos que solicitó estaban disponibles. Las cantidades originales que solicitó aparecen tachadas a continuación." + email_so_payment_success_intro_html: "Se ha procesado un pago automático para su pedido desde %{distributor} ." + email_so_placement_explainer_html: "Esta orden se creó automáticamente para usted." + email_so_edit_true_html: "Puede realizar cambios hasta que los pedidos se cierren en %{orders_close_at}." + email_so_edit_false_html: "Puede ver detalles de este pedido en cualquier momento." + email_so_contact_distributor_html: "Si tiene alguna pregunta, puede contactar %{distributor} a través de %{email}." + email_so_contact_distributor_to_change_order_html: "Has creado este pedido automáticamente. Puedes realizar cambios hasta que los pedidos se cierren en %{orders_close_at} contactando %{distributor} a través de %{email}." + email_so_confirmation_intro_html: "Tu pedido con %{distributor} ahora está confirmado" + email_so_confirmation_explainer_html: "Este pedido fue colocado automáticamente para usted, y ahora ha sido finalizado." + email_so_confirmation_details_html: "Aquí encontrará todo lo que necesita saber sobre su pedido en %{distributor} :" + email_so_empty_intro_html: "Intentamos realizar un nuevo pedido con %{distributor} , pero tuvimos algunos problemas ..." + email_so_empty_explainer_html: "Lamentablemente, ninguno de los productos que ordenó estaba disponible, por lo que no se realizó ningún pedido. Las cantidades originales que solicitó aparecen tachadas a continuación." + email_so_empty_details_html: "Aquí están los detalles del pedido no realizado para %{distributor} :" + email_so_failed_payment_intro_html: "Intentamos procesar un pago, pero tuvimos algunos problemas ..." + email_so_failed_payment_explainer_html: "El pago de su suscripción con %{distributor} ha fallado debido a un problema con su tarjeta de crédito. %{distributor} ha recibido notificación de este pago fallido." + email_so_failed_payment_details_html: "Aquí están los detalles del fallo proporcionados por la pasarela de pago:" + email_shipping_delivery_details: Detalles de entrega + email_shipping_delivery_time: "Entregar en:" + email_shipping_delivery_address: "Dirección de entrega:" + email_shipping_collection_details: Detalles de recolección + email_shipping_collection_time: "Listo para la recolección:" + email_shipping_collection_instructions: "Instrucciones de recolección:" + email_special_instructions: "Sus notas:" + email_signup_greeting: ¡Hola! + email_signup_welcome: "Bienvenido a %{sitename}!" + email_signup_confirmed_email: "Gracias por confirmar su email." + email_signup_shop_html: "Ahora puedes iniciar sesión en %{link}." + email_signup_text: "Gracias por unirte a la red. Si eres un comprador, ¡esperamos presentarte a muchos agricultores, grupos de consumo y deliciosa comida! Si eres una productora o formas parte de una organización de alimentos, estamos emocionados de que formes parte de la red." + email_signup_help_html: "Agradecemos todas tus preguntas y feedback; puedes usar el botón de Enviar Feedback en el sitio o escribir un email a %{email}" + invite_email: + greeting: "¡Hola!" + invited_to_manage: "Ha sido invitado a administrar %{enterprise} en %{instance}." + confirm_your_email: "Debería haber recibido o recibirá pronto un correo electrónico con un enlace de confirmación. No podrá acceder al perfil de %{enterprise} hasta que haya confirmado su correo electrónico." + set_a_password: "Luego se le pedirá que establezca una contraseña antes de poder administrar la organización." + mistakenly_sent: "¿No está seguro de por qué ha recibido este correo electrónico? Por favor, póngase en contacto con %{owner_email} para más información." + producer_mail_greeting: "Estimada" + producer_mail_text_before: "Ahora tenemos todas los pedidos de las consumidoras para la siguiente ronda." + producer_mail_order_text: "Se muestra un resumen de los pedidos de tus productos:" + producer_mail_delivery_instructions: "Instrucciones de recogida/entrega de stock:" + producer_mail_signoff: "Gracias y hasta pronto" + shopping_oc_closed: Los pedidos están cerrados + shopping_oc_closed_description: "Por favor espere hasta que el próximo ciclo abra (o contactanos de forma directa para ver si podemos aceptar algunos pedidos tardíos)" + shopping_oc_last_closed: "El último ciclo cerró hace %{distance_of_time}" + shopping_oc_next_open: "El próximo ciclo abrirá en %{distance_of_time}" + shopping_oc_select: "Seleccionar" + shopping_tabs_home: "Inicio" + shopping_tabs_shop: "Tienda" + shopping_tabs_about: "Acerca de" + shopping_tabs_contact: "Contacto" + shopping_contact_address: "Dirección" + shopping_contact_web: "Contacto" + shopping_contact_social: "Seguir" + shopping_groups_part_of: "es parte de:" + shopping_producers_of_hub: "productoras de %{hub}:" + enterprises_next_closing: "Los pedidos se cerrarán" + enterprises_ready_for: "Listo para" + enterprises_choose: "Hay más de un ciclo abierto. Escoge en cuál quieres realizar el pedido:" + maps_open: "Abierta" + maps_closed: "Cerrado" + hubs_buy: "Comprar:" + hubs_shopping_here: "Comprando aquí" + hubs_orders_closed: "Pedidos cerrados" + hubs_profile_only: "Solo perfil" + hubs_delivery_options: "Opciones de entrega" + hubs_pickup: "Recoger" + hubs_delivery: "Entrega" + hubs_producers: "Nuestras productoras" + hubs_filter_by: "Filtrar por" + hubs_filter_type: "Tipo" + hubs_filter_delivery: "Entrega" + hubs_filter_property: "Propiedad" + hubs_matches: "¿Quiso decir?" + hubs_intro: Compra en tu localidad + hubs_distance: Más cercano a + hubs_distance_filter: "Muéstrame tiendas cerca de %{location}" + shop_changeable_orders_alert_html: + one: Su pedido con %{shop} / %{order} está abierto para revisión. Puede realizar cambios hasta %{oc_close}. + other: 'Usted tiene %{count} pedidos con %{shop} actualmente abiertos para revisión. Puede realizar cambios hasta %{oc_close}. ' + orders_changeable_orders_alert_html: Este pedido ha sido confirmado, pero puede realizar cambios hasta %{oc_close}. + products_clear_all: Limpiar todo + products_showing: "Mostrando:" + products_or: "Ó" + products_with: con + products_search: "Buscar por producto o productora" + products_loading: "Cargando productos..." + products_updating_cart: "Actualizando su carrito..." + products_cart_empty: "Carrito vacío" + products_edit_cart: "Editar su carrito" + products_from: desde + products_change: "No hay cambios para guardar." + products_update_error: "No se ha podido guardar por los siguientes errores:" + products_update_error_msg: "No se ha podido guardar." + products_update_error_data: "Error al guardar datos no válidos:" + products_changes_saved: "Cambios guardados." + search_no_results_html: "Lo sentimos, no hay resultados para %{query}. ¿Intentar otra búsqueda?" + components_profiles_popover: "Los perfiles no tienen una tienda en Open Food Network, pero pueden tener su propia tienda física o en línea en otro lugar" + components_profiles_show: "Mostrar perfiles" + components_filters_nofilters: "Sin filtros" + components_filters_clearfilters: "Limpiar todos los filtros" + groups_title: Redes + groups_headline: Redes / regiones + groups_text: "Cada productora es única. Cada organización tiene algo diferente que ofrecer. Nuestras redes son colectivos de productoras, grupos y distribuidoras que comparten valores agroecológicos. Esto hace que tu experiencia de compra sea más fácil. Puedes buscar las redes y estar seguro que se ha hecho una selección de proyectos con estos criterios." + groups_search: "Buscar nombre o palabra clave" + groups_no_groups: "No se encontraron redes" + groups_about: "Acerca de nosotras" + groups_producers: "Nuestras productoras" + groups_hubs: "Nuestros Grupos de Consumo" + groups_contact_web: Contacto + groups_contact_social: Seguir + groups_contact_address: Dirección + groups_contact_email: Envíenos un correo electrónico + groups_contact_website: Visite nuestro sitio web + groups_contact_facebook: Síganos en Facebook + groups_signup_title: Registrarse como un grupo + groups_signup_headline: Registro de redes + groups_signup_intro: "Somos una asombrosa plataforma de mercadeo colaborativo, la forma más sencilla para que sus miembros e interesados encuentren nuevos mercados. No tenemos fines de lucro, somos asequibles y simples." + groups_signup_email: Envíenos un correo electrónico + groups_signup_motivation1: Nosotros transformamos sistemas de comida de forma justa. + groups_signup_motivation2: Es por lo que salimos de la cama cada día. Somos una organización sin fines de lucro global, basada en código de fuente abierta. Jugamos de forma justa. Siempre puede confiar en nosotros. + groups_signup_motivation3: Sabemos que tiene grandes ideas, y queremos ayudar. Compartiremos nuestro conocimiento, redes y recursos. Sabemos que el aislamiento no crea cambio, entonces nos asociaremos con usted. + groups_signup_motivation4: Nos reunimos con usted en donde esté. + groups_signup_motivation5: Quizás eres un grupo de consumo, productora o distribuidora u otra organización. + groups_signup_motivation6: Cualquiera que sea su rol en el movimiento de comida local, estamos listos para ayudar. De cualquier forma en que se pregunte cómo se vería Open Food Network o qué está haciendo en su parte del mundo, empecemos la conversación. + groups_signup_motivation7: Hacemos que los movimientos alimenticios tengan más sentido. + groups_signup_motivation8: Necesita activar y habilitar sus redes. Le ofrecemos una plataforma para conversación y acción. Necesita involucramiento real. Le ayudaremos a alcanzar todos los actores, todos los interesados, todos los sectores. + groups_signup_motivation9: Necesita recursos. Le brindaremos todas nuestras experiencias para portar. Necesita cooperación. Lo conectaremos mejor a una red global de pares. + groups_signup_pricing: Cuenta de grupo + groups_signup_studies: Casos de estudio + groups_signup_contact: ¿Listo para discutir? + groups_signup_contact_text: "Póngase en conta para descubrir qué puede hacer OFN por usted:" + groups_signup_detail: "Aquí está el detalle." + login_invalid: "Correo electrónico o contraseña inválidos" + modal_hubs: "Hubs" + modal_hubs_abstract: ¡Nuestros Grupos de Consumo son el punto de contacto entre usted y la gente que hace su comida! + modal_hubs_content1: Puede buscar un grupo de consumo conveniente por ubicación o nombre. Algunos grupos de consumo tienen múltiples puntos en loa que puede recoger las compras, y algunos también brindan opciones de entrega a domicilio. Cada Grupo de Consumo es un punto de venta con operaciones de negocio y logística independientes, entonces puede esperar diferencias entre Grupos de Consumo. + modal_hubs_content2: Sólo puedes comprar en un grupo de consumo a la vez. + modal_groups: "Redes / Regiones" + modal_groups_content1: Estas son las organizaciones y relaciones entre grupos de consumo que conforman el Open Food Network. + modal_groups_content2: Algunas redes están organizadas por ubicación, otros por afinidades no geográficas. + modal_how: "Cómo funciona" + modal_how_shop: Comprar en Open Food Network + modal_how_shop_explained: ¡Buscar un grupo de consumo cerca de ti para empezar a comprar! Puedes expandir cada grupo de consumo para ver qué tipos de productos están disponibles, y hacer clic para empezar a comprar. (Sólo puedes comprar en un grupo de consumo a la vez.) + modal_how_pickup: Recogida, entrega y gastos de envío + modal_how_pickup_explained: Algunos grupos de consumo hacen entregas hasta su puerta, mientras otros requieren que recojas las compras. Puedes ver que opciones están disponibles en su página de inicio, y seleccionar cuál te gustaría en las páginas de compras y revisión. Las entregas costarán más, y el precio cambia entre grupos de consumo. Cada grupo es un punto de venta con operaciones y logística independientes, las diferencias son normales y deseables. + modal_how_more: Aprender más + modal_how_more_explained: "Si quieres saber más acerca de Open Food Network, cómo trabajamos y nos organizamos, visita:" + modal_producers: "Productoras" + modal_producers_explained: "Nuestras productoras hacen todos los deliciosos alimentos que puedes comprar en Open Food Network." + producers_about: Acerca de nosotras + producers_buy: Comprar + producers_contact: Contacto + producers_contact_phone: Llamar + producers_contact_social: Seguir + producers_buy_at_html: "Comprar productos de %{enterprise} en:" + producers_filter: Filtrar por + producers_filter_type: Tipo + producers_filter_property: Propiedad + producers_title: Productoras + producers_headline: Encuentra productoras locales + producers_signup_title: Registrarse como productora + producers_signup_headline: Productoras de alimentos, empoderadas. + producers_signup_motivation: Venda sus alimentos y cuente sus historias en distintos nuevos mercados. Ahorre tiempo y dinero en costos administrativos. Apoyamos la innovación sin el riesgo. Hemos nivelado el campo de juego. + producers_signup_send: Únase ahora + producers_signup_enterprise: Cuentas de organización + producers_signup_studies: Historias de nuestras productoras. + producers_signup_cta_headline: ¡Únase ahora! + producers_signup_cta_action: Únase ahora + producers_signup_detail: Aquí esta el detalle. + products_item: Artículo + products_description: Descripción + products_variant: Variante + products_quantity: Cantidad + products_available: ¿Disponible? + products_producer: "Productora" + products_price: "Precio" + name_or_sku: "NOMBRE O CÓDIGO SKU" + register_title: Registro + sell_title: "Registro" + sell_headline: "¡Consíguelo en Open Food Network!" + sell_motivation: "Muestra tus preciosos alimentos." + sell_producers: "Productoras" + sell_hubs: "Hubs" + sell_groups: "Redes" + sell_producers_detail: "Crea tu perfil en OFN en cuestión de minutos. En cualquier momento puedes actualizar tu perfil a una tienda en línea y vender tus productos directamente a los consumidores." + sell_hubs_detail: "Crea un perfil para tu organización en OFN. En cualquier momento puedes actualizar tu perfil a una tienda de varias productoras." + sell_groups_detail: "Crea un directorio personalizado de organizaciones (productoras u otras organizaciones) para tu región o para tu organización." + sell_user_guide: "Descubre mucho más en la guía de usuario." + sell_listing_price: "Listado en la OFN es gratis. Abrir y administrar una tienda en OFN es gratis hasta $ 500 en ventas mensuales. Si vende más, puede elegir la contribución de su comunidad entre el 1% y el 3% de las ventas. Para obtener más detalles sobre los precios, visite la sección Plataforma de software a través del enlace Acerca de en el menú superior." + sell_embed: "También podemos incrustar una tienda OFN en tu propia web personalizada o crear un sitio web de la red local a medida para tu región." + sell_ask_services: "Pregúntanos sobre los servicios de OFN" + shops_title: Tiendas + shops_headline: Compras, transformadas. + shops_text: Los alimentos crecen en ciclos, los agricultores cosechan en ciclos, y nosotros pedimos la comida en ciclos. Si encuentras un ciclo de pedido cerrado, vuelve a visitarlo pronto. + shops_signup_title: Registrarse como un grupo de consumo + shops_signup_headline: Grupos de Consumo, sin límites. + shops_signup_motivation: Cualquiera que sea su modelo, lo apoyamos. De cualquier forma que cambie, estamos con usted. Somos una organización sin findes de lucro, independiente, y de código abierto. Somos los socios de software con los que ha soñado. + shops_signup_action: Únase ahora + shops_signup_pricing: Cuentas de organización + shops_signup_stories: Historias de nuestros grupos de consumo. + shops_signup_help: Estamos listos para ayudar. + shops_signup_help_text: Usted necesita un mejor retorno. Usted necesita nuevos compradores y socios de logística. Usted necesita que su historia sea contada a través de ventas al por mayor, al detalle y en la mesa de la cocina. + shops_signup_detail: Aquí está el detalle. + orders: Pedidos + orders_fees: Comisiones... + orders_edit_title: Carrito de compras + orders_edit_headline: Su carrito de compras + orders_edit_time: Pedido listo para + orders_edit_continue: Continuar comprando + orders_edit_checkout: Validar + orders_form_empty_cart: "Vaciar carrito" + orders_form_subtotal: Subtotal de productos + orders_form_admin: Administrar y Gestionar + orders_form_total: Total + orders_oc_expired_headline: Los pedidos están cerrados para este ciclo + orders_oc_expired_text: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos." + orders_oc_expired_text_others_html: "Lo sentimos, ¡los pedidos para este ciclo cerraron hace %{time}! Contacta con tu grupo de consumo directamente para ver si pueden aceptar pedidos tardíos %{link}." + orders_oc_expired_text_link: "o visitar otros ciclos de pedidos disponibles en este grupo de consumo" + orders_oc_expired_email: "Correo electrónico:" + orders_oc_expired_phone: "Teléfono:" + orders_show_title: Confirmación del pedido + orders_show_time: Pedido listo en + orders_show_order_number: "Pedido #%{number}" + orders_show_cancelled: Cancelado + orders_show_confirmed: Confirmado + orders_your_order_has_been_cancelled: "Su pedido ha sido cancelado" + orders_could_not_cancel: "Lo sentimos, no se pudo cancelar el pedido" + orders_cannot_remove_the_final_item: "No se puede quitar el último artículo de un pedido, en su lugar, por favor cancele el pedido." + orders_bought_items_notice: + one: "Un elemento adicional ya está confirmado para este ciclo de pedido" + other: "%{count} artículos adicionales ya confirmados para este ciclo de pedido" + orders_bought_edit_button: Editar artículos confirmados + orders_bought_already_confirmed: "* ya confirmados" + orders_confirm_cancel: Seguro que desea cancelar este pedido? + order_processed_successfully: "Su pedido ha sido procesado con éxito." + products_cart_distributor_choice: "Distribuidora para tu pedido:" + products_cart_distributor_change: "Su distribuidora para este pedido se cambiará a %{name} si agregas este producto al carrito." + products_cart_distributor_is: "Tu distribuidora para este pedido es %{name}." + products_distributor_error: "Completa tu pedido en %{link} antes de comprar con otra distribuidora." + products_oc: "Ciclo de pedido para tu pedido:" + products_oc_change: "Tu ciclo de pedido para este pedido será cambiado a %{name} si agregas este producto al carrito." + products_oc_is: "Tu ciclo de pedido para este pedido es %{name}." + products_oc_error: "Completa este pedido de %{link} antes de comprar en un ciclo de pedido diferente." + products_oc_current: "tu ciclo de de pedido actual" + products_max_quantity: Cantidad máxima + products_distributor: Distribuidor + products_distributor_info: Cuando selecciones una distribuidora para tu pedido, tu dirección y tiempo de recolección se mostrarán aquí. + password: Contraseña + remember_me: Recordarme + are_you_sure: "¿Está seguro?" + orders_open: Pedidos abiertos + closing: "Cerrando " + going_back_to_home_page: "Le estamos llevando de vuelta a la página de inicio" + creating: Creando + updating: Actualizando + failed_to_create_enterprise: "Error al crear tu organización." + failed_to_create_enterprise_unknown: "Error al crear tu organización.\nAsegúrate de haber rellenado todos los campos." + failed_to_update_enterprise_unknown: "Error al actualizar tu organización.\nAsegúrate de haber rellenado todos los campos." + enterprise_confirm_delete_message: "Esto también eliminará el %{product} que suministra esta organización. ¿Estás seguro de que quieres continuar?" + order_not_saved_yet: "Su orden aun no ha sido guardada. ¡Denos unos cuantos segundos para terminar!" + filter_by: "Fitrar por" + hide_filters: "Esconder filtros" + one_filter_applied: "1 filtro aplicado" + x_filters_applied: "filtros aplicados" + submitting_order: "Enviando su orden: espere" + confirm_hub_change: "¿Está seguro? Esto cambiará tu grupo de consumo seleccionado y eliminará cualquier artículo en tu carrito de la compra." + confirm_oc_change: "¿Está seguro? Esto cambiará su ciclo de orden seleccionado y eliminará cualquier artículo en su carrito de compras." + location_placeholder: "Escriba una ubicación..." + error_required: "no puede estar vacío" + error_number: "debe ser un número" + error_email: "debe ser una dirección de correo electrónico" + error_not_found_in_database: "%{name} no se encuentra en la base de datos" + error_not_primary_producer: "%{name} no está habilitado como productora" + error_no_permission_for_enterprise: "\"%{name}\": no tiene permiso para administrar productos para esta organización" + item_handling_fees: "Comisiones de manejo de artículos (incluída en el total de artículos)" + january: "Enero" + february: "Febrero" + march: "Marzo" + april: "Abril" + may: "Mayo" + june: "Junio" + july: "Julio" + august: "Agosto" + september: "Setiembre" + october: "Octubre" + november: "Noviembre" + december: "Diciembre" + email_not_found: "Dirección de correo electrónico no encontrada" + email_unconfirmed: "Debe confirmar su dirección de correo electrónico antes de poder restablecer su contraseña." + email_required: "Debe brindar una dirección de correo electrónico" + logging_in: "Espere un momento, le vamos a iniciar una sesión" + signup_email: "Tu correo electrónico" + choose_password: "Escoje una contraseña" + confirm_password: "Confirmar contraseña" + action_signup: "Registrarse ahora" + forgot_password: "¿No recuerdas tu contraseña?" + password_reset_sent: "¡Le enviamos un correo electrónico con instrucciones para restaurar la contraseña!" + reset_password: "Restaurar contraseña" + update_and_recalculate_fees: "Actualizar y recalcular comisiones" + registration: + steps: + introduction: + registration_greeting: "¡Hola!" + registration_intro: "Ahora puedes crear un perfil para tu Productora o Grupo de Consumo" + registration_checklist: "¿Qué necesito?" + registration_time: "5-10 minutos" + registration_enterprise_address: "Dirección de la organización" + registration_contact_details: "Detalles de contacto principal" + registration_logo: "Su imagen de logo" + registration_promo_image: "Imagen en formato apaisado para su perfil" + registration_about_us: "Texto 'Acerca de nosotras'" + registration_outcome_headline: "¿Para qué sirve?" + registration_outcome1_html: "Su perfil le ayuda a las personas a encontrarle y contactarle en la Open Food Network." + registration_outcome2: "Use este espacio para contar la historia de tu organización, para ayudar a impulsar las conexiones a tu presencia social y en línea." + registration_outcome3: "También es el primer paso para empezar en Open Food Network, o abrir una tienda online." + registration_action: "¡Empecemos!" + details: + title: "Detalles" + headline: "Empecemos" + enterprise: "Ei! Primero necesitamos saber un poco sobre tu organización:" + producer: "Primero necesitamos saber un poco sobre tu productora:" + enterprise_name_field: "Nombre de la organización:" + producer_name_field: "Nombre de la productora:" + producer_name_field_placeholder: "p.ej. La impresionante granja de Charlie" + producer_name_field_error: "Elija un nombre único para su organización." + address1_field: "Dirección Línea 1:" + address1_field_placeholder: "p.ej. Passeig Sant Joan" + address1_field_error: "Introduce una dirección" + address2_field: "Dirección línea 2:" + suburb_field: "Barrio:" + suburb_field_placeholder: "e.g. Gràcia" + suburb_field_error: "Introduce un barrio" + postcode_field: "Código postal:" + postcode_field_placeholder: "p.ej. 08025" + postcode_field_error: "Requiere un código postal" + state_field: "Región:" + state_field_error: "Región requerida" + country_field: "País:" + country_field_error: "Por favor selecciona un país" + contact: + title: "Contacto" + who_is_managing_enterprise: "¿Quién es responsable de administrar %{enterprise}?" + contact_field: "Contacto principal" + contact_field_placeholder: "Nombre de contacto" + contact_field_required: "Debes introducir un contacto principal." + phone_field: "Número de teléfono" + phone_field_placeholder: "p.ej. 93 250 16 45" + type: + title: "Tipo" + headline: "Último paso para añadir %{enterprise}!" + question: "¿Eres una productora?" + yes_producer: "Si soy una productora" + no_producer: "No, no soy una productora" + producer_field_error: "Por favor elige uno. ¿Eres una productora?" + yes_producer_help: "Las productoras hacen cosas deliciosas para comer y/o beber. Eres una productora si lo cultivas, lo haces crecer, lo preparas, lo horneas, lo fermentas, lo ordeñas, ..." + no_producer_help: "Si no eres una productora, probablemente conozcas a alguien que venda o distribuya comida. También podrías convertirte en un grupo de consumo u otro tipo de organización." + create_profile: "Crear Perfil" + about: + title: "Acerca de" + headline: "¡Seguimos!" + message: "Ahora vamos a profundizar en los detalles acerca de" + success: "¡Éxito! %{enterprise} agregado a Open Food Network" + registration_exit_message: "Si sales de este asistente en cualquier etapa puedes continuar creando tu perfil yendo a la interfaz de administración." + enterprise_description: "Descripción corta" + enterprise_description_placeholder: "Una frase corta que describa tu organización" + enterprise_long_desc: "Descripción larga" + enterprise_long_desc_placeholder: "Esta es tu oportunidad de contar la historia de tu organización - ¿qué la hace diferente? Sugerimos mantener la descripción en menos de 600 caracteres o 150 palabras." + enterprise_long_desc_length: "%{num} caracteres / recomentdamos hasta 600" + enterprise_abn: "NIF" + enterprise_abn_placeholder: "ej. 99 123 456 789" + enterprise_acn: "ACN" + enterprise_acn_placeholder: "ej. 123 456 789" + enterprise_tax_required: "Necesita seleccionar algo." + images: + title: "Imágenes" + headline: "¡Ya casi lo tenemos!" + description: "¡Sube algunas fotografías así el perfil se verá mucho mejor! :)" + uploading: "Subiendo..." + continue: "Continuar" + back: "Atrás" + logo: + select_logo: "Paso 1. Seleccione una imagen de logotipo" + logo_tip: "Consejo: Imágenes cuadradas funcionan mejor, de preferencia por lo menos de 300×300px" + logo_label: "Escoja una imagen de logo" + logo_drag: "Arrastre y suelte su logo aquí" + review_logo: "Paso 2. Revise su logo" + review_logo_tip: "Consejo: para mejores resultados, su logo debería llenar el espacio disponible" + logo_placeholder: "El logo aparecerá aquí para ser revisado cuando se haya subido" + promo: + select_promo_image: "Paso 3. Seleccione una imagen promocional" + promo_image_tip: "Consejo: Se muestra como una pancarta, el tamaño preferido es 1200×260px" + promo_image_label: "Escoja una imagen promocional" + promo_image_drag: "Arrastre y suelte su imagen promocional aquí" + review_promo_image: "Paso 4. Revise su pancarta promocional" + review_promo_image_tip: "Consejo: para mejores resultados, su imagen promocional debería llenar el espacio disponible" + promo_image_placeholder: "El logo aparecerá aquí para ser revisado cuando se haya subido" + social: + title: "Social" + enterprise_final_step: "¡Paso final!" + enterprise_social_text: "¿Cómo puede la gente encontrar a %{enterprise} en línea?" + website: "Website" + website_placeholder: "eg. openfoodnetwork.org.au" + facebook: "Facebook" + facebook_placeholder: "eg. www.facebook.com/NombreDePáginaAquí" + linkedin: "LinkedIn" + linkedin_placeholder: "eg. www.linkedin.com/SuNombreAquí" + twitter: "Twitter" + twitter_placeholder: "usuario_de_twitter" + instagram: "Instagram" + instagram_placeholder: "usuario_de_instagram" + limit_reached: + headline: "¡Ay no!" + message: "¡Ha alcanzado el límite!" + text: "Has alcanzado el límite de organizaciones de las que puedes gestionar en " + action: "Regresar a la página de inicio" + finished: + headline: "¡Terminado!" + thanks: "Gracias por llenar los detalles de %{enterprise}." + login: "Puede cambiar o actualizar su negocio en cualquier etapa iniciando sesión en Open Food Network y yendo a Admin." + action: "Ir al Panel de Organización" + back: "Atrás" + continue: "Continuar" + action_or: "Ó" + enterprise_limit: Límite de la Organización + shipping_method_destroy_error: "Ese método de envío no puede ser eliminado ya que se hace referencia en un pedido: %{number}." + fees: "Comisiones" + item_cost: "Costo del artículo" + bulk: "Agrupar" + shop_variant_quantity_min: "mínimo" + shop_variant_quantity_max: "máximo" + follow: "Seguir" + shop_for_products_html: "Comprar productos de %{enterprise} en:" + change_shop: "Cambiar de tienda:" + shop_at: "Comprar en:" + price_breakdown: "Desglose de precios completo" + admin_fee: "Comisión de administración" + sales_fee: "Comisión de ventas" + packing_fee: "Comisión de empaquetado" + transport_fee: "Comisión de transporte" + fundraising_fee: "Comisión para recaptación de fondos" + price_graph: "Gráfico de precios" + included_tax: "Impuesto incluido" + balance: "Saldo" + transaction: "Transacción" + transaction_date: "Fecha" + payment_state: "Estado de pago" + shipping_state: "Estado del envío" + value: "Valor" + balance_due: "Saldo debido" + credit: "Crédito" + Paid: "Pagado" + Ready: "Listo" + ok: OK + not_visible: no visible + you_have_no_orders_yet: "No tienes pedidos todavía" + show_only_complete_orders: "Mostrar solo pedidos completos" + successfully_created: '%{resource} se ha creado exitosamente!' + successfully_removed: '%{resource} ha sido eliminado exitosamente!' + successfully_updated: '%{resource} ha sido actualizado exitosamente!' + running_balance: "Saldo actual" + outstanding_balance: "Saldo extraordinario" + admin_enterprise_relationships: "Permisos de la organización" + admin_enterprise_relationships_everything: "Marcar todos" + admin_enterprise_relationships_permits: "Permite" + admin_enterprise_relationships_seach_placeholder: "Buscar" + admin_enterprise_relationships_button_create: "Crear" + admin_enterprise_groups: "Redes de organizaciones" + admin_enterprise_groups_name: "Nombre" + admin_enterprise_groups_owner: "Propietaria" + admin_enterprise_groups_on_front_page: "¿En la página principal?" + admin_enterprise_groups_enterprise: "Organizaciones" + admin_enterprise_groups_data_powertip: "El principal usuario responsable de este grupo." + admin_enterprise_groups_data_powertip_logo: "Este es el logo del grupo" + admin_enterprise_groups_data_powertip_promo_image: "Esta imagen se mostrará en la cabecera del perfil del Grupo" + admin_enterprise_groups_contact: "Contacto" + admin_enterprise_groups_contact_phone_placeholder: "ej. 98 7654 3210" + admin_enterprise_groups_contact_address1_placeholder: "ej. Carrer Torrent de l'Olla" + admin_enterprise_groups_contact_city: "Barrio" + admin_enterprise_groups_contact_city_placeholder: "ej. Barcelona" + admin_enterprise_groups_contact_zipcode: "Código Postal" + admin_enterprise_groups_contact_zipcode_placeholder: "ej. 08025" + admin_enterprise_groups_contact_state_id: "Provincia" + admin_enterprise_groups_contact_country_id: "País" + admin_enterprise_groups_web: "Recursos Web" + admin_enterprise_groups_web_twitter: "ej: the_prof" + admin_enterprise_groups_web_website_placeholder: "ej. www.truffles.com" + admin_order_cycles: "Ciclos de Pedidos del Admin" + open: "Abierta" + close: "Cerrar" + create: "Crear" + search: "Buscar" + supplier: "Proveedora" + product_name: "nombre del producto" + product_description: "Descripción del producto" + units: "Unidad de medida" + coordinator: "Coordinadora" + distributor: "Distribuidor" + enterprise_fees: "Comisiones de la Organización" + process_my_order: "Procesar mi pedido" + delivery_instructions: Instrucciones de Entrega + delivery_method: Método de entrega + fee_type: "Tipo de Comisión" + tax_category: "Categoría del impuesto" + calculator: "Calculadora" + calculator_values: "Calculadora de valores" + calculator_settings_warning: "Si está cambiando el tipo de calculadora, debe de salvar primero antes de editar las configuraciones de la calculadora" + flat_percent_per_item: "Porcentaje fijo (por artículo)" + flat_rate_per_item: "Tarifa plana (por artículo)" + flat_rate_per_order: "Tarifa plana (por pedido)" + flexible_rate: "Tarifa flexible" + price_sack: "Precio saco" + new_order_cycles: "Nuevos Ciclos de Pedidos" + new_order_cycle: "Nuevo Ciclo de Pedido" + select_a_coordinator_for_your_order_cycle: "Selecciona un coordinador para vuestro ciclo de pedido" + notify_producers: 'Notificar a las productoras' + edit_order_cycle: "Editar Ciclo de Pedido" + roles: "Roles" + update: "Actualizar" + delete: Borrar + add_producer_property: "Añadir propiedad de productora" + in_progress: "En Proceso" + started_at: "Empezo el" + queued: "En Cola" + scheduled_for: "Planificado para" + customers: "Consumidores" + please_select_hub: "Selecciona un Grupo" + loading_customers: "Cargando Consumidores" + no_customers_found: "No se encuentran consumidores" + go: "Ir" + hub: "Grupo de Consumo" + producer: "Productora" + product: "Producto" + price: "Precio" + on_hand: "Disponibles" + review: "Revisión" + save_changes: "Guardar Cambios" + order_saved: "Pedido Guardado" + no_products: No hay productos + spree_admin_overview_enterprises_header: "Mis Organizaciones" + spree_admin_overview_enterprises_footer: "GESTIONAR MIS ORGANIZACIONES" + spree_admin_enterprises_hubs_name: "Nombre" + spree_admin_enterprises_create_new: "CREAR NUEVA" + spree_admin_enterprises_shipping_methods: "Métodos de envío" + spree_admin_enterprises_fees: "Comisiones de la Organización" + spree_admin_enterprises_none_create_a_new_enterprise: "CREAR NUEVA ORGANIZACIÓN" + spree_admin_enterprises_none_text: "No tienes ninguna organización" + spree_admin_enterprises_tabs_hubs: "HUBS" + spree_admin_enterprises_producers_manage_products: "GESTIONAR PRODUCTOS" + spree_admin_enterprises_create_new_product: "CREAR UN NUEVO PRODUCTO" + spree_admin_single_enterprise_alert_mail_confirmation: "Confirma la dirección de email para" + spree_admin_single_enterprise_alert_mail_sent: "Te hemos enviado un mail a" + spree_admin_overview_action_required: "Acción Requerida" + spree_admin_overview_check_your_inbox: "Revisa tu bandeja de entrada para las siguientes instrucciones. Gracias!" + spree_admin_unit_value: Valor unidad + spree_admin_unit_description: Descripción de la unidad + spree_admin_variant_unit: Variante + spree_admin_variant_unit_scale: Escala de unidad + spree_admin_supplier: Proveedora + spree_admin_product_category: categoría del producto + spree_admin_variant_unit_name: Nombre de la variante + unit_name: "Nombre de la unidad" + change_package: "Cambiar Perfil" + spree_admin_single_enterprise_hint: "Sugerencia: Para permitir que la gente te encuentre, activa tu visibilidad" + spree_admin_eg_pickup_from_school: "p.ej. 'Recogida en la Cooperativa'" + spree_admin_eg_collect_your_order: "p.ej. 'Por favor recoge tu pedido en la Calle del Hormiguero nº3'" + spree_classification_primary_taxon_error: "La clasificación %{taxon} es la clasificación primaria de %{product} y no puede ser eliminada" + spree_order_availability_error: "El Distribuidor o el Ciclo de Pedido no pueden suministrar los productos en su carrito" + spree_order_populator_error: "Este Distribuidor o Ciclo de Pedido no puede suministrar todos los productos en tu carrito. Por favor, elige otro." + spree_order_populator_availability_error: "Este producto no está disponible por el distribuidor o Ciclo de Pedido elegido." + spree_distributors_error: "Se debe seleccionar al menos un Grupo" + spree_user_enterprise_limit_error: "^ %{email} no está autorizado a tener más organizaciones (el límite es %{enterprise_limit})." + spree_variant_product_error: Debes tener al menos una variante + your_profil_live: "Tu perfil online" + on_ofn_map: "en el mapa Open Food Network" + see: "Ver" + live: "En directo" + manage: "Gestionar" + resend: "Reenviar" + add_and_manage_products: "Añadir y gestionar productos" + add_and_manage_order_cycles: "Añadir y gestionar ciclos de pedidos" + manage_order_cycles: "Gestionar ciclos de pedidos" + manage_products: "Gestionar productos" + edit_profile_details: "Editar detalles del perfil" + edit_profile_details_etc: "Cambia tu descripción, imágenes, etc." + order_cycle: "Ciclo de Pedido" + order_cycles: "Ciclos de Pedidos" + enterprise_relationships: "Permisos de la organización" + remove_tax: "Eliminar impuesto" + first_name_begins_with: "El nombre comienza con" + last_name_begins_with: "El apellido comienza con" + enterprise_tos_link: "Enlace a los Términos del Servicio de la Organización" + enterprise_tos_message: "Queremos trabajar con personas que compartan nuestros objetivos y valores. Por ello, pedimos a las nuevas organizaciones que acepten" + enterprise_tos_link_text: "Términos del Servicio." + enterprise_tos_agree: "Estoy de acuerdo con los Términos del Servicio" + tax_settings: "Configuración de Impuestos" + products_require_tax_category: "Los productos requieren categoría de impuesto" + admin_shared_address_1: "Dirección" + admin_shared_address_2: "Dirección (cont.)" + admin_share_city: "Ciudad" + admin_share_zipcode: "Código Postal" + admin_share_country: "País" + admin_share_state: "Estado" + hub_sidebar_hubs: "Hubs" + hub_sidebar_none_available: "Ninguno Disponible" + hub_sidebar_manage: "Gestionar" + hub_sidebar_at_least: "Al menos un grupo debe ser seleccionado" + hub_sidebar_blue: "azul" + hub_sidebar_red: "rojo" + report_customers_distributor: "Distribuidor" + report_customers_supplier: "Proveedora" + report_customers_cycle: "Ciclo de Pedido" + report_customers_type: "Tipo de Informe" + report_customers_csv: "Descargar como CSV" + report_producers: "Productoras:" + report_type: "Tipo de Informe:" + report_hubs: "Hubs: " + report_payment: "Métodos de Pago:" + report_distributor: "Distribuidora:" + report_payment_by: 'Pagos por Tipo' + report_itemised_payment: 'Pagos Totales Detallados' + report_payment_totals: 'Pagos Totales' + report_all: 'Todo' + report_order_cycle: "Ciclo de Pedido:" + report_enterprises: "Organizaciones:" + report_users: "Usuarias:" + report_tax_rates: Porcentajes de los Impuestos + report_tax_types: Tipos de Impuestos + report_header_order_cycle: Ciclo de Pedido + report_header_user: Usuaria + report_header_email: Email + report_header_status: Estado + report_header_comments: Comentarios + report_header_first_name: Nombre + report_header_last_name: Apellido + report_header_phone: Teléfono + report_header_suburb: Barrio + report_header_address: Dirección + report_header_billing_address: Dirección de Facturación + report_header_relationship: Relación + report_header_hub: Grupo + report_header_hub_address: Dirección del Grupo + report_header_to_hub: Al Grupo + report_header_hub_code: Código de Grupo + report_header_code: Código + report_header_paid: ¿Pagado? + report_header_delivery: ¿Entregado? + report_header_shipping: Envío + report_header_shipping_method: Método de envío + report_header_shipping_instructions: Instrucciones de envío + report_header_ship_street: Calle de envío + report_header_ship_street_2: Calle de envío 2 + report_header_ship_city: Ciudad de envío + report_header_ship_postcode: Código postal de envío + report_header_ship_state: Provincia de envío + report_header_billing_street: Calle de facturación + report_header_billing_street_2: Calle de facturación 2 + report_header_billing_street_3: Calle de facturación 3 + report_header_billing_street_4: Calle de facturación 4 + report_header_billing_city: Ciudad de facturación + report_header_billing_postcode: Código postal de facturación + report_header_billing_state: Provincia de facturación + report_header_incoming_transport: Transporte entrante + report_header_special_instructions: instrucciones especiales + report_header_order_number: Número de pedido + report_header_date: Fecha + report_header_confirmation_date: Fecha de confirmación + report_header_tags: Tags + report_header_items: Artículos + report_header_items_total: "Artículos en total %{currency_symbol}" + report_header_taxable_items_total: "Artículos con Impuestos en Total (%{currency_symbol})" + report_header_sales_tax: "Impuesto sobre las Ventas (%{currency_symbol})" + report_header_delivery_charge: "Gastos de Envío (%{currency_symbol})" + report_header_tax_on_delivery: "Impuestos sobre la entrega (%{currency_symbol})" + report_header_tax_on_fees: "Impuesto sobre las comisiones (%{currency_symbol})" + report_header_total_tax: "Total Impuestos (%{currency_symbol})" + report_header_enterprise: Organización + report_header_customer: Consumidora + report_header_customer_code: Código de consumidora + report_header_product: Producto + report_header_product_properties: Propiedades del producto + report_header_quantity: Cantidad + report_header_max_quantity: Cantidad máxima + report_header_variant: Variante + report_header_variant_value: Valor de la variante + report_header_variant_unit: Unidad Variante + report_header_total_available: Total disponible + report_header_unallocated: Sin asignar + report_header_max_quantity_excess: Cantidad máxima + report_header_taxons: Clasificación + report_header_supplier: Proveedor + report_header_producer: Productora + report_header_producer_suburb: Barrio Productora + report_header_unit: Unidad + report_header_group_buy_unit_quantity: Agrupar por cantidad unidad + report_header_cost: Coste + report_header_shipping_cost: Coste del envío + report_header_curr_cost_per_unit: Coste por unidad actual + report_header_total_shipping_cost: Coste total del envío + report_header_payment_method: Método de pago + report_header_sells: Vende + report_header_visible: Visible + report_header_price: Precio + report_header_unit_size: Unidad de medida + report_header_distributor: Distribuidora + report_header_distributor_address: Dirección del distribuidor + report_header_distributor_city: Ciudad del distribuidor + report_header_distributor_postcode: Código postal del distribuidor + report_header_delivery_address: Dirección de entrega + report_header_delivery_postcode: Código postal de entrega + report_header_bulk_unit_size: Tamaño de la unidad a granel + report_header_weight: Peso + report_header_sum_total: Suma Total + report_header_date_of_order: Fecha de pedido + report_header_amount_owing: Cantidad adeudada + report_header_amount_paid: Cantidad pagada + report_header_units_required: Unidades requeridas + report_header_remainder: Recordatorio + report_header_order_date: Fecha de pedido + report_header_order_id: ID de Pedido + report_header_item_name: Nombre del artículo + report_header_temp_controlled_items: ¿Artículos de temperatura controlada? + report_header_customer_name: Nombre de la consumidora + report_header_customer_email: Correo electrónico de la consumidora + report_header_customer_phone: Teléfono de la Consumidora + report_header_customer_city: Ciudad de la Consumidora + report_header_payment_state: Estado del pago + report_header_payment_type: Tipo de pago + report_header_item_price: "Artículo (%{currency})" + report_header_item_fees_price: "Artículo + Comisiones (%{currency})" + report_header_admin_handling_fees: "Administración y Gestión (%{currency})" + report_header_ship_price: "Envío (%{currency})" + report_header_pay_fee_price: "Comisión de pago (%{currency})" + report_header_total_price: "Total (%{currency})" + report_header_product_total_price: "Producto Total (%{currency})" + report_header_shipping_total_price: "Total envíos (%{currency})" + report_header_outstanding_balance_price: "Saldo pendiente (%{currency})" + report_header_eft_price: "Transferencia (%{currency})" + report_header_paypal_price: "PayPal (%{currency})" + report_header_sku: SKU + report_header_amount: Cantidad + report_header_balance: Saldo + report_header_total_cost: "Coste total" + report_header_total_ordered: Total pedidos + report_header_total_max: Total Max + report_header_total_units: Unidades totales + report_header_sum_max_total: "Suma Máx. Total" + report_header_total_excl_vat: "Total Impuestos excl. (%{currency_symbol})" + report_header_total_incl_vat: "Total Impuestos incl. (%{currency_symbol})" + report_header_temp_controlled: ¿Control de Temperatura? + report_header_is_producer: ¿Productora? + report_header_not_confirmed: No confirmado + report_header_gst_on_income: IVA sobre Ingresos + report_header_gst_free_income: Ingresos sin IVA + report_header_total_untaxable_produce: Total productos sin impuestos + report_header_total_taxable_produce: Total productos con impuestos + report_header_total_untaxable_fees: Total comisiones no imponibles (sin impuestos) + report_header_total_taxable_fees: Total de impuestos imponibles (impuestos incluidos) + report_header_delivery_shipping_cost: Gastos de envío (impuestos incluidos) + report_header_transaction_fee: Comisión por transacción (sin impuestos) + report_header_total_untaxable_admin: Total de ajustes administrativos no tributables (sin impuestos) + report_header_total_taxable_admin: Total de ajustes tributarios de administración (impuestos incluidos) + initial_invoice_number: "Número inicial de Factura:" + invoice_date: "Fecha de la factura:" + due_date: "Fecha de vencimiento:" + account_code: "Código de la Cuenta:" + equals: "Iguales" + contains: "Contiene" + discount: "Descuento" + filter_products: "Filtrar Poductos" + delete_product_variant: "¡La última variedad no puede ser borrada!" + progress: "Progreso" + saving: "Guardando.." + success: "completado" + failure: "fallo" + unsaved_changes_confirmation: "Los cambios no guardados se perderán. ¿Continuar igualmente? " + one_product_unsaved: "Los cambios de un producto aún no se han guardado." + products_unsaved: "Los cambios de %{n} productos aún no se han guardado." + is_already_manager: "¡Ya eres un administrador!" + no_change_to_save: "No hay cambios para guardar" + user_invited: "%{email} ha sido invitado a administrar esta organización" + add_manager: "Agrega un usuario existente" + users: "Usuarias" + about: "Acerca de" + images: "Imagenes" + web: "Web" + primary_details: "Detalles Principales" + adrdress: "Dirección" + contact: "Contacto" + social: "Social" + business_details: "Detalles de la Organización" + properties: "Propiedades" + shipping: "Envío" + shipping_methods: "Métodos de envío" + payment_methods: "Métodos de Pago" + payment_method_fee: "Comisión de Transacción" + payment_processing_failed: "No se pudo procesar el pago, por favor verifique los detalles que introdujo" + payment_method_not_supported: "Ese método de pago no está soportado. Por favor elije otro." + payment_updated: "Pago actualizado" + inventory_settings: "Configuración del Inventario" + tag_rules: "Reglas de las Etiquetas" + shop_preferences: "Configuración de la tienda" + enterprise_fee_whole_order: Pedido completo + enterprise_fee_by: "%{type} comisión por %{role} %{enterprise_name}" + validation_msg_relationship_already_established: "^Esta relación ya existe." + validation_msg_at_least_one_hub: "^Al menos se debe seleccionar un grupo de consumo" + validation_msg_tax_category_cant_be_blank: "^La Categoría del Impuesto no puede estar vacía" + validation_msg_is_associated_with_an_exising_customer: "Está asociado con un consumidor existente" + content_configuration_pricing_table: "(TODO: tabla de precios)" + content_configuration_case_studies: "(TODO: Casos de Estudio)" + content_configuration_detail: "(TODO: Detalle)" + enterprise_name_error: "ya está en uso. Si esta es su organización y le gustaría reclamar la propiedad, o si desea negociar con esta organización, comuníquese con el gestor actual de este perfil al %{email}." + enterprise_owner_error: "^ %{email} no está autorizado a tener más organizaciones (el límite es %{enterprise_limit})." + enterprise_role_uniqueness_error: "^Este rol ya está presente." + inventory_item_visibility_error: Debe ser verdadero o falso + product_importer_file_error: "Error: no se ha subido ningún archivo" + product_importer_spreadsheet_error: "No se pudo procesar el archivo: tipo de archivo inválido" + product_importer_products_save_error: No se guardó ningún producto con éxito + product_import_file_not_found_notice: 'Archivo no encontrado o no se pudo abrir' + product_import_no_data_in_spreadsheet_notice: 'No se encontraron datos en la hoja de cálculo' + order_choosing_hub_notice: Tu Grupo se ha seleccionado. + order_cycle_selecting_notice: Se ha seleccionado el ciclo de pedido. + adjustments_tax_rate_error: "^Comprueba que los impuestos para este ajuste es correcta." + active_distributors_not_ready_for_checkout_message_singular: >- + El Grupo %{distributor_names} aparece en un ciclo de pedido activo, pero no + tiene métodos de envío y pago válidos. Hasta que los configure, los clientes + no podrán comprar en este grupo. + active_distributors_not_ready_for_checkout_message_plural: >- + Los Grupos %{distributor_names} se listan los ciclos de pedido activos, pero + no tienen métodos de envío y pago válidos. Hasta que los configure, los clientes + no podrán comprar en estos concentradores. + enterprise_fees_update_notice: Las comisiones de tu Organización se han actualizado. + enterprise_register_package_error: "Seleccione un paquete" + enterprise_register_error: "No se pudo completar el registro para %{enterprise}" + enterprise_register_success_notice: "¡Felicidades! ¡Se ha completado el registro de %{enterprise}!" + enterprise_bulk_update_success_notice: "Organizaciones actualizadas con éxito" + enterprise_bulk_update_error: 'Error en la actualización' + enterprise_shop_show_error: "La tienda que busca no existe o esta inactiva en OFN. por favor visita otras tiendas." + order_cycles_create_notice: 'Se ha creado el ciclo de pedido.' + order_cycles_update_notice: 'Se ha actualizado su ciclo de pedido.' + order_cycles_bulk_update_notice: 'Los ciclos de pedido han sido actualizados.' + order_cycles_clone_notice: "Su ciclo de pedido %{name} ha sido clonado." + order_cycles_email_to_producers_notice: 'Los correos electrónicos que se enviarán a las productoras se han puesto en cola para enviarlos.' + order_cycles_no_permission_to_coordinate_error: "Ninguna de tus organizaciones tiene permiso para coordinar un ciclo de pedido" + order_cycles_no_permission_to_create_error: "No tienes permiso para crear un ciclo de pedido coordinado por esta empresa." + back_to_orders_list: "Volver a la lista de pedidos" + no_orders_found: "No se encontraron pedidos" + order_information: "información del pedido" + date_completed: "Fecha de finalización" + amount: "Cantidad" + state_names: + ready: Listo + pending: Pendiente + shipped: Enviado + js: + saving: 'Guardando...' + changes_saved: 'Cambios guardados.' + save_changes_first: Guarda los cambios primero. + all_changes_saved: Todos los cambios guardados + unsaved_changes: Tienes cambios sin guardar + all_changes_saved_successfully: Todos los cambios guardados correctamente + oh_no: "¡Vaya! No se ha podido guardar los cambios." + unauthorized: "No estás autorizado a acceder a esta página." + error: Error + unavailable: No Disponible + profile: Perfil + hub: Grupo + shop: Tienda + choose: Escoger + resolve_errors: Resuelve los siguientes errores + more_items: "+ %{count} Más" + default_card_updated: Tarjeta predeterminada actualizada + admin: + enterprise_limit_reached: "Has alcanzado el límite estándar de organizaciones por cuenta. Escriba a %{contact_email} si necesita aumentarlo." + modals: + got_it: Lo entiendo + close: "Cerrar" + invite: "Invitar" + invite_title: "Invitar a un usuario no registrado" + tag_rule_help: + title: Reglas de las Etiquetas + overview: Visión general + overview_text: > + Las reglas de etiqueta proporcionan una manera de describir qué elementos + son visibles o no para determinados consumidores. Los artículos pueden + ser métodos de envío, métodos de pago, productos y ciclos de pedido. + by_default_rules: "'Por Defecto...' Reglas" + by_default_rules_text: > + Las reglas predeterminadas permiten ocultar los elementos para que no + estén visibles de forma predeterminada. Este comportamiento puede ser + invalidado por reglas no predeterminadas para consumidores con etiquetas + particulares. + customer_tagged_rules: "Reglas de \"clientes etiquetados ...\"" + customer_tagged_rules_text: > + Al crear reglas relacionadas con una etiqueta de consumidor específica, + puedes anular el comportamiento predeterminado (ya sea para mostrar + u ocultar elementos) para los consumidores con la etiqueta concreta. + panels: + save: GUARDAR + saved: GUARDADO + saving: GUARDANDO + enterprise_package: + hub_profile: Perfil del Grupo + hub_profile_cost: "COSTE: GRATUITO PARA SIEMPRE" + hub_profile_text1: > + La gente puede encontrarte y ponerse en contacto contigo en Open Food + Network. Tu organización será visible en el mapa y se podrá buscar en + los listados. + hub_profile_text2: > + Tener un perfil y hacer vínculos a través de Open Food Network será + gratis para siempre. + hub_shop: Tienda + hub_shop_text1: > + Tu organización es la columna vertebral de un sistema de consumo local. + Agrega productos de otras organizaciones y véndelo a través de tu tienda + en Open Food Network. + hub_shop_text2: > + Los grupos pueden tener diferentes finalidades, ya sea una cooperativa + de alimentos, un grupo de consumo, un supermercado local, ... + hub_shop_text3: > + Si también quieres vender tus propios productos, tendrás que cambiar + esta organización para ser una productora. + choose_package: Seleccione un Perfil + choose_package_text1: > + Su organización no se activará completamente hasta que seleccione un + perfil de las opciones de la izquierda. + choose_package_text2: > + Haga click en una opción para ver información más detallada acerca de + cada perfil, y pulse el botón rojo GUARDAR cuando hayas terminado. + profile_only: Solo perfil + profile_only_cost: "COSTE: GRATUITO PARA SIEMPRE" + profile_only_text1: >+ + El perfil te hace visible y permite que las personas te puedan contactar. + Es una manera de aportar la máxima transparencia y explicar tu historia. + + profile_only_text2: > + Si prefieres concentrarte en producir alimentos y deseas dejar el trabajo + de venderlo a otras personas, no necesitas una tienda en Open Food Network. + profile_only_text3: > + Añade tus productos a Open Food Network, permitiendo a los Grupos de + Consumo vender tus productos. + producer_shop: Tienda Productora + producer_shop_text1: > + Vende tus productos directamente a los consumidores con tu tienda en + Open Food Network. + producer_shop_text2: > + Una tienda de productora es para tu producto solamente, si quieres vender + productos de otros productores, selecciona 'Grupo de Productores'. + producer_hub: Grupo de Productoras + producer_hub_text1: > + Tu organización es la columna vertebral de un sistema de consumo local. + Agrega productos tuyos o de otras organizaciones y véndelo a través + de tu tienda en Open Food Network. + producer_hub_text2: > + Los Grupos de Productoras pueden tener diferentes finalidades, ya sea + una cooperativa de alimentos, un grupo de consumo, un supermercado local, + ... + producer_hub_text3: > + Open Food Network tiene como objetivo apoyar tantos modelos de organizaciones + como sea posible, queremos aportarte las herramientas que necesites + para poner en marcha tu organización. + get_listing: Obtener un listado + always_free: SIEMPRE GRATIS + sell_produce_others: Vender la producción de otros + sell_own_produce: Vende tu propia producción. + sell_both: Vende tu propia producción y la de otros + enterprise_producer: + producer: Productora + producer_text1: > + Los productores pueden crear cosas deliciosas para comer o beber. Usted + es un productor si cultiva, mejora, fermenta, ordeña o moldea. + producer_text2: > + Las Productoras pueden también realizar otras acciones, como agregar + productos de otras organizaciones y venderlos a través de su tienda + en Open Food Network. + non_producer: No-productora + non_producer_text1: > + Las no-productoras no producen alimentos por si mismas, lo que significa + que no pueden crear sus propios productos para ofrecerlos a través de + Open Food Network. + non_producer_text2: > + En cambio, las no-productoras se especializan en vincular a las productoras + con los consumidores finales, ya sea entregando, empaquetando, vendiendo + alimentos. + producer_desc: Productoras + producer_example: ej. AGRICULTORES, PRODUCTORAS + non_producer_desc: Todas las demás organizaciones + non_producer_example: ej. Grupos de consumo, Tiendas de proximidad, ... + enterprise_status: + status_title: "%{name} está configurado y listo para funcionar!" + severity: Gravedad + description: Descripción + resolve: Resolver + exchange_products: + load_more_variants: "Cargar mas variantes" + load_all_variants: "cargar todas las variantes" + select_all_variants: "Seleccionar todo" + variants_loaded: "%{num_of_variants_loaded} de %{total_number_of_variants} variantes cargadas" + loading_variants: "Cargando variantes" + tag_rules: + shipping_method_tagged_top: "Métodos de envío etiquetados" + shipping_method_tagged_bottom: "son:" + payment_method_tagged_top: "Métodos de pago etiquetados" + payment_method_tagged_bottom: "son:" + order_cycle_tagged_top: "Ciclos de pedido etiquetados" + order_cycle_tagged_bottom: "son:" + inventory_tagged_top: "Variantes de inventario etiquetadas" + inventory_tagged_bottom: "son:" + new_tag_rule_dialog: + select_rule_type: "Selecciona un tipo de regla:" + add_rule: "Añadir regla" + enterprise_fees: + inherit_from_product: "Heredar del producto" + orders: + index: + per_page: "%{results} por página" + view_file: "Ver archivo" + compiling_invoices: "Generando facturas" + bulk_invoice_created: "Factura conjunta creada" + bulk_invoice_failed: "Error al crear la factura conjunta" + please_wait: "Por favor, espere hasta que el PDF esté listo antes de cerrar esta ventana." + order_state: + address: "dirección" + adjustments: "ajustes" + awaiting_return: "Esperando retorno" + canceled: "cancelado" + cart: "carrito" + complete: "completar" + confirm: "Confirmar" + delivery: "Entrega" + paused: "pausado" + payment: "pago" + pending: "pendiente" + resumed: "resumido" + returned: "devuelto" + skrill: "skrill" + shipment_states: + backorder: "orden pendiente" + partial: "parcial" + pending: "pendiente" + ready: "Listo" + shipped: "enviado" + canceled: "cancelado" + payment_states: + balance_due: "saldo debido" + completed: "completado" + checkout: "validar" + credit_owed: "crédito debido" + failed: "fallido" + paid: "pagado" + pending: "pendiente" + processing: "procesando" + void: "vacío" + invalid: "inválido" + resend_user_email_confirmation: + resend: "Reenviar" + sending: "Reenviar..." + done: "Reenvio hecho ✓" + failed: "Reenvio fallido ✗" + order_cycles: + schedules: + adding_a_new_schedule: "Agregar una nueva programación" + updating_a_schedule: "Actualización de una programación" + create_schedule: "Crear programación" + update_schedule: "Actualizar programación" + delete_schedule: "Eliminar programación" + schedule_name_placeholder: "Nombre de la programación" + created_schedule: "Programación creada" + updated_schedule: "Programación actualizada" + deleted_schedule: "Programación eliminada" + name_required_error: "Por favor ingrese un nombre para esta programación" + no_order_cycles_error: "Seleccione al menos un ciclo de pedido (arrastrar y soltar)" + available: "Disponible" + selected: "Seleccionado" + customers: + index: + add_customer: "Añadir Consumidor" + add_a_new_customer_for: "Añadir un nuevo consumidor para %{shop_name}" + customer_placeholder: "customer@example.org" + valid_email_error: "Introduce un email válido" + subscriptions: + error_saving: "Error al salvar suscripción " + new: + please_select_a_shop: "Por favor seleccione una tienda" + insufficient_stock: "Stock insuficiente disponible, solo quedan %{on_hand}" + out_of_stock: + reduced_stock_available: Stock reducido disponible + out_of_stock_text: > + Mientras estabas comprando, los niveles de stock para uno o más de los productos + de tu carrito se han reducido. Aquí está lo que ha cambiado: + now_out_of_stock: está ahora fuera de stock. + only_n_remainging: "Solo quedan %{num} ." + variants: + on_demand: + 'yes': "Bajo demanda" + variant_overrides: + on_demand: + use_producer_settings: "Utilizar la configuración de estoc de la productora." + 'yes': "Sí" + 'no': "No" + inventory_products: "Productos del Inventario" + hidden_products: "Productos ocultos" + new_products: "Nuevos productos" + reset_stock_levels: Restablecer niveles de stock a valores predeterminados + changes_to: Cambios a + one_override: Una se ha sobrescrito + overrides: sobrescribe + remain_unsaved: Permanecen sin guardar. + no_changes_to_save: No hay cambios para guardar. ' + no_authorisation: "No se ha podido obtener autorización para guardar estos cambios, por lo que no se guardarán." + some_trouble: "Han habido algunos problemas al guardar: %{errors}" + changing_on_hand_stock: Cambiando los niveles de stock... + stock_reset: Reset Stock a valores por defecto + tag_rules: + show_hide_variants: 'Mostrar u ocultar variantes en mi tienda' + show_hide_shipping: 'Mostrar u ocultar los métodos de envío al comprar' + show_hide_payment: 'Mostrar u ocultar los métodos de pago al comprar' + show_hide_order_cycles: 'Mostrar u ocultar ciclos de pedido en mi tienda' + visible: VISIBLE + not_visible: NO VISIBLE + services: + unsaved_changes_message: Los cambios no guardados existen todavía, ¿guardar ahora o ignorar? + save: GUARDAR + ignore: IGNORAR + add_to_order_cycle: "Añadir al Ciclo de Pedido" + manage_products: "Gestionar productos" + edit_profile: "Editar perfil" + add_products_to_inventory: "Añadir productos al inventario" + resources: + could_not_delete_customer: 'No se pudo eliminar al consumidor' + product_import: + confirmation: | + Esto establecerá el nivel de stock a cero en todos los productos para este + organización no está presente en el archivo subido. + order_cycles: + create_failure: "Error al crear el ciclo de pedido" + update_success: 'Se ha actualizado su ciclo de pedido.' + update_failure: "Error al actualizar el ciclo de pedido" + no_distributors: No hay distribuidores en este ciclo de pedido. Este ciclo de pedido no será visible para las consumidoras hasta que agregues uno. ¿Deseas continuar guardando este ciclo de pedido? ' + enterprises: + producer: "Productora" + non_producer: "No productor" + customers: + select_shop: 'Seleccione primero una tienda' + could_not_create: ¡Lo siento! No se pudo crear + subscriptions: + closes: cierra + closed: cerrado + close_date_not_set: Fecha de cierre no establecida + spree: + users: + order: "Pedido" + registration: + welcome_to_ofn: "Bienvenida a Open Food Network!" + signup_or_login: "Empieza registrándose (o iniciando sesión)" + have_an_account: "¿Ya tiene una cuenta?" + action_login: "Inicie sesión ahora." + inflections: + each: + one: "each" + other: "cada" + bunch: + one: "manojo" + other: "manojos" + pack: + one: "paquete" + other: "paquetes" + box: + one: "caja" + other: "cajas" + bottle: + one: "botella" + other: "botellas" + jar: + one: "frasco" + other: "frascos" + head: + one: "cabeza" + other: "cabezas" + bag: + one: "bolsa" + other: "bolsas" + loaf: + one: "hogaza" + other: "hogazas" + single: + one: "single" + other: "individuales" + tub: + one: "tub" + other: "recipientes" + punnet: + one: "canastilla" + other: "canastillas" + packet: + one: "paquete" + other: "paquetes" + item: + one: "elemento" + other: "elementos" + dozen: + one: "docena" + other: "docenas" + unit: + one: "unidad" + other: "unidades" + serve: + one: "serve" + other: "porción" + tray: + one: "bandeja" + other: "bandejas" + piece: + one: "pieza" + other: "piezas" + pot: + one: "maceta" + other: "contenedores" + bundle: + one: "haz" + other: "paquetes" + flask: + one: "flask" + other: "frascos" + basket: + one: "canasta" + other: "canastas" + sack: + one: "sacos" + other: "sacos" + producers: + signup: + start_free_profile: "Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" + order_management: + reports: + enterprise_fee_summary: + date_end_before_start_error: "debe ser después del comienzo" + parameter_not_allowed_error: "No está autorizado a usar uno o más filtros seleccionados para este informe." + fee_calculated_on_transfer_through_all: "Todos" + fee_calculated_on_transfer_through_entire_orders: "Pedidos completos a través de %{distributor}" + tax_category_various: "Varios" + fee_type: + payment_method: "Transaccion de pago" + shipping_method: "Envío" + fee_placements: + supplier: "Entrante" + distributor: "Saliente" + coordinator: "Coordinadora" + tax_category_name: + shipping_instance_rate: "Tarifa de plataforma" + formats: + csv: + header: + fee_type: "Tipo de Comisión" + enterprise_name: "Propietario de la organización" + fee_name: "Nombre de la comisión" + customer_name: "Consumidora" + fee_placement: "Asignación de comisiones" + fee_calculated_on_transfer_through_name: "Cálculo de comisiones a través de transferencias" + tax_category_name: "Categoría de impuestos" + total_amount: "€€ SUM" + html: + header: + fee_type: "Tipo de Comisión" + enterprise_name: "Propietario de la organización" + fee_name: "Nombre de la comisión" + customer_name: "Consumidora" + fee_placement: "Asignación de comisiones" + fee_calculated_on_transfer_through_name: "Cálculo de comisiones a través de transferencias" + tax_category_name: "Categoría de impuestos" + total_amount: "€€ SUM" + invalid_filter_parameters: "Los filtros que seleccionó para este informe no son válidos." + order: "Pedido" + distribution: "Distribución" + order_details: "Detalles del pedido" + customer_details: "Detalles de la consumidora" + adjustments: "Ajustes" + payments: "Pagos" + payment: "Pago" + payment_method: "Método de pago" + shipment: "Envío" + shipment_inc_vat: "Envío incluido VAT" + shipping_tax_rate: "Impuestos de envío" + category: "Categoría" + delivery: "Entrega" + temperature_controlled: "Control de temperatura" + new_product: "Nuevo producto" + administration: "Administración" + logged_in_as: "Conectado como" + account: "Cuenta" + logout: "Cerrar sesión" + date_range: "Rango de fechas" + status: "estado" + new: "Nuevo" + start: "Inicio" + end: "Final" + stop: "Detener" + first: "primero" + previous: "Anterior" + last: "Último" + spree: + your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" + add_product: "Añadir Producto" + name_or_sku: "Nombre o código SKU (ingrese al menos los primeros 4 caracteres del nombre del producto)" + resend: Reenviar + back_to_orders_list: Volver a la lista de pedidos + return_authorizations: Autorizaciones de devolución + cannot_create_returns: No se pueden crear devoluciones ya que este pedido no tiene unidades enviadas. + select_stock: "Seleccionar stock" + location: "Ubicación" + count_on_hand: "Cuenta de disponibilidad" + quantity: "Cantidad" + package_from: "perfil de" + item_description: "Descripción del artículo" + price: "Precio" + total: "Total" + edit: "Editar" + split: "División" + delete: "Borrar" + cannot_set_shipping_method_without_address: "No se puede establecer el método de envío hasta que se proporcionen los detalles de la consumidora." + no_tracking_present: "No se han proporcionado detalles de seguimiento." + order_total: "Total del pedido" + customer_details: "Detalles de la consumidora" + customer_search: "Búsqueda de consumidores" + choose_a_customer: "Elige una consumidora " + account: "Cuenta" + billing_address: "Dirección de facturación" + shipping_address: "Dirección de envío" + first_name: "Nombre" + last_name: "Apellido" + street_address: "Dirección" + street_address_2: "Dirección (cont.)" + city: "Ciudad" + zip: "Código postal" + country: "País" + state: "Provincia" + phone: "Teléfono" + update: "Actualizar" + use_billing_address: "Utilice la dirección de facturación" + adjustments: "Ajustes" + continue: "Continuar" + fill_in_customer_info: "Por favor complete la información de la consumidora" + new_payment: "Nuevo pago" + capture: "Captura" + void: "Vacío" + configurations: "Configuraciones" + general_settings: "Configuración general" + site_name: "Nombre del sitio" + site_url: "URL del sitio" + default_seo_title: "Título Seo predeterminado" + default_meta_description: "Meta Descripción predeterminada" + default_meta_keywords: "Palabras clave Meta predeterminadas" + security_settings: "Configuraciones de seguridad" + allow_ssl_in_development_and_test: "Permitir el uso de SSL en los modos de desarrollo y prueba" + allow_ssl_in_production: "Permitir que SSL se utilice en modo de producción" + allow_ssl_in_staging: "Permitir que SSL se utilice en modo de staging" + currency_decimal_mark: "Marca decimal de la moneda" + currency_settings: "Ajustes de moneda" + currency_symbol_position: ¿Poner "símbolo de moneda antes o después de la cantidad?" + currency_thousands_separator: "Separador de miles de la moneda" + hide_cents: "Ocultar céntimos" + display_currency: "Mostrar moneda" + choose_currency: "Elegir moneda" + mail_method_settings: "Configuración del método de correo" + general: "General" + enable_mail_delivery: "Habilitar entrega de correo" + send_mails_as: "Enviar correos como" + smtp_send_all_emails_as_from_following_address: "Enviar todos los correos a partir de la siguiente dirección." + send_copy_of_all_mails_to: "Enviar copia de todos los correos a" + smtp_send_copy_to_this_addresses: "Envía una copia de todos los correos salientes a esta dirección. Para direcciones múltiples, sepárelas con comas." + intercept_email_address: "Interceptar la dirección de correo electrónico" + intercept_email_instructions: "Anular destinatario de correo electrónico y reemplazar con esta dirección." + smtp: "SMTP" + smtp_domain: "Dominio SMTP" + smtp_mail_host: "Alojamiento de correo SMTP" + smtp_port: "Puerto SMTP" + secure_connection_type: "Tipo de conexión segura" + smtp_authentication_type: "Tipo de autenticación SMTP" + smtp_username: "Nombre de usuario SMTP" + smtp_password: "Contraseña SMTP" + image_settings: "Ajustes de imagen" + image_settings_warning: "Deberá regenerar las miniaturas si actualiza los estilos de paperclip. Utilize rake paperclip:refresh:thumbnails CLASS=Spree::Image para hacer esto." + attachment_default_style: Estilo de los archivos adjuntos + attachment_default_url: "URL predeterminada de los archivos adjuntos" + attachment_path: "Ruta de los archivos adjuntos" + attachment_styles: "Estilos de clip" + attachment_url: "URL de los archivos adjuntos" + add_new_style: "Añadir nuevo estilo" + image_settings_updated: "Configuración de la imagen se actualizó correctamente." + tax_categories: "Categorías de impuestos" + listing_tax_categories: "Listado de categorías de impuestos" + back_to_tax_categories_list: "Volver a la lista de categorías de impuestos" + tax rate: "% Impuestos" + new_tax_rate: "Nuevo impuesto" + tax_category: "Categoría de impuestos" + rate: "Impuesto" + tax_rate_amount_explanation: "Las tasas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" + included_in_price: "Incluido en el precio" + show_rate_in_label: "Mostrar impuesto en la etiqueta" + back_to_tax_rates_list: "Volver a la lista de impuestos" + tax_settings: "Configuración de Impuestos" + zones: "Zonas" + new_zone: "Nueva zona" + default_tax: "Impuesto por Defecto" + default_tax_zone: "Zona de impuestos predeterminada" + country_based: "Basado en el país" + state_based: "Basado en el estado" + countries: "Países" + listing_countries: "Listado de países" + iso_name: "Nombre ISO" + states_required: "Estados requeridos" + editing_country: "Editar país" + back_to_countries_list: "Volver a la lista de países" + states: "Estados" + abbreviation: "Abreviatura" + new_state: "Nuevo estado" + payment_methods: "Métodos de Pago" + new_payment_method: "Nuevo método de pago" + provider: "Proveedor" + taxonomies: "Taxonomias" + new_taxonomy: "Nueva taxonomía" + back_to_taxonomies_list: "Volver a la Lista de Taxonomías" + shipping_methods: "Métodos de envío" + shipping_categories: "Categorías de envío" + new_shipping_category: "Nueva categoría de envío" + back_to_shipping_categories: "Volver a las categorías de envío" + analytics_trackers: "Analizadores de seguimiento" + no_trackers_found: "No se encontraron rastreadores" + new_tracker: "Nuevo rastreador" + add_one: "Agrega uno" + google_analytics_id: "ID d'Analytics" + back_to_trackers_list: "Volver a la lista de rastreadores" + name: "Nombre" + description: "Descripción" + type: "Tipo" + default: "por defecto" + calculator: "Calculadora" + zone: "Zona" + display: "Mostrar" + environment: "Ambiente" + active: "Activo" + nore: "Más" + no_results: "No hay resultados" + create: "Crear" + loading: "Cargando" + flat_percent: "Porcentaje plano" + per_kg: "Por kg" + amount: "Cantidad" + currency: "Moneda" + first_item: "Costo del primer artículo" + additional_item: "Costo del artículo adicional" + max_items: "Max Artículos" + minimal_amount: "Cantidad mínima" + normal_amount: "Cantidad normal" + discount_amount: "Importe de descuento" + no_images_found: "No se encontraron imágenes " + new_image: "Nueva Imagen" + filename: "Nombre de archivo" + alt_text: "Texto Alternativo" + thumbnail: "Miniatura" + back_to_images_list: "Volver a lista de imágenes " + email: Email + account_updated: "Cuenta actualizada!" + email_updated: "La cuenta se actualizará una vez que se confirme el nuevo correo electrónico." + my_account: "Mi cuenta" + date: "Fecha" + time: "Hora" + inventory_error_flash_for_insufficient_quantity: "Un artículo de su carrito ya no está disponible." + inventory: Inventario + zipcode: Código Postal + weight: Peso (en kg) + error_user_destroy_with_orders: "Los usuarios con pedidos completados no pueden ser eliminados" + cannot_create_payment_without_payment_methods: "No se puede crear un pago para una orden sin un medio de pago definido" + please_define_payment_methods: "por favor definir métodos de pago" + options: "Opciones" + actions: + update: "Actualizar" + errors: + messages: + blank: "no puede estar vacío" + layouts: + admin: + header: + store: Tienda + admin: + tab: + dashboard: "Panel de inicio" + orders: "Pedidos" + bulk_order_management: "Gestión de pedidos en bloque" + subscriptions: "Suscripciones" + products: "Productos" + option_types: "Tipos de opciones" + properties: "Propiedades" + variant_overrides: "Inventario" + reports: "Informes" + configuration: "Configuración" + users: "Usuarias" + roles: "Roles" + order_cycles: "Ciclos de Pedido" + enterprises: "Organizaciones" + enterprise_relationships: "Permisos" + customers: "Consumidoras" + groups: "Redes" + product_properties: + index: + inherits_properties_checkbox_hint: "¿Heredar propiedades desde %{supplier}? (a menos que sea anulado arriba)" + add_product_properties: "Agregar Propiedades del producto" + select_from_prototype: "seleccionar de prototipo" + properties: + index: + properties: "Propiedades" + new_property: "Nueva propiedad" + name: "Nombre" + presentation: "presentación" + new: + new_property: "Nueva propiedad" + edit: + editing_property: "Editar Propiedad" + back_to_properties_list: "volver a lista de propiedades" + form: + name: "Nombre" + presentation: "presentación" + return_authorizations: + index: + new_return_authorization: "Nueva autorización de devolución" + return_authorizations: "Autorizaciones de devolución" + back_to_orders_list: "Volver a la lista de pedidos" + rma_number: "número RMA" + status: "Estado" + amount: "Cantidad" + cannot_create_returns: "No se pueden crear devoluciones ya que este pedido no tiene unidades enviadas." + continue: "Continuar" + new: + new_return_authorization: "Nueva autorización de devolución" + back_to_return_authorizations_list: "Back To Return Authorization List" + continue: "Continuar" + edit: + receive: "recibir" + are_you_sure: "¿Está seguro?" + return_authorization: "volver a autorización" + form: + product: "Producto" + quantity_shipped: "cantidad enviada" + quantity_returned: "Cantidad devuelta" + return_quantity: "cantidad a devolver" + amount: "Cantidad" + rma_value: "Valor RMA" + reason: "razón" + stock_location: "localización de inventario" + states: + authorized: "autorizado" + received: "recibido" + canceled: "cancelado" + orders: + index: + listing_orders: "Pedidos de listado" + new_order: "Nuevo pedido" + capture: "Captura" + ship: "Envío" + edit: "Editar" + order_not_updated: "El pedido no se pudo actualizar" + note: "Nota" + first: "primero" + last: "Último" + previous: "Anterior" + next: "Siguiente" + loading: "Cargando" + no_orders_found: "No se encontraron pedidos" + results_found: "%{number} Resultados encontrados." + viewing: "Viendo de %{start}a %{end}." + print_invoices: "Imprimir facturas" + sortable_header: + payment_state: "Estado del pago" + shipment_state: "Estado del envío" + completed_at: "Completado en" + number: "Número" + state: "Provincia" + email: "E-mail del consumidor" + invoice: + issued_on: "Emitido el" + tax_invoice: "FACTURA DE IMPUESTOS" + code: "Código" + from: "De" + to: "Facturar a" + shipping: "envío" + form: + distribution_fields: + title: "Distribución" + distributor: "Distribuidora:" + order_cycle: "Ciclo de pedido:" + line_item_adjustments: "Ajustes de artículo" + order_adjustments: "Ajustes de pedido" + order_total: "Total del pedido" + overview: + enterprises_header: + ofn_with_tip: Las Organizaciones son Productoras y/o Grupos y son la unidad básica de organización dentro de la Open Food Network. + products: + active_products: + zero: "No tienes ningún producto activo" + one: "Tiene un producto activo." + other: "Tiene %{count} productos activos" + order_cycles: + order_cycles: "Ciclos de Pedido" + order_cycles_tip: "Los ciclos de pedido determinan cuándo y dónde los productos están disponibles para las consumidoras." + you_have_active: + zero: "No tienes ningún ciclo de pedido activo." + one: "Tienes un ciclo de pedido activo." + other: "Tienes %{count} ciclos de pedido activos." + manage_order_cycles: "GESTIONA LOS CICLOS DE PEDIDO" + shipping_methods: + index: + shipping_methods: "Métodos de envío" + new_shipping_method: "Nuevo método de envío" + name: "Nombre" + products_distributor: "Distribuidora" + zone: "Zona" + calculator: "Calculadora" + display: "Mostrar" + both: "Ambos" + front_end: "Front End" + back_end: "Back End" + no_shipping_methods_found: "No se encontraron métodos de envío" + new: + new_shipping_method: "Nuevo método de envío" + back_to_shipping_methods_list: "Volver a la lista de métodos de envío" + edit: + editing_shipping_method: "Edición del método de envío" + new: "Nuevo" + back_to_shipping_methods_list: "Volver a la lista de métodos de envío" + form: + categories: "Categorías" + zones: "Zonas" + both: "Ambos" + front_end: "Front End" + back_end: "Back End" + payment_methods: + new: + new_payment_method: "Nuevo método de pago" + back_to_payment_methods_list: "Volver a la lista de métodos de pago" + edit: + editing_payment_method: "Edición del método de pago" + back_to_payment_methods_list: "Volver a la lista de métodos de pago" + stripe_connect: + enterprise_select_placeholder: Escoge... + loading_account_information_msg: Cargando la información de la cuenta de Stripe, espere un momento ... + stripe_disabled_msg: El administrador del sistema ha deshabilitado los pagos por Stripe. + request_failed_msg: Lo sentimos. Algo salió mal al intentar verificar los detalles de la cuenta con Stripe ... + account_missing_msg: No existe una cuenta Stripe para esta organización. + connect_one: Connect One + access_revoked_msg: El acceso a esta cuenta de Stripe ha sido anulado, por favor, vuelve a conectar tu cuenta. + status: Estado + connected: Conectado + account_id: Account ID + business_name: Nombre de la Organización + charges_enabled: Cargos habilitados + payments: + source_forms: + stripe: + error_saving_payment: Error al guardar el pago + submitting_payment: Enviando pago... + products: + image_upload_error: "La imagen del producto no fue reconocida. Por favor, cargue una imagen en formato PNG o JPG." + new: + title: "Nuevo producto" + new_product: "Nuevo producto" + supplier: "Proveedora" + product_name: "nombre del producto" + units: "Unidad de medida" + value: "Valor" + unit_name: "Nombre de la unidad" + price: "Precio" + on_hand: "Disponibles" + on_demand: "Bajo demanda" + product_description: "Descripción del producto" + image: "Imagen" + or: "o" + unit_name_placeholder: 'ej. manojos' + index: + header: + title: Editar varios Productos + indicators: + title: CARGANDO PRODUCTOS + no_products: "Todavía no hay productos. Añade algunos antes" + no_results: "No se han encontrado resultados" + products_head: + name: Nombre + unit: Unidad + display_as: Mostrar como + category: Categoría + tax_category: Categoría de impuestos + inherits_properties?: ¿Hereda propiedades? + available_on: Disponible en + av_on: "Av. En" + import_date: "Fecha de importación" + products_variant: + variant_has_n_overrides: "Esta variante tiene %{n} override(s)" + new_variant: "Nueva variante" + product_name: nombre del producto + primary_taxon_form: + product_category: categoría del producto + group_buy_form: + group_buy: "¿Agrupado por?" + bulk_unit_size: Tamaño de la unidad a granel + display_as: + display_as: Mostrar como + reports: + table: + select_and_search: "Seleccione filtros y haga clic en %{option} para acceder a sus datos." + bulk_coop: + bulk_coop_supplier_report: 'Bulk Co-op - Totales por Proveedor' + bulk_coop_allocation: 'Bulk Co-op - Asignación' + bulk_coop_packing_sheets: 'Bulk Co-op - Hojas de Empaquetado' + bulk_coop_customer_payments: 'Bulk Co-op - Pagos de las Consumidoras' + enterprise_fee_summaries: + filters: + date_range: "Rango de fechas" + report_format_csv: "Descargar como CSV" + generate_report: "Generar informe" + report: + none: "Ninguno" + select_and_search: "Seleccione los filtros y haga clic en GENERAR INFORME para acceder a sus datos." + users: + index: + listing_users: "Listado de Usuarias" + new_user: "Nueva usuaria" + user: "Usuaria" + enterprise_limit: "Límite de la Organización" + search: "Buscar" + email: "Email" + edit: + editing_user: "Editando usuarias" + back_to_users_list: "Volver a la lista de usuarias" + general_settings: "Configuración general" + form: + email: "Email" + roles: "Roles" + enterprise_limit: "Límite de la Organización" + confirm_password: "Confirmar contraseña" + password: "Contraseña" + email_confirmation: + confirmation_pending: "La confirmación por correo electrónico está pendiente. Hemos enviado un correo electrónico de confirmación a %{address}." + variants: + index: + sku: "SKU" + price: "Precio" + options: "Opciones" + no_results: "No hay resultados" + to_add_variants_you_must_first_define: "para agregar variantes, se debe primero definir" + option_types: "Tipos de opciones" + option_values: "valores de opción" + and: "y" + new_variant: "Nueva Variante" + show_active: "mostrar activo" + show_deleted: "Mostrar eliminados" + new: + new_variant: "Nueva Variante" + form: + cost_price: "Precio de costo" + sku: "SKU" + price: "Precio" + display_as: "Mostrar como" + display_name: "Nombre para mostrar" + autocomplete: + producer_name: "Productora" + unit: "Unidad" + general_settings: + edit: + legal_settings: "Configuraciones legales" + cookies_consent_banner_toggle: "Mostrar el banner de consentimiento de cookies" + privacy_policy_url: "Vínculo con la Política de privacidad" + enterprises_require_tos: "Las organizaciones deben aceptar los Términos del Servicio" + cookies_policy_matomo_section: "Mostrar la sección de Matomo en la página de política de cookies" + cookies_policy_ga_section: "Mostrar la sección de Google Analytics en la página de la política de cookies" + footer_tos_url: "URL de términos y servicios" + checkout: + payment: + stripe: + choose_one: Elige uno + enter_new_card: Introduce los detalles para una nueva tarjeta + used_saved_card: "Usa una tarjeta guardada:" + or_enter_new_card: "O introduce los detalles de una nueva tarjeta:" + remember_this_card: ¿Recordar esta tarjeta? + stripe_sca: + choose_one: Elige uno + enter_new_card: Introduce los detalles para una nueva tarjeta + used_saved_card: "Usa una tarjeta guardada:" + or_enter_new_card: "O introduce los detalles de una nueva tarjeta:" + remember_this_card: ¿Recordar esta tarjeta? + date_picker: + format: '%Y-%m-%d' + js_format: 'yy-mm-dd' + orders: + error_flash_for_unavailable_items: "Un artículo de su carrito ya no está disponible." + edit: + login_to_view_order: "Por favor inicie sesión para ver su pedido." + bought: + item: "Pedido en este ciclo de pedido" + line_item: + insufficient_stock: "Stock insuficiente disponible, solo quedan %{on_hand}" + out_of_stock: "Agotado" + unavailable_item: "actualmente no disponible" + shipment_states: + backorder: orden pendiente + partial: parcial + pending: pendiente + ready: Listo + shipped: enviado + payment_states: + balance_due: saldo debido + completed: completado + checkout: validar + credit_owed: crédito debido + failed: fallido + paid: pagado + pending: pendiente + processing: procesando + void: vacío + invalid: inválido + order_mailer: + cancel_email: + customer_greeting: "Hola %{name}!" + instructions: "Su pedido ha sido CANCELADO. Por favor, conserve esta información de cancelación para sus registros." + order_summary_canceled: "Resumen del pedido [CANCELADO]" + subject: "Cancelación del pedido" + confirm_email: + subject: "Confirmación del pedido" + invoice_email: + hi: "Hola %{name}" + invoice_attached_text: Adjunta una factura para su pedido reciente de + order_state: + address: dirección + adjustments: ajustes + awaiting_return: Esperando retorno + canceled: cancelado + cart: carrito + complete: completar + confirm: Confirmar + delivery: Entrega + paused: pausado + payment: pago + pending: pendiente + resumed: resumido + returned: devuelto + skrill: skrill + subscription_state: + active: activo + pending: pendiente + ended: terminado + paused: pausado + canceled: cancelado + user_mailer: + reset_password_instructions: + request_sent_text: | + Se ha solicitado el cambio de tu contraseña. + Si tu no lo has solicitado simplemente ignora este email. + link_text: > + Si has solicitado esta acción haz click en el siguiente enlace: + issue_text: | + Si el enlace no funciona prueba a copiarlo y pegarlo en tu navegador. + Si los problemas continúan no dudes en contactarnos. + confirmation_instructions: + subject: Por favor, confirma tu cuenta de OFN + users: + form: + account_settings: Configuración de la cuenta + show: + tabs: + orders: Pedidos + cards: Tarjetas de crédito + transactions: Transacciones + settings: Configuración de la cuenta + unconfirmed_email: "Correo electrónico pendiente de confirmación para: %{unconfirmed_email}. Su dirección de correo electrónico se actualizará una vez que se confirme el nuevo correo electrónico." + orders: + open_orders: Pedidos Abiertos + past_orders: Pedidos anteriores + transactions: + transaction_history: Historial de transacciones + open_orders: + order: Pedido + shop: Tienda + changes_allowed_until: Se permiten cambios hasta + items: Artículos + total: Total + edit: Editar + cancel: Cancelar + closed: Cerrado + until: Hasta + past_orders: + order: Pedido + shop: Tienda + completed_at: Completado en + items: Artículos + total: Total + paid?: ¿Pagado? + view: Ver + saved_cards: + default?: ¿Por defecto? + delete?: ¿Borrar? + cards: + authorised_shops: Tiendas autorizadas + authorised_shops_popover: Esta es la lista de tiendas a las que se les permite cobrar a su tarjeta de crédito predeterminada por sus suscripciones (es decir, pedidos repetidos) que pueda tener. Los detalles de su tarjeta se mantendrán seguros y no se compartirán con los propietarios de las tiendas. Siempre se le notificará cuando se le cobra. + saved_cards_popover: Esta es la lista de tarjetas que ha optado por guardar para su uso posterior. Su "valor predeterminado" se seleccionará automáticamente al momento de realizar un pedido, y puede ser cobrado por cualquier tienda que tenga permitido hacerlo (ver a la derecha). + authorised_shops: + shop_name: "Nombre de tienda" + allow_charges?: "¿Permitir cargos?" + localized_number: + invalid_format: tiene un formato invalido. Por favor introduzca un numero. + api: + invalid_api_key: "La llave de API especificada (%{key}) es inválida." + unauthorized: "No tiene autorización para realizar esta acción." + invalid_resource: "Recurso inválido. Por favor corrija los errores e intente nuevamente." + resource_not_found: "El recurso que buscaba no puede ser encontrado." + access: "acceso al API" + key: "Llave" + clear_key: "valor vacío" + regenerate_key: "Regenerar llave" + no_key: "sin valor" + generate_key: "Generar llave de API" + key_generated: "Llave generada" + key_cleared: "valor borrado" + shipment: + cannot_ready: "No se puede completar envío" + invalid_taxonomy_id: "El identificador de taxonomía es inválido." From d0c797b797bcf25710c49c656f912d69bd7918d2 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Sun, 12 Apr 2020 07:12:21 +1000 Subject: [PATCH 103/166] Updating translations for config/locales/es_CR.yml --- config/locales/es_CR.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index 845b8838c2..d88ff9975f 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -10,12 +10,12 @@ es_CR: completed_at: Completado en number: Número state: Provincia - email: E-mail del consumidor + email: e-mail de la consumidora spree/payment: amount: Cantidad spree/product: primary_taxon: "categoría del producto" - supplier: "Proveedora" + supplier: "Proveedor" shipping_category_id: "Categoría de envío" variant_unit: "Unidad Variante" variant_unit_name: "Nombre de la unidad de la variante" From 7341912390fc977bb8135cbe5e42eaa63ee3c8d4 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Sun, 12 Apr 2020 07:14:21 +1000 Subject: [PATCH 104/166] Updating translations for config/locales/pt_BR.yml --- config/locales/pt_BR.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 158198a36d..588f9cf757 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -19,6 +19,8 @@ pt_BR: shipping_category_id: "Tipos de Envio" variant_unit: "Unidade variante" variant_unit_name: "Nome da unidade variante" + spree/credit_card: + base: "Cartão de Crédito" order_cycle: orders_close_at: Dia de fechamento errors: @@ -29,6 +31,10 @@ pt_BR: taken: "Já existe uma conta para este e-mail. Por favor, faça login ou redefina sua senha." spree/order: no_card: Não há cartões de crédito válidos disponíveis + spree/credit_card: + attributes: + base: + card_expired: "expirou" order_cycle: attributes: orders_close_at: From 9fa892346e92eb376da647e6a1628e70ea9f4fdc Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Mon, 13 Apr 2020 10:30:00 +1000 Subject: [PATCH 105/166] Updating translations for config/locales/es_CR.yml --- config/locales/es_CR.yml | 234 +++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index d88ff9975f..f3d0609a9a 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -10,11 +10,11 @@ es_CR: completed_at: Completado en number: Número state: Provincia - email: e-mail de la consumidora + email: Correo electrónico del cliente spree/payment: amount: Cantidad spree/product: - primary_taxon: "categoría del producto" + primary_taxon: "Categoría del producto" supplier: "Proveedor" shipping_category_id: "Categoría de envío" variant_unit: "Unidad Variante" @@ -28,9 +28,9 @@ es_CR: spree/user: attributes: email: - taken: "Ya existe una cuenta con este email. Inicie sesión o restablezca tu contraseña." + taken: "Ya existe una cuenta con este correo electrónico. Inicie sesión o restablezca tu contraseña." spree/order: - no_card: No hay tarjetas de crédito autorizadas disponibles para cargar + no_card: No hay tarjetas de crédito autorizadas disponibles para realizar el cargo spree/credit_card: attributes: base: @@ -41,20 +41,20 @@ es_CR: after_orders_open_at: debe ser después de la fecha de apertura variant_override: count_on_hand: - using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de estoc de la productora" - on_demand_but_count_on_hand_set: "debe estar en blanco si está bajo demanda" - limited_stock_but_no_count_on_hand: "se debe especificar porque se ha definido estoc limitado" + using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de inventario de la productora" + on_demand_but_count_on_hand_set: "debe estar en blanco si es bajo demanda" + limited_stock_but_no_count_on_hand: "se debe especificar porque se ha definido un inventario limitado" activemodel: attributes: order_management/reports/enterprise_fee_summary/parameters: start_at: "Inicio" end_at: "Final" - distributor_ids: "Hubs" + distributor_ids: "Centros de acopio" producer_ids: "Productoras" order_cycle_ids: "Ciclos de Pedido" enterprise_fee_ids: "Nombres de las comisiones" shipping_method_ids: "Métodos de envío" - payment_method_ids: "Métodos de Pago" + payment_method_ids: "Métodos de pago" errors: messages: inclusion: "no está incluido en la lista" @@ -62,27 +62,27 @@ es_CR: order_management/subscriptions/validator: attributes: subscription_line_items: - at_least_one_product: "^Por favor agrega al menos un producto" - not_available: "^%{name} no está disponible en el programa seleccionado" + at_least_one_product: "^Por favor, agregue al menos un producto" + not_available: "^%{name} no está disponible en el horario seleccionado" ends_at: - after_begins_at: "debe ser después comienza en" + after_begins_at: "debe ser después del inicio en" customer: does_not_belong_to_shop: "no pertenece a %{shop}" schedule: - not_coordinated_by_shop: "no está coordinado por %{shop}" + not_coordinated_by_shop: "no es coordinado por %{shop}" payment_method: not_available_to_shop: "no está disponible para %{shop}" - invalid_type: "El método debe ser Cash o Stripe" - charges_not_allowed: "^ Los cargos de la tarjeta de crédito no estan permitidos para esta consumidora" - no_default_card: "^ Ninguna tarjeta predeterminada disponible para esta consumidora" + invalid_type: "El método debe ser en efectivo o Stripe" + charges_not_allowed: "^Los cargos de la tarjeta de crédito no están permitidos para este cliente" + no_default_card: "^No hay una tarjeta predeterminada disponible para este cliente" shipping_method: not_available_to_shop: "no está disponible para %{shop}" devise: confirmations: - send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + send_instructions: "En unos minutos recibirá un correo electrónico con instrucciones sobre cómo confirmar su cuenta." failed_to_send: "Se produjo un error al enviar su correo electrónico de confirmación." resend_confirmation_email: "Reenviar el correo electrónico de confirmación." - confirmed: "¡Gracias por confirmar tu correo electrónico! Ahora puedes iniciar sesión." + confirmed: "¡Gracias por confirmar su correo electrónico! Ahora puede iniciar sesión." not_confirmed: "Su dirección de correo electrónico no pudo ser confirmada. Tal vez ya has completado este paso?" user_confirmations: spree_user: @@ -124,7 +124,7 @@ es_CR: email_welcome: "Bienvenido" email_registered: "ahora es parte de" email_userguide_html: "La Guía de Usuario con soporte detallado para configurar su Productora o Grupo de Consumo está aquí: %{link}" - userguide: "Guía de usuario de Open Food Network" + userguide: "Guía de usuario de La Feria" email_admin_html: "Puede administrar su cuenta iniciando sesión en %{link} o haciendo clic en el engrane arriba a la derecha de la página de inicio, y seleccionando Administración." admin_panel: "Panel de administración" email_community_html: "También tenemos un foro en líea para la discusión comunal relacionada con el programa OFN y los retos únicos del funcionamiento de una organización de alimentación. Lo invitamos a unirse. Estamos evolucionando de forma constante y su aporte en este formo le dará forma a lo que pase luego. %{link}" @@ -133,14 +133,14 @@ es_CR: subject: "%{enterprise} te ha invitado a ser administrador" producer_mailer: order_cycle: - subject: "Informe Ciclo de Pedido para %{producer}" + subject: "Reporte de Ciclo de Pedido para %{producer}" shipment_mailer: shipped_email: - dear_customer: "Estimada consumidora," - instructions: "Tu pedido ha sido enviado" + dear_customer: "Estimado cliente," + instructions: "Su pedido ha sido enviado" shipment_summary: "Resumen de envío" subject: "Notificación de envío" - thanks: "Gracias por hacer negocios." + thanks: "Gracias por su negocio." track_information: "Información de seguimiento: %{tracking}" track_link: "Enlace de seguimiento: %{url}" subscription_mailer: @@ -157,15 +157,15 @@ es_CR: success_zero: De estos, ninguno fue procesado. success_some: De estos, %{count} se procesaron con éxito. success_all: Todos fueron procesados ​​con éxito. - issues: Los detalles de los problemas encontrados se proporcionan a continuación. + issues: Los detalles de los problemas encontrados se mostrarán a continuación. summary_detail: no_message_provided: No hay mensajes de error changes: - title: Insufficient Stock (%{count} pedidos) - explainer: Estos pedidos se procesaron pero no se dispuso de existencias suficientes para algunos artículos solicitados + title: Inventario insuficiente (%{count} pedidos) + explainer: Estos pedidos se procesaron pero no había suficiente inventario disponible para algunos artículos solicitados. empty: - title: Sin stock (%{count} pedidos) - explainer: Estas órdenes no se pudieron procesar porque no había existencias disponibles para los artículos solicitados + title: Sin inventario (%{count} pedidos) + explainer: Estas órdenes no se pudieron procesar porque no había inventario disponibles para los artículos solicitados complete: title: Ya procesado (%{count} pedidos) explainer: Estas órdenes ya estaban marcadas como completas y, por lo tanto, no se modificaron @@ -194,7 +194,7 @@ es_CR: edit_order: "Editar pedido" ship_order: "Enviar pedido" cancel_order: "Cancelar pedido" - confirm_send_invoice: "Una factura para esta orde se envió al cliente. ¿Está seguro que quiere continuar?" + confirm_send_invoice: "Al cliente se enviará una factura por este pedido. ¿Desea continuar?" confirm_resend_order_confirmation: "¿Estás seguro que quieres reenviar el correo de confirmación del pedido?" must_have_valid_business_number: "%{enterprise_name} debe tener un NIF válido antes de que las facturas se puedan enviar." invoice: "Factura" @@ -206,7 +206,7 @@ es_CR: ship_address: Dirección de envío sort_order_cycles_on_shopfront_by: "Ordenar Ciclos de Pedidos en Tienda por" required_fields: Los campos obligatorios se indican con un asterisco - select_continue: Selecciona y Continua + select_continue: Seleccione y Continue remove: Eliminar or: o collapse_all: Contraer todos @@ -222,7 +222,7 @@ es_CR: bulk_order_management: Gestión de pedidos en bloque enterprises: Organizaciones enterprise_groups: Redes - reports: Informes + reports: Reportes variant_overrides: Inventario import: Importar spree_products: Productos Spree @@ -279,7 +279,7 @@ es_CR: admin: begins_at: Empieza en begins_on: Comienza en - customer: Consumidora + customer: Cliente date: Fecha email: Email ends_at: Termina en @@ -331,8 +331,8 @@ es_CR: tag_has_rules: "Reglas existentes para esta etiqueta: %{num}" has_one_rule: "Tiene una regla" has_n_rules: "Tiene %{num} reglas" - unsaved_confirm_leave: "Has cambios sin guardar en esta página ¿Continuar sin guardar?" - unsaved_changes: "Tienes cambios sin guardar" + unsaved_confirm_leave: "Hay cambios sin guardar en esta página ¿Desea continuar?" + unsaved_changes: "Tiene cambios sin guardar" shopfront_settings: embedded_shopfront_settings: "Configuración de la tienda integrada" enable_embedded_shopfronts: "Habilitar tiendas integradas" @@ -371,7 +371,7 @@ es_CR: config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." customers: index: - new_customer: "Nuevo Consumidor" + new_customer: "Nuevo Cliente" code: Código duplicate_code: "Este código ya se ha usado." bill_address: "Dirección de Facturación" @@ -389,14 +389,14 @@ es_CR: search_by_email: "Buscar por email/código" guest_label: 'Hacer pedido como invitado' destroy: - has_associated_orders: 'Se ha producido un error en la eliminación: la consumidora tiene pedidos asociados en su tienda.' + has_associated_orders: 'Error al eliminar: el cliente tiene pedidos asociados a su tienda.' contents: edit: title: Contenido header: Encabezamiento home_page: Página principal producer_signup_page: Página de registro del productor - hub_signup_page: Página de registro del Grupo + hub_signup_page: 'Página para registro del centro de acopio ' group_signup_page: Página de registro de grupo main_links: Enlaces al menú principal footer_and_external_links: Pie de página y enlaces externos @@ -740,7 +740,7 @@ es_CR: title: Conectar con Stripe part1: Stripe es un servicio de pagos que permite a las tiendas aceptar pagos con tarjeta de crédito de las consumidoras. part2: Para usar esta función, debes conectar tu cuenta Stripe con OFN. Al hacer clic en 'Acepto' a continuación, se redireccionará al sitio web de Stripe donde puedes conectar una cuenta de Stripe existente o crear una nueva si aún no la tienes. - part3: Esto permitirá que Open Food Network acepte pagos con tarjeta de crédito de los clientes en tu nombre. Ten en cuenta que deberás mantener tu propia cuenta de Stripe, pagar las tarifas de Stripe y gestionar los reembolsos y el servicio al cliente. + part3: Esto permitirá que Open Food Network acepte pagos con tarjeta de crédito de los clientes en su nombre. Tenga en cuenta que deberá mantener su propia cuenta de Stripe, pagar las tarifas de Stripe y gestionar los reembolsos y el servicio al cliente por usted mismo. i_agree: Estoy de acuerdo cancel: Cancelar tag_rules: @@ -796,13 +796,13 @@ es_CR: sell_your_produce: Vende tu propia producción producer_shop_description_text: Venda sus productos directamente a los clientes a través de su propia tienda. producer_shop_description_text2: Una tienda de productora es para vender sus productos solamente, si quiere vender productos de otros productores, seleccione "Grupo de Productoras" - producer_hub: Grupo + producer_hub: Centro de acopio producer_hub_text: Vende tu propia producción y la de otros producer_hub_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos tuyos o de otras organizaciones y véndelo a través de tu tienda en Open Food Network. profile: Solo perfil get_listing: Obtener un listado profile_description_text: La gente podrá encontrarte y ponerse en contacto contigo en Open Food Network. Su organización será visible en el mapa y se podrá buscar en los listados. - hub_shop: Tienda + hub_shop: Tienda del centro de acopio hub_shop_text: Vender la producción de otros hub_shop_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos de otras organizaciones y véndelo a través de tu tienda en Open Food Network. choose_option: Por favor, elija una de las opciones anteriores. @@ -885,7 +885,7 @@ es_CR: incoming: "2. Productos entrantes" outgoing: "3. Productos salientes" exchange_form: - pickup_time_tip: Cuando los pedidos de este ciclo de pedido estarán listos para la consumidora + pickup_time_tip: Cuándo estarán listos los pedidos de este ciclo de pedido para los clientes pickup_instructions_placeholder: "Instrucciones de recogida" pickup_instructions_tip: Estas instrucciones se muestran a las consumidoras después de completar un pedido. pickup_time_placeholder: "Listo para ( Fecha / Hora)" @@ -937,7 +937,7 @@ es_CR: simple_form: ready_for: Listo para ready_for_placeholder: Fecha / hora - customer_instructions: Instrucciones del Consumidor + customer_instructions: Instrucciones del cliente customer_instructions_placeholder: Notas de la recogida o entrega products: Productos fees: Comisiones @@ -980,29 +980,29 @@ es_CR: supplier_totals: Totales de proveedores del Ciclo de Pedido supplier_totals_by_distributor: Totales de proveedores por Distribuidor del Ciclo de pedidos totals_by_supplier: Totales del distribuidor por proveedor del Ciclos de Pedido  - customer_totals: Totales de los consumidores del Ciclo de Pedido  + customer_totals: Totales de clientes del Ciclo de Pedido all_products: Todos los productos inventory: Inventario (disponible) lettuce_share: LettuceShare mailing_list: Lista de correo addresses: Direcciones - payment_methods: Informe de los métodos de pago - delivery: Informe de entrega + payment_methods: Reporte de los métodos de pago + delivery: Reporte de entrega tax_types: Tipos de impuestos tax_rates: '% Impuestos' - pack_by_customer: Pack por Consumidor + pack_by_customer: Paquete por cliente pack_by_supplier: Pack por proveedor orders_and_distributors: name: Pedidos y Distribuidores description: Pedidos con detalles de distribuidor bulk_coop: name: Bulk Co-Op - description: Informes para pedidos de Bulk Co-Op + description: Reporte para pedidos de Bulk Co-Op payments: - name: Informes de pago - description: Informes de pagos + name: Reportes de pago + description: Reportes de pagos orders_and_fulfillment: - name: Informes de Pedidos & Repartos + name: Reportes de Pedidos y Repartos customers: name: Consumidoras products_and_inventory: @@ -1018,7 +1018,7 @@ es_CR: name: Facturas Xero description: Facturas para la importación en Xero packing: - name: Informes de empaquetado + name: Reportes de empaquetado enterprise_fee_summary: name: "Resumen de las comisiones de la organización" description: "Resumen de las comisiones de la organización recolectadas" @@ -1067,9 +1067,9 @@ es_CR: invalid_error: Ups! Por favor complete todos los campos requeridos ... allowed_payment_method_types_tip: Solo se pueden usar métodos de pago en efectivo y Stripe en este momento credit_card: Tarjeta de crédito - charges_not_allowed: Los cargos no están permitidos para esta consumidora - no_default_card: La consumidora no tiene tarjetas disponibles para cargar - card_ok: La consumidora tiene una tarjeta disponible para cargar + charges_not_allowed: Los cargos no están permitidos para este cliente + no_default_card: El cliente no tiene tarjetas disponibles para el cobro + card_ok: El cliente tiene una tarjeta disponible para el cobro begins_at_placeholder: "Seleccione una fecha" ends_at_placeholder: "Opcional" loading_flash: @@ -1085,7 +1085,7 @@ es_CR: saved: "GUARDADO" product_already_in_order: Este producto ya ha sido agregado a la orden. Por favor edite la cantidad directamente. stock: - insufficient_stock: "Stock disponible insuficiente" + insufficient_stock: "Inventario insuficiente" out_of_stock: "Agotado" orders: number: Número @@ -1094,9 +1094,9 @@ es_CR: cancel_failure_msg: "Lo sentimos, ¡la cancelación falló!" confirm_pause_msg: "¿Seguro que quieres pausar esta suscripción?" pause_failure_msg: "Lo sentimos, pausar falló!" - confirm_unpause_msg: "Si tiene un ciclo de pedido abierto en la programación de esta suscripción, se creará un pedido para esta consumidora. ¿Estás seguro de que deseas anular la pausa de esta suscripción?" + confirm_unpause_msg: "Si tiene un ciclo de pedido abierto en el horario de esta suscripción, se creará un pedido para este cliente. ¿Estás seguro de que deseas anular la pausa de esta suscripción?" unpause_failure_msg: "Lo sentimos, ¡no se pudo reanudar!" - confirm_cancel_open_orders_msg: "Algunas órdenes para esta suscripción están actualmente abiertas. El cliente ya ha sido notificado de que se realizará el pedido. ¿Desea cancelar estos pedidos o conservarlos?" + confirm_cancel_open_orders_msg: "Algunos pedidos de esta suscripción están actualmente abiertos. El cliente ya ha sido notificado de que se realizará el pedido. ¿Desea cancelar estos pedidos o conservarlos?" resume_canceled_orders_msg: "Algunos pedidos de esta suscripción se pueden reanudar en este momento. Puede reanudarlos desde el menú desplegable de pedidos." yes_cancel_them: Cancelarlos no_keep_them: Guárdalos @@ -1170,7 +1170,7 @@ es_CR: signup: "Regístrate" contact: "contactar" require_customer_login: "Sólo las consumidoras aprobadas pueden acceder a esta tienda." - require_login_html: "Si ya eres una consumidora aprobado, %{login} o %{signup} para continuar. ¿Quieres empezar a comprar aquí? Por favor, %{contact} %{enterprise} y pide tu adhesión." + require_login_html: "Si ya es un cliente aprobado, %{login} o %{signup} para continuar. ¿Quiere empezar a comprar aquí? Por favor, %{contact} %{enterprise} y pida su adhesión." require_customer_html: "Si desea comenzar a comprar aquí, por favor %{contact} %{enterprise} para preguntar acerca de incorporación." card_could_not_be_updated: La tarjeta no se pudo actualizar card_could_not_be_saved: la tarjeta no se pudo guardar @@ -1208,7 +1208,7 @@ es_CR: menu_4_title: "Redes" menu_4_url: "/groups" menu_5_title: "Acerca de" - menu_5_url: "http://katuma.org/" + menu_5_url: "https://laferia.cr/" menu_6_title: "Conectar" menu_6_url: " " menu_7_title: "Aprender" @@ -1241,7 +1241,7 @@ es_CR: city: Ciudad city_placeholder: ej. Barcelona postcode: Código postal - postcode_placeholder: ej. 08025 + postcode_placeholder: ej. 20307 suburb: Barrio state: Estado country: País @@ -1289,9 +1289,9 @@ es_CR: card_masked_digit: "X" card_expiry_abbreviation: "Exp" new_credit_card: "Nueva tarjeta de crédito" - my_credit_cards: Mis tarjetas de credito + my_credit_cards: Mis tarjetas de crédito add_new_credit_card: Añadir nueva tarjeta de crédito - saved_cards: Tarjetas guardadas + saved_cards: Tarjetas de crédito guardadas add_a_card: Añade una tarjeta add_card: Añadir tarjeta you_have_no_saved_cards: Aún no has guardado ninguna tarjeta. @@ -1300,11 +1300,11 @@ es_CR: card_could_not_be_removed: Lo sentimos, la tarjeta no se pudo quitar invalid_credit_card: "Tarjeta de crédito inválida" ie_warning_headline: "Su navegador está desactualizado :-(" - ie_warning_text: "Para la mejor esperiencia de Open Food Network, recomendamos actualizar su navegador:" + ie_warning_text: "Para una mejor experiencia utilizando La Feria, le recomendamos actualizar su navegador:" ie_warning_chrome: Descargar Chrome ie_warning_firefox: Descargar Firefox ie_warning_ie: Actualizar Internet Explorer - ie_warning_other: "¿No puede actualizar su navegador? Pruebe Open Food Network en su teléfono :-)" + ie_warning_other: "¿No puede actualizar su navegador? Pruebe usar La Feria en su teléfono :-)" legal: cookies_policy: header: "Cómo utilizamos las cookies" @@ -1413,7 +1413,7 @@ es_CR: order_total_price: Total order_includes_tax: (incluye impuesto) order_payment_paypal_successful: Su pago a través de PayPal ha sido procesado con éxito. - order_hub_info: Información del Grupo + order_hub_info: Información del centro de acopio order_back_to_store: Volver a la Tienda order_back_to_cart: Volver al Carrito bom_tip: "Usa esta página para alterar la cantidad del producto en varios pedidos a la vez. Los productos pueden ser eliminados de los pedidos si es necesario. " @@ -1483,7 +1483,7 @@ es_CR: email_signup_welcome: "Bienvenido a %{sitename}!" email_signup_confirmed_email: "Gracias por confirmar su email." email_signup_shop_html: "Ahora puedes iniciar sesión en %{link}." - email_signup_text: "Gracias por unirte a la red. Si eres un comprador, ¡esperamos presentarte a muchos agricultores, grupos de consumo y deliciosa comida! Si eres una productora o formas parte de una organización de alimentos, estamos emocionados de que formes parte de la red." + email_signup_text: "Gracias por unirse a la red. Si es un comprador, ¡esperamos presentarle a muchos agricultores, grupos de consumo y comida deliciosa! Si eres una productora o formas parte de una organización de alimentos, estamos emocionados de que formes parte de la red." email_signup_help_html: "Agradecemos todas tus preguntas y feedback; puedes usar el botón de Enviar Feedback en el sitio o escribir un email a %{email}" invite_email: greeting: "¡Hola!" @@ -1604,7 +1604,7 @@ es_CR: modal_how_more_explained: "Si quieres saber más acerca de Open Food Network, cómo trabajamos y nos organizamos, visita:" modal_producers: "Productoras" modal_producers_explained: "Nuestras productoras hacen todos los deliciosos alimentos que puedes comprar en Open Food Network." - producers_about: Acerca de nosotras + producers_about: Acerca de nosotros producers_buy: Comprar producers_contact: Contacto producers_contact_phone: Llamar @@ -1750,7 +1750,7 @@ es_CR: choose_password: "Escoje una contraseña" confirm_password: "Confirmar contraseña" action_signup: "Registrarse ahora" - forgot_password: "¿No recuerdas tu contraseña?" + forgot_password: "¿Se le olvidó su contraseña?" password_reset_sent: "¡Le enviamos un correo electrónico con instrucciones para restaurar la contraseña!" reset_password: "Restaurar contraseña" update_and_recalculate_fees: "Actualizar y recalcular comisiones" @@ -1855,7 +1855,7 @@ es_CR: title: "Social" enterprise_final_step: "¡Paso final!" enterprise_social_text: "¿Cómo puede la gente encontrar a %{enterprise} en línea?" - website: "Website" + website: "Sitio web" website_placeholder: "eg. openfoodnetwork.org.au" facebook: "Facebook" facebook_placeholder: "eg. www.facebook.com/NombreDePáginaAquí" @@ -1910,7 +1910,7 @@ es_CR: ok: OK not_visible: no visible you_have_no_orders_yet: "No tienes pedidos todavía" - show_only_complete_orders: "Mostrar solo pedidos completos" + show_only_complete_orders: "Mostrar solo pedidos completados" successfully_created: '%{resource} se ha creado exitosamente!' successfully_removed: '%{resource} ha sido eliminado exitosamente!' successfully_updated: '%{resource} ha sido actualizado exitosamente!' @@ -2056,7 +2056,7 @@ es_CR: admin_share_city: "Ciudad" admin_share_zipcode: "Código Postal" admin_share_country: "País" - admin_share_state: "Estado" + admin_share_state: "Provincia" hub_sidebar_hubs: "Hubs" hub_sidebar_none_available: "Ninguno Disponible" hub_sidebar_manage: "Gestionar" @@ -2066,10 +2066,10 @@ es_CR: report_customers_distributor: "Distribuidor" report_customers_supplier: "Proveedora" report_customers_cycle: "Ciclo de Pedido" - report_customers_type: "Tipo de Informe" + report_customers_type: "Tipo de Reporte" report_customers_csv: "Descargar como CSV" report_producers: "Productoras:" - report_type: "Tipo de Informe:" + report_type: "Tipo de Reporte:" report_hubs: "Hubs: " report_payment: "Métodos de Pago:" report_distributor: "Distribuidora:" @@ -2131,8 +2131,8 @@ es_CR: report_header_tax_on_fees: "Impuesto sobre las comisiones (%{currency_symbol})" report_header_total_tax: "Total Impuestos (%{currency_symbol})" report_header_enterprise: Organización - report_header_customer: Consumidora - report_header_customer_code: Código de consumidora + report_header_customer: Cliente + report_header_customer_code: Código del cliente report_header_product: Producto report_header_product_properties: Propiedades del producto report_header_quantity: Cantidad @@ -2176,10 +2176,10 @@ es_CR: report_header_order_id: ID de Pedido report_header_item_name: Nombre del artículo report_header_temp_controlled_items: ¿Artículos de temperatura controlada? - report_header_customer_name: Nombre de la consumidora - report_header_customer_email: Correo electrónico de la consumidora - report_header_customer_phone: Teléfono de la Consumidora - report_header_customer_city: Ciudad de la Consumidora + report_header_customer_name: Nombre del cliente + report_header_customer_email: Correo electrónico del cliente + report_header_customer_phone: Teléfono del cliente + report_header_customer_city: Ciudad del cliente report_header_payment_state: Estado del pago report_header_payment_type: Tipo de pago report_header_item_price: "Artículo (%{currency})" @@ -2261,7 +2261,7 @@ es_CR: validation_msg_relationship_already_established: "^Esta relación ya existe." validation_msg_at_least_one_hub: "^Al menos se debe seleccionar un grupo de consumo" validation_msg_tax_category_cant_be_blank: "^La Categoría del Impuesto no puede estar vacía" - validation_msg_is_associated_with_an_exising_customer: "Está asociado con un consumidor existente" + validation_msg_is_associated_with_an_exising_customer: "está asociado con un cliente existente" content_configuration_pricing_table: "(TODO: tabla de precios)" content_configuration_case_studies: "(TODO: Casos de Estudio)" content_configuration_detail: "(TODO: Detalle)" @@ -2348,9 +2348,9 @@ es_CR: particulares. customer_tagged_rules: "Reglas de \"clientes etiquetados ...\"" customer_tagged_rules_text: > - Al crear reglas relacionadas con una etiqueta de consumidor específica, - puedes anular el comportamiento predeterminado (ya sea para mostrar - u ocultar elementos) para los consumidores con la etiqueta concreta. + Al crear reglas relacionadas con una etiqueta de cliente específica, + puede anular el comportamiento predeterminado (ya sea para mostrar u + ocultar elementos) a cliente con dicha etiqueta. panels: save: GUARDAR saved: GUARDADO @@ -2530,9 +2530,9 @@ es_CR: selected: "Seleccionado" customers: index: - add_customer: "Añadir Consumidor" - add_a_new_customer_for: "Añadir un nuevo consumidor para %{shop_name}" - customer_placeholder: "customer@example.org" + add_customer: "Añadir cliente" + add_a_new_customer_for: "Añadir un nuevo cliente para %{shop_name}" + customer_placeholder: "cliente@ejemplo.org" valid_email_error: "Introduce un email válido" subscriptions: error_saving: "Error al salvar suscripción " @@ -2583,7 +2583,7 @@ es_CR: edit_profile: "Editar perfil" add_products_to_inventory: "Añadir productos al inventario" resources: - could_not_delete_customer: 'No se pudo eliminar al consumidor' + could_not_delete_customer: 'No se pudo eliminar al cliente' product_import: confirmation: | Esto establecerá el nivel de stock a cero en todos los productos para este @@ -2691,7 +2691,7 @@ es_CR: reports: enterprise_fee_summary: date_end_before_start_error: "debe ser después del comienzo" - parameter_not_allowed_error: "No está autorizado a usar uno o más filtros seleccionados para este informe." + parameter_not_allowed_error: "Usted no está autorizado a usar uno o más filtros seleccionados para este reporte." fee_calculated_on_transfer_through_all: "Todos" fee_calculated_on_transfer_through_entire_orders: "Pedidos completos a través de %{distributor}" tax_category_various: "Varios" @@ -2710,7 +2710,7 @@ es_CR: fee_type: "Tipo de Comisión" enterprise_name: "Propietario de la organización" fee_name: "Nombre de la comisión" - customer_name: "Consumidora" + customer_name: "Cliente" fee_placement: "Asignación de comisiones" fee_calculated_on_transfer_through_name: "Cálculo de comisiones a través de transferencias" tax_category_name: "Categoría de impuestos" @@ -2720,16 +2720,16 @@ es_CR: fee_type: "Tipo de Comisión" enterprise_name: "Propietario de la organización" fee_name: "Nombre de la comisión" - customer_name: "Consumidora" + customer_name: "Cliente" fee_placement: "Asignación de comisiones" fee_calculated_on_transfer_through_name: "Cálculo de comisiones a través de transferencias" tax_category_name: "Categoría de impuestos" total_amount: "€€ SUM" - invalid_filter_parameters: "Los filtros que seleccionó para este informe no son válidos." + invalid_filter_parameters: "Los filtros que seleccionó para este reporte no son válidos." order: "Pedido" distribution: "Distribución" order_details: "Detalles del pedido" - customer_details: "Detalles de la consumidora" + customer_details: "Detalles del cliente" adjustments: "Ajustes" payments: "Pagos" payment: "Pago" @@ -2762,7 +2762,7 @@ es_CR: back_to_orders_list: Volver a la lista de pedidos return_authorizations: Autorizaciones de devolución cannot_create_returns: No se pueden crear devoluciones ya que este pedido no tiene unidades enviadas. - select_stock: "Seleccionar stock" + select_stock: "Seleccionar inventario" location: "Ubicación" count_on_hand: "Cuenta de disponibilidad" quantity: "Cantidad" @@ -2773,12 +2773,12 @@ es_CR: edit: "Editar" split: "División" delete: "Borrar" - cannot_set_shipping_method_without_address: "No se puede establecer el método de envío hasta que se proporcionen los detalles de la consumidora." + cannot_set_shipping_method_without_address: "No se puede establecer el método de envío hasta que se proporcionen los detalles del cliente." no_tracking_present: "No se han proporcionado detalles de seguimiento." order_total: "Total del pedido" - customer_details: "Detalles de la consumidora" - customer_search: "Búsqueda de consumidores" - choose_a_customer: "Elige una consumidora " + customer_details: "Detalles del cliente" + customer_search: "Búsqueda de clientes" + choose_a_customer: "Elija un cliente " account: "Cuenta" billing_address: "Dirección de facturación" shipping_address: "Dirección de envío" @@ -2795,7 +2795,7 @@ es_CR: use_billing_address: "Utilice la dirección de facturación" adjustments: "Ajustes" continue: "Continuar" - fill_in_customer_info: "Por favor complete la información de la consumidora" + fill_in_customer_info: "Por favor complete la información del cliente" new_payment: "Nuevo pago" capture: "Captura" void: "Vacío" @@ -2948,7 +2948,7 @@ es_CR: option_types: "Tipos de opciones" properties: "Propiedades" variant_overrides: "Inventario" - reports: "Informes" + reports: "Reportes" configuration: "Configuración" users: "Usuarias" roles: "Roles" @@ -3031,7 +3031,7 @@ es_CR: completed_at: "Completado en" number: "Número" state: "Provincia" - email: "E-mail del consumidor" + email: "Correo electrónico del cliente" invoice: issued_on: "Emitido el" tax_invoice: "FACTURA DE IMPUESTOS" @@ -3166,15 +3166,15 @@ es_CR: bulk_coop_supplier_report: 'Bulk Co-op - Totales por Proveedor' bulk_coop_allocation: 'Bulk Co-op - Asignación' bulk_coop_packing_sheets: 'Bulk Co-op - Hojas de Empaquetado' - bulk_coop_customer_payments: 'Bulk Co-op - Pagos de las Consumidoras' + bulk_coop_customer_payments: 'Bulk Co-op - Pagos de clientes' enterprise_fee_summaries: filters: date_range: "Rango de fechas" report_format_csv: "Descargar como CSV" - generate_report: "Generar informe" + generate_report: "Generar reporte" report: none: "Ninguno" - select_and_search: "Seleccione los filtros y haga clic en GENERAR INFORME para acceder a sus datos." + select_and_search: "Seleccione los filtros y haga clic en GENERAR REPORTE para acceder a sus datos." users: index: listing_users: "Listado de Usuarias" @@ -3252,7 +3252,7 @@ es_CR: bought: item: "Pedido en este ciclo de pedido" line_item: - insufficient_stock: "Stock insuficiente disponible, solo quedan %{on_hand}" + insufficient_stock: "Inventario insuficiente, solo quedan %{on_hand}" out_of_stock: "Agotado" unavailable_item: "actualmente no disponible" shipment_states: @@ -3312,8 +3312,8 @@ es_CR: link_text: > Si has solicitado esta acción haz click en el siguiente enlace: issue_text: | - Si el enlace no funciona prueba a copiarlo y pegarlo en tu navegador. - Si los problemas continúan no dudes en contactarnos. + Si el enlace anterior no funciona pruebe con copiarlo y pegarlo en su navegador. + Si los problemas continúan no dude en contactarnos. confirmation_instructions: subject: Por favor, confirma tu cuenta de OFN users: @@ -3354,26 +3354,26 @@ es_CR: delete?: ¿Borrar? cards: authorised_shops: Tiendas autorizadas - authorised_shops_popover: Esta es la lista de tiendas a las que se les permite cobrar a su tarjeta de crédito predeterminada por sus suscripciones (es decir, pedidos repetidos) que pueda tener. Los detalles de su tarjeta se mantendrán seguros y no se compartirán con los propietarios de las tiendas. Siempre se le notificará cuando se le cobra. + authorised_shops_popover: Esta es la lista de tiendas a las que se les permite cobrar a su tarjeta de crédito predeterminada por las suscripciones (como por ejemplo, pedidos repetidos) que pueda tener. Los detalles de su tarjeta se mantendrán seguros y no se compartirán con los propietarios de las tiendas. Siempre se le notificará cuando se le cobra. saved_cards_popover: Esta es la lista de tarjetas que ha optado por guardar para su uso posterior. Su "valor predeterminado" se seleccionará automáticamente al momento de realizar un pedido, y puede ser cobrado por cualquier tienda que tenga permitido hacerlo (ver a la derecha). authorised_shops: - shop_name: "Nombre de tienda" - allow_charges?: "¿Permitir cargos?" + shop_name: "Nombre de la tienda" + allow_charges?: "¿Permitir cobros?" localized_number: - invalid_format: tiene un formato invalido. Por favor introduzca un numero. + invalid_format: tiene un formato invalido. Por favor introduzca un número. api: - invalid_api_key: "La llave de API especificada (%{key}) es inválida." - unauthorized: "No tiene autorización para realizar esta acción." + invalid_api_key: "La llave de API utilizada (%{key}) es inválida." + unauthorized: "No está autorizado para realizar esta acción." invalid_resource: "Recurso inválido. Por favor corrija los errores e intente nuevamente." - resource_not_found: "El recurso que buscaba no puede ser encontrado." - access: "acceso al API" + resource_not_found: "El recurso que buscaba no fue encontrado." + access: "Acceso al API" key: "Llave" - clear_key: "valor vacío" + clear_key: "Borrar llave" regenerate_key: "Regenerar llave" - no_key: "sin valor" + no_key: "Sin llave" generate_key: "Generar llave de API" key_generated: "Llave generada" - key_cleared: "valor borrado" + key_cleared: "Llave borrada" shipment: cannot_ready: "No se puede completar envío" invalid_taxonomy_id: "El identificador de taxonomía es inválido." From 9a7e7821025f62215f8ff60f10fab7e31b75ca2c Mon Sep 17 00:00:00 2001 From: Rob H Date: Sat, 11 Apr 2020 17:33:16 +1000 Subject: [PATCH 106/166] Only load up variant overrides for relevant hubs --- .../orders_and_fulfillments_report.rb | 7 ++- .../reports/variant_overrides.rb | 14 +++-- .../reports/variant_overrides_spec.rb | 57 ++++++++++++++++--- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index bf7be98cbd..49414c72ef 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -51,7 +51,7 @@ module OpenFoodNetwork @variant_scopers_by_distributor_id[distributor_id] ||= OpenFoodNetwork::ScopeVariantToHub.new( distributor_id, - report_variant_overrides[distributor_id] + report_variant_overrides[distributor_id] || {}, ) end @@ -102,7 +102,10 @@ module OpenFoodNetwork def report_variant_overrides @report_variant_overrides ||= - Reports::VariantOverrides.new(order_permissions.visible_line_items).indexed + Reports::VariantOverrides.new( + line_items: order_permissions.visible_line_items, + distributor_ids: report_line_items.orders.result.select('DISTINCT distributor_id'), + ).indexed end end end diff --git a/lib/open_food_network/reports/variant_overrides.rb b/lib/open_food_network/reports/variant_overrides.rb index 2b2a02845b..28679e016c 100644 --- a/lib/open_food_network/reports/variant_overrides.rb +++ b/lib/open_food_network/reports/variant_overrides.rb @@ -3,8 +3,9 @@ module OpenFoodNetwork module Reports class VariantOverrides - def initialize(line_items) + def initialize(line_items:, distributor_ids:) @line_items = line_items + @distributor_ids = distributor_ids end def indexed @@ -15,11 +16,16 @@ module OpenFoodNetwork private - attr_reader :line_items + attr_reader :line_items, :distributor_ids def variant_overrides - VariantOverride.joins(:variant) - .where(spree_variants: { id: line_items.select(:variant_id) }) + VariantOverride + .joins(:variant) + .preload(:variant) + .where( + hub_id: distributor_ids, + variant_id: line_items.select(:variant_id) + ) end def hash_of_hashes diff --git a/spec/lib/open_food_network/reports/variant_overrides_spec.rb b/spec/lib/open_food_network/reports/variant_overrides_spec.rb index 684b79ae4e..b9c86bb95a 100644 --- a/spec/lib/open_food_network/reports/variant_overrides_spec.rb +++ b/spec/lib/open_food_network/reports/variant_overrides_spec.rb @@ -3,29 +3,70 @@ require 'open_food_network/reports/variant_overrides' module OpenFoodNetwork::Reports describe VariantOverrides do - subject(:variant_overrides) { described_class.new(order.line_items) } + subject(:variant_overrides) do + described_class.new( + line_items: order.line_items, + distributor_ids: [distributor.id], + ) + end let(:distributor) { create(:distributor_enterprise) } let(:order) do create(:completed_order_with_totals, line_items_count: 1, distributor: distributor) end - let(:variant) { order.line_items.first.variant } + let(:line_item) { order.line_items.first } let!(:variant_override) do create( :variant_override, - hub: distributor, - variant: variant, + hub: vo_distributor, + variant: vo_variant, ) end describe '#indexed' do let(:result) { variant_overrides.indexed } - it 'indexes variant override mappings by distributor id' do - expect(variant_overrides.indexed).to eq( - distributor.id => { variant => variant_override } - ) + context 'when variant overrides exist for variants of specified line items' do + let(:vo_variant) { line_item.variant } + + context 'when variant overrides apply to one of the specified distributors' do + let(:vo_distributor) { distributor } + + it 'they are included in the mapping' do + expect(result).to eq( + distributor.id => { line_item.variant => variant_override } + ) + end + end + + context 'when variant overrides don\'t apply to one of the specified distributors' do + let(:vo_distributor) { create(:distributor_enterprise) } + + it 'they are not included in the mapping' do + expect(result).to eq({}) + end + end + end + + context 'when variant overrides exist for other variants' do + let(:vo_variant) { create(:variant) } + + context 'when variant overrides apply to one of the specified distributors' do + let(:vo_distributor) { distributor } + + it 'they are not included in the mapping' do + expect(result).to eq({}) + end + end + + context 'when variant overrides don\'t apply to one of the specified distributors' do + let(:vo_distributor) { create(:distributor_enterprise) } + + it 'they are not included in the mapping' do + expect(result).to eq({}) + end + end end end end From 4a4173bdc08999a8e4ef6ebf3df2061b9de742de Mon Sep 17 00:00:00 2001 From: Rob H Date: Mon, 13 Apr 2020 21:54:10 +1000 Subject: [PATCH 107/166] Move VariantOverrides class to app/services --- app/services/variant_overrides.rb | 32 ++++++++ .../orders_and_fulfillments_report.rb | 3 +- .../reports/variant_overrides.rb | 36 --------- .../reports/variant_overrides_spec.rb | 73 ------------------- spec/services/variant_overrides_spec.rb | 70 ++++++++++++++++++ 5 files changed, 103 insertions(+), 111 deletions(-) create mode 100644 app/services/variant_overrides.rb delete mode 100644 lib/open_food_network/reports/variant_overrides.rb delete mode 100644 spec/lib/open_food_network/reports/variant_overrides_spec.rb create mode 100644 spec/services/variant_overrides_spec.rb diff --git a/app/services/variant_overrides.rb b/app/services/variant_overrides.rb new file mode 100644 index 0000000000..c33f67484d --- /dev/null +++ b/app/services/variant_overrides.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class VariantOverrides + def initialize(line_items:, distributor_ids:) + @line_items = line_items + @distributor_ids = distributor_ids + end + + def indexed + variant_overrides.each_with_object(hash_of_hashes) do |variant_override, indexed| + indexed[variant_override.hub_id][variant_override.variant] = variant_override + end + end + + private + + attr_reader :line_items, :distributor_ids + + def variant_overrides + VariantOverride + .joins(:variant) + .preload(:variant) + .where( + hub_id: distributor_ids, + variant_id: line_items.select(:variant_id) + ) + end + + def hash_of_hashes + Hash.new { |h, k| h[k] = {} } + end +end diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index 49414c72ef..9e724416c2 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -1,5 +1,4 @@ require "open_food_network/reports/line_items" -require "open_food_network/reports/variant_overrides" require "open_food_network/orders_and_fulfillments_report/supplier_totals_report" require "open_food_network/orders_and_fulfillments_report/supplier_totals_by_distributor_report" require "open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report" @@ -102,7 +101,7 @@ module OpenFoodNetwork def report_variant_overrides @report_variant_overrides ||= - Reports::VariantOverrides.new( + VariantOverrides.new( line_items: order_permissions.visible_line_items, distributor_ids: report_line_items.orders.result.select('DISTINCT distributor_id'), ).indexed diff --git a/lib/open_food_network/reports/variant_overrides.rb b/lib/open_food_network/reports/variant_overrides.rb deleted file mode 100644 index 28679e016c..0000000000 --- a/lib/open_food_network/reports/variant_overrides.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -module OpenFoodNetwork - module Reports - class VariantOverrides - def initialize(line_items:, distributor_ids:) - @line_items = line_items - @distributor_ids = distributor_ids - end - - def indexed - variant_overrides.each_with_object(hash_of_hashes) do |variant_override, indexed| - indexed[variant_override.hub_id][variant_override.variant] = variant_override - end - end - - private - - attr_reader :line_items, :distributor_ids - - def variant_overrides - VariantOverride - .joins(:variant) - .preload(:variant) - .where( - hub_id: distributor_ids, - variant_id: line_items.select(:variant_id) - ) - end - - def hash_of_hashes - Hash.new { |h, k| h[k] = {} } - end - end - end -end diff --git a/spec/lib/open_food_network/reports/variant_overrides_spec.rb b/spec/lib/open_food_network/reports/variant_overrides_spec.rb deleted file mode 100644 index b9c86bb95a..0000000000 --- a/spec/lib/open_food_network/reports/variant_overrides_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'spec_helper' -require 'open_food_network/reports/variant_overrides' - -module OpenFoodNetwork::Reports - describe VariantOverrides do - subject(:variant_overrides) do - described_class.new( - line_items: order.line_items, - distributor_ids: [distributor.id], - ) - end - - let(:distributor) { create(:distributor_enterprise) } - let(:order) do - create(:completed_order_with_totals, line_items_count: 1, - distributor: distributor) - end - let(:line_item) { order.line_items.first } - let!(:variant_override) do - create( - :variant_override, - hub: vo_distributor, - variant: vo_variant, - ) - end - - describe '#indexed' do - let(:result) { variant_overrides.indexed } - - context 'when variant overrides exist for variants of specified line items' do - let(:vo_variant) { line_item.variant } - - context 'when variant overrides apply to one of the specified distributors' do - let(:vo_distributor) { distributor } - - it 'they are included in the mapping' do - expect(result).to eq( - distributor.id => { line_item.variant => variant_override } - ) - end - end - - context 'when variant overrides don\'t apply to one of the specified distributors' do - let(:vo_distributor) { create(:distributor_enterprise) } - - it 'they are not included in the mapping' do - expect(result).to eq({}) - end - end - end - - context 'when variant overrides exist for other variants' do - let(:vo_variant) { create(:variant) } - - context 'when variant overrides apply to one of the specified distributors' do - let(:vo_distributor) { distributor } - - it 'they are not included in the mapping' do - expect(result).to eq({}) - end - end - - context 'when variant overrides don\'t apply to one of the specified distributors' do - let(:vo_distributor) { create(:distributor_enterprise) } - - it 'they are not included in the mapping' do - expect(result).to eq({}) - end - end - end - end - end -end diff --git a/spec/services/variant_overrides_spec.rb b/spec/services/variant_overrides_spec.rb new file mode 100644 index 0000000000..33c5b69363 --- /dev/null +++ b/spec/services/variant_overrides_spec.rb @@ -0,0 +1,70 @@ +require 'spec_helper' + +describe VariantOverrides do + subject(:variant_overrides) do + described_class.new( + line_items: order.line_items, + distributor_ids: [distributor.id], + ) + end + + let(:distributor) { create(:distributor_enterprise) } + let(:order) do + create(:completed_order_with_totals, line_items_count: 1, + distributor: distributor) + end + let(:line_item) { order.line_items.first } + let!(:variant_override) do + create( + :variant_override, + hub: vo_distributor, + variant: vo_variant, + ) + end + + describe '#indexed' do + let(:result) { variant_overrides.indexed } + + context 'when variant overrides exist for variants of specified line items' do + let(:vo_variant) { line_item.variant } + + context 'when variant overrides apply to one of the specified distributors' do + let(:vo_distributor) { distributor } + + it 'they are included in the mapping' do + expect(result).to eq( + distributor.id => { line_item.variant => variant_override } + ) + end + end + + context 'when variant overrides don\'t apply to one of the specified distributors' do + let(:vo_distributor) { create(:distributor_enterprise) } + + it 'they are not included in the mapping' do + expect(result).to eq({}) + end + end + end + + context 'when variant overrides exist for other variants' do + let(:vo_variant) { create(:variant) } + + context 'when variant overrides apply to one of the specified distributors' do + let(:vo_distributor) { distributor } + + it 'they are not included in the mapping' do + expect(result).to eq({}) + end + end + + context 'when variant overrides don\'t apply to one of the specified distributors' do + let(:vo_distributor) { create(:distributor_enterprise) } + + it 'they are not included in the mapping' do + expect(result).to eq({}) + end + end + end + end +end From 6820919552049ffef9c42e0c584f55bef08d1712 Mon Sep 17 00:00:00 2001 From: Rob H Date: Mon, 13 Apr 2020 21:56:37 +1000 Subject: [PATCH 108/166] Rename VariantOverrides class to VariantOverridesIndexed --- .../{variant_overrides.rb => variant_overrides_indexed.rb} | 2 +- lib/open_food_network/orders_and_fulfillments_report.rb | 2 +- ...iant_overrides_spec.rb => variant_overrides_indexed_spec.rb} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename app/services/{variant_overrides.rb => variant_overrides_indexed.rb} (95%) rename spec/services/{variant_overrides_spec.rb => variant_overrides_indexed_spec.rb} (98%) diff --git a/app/services/variant_overrides.rb b/app/services/variant_overrides_indexed.rb similarity index 95% rename from app/services/variant_overrides.rb rename to app/services/variant_overrides_indexed.rb index c33f67484d..1264f0bddd 100644 --- a/app/services/variant_overrides.rb +++ b/app/services/variant_overrides_indexed.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class VariantOverrides +class VariantOverridesIndexed def initialize(line_items:, distributor_ids:) @line_items = line_items @distributor_ids = distributor_ids diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index 9e724416c2..db039b515d 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -101,7 +101,7 @@ module OpenFoodNetwork def report_variant_overrides @report_variant_overrides ||= - VariantOverrides.new( + VariantOverridesIndexed.new( line_items: order_permissions.visible_line_items, distributor_ids: report_line_items.orders.result.select('DISTINCT distributor_id'), ).indexed diff --git a/spec/services/variant_overrides_spec.rb b/spec/services/variant_overrides_indexed_spec.rb similarity index 98% rename from spec/services/variant_overrides_spec.rb rename to spec/services/variant_overrides_indexed_spec.rb index 33c5b69363..fab68a0957 100644 --- a/spec/services/variant_overrides_spec.rb +++ b/spec/services/variant_overrides_indexed_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe VariantOverrides do +describe VariantOverridesIndexed do subject(:variant_overrides) do described_class.new( line_items: order.line_items, From dcdd3f24445d0a1113981c8d9b0133c28c863534 Mon Sep 17 00:00:00 2001 From: Rob H Date: Mon, 13 Apr 2020 22:11:58 +1000 Subject: [PATCH 109/166] Modify interface of VariantOverridesIndexed#indexed Stop using keyword args and accept variant_ids instead of line_items --- app/services/variant_overrides_indexed.rb | 8 ++++---- .../orders_and_fulfillments_report.rb | 4 ++-- .../variant_overrides_indexed_spec.rb | 19 +++++-------------- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/app/services/variant_overrides_indexed.rb b/app/services/variant_overrides_indexed.rb index 1264f0bddd..587699a519 100644 --- a/app/services/variant_overrides_indexed.rb +++ b/app/services/variant_overrides_indexed.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class VariantOverridesIndexed - def initialize(line_items:, distributor_ids:) - @line_items = line_items + def initialize(variant_ids, distributor_ids) + @variant_ids = variant_ids @distributor_ids = distributor_ids end @@ -14,7 +14,7 @@ class VariantOverridesIndexed private - attr_reader :line_items, :distributor_ids + attr_reader :variant_ids, :distributor_ids def variant_overrides VariantOverride @@ -22,7 +22,7 @@ class VariantOverridesIndexed .preload(:variant) .where( hub_id: distributor_ids, - variant_id: line_items.select(:variant_id) + variant_id: variant_ids, ) end diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index db039b515d..ae359aba19 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -102,8 +102,8 @@ module OpenFoodNetwork def report_variant_overrides @report_variant_overrides ||= VariantOverridesIndexed.new( - line_items: order_permissions.visible_line_items, - distributor_ids: report_line_items.orders.result.select('DISTINCT distributor_id'), + order_permissions.visible_line_items.select('DISTINCT variant_id'), + report_line_items.orders.result.select('DISTINCT distributor_id'), ).indexed end end diff --git a/spec/services/variant_overrides_indexed_spec.rb b/spec/services/variant_overrides_indexed_spec.rb index fab68a0957..15af405683 100644 --- a/spec/services/variant_overrides_indexed_spec.rb +++ b/spec/services/variant_overrides_indexed_spec.rb @@ -1,19 +1,10 @@ require 'spec_helper' describe VariantOverridesIndexed do - subject(:variant_overrides) do - described_class.new( - line_items: order.line_items, - distributor_ids: [distributor.id], - ) - end + subject(:variant_overrides) { described_class.new([variant.id],[distributor.id]) } let(:distributor) { create(:distributor_enterprise) } - let(:order) do - create(:completed_order_with_totals, line_items_count: 1, - distributor: distributor) - end - let(:line_item) { order.line_items.first } + let(:variant) { create(:variant) } let!(:variant_override) do create( :variant_override, @@ -25,15 +16,15 @@ describe VariantOverridesIndexed do describe '#indexed' do let(:result) { variant_overrides.indexed } - context 'when variant overrides exist for variants of specified line items' do - let(:vo_variant) { line_item.variant } + context 'when variant overrides exist for variants of specified variants' do + let(:vo_variant) { variant } context 'when variant overrides apply to one of the specified distributors' do let(:vo_distributor) { distributor } it 'they are included in the mapping' do expect(result).to eq( - distributor.id => { line_item.variant => variant_override } + distributor.id => { variant => variant_override } ) end end From f71045b3f2794c0936a253f2abc61ee2184462ad Mon Sep 17 00:00:00 2001 From: Rob H Date: Mon, 13 Apr 2020 22:24:25 +1000 Subject: [PATCH 110/166] Improve naming of variables in VariantOverridesIndexed for readability --- app/services/variant_overrides_indexed.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/services/variant_overrides_indexed.rb b/app/services/variant_overrides_indexed.rb index 587699a519..2c2ead6e44 100644 --- a/app/services/variant_overrides_indexed.rb +++ b/app/services/variant_overrides_indexed.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true +# Produces mappings of variant overrides by distributor id and variant id +# The primary use case for data structured in this way is for injection into +# the initializer of the OpenFoodNetwork::ScopeVariantToHub class + class VariantOverridesIndexed def initialize(variant_ids, distributor_ids) @variant_ids = variant_ids @@ -7,7 +11,7 @@ class VariantOverridesIndexed end def indexed - variant_overrides.each_with_object(hash_of_hashes) do |variant_override, indexed| + scoped_variant_overrides.each_with_object(hash_of_hashes) do |variant_override, indexed| indexed[variant_override.hub_id][variant_override.variant] = variant_override end end @@ -16,7 +20,7 @@ class VariantOverridesIndexed attr_reader :variant_ids, :distributor_ids - def variant_overrides + def scoped_variant_overrides VariantOverride .joins(:variant) .preload(:variant) @@ -27,6 +31,6 @@ class VariantOverridesIndexed end def hash_of_hashes - Hash.new { |h, k| h[k] = {} } + Hash.new { |hash, key| hash[key] = {} } end end From 7414047b924eb0cf241b7ceb108f88ddd8468a0c Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 10 Apr 2020 12:21:42 +0100 Subject: [PATCH 111/166] Switch from old success/error to modern then/catch structure Catch() will get a few more errors then errors() Also, add try/catch inside catch to detect any errors parsing the response error payload --- .../darkswarm/services/checkout.js.coffee | 22 +++++++++++-------- .../services/checkout_spec.js.coffee | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index 83cf018365..890d45c2e5 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -14,15 +14,19 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE submit: => Loading.message = t 'submitting_order' - $http.put('/checkout.json', {order: @preprocess()}).success (data, status)=> - Navigation.go data.path - .error (response, status)=> - if response.path - Navigation.go response.path - else - Loading.clear() - @errors = response.errors - RailsFlashLoader.loadFlash(response.flash) + $http.put('/checkout.json', {order: @preprocess()}) + .then (response) => + Navigation.go response.data.path + .catch (response) => + try + if response.data.path + Navigation.go response.data.path + else + Loading.clear() + @errors = response.data.errors + RailsFlashLoader.loadFlash(response.data.flash) + catch error + RailsFlashLoader.loadFlash("Unkown error occurred") # Rails wants our Spree::Address data to be provided with _attributes preprocess: -> diff --git a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee index 4ff2f0d97a..6b1b7d6e40 100644 --- a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee @@ -119,6 +119,7 @@ describe 'Checkout service', -> it "puts errors into the scope", -> $httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "frogs"}} Checkout.submit() + $httpBackend.flush() expect(Checkout.errors).toEqual {error: "frogs"} From cdf5bcb7eb129820f44a48696810eece78c0ba41 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 14 Apr 2020 13:44:58 +0100 Subject: [PATCH 112/166] Improve unexpected error handling and add test cases for it --- .../darkswarm/services/checkout.js.coffee | 5 +++- .../services/checkout_spec.js.coffee | 28 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index 890d45c2e5..c6e9282c59 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -22,11 +22,14 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE if response.data.path Navigation.go response.data.path else + throw response unless response.data.errors || response.data.flash + Loading.clear() @errors = response.data.errors RailsFlashLoader.loadFlash(response.data.flash) catch error - RailsFlashLoader.loadFlash("Unkown error occurred") + RailsFlashLoader.loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error + throw error # generate a BugsnagJS alert # Rails wants our Spree::Address data to be provided with _attributes preprocess: -> diff --git a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee index 6b1b7d6e40..b8575f5336 100644 --- a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee @@ -6,7 +6,9 @@ describe 'Checkout service', -> flash = null scope = null FlashLoaderMock = - loadFlash: (arg)-> + loadFlash: (arg) -> + Loading = + clear: (arg)-> paymentMethods = [{ id: 99 test: "foo" @@ -48,6 +50,7 @@ describe 'Checkout service', -> module 'Darkswarm' module ($provide)-> $provide.value "RailsFlashLoader", FlashLoaderMock + $provide.value "Loading", Loading $provide.value "currentOrder", orderData $provide.value "shippingMethods", shippingMethods $provide.value "paymentMethods", paymentMethods @@ -123,6 +126,29 @@ describe 'Checkout service', -> $httpBackend.flush() expect(Checkout.errors).toEqual {error: "frogs"} + it "throws an exception and sends a flash message to the flash service when reponse doesnt contain errors nor a flash message", -> + spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location + $httpBackend.expectPUT("/checkout.json").respond 400, "broken response" + try + Checkout.submit() + $httpBackend.flush() + catch e + expect(e.data).toBe("broken response") + + expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") }) + + it "throws an exception and sends a flash message to the flash service when an exception is thrown while handling the error", -> + spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location + spyOn(Loading, "clear").and.callFake(-> throw "unexpected error") + $httpBackend.expectPUT("/checkout.json").respond 400, {flash: {error: "frogs"}} + try + Checkout.submit() + $httpBackend.flush() + catch e + expect(e).toBe("unexpected error") + + expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") }) + describe "when using the Stripe Connect gateway", -> beforeEach inject ($injector, StripeElements) -> Checkout.order.payment_method_id = 666 From 62471bf2abfa2056119ffda116ea0fe89332e724 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 14 Apr 2020 13:50:38 +0100 Subject: [PATCH 113/166] Clear Loading spinner when exception is caught --- .../javascripts/darkswarm/services/checkout.js.coffee | 1 + .../unit/darkswarm/services/checkout_spec.js.coffee | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index c6e9282c59..d974004d92 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -28,6 +28,7 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE @errors = response.data.errors RailsFlashLoader.loadFlash(response.data.flash) catch error + Loading.clear() RailsFlashLoader.loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error throw error # generate a BugsnagJS alert diff --git a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee index b8575f5336..263fe502f2 100644 --- a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee @@ -3,6 +3,7 @@ describe 'Checkout service', -> orderData = null $httpBackend = null Navigation = null + navigationSpy = null flash = null scope = null FlashLoaderMock = @@ -64,7 +65,7 @@ describe 'Checkout service', -> scope.Checkout = Checkout Navigation = $injector.get("Navigation") flash = $injector.get("flash") - spyOn(Navigation, "go") # Stubbing out writes to window.location + navigationSpy = spyOn(Navigation, "go") # Stubbing out writes to window.location it "defaults to no shipping method", -> expect(Checkout.order.shipping_method_id).toEqual null @@ -139,8 +140,8 @@ describe 'Checkout service', -> it "throws an exception and sends a flash message to the flash service when an exception is thrown while handling the error", -> spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location - spyOn(Loading, "clear").and.callFake(-> throw "unexpected error") - $httpBackend.expectPUT("/checkout.json").respond 400, {flash: {error: "frogs"}} + navigationSpy.and.callFake(-> throw "unexpected error") + $httpBackend.expectPUT("/checkout.json").respond 400, {path: 'path'} try Checkout.submit() $httpBackend.flush() From 47a93568dcecfcd03b164848ed7fd890ae85c164 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 14 Apr 2020 13:55:20 +0100 Subject: [PATCH 114/166] Make code simpler by extracting methods --- .../darkswarm/services/checkout.js.coffee | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index d974004d92..3b7c2756d7 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -19,19 +19,24 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE Navigation.go response.data.path .catch (response) => try - if response.data.path - Navigation.go response.data.path - else - throw response unless response.data.errors || response.data.flash - - Loading.clear() - @errors = response.data.errors - RailsFlashLoader.loadFlash(response.data.flash) + @handle_checkout_error_response(response) catch error - Loading.clear() - RailsFlashLoader.loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error + @loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error throw error # generate a BugsnagJS alert + handle_checkout_error_response: (response) => + if response.data.path + Navigation.go response.data.path + else + throw response unless response.data.errors || response.data.flash + + @errors = response.data.errors + @loadFlash(response.data.flash) + + loadFlash: (flash) => + Loading.clear() + RailsFlashLoader.loadFlash(flash) + # Rails wants our Spree::Address data to be provided with _attributes preprocess: -> munged_order = From cedf1b26f2ed1af96f8a61edc2c79379786af599 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Tue, 14 Apr 2020 14:24:08 +0100 Subject: [PATCH 115/166] If no flash is sent from the server, show the generic error --- .../darkswarm/services/checkout.js.coffee | 2 +- .../services/checkout_spec.js.coffee | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee index 3b7c2756d7..f0da646ebe 100644 --- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee +++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee @@ -28,7 +28,7 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE if response.data.path Navigation.go response.data.path else - throw response unless response.data.errors || response.data.flash + throw response unless response.data.flash @errors = response.data.errors @loadFlash(response.data.flash) diff --git a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee index 263fe502f2..d7e23b457b 100644 --- a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee @@ -120,21 +120,31 @@ describe 'Checkout service', -> $httpBackend.flush() expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith {error: "frogs"} - it "puts errors into the scope", -> - $httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "frogs"}} + it "puts errors into the scope when there is a flash messages", -> + $httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "frogs"}, flash: {error: "flash frogs"}} Checkout.submit() $httpBackend.flush() expect(Checkout.errors).toEqual {error: "frogs"} + it "throws exception and sends generic flash message when there are errors but no flash message", -> + $httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "broken response"}} + try + Checkout.submit() + $httpBackend.flush() + catch error + expect(error.data.errors.error).toBe("broken response") + + expect(Checkout.errors).toEqual {} + it "throws an exception and sends a flash message to the flash service when reponse doesnt contain errors nor a flash message", -> spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location $httpBackend.expectPUT("/checkout.json").respond 400, "broken response" try Checkout.submit() $httpBackend.flush() - catch e - expect(e.data).toBe("broken response") + catch error + expect(error.data).toBe("broken response") expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") }) @@ -145,8 +155,8 @@ describe 'Checkout service', -> try Checkout.submit() $httpBackend.flush() - catch e - expect(e).toBe("unexpected error") + catch error + expect(error).toBe("unexpected error") expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") }) From 5e1dea61a8c06972305225fa3be0c8d13d25ef2d Mon Sep 17 00:00:00 2001 From: jeffrey s hill md Date: Tue, 14 Apr 2020 11:20:56 -0500 Subject: [PATCH 116/166] added missing translations to enterprise_relationship page --- .../_enterprise_relationship.html.haml | 3 ++- app/views/admin/enterprise_relationships/_form.html.haml | 3 ++- config/locales/en.yml | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml index c1c6ccbc4b..9264c90f01 100644 --- a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml +++ b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml @@ -6,6 +6,7 @@ %td %ul %li{"ng-repeat" => "permission in enterprise_relationship.permissions"} - to {{ EnterpriseRelationships.permission_presentation(permission.name) }} + = t 'admin_enterprise_relationships_to' + {{ EnterpriseRelationships.permission_presentation(permission) }} %td.actions %a.delete-enterprise-relationship.icon-trash.no-text{'ng-click' => 'delete(enterprise_relationship)'} diff --git a/app/views/admin/enterprise_relationships/_form.html.haml b/app/views/admin/enterprise_relationships/_form.html.haml index 958ce53074..e79da0b144 100644 --- a/app/views/admin/enterprise_relationships/_form.html.haml +++ b/app/views/admin/enterprise_relationships/_form.html.haml @@ -13,7 +13,8 @@ %div{"ng-repeat" => "permission in EnterpriseRelationships.all_permissions"} %label %input{type: "checkbox", "ng-model" => "permissions[permission]"} - to {{ EnterpriseRelationships.permission_presentation(permission) }} + = t 'admin_enterprise_relationships_to' + {{ EnterpriseRelationships.permission_presentation(permission) }} %td.actions %input{type: "button", value: t(:admin_enterprise_relationships_button_create), "ng-click" => "create()"} .errors {{ EnterpriseRelationships.create_errors }} diff --git a/config/locales/en.yml b/config/locales/en.yml index 21d9ab39cf..feb9c77e1e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2053,6 +2053,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using admin_enterprise_relationships_permits: "permits" admin_enterprise_relationships_seach_placeholder: "Search" admin_enterprise_relationships_button_create: "Create" + admin_enterprise_relationships_to: "to" admin_enterprise_groups: "Enterprise Groups" admin_enterprise_groups_name: "Name" admin_enterprise_groups_owner: "Owner" From e23045b19ebad2c2dc9f67445cb6b997008f53fa Mon Sep 17 00:00:00 2001 From: jeffrey s hill md Date: Tue, 14 Apr 2020 14:15:57 -0500 Subject: [PATCH 117/166] Add product translations --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 21d9ab39cf..29dc640c6d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2910,6 +2910,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" From 8f7b3df9b598901f32cbf6ff78ec16750229deb5 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Mon, 13 Apr 2020 20:00:56 +0100 Subject: [PATCH 118/166] Make payment controller authorize stripe_sca payments before processing them or advancing order workflow (that also calls payment.process) --- .../spree/admin/payments_controller.rb | 11 +- .../spree/admin/payments_controller_spec.rb | 104 ++++++++++++++++-- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/app/controllers/spree/admin/payments_controller.rb b/app/controllers/spree/admin/payments_controller.rb index 0c17f8154a..a239652ed0 100644 --- a/app/controllers/spree/admin/payments_controller.rb +++ b/app/controllers/spree/admin/payments_controller.rb @@ -29,6 +29,8 @@ module Spree return end + authorize_stripe_sca_payment + if @order.completed? @payment.process! flash[:success] = flash_message_for(@payment, :successfully_created) @@ -93,7 +95,7 @@ module Spree available(:back_end). select{ |pm| pm.has_distributor? @order.distributor } - @payment_method = if @payment && @payment.payment_method + @payment_method = if @payment&.payment_method @payment.payment_method else @payment_methods.first @@ -124,6 +126,13 @@ module Spree def load_payment @payment = Payment.find(params[:id]) end + + def authorize_stripe_sca_payment + return unless @payment.payment_method.class == Spree::Gateway::StripeSCA + + @payment.authorize! + raise Spree::Core::GatewayError, I18n.t('authorization_failure') unless @payment.pending? + end end end end diff --git a/spec/controllers/spree/admin/payments_controller_spec.rb b/spec/controllers/spree/admin/payments_controller_spec.rb index 55b20d3484..115886ec7f 100644 --- a/spec/controllers/spree/admin/payments_controller_spec.rb +++ b/spec/controllers/spree/admin/payments_controller_spec.rb @@ -12,16 +12,104 @@ describe Spree::Admin::PaymentsController, type: :controller do context "#create" do let!(:payment_method) { create(:payment_method, distributors: [shop]) } - let!(:order) do - create(:order_with_totals_and_distribution, distributor: shop, state: "payment") - end - let(:params) { { amount: order.total, payment_method_id: payment_method.id } } - it "advances the order state" do - expect { - spree_post :create, payment: params, order_id: order.number - }.to change { order.reload.state }.from("payment").to("complete") + context "order is not complete" do + let!(:order) do + create(:order_with_totals_and_distribution, distributor: shop, state: "payment") + end + + it "advances the order state" do + expect { + spree_post :create, payment: params, order_id: order.number + }.to change { order.reload.state }.from("payment").to("complete") + end + end + + context "order is complete" do + let!(:order) do + create(:order_with_totals_and_distribution, distributor: shop, state: "complete", completed_at: Time.zone.now) + end + + context "with Check payment (payment.process! does nothing)" do + it "redirects to list of payments with success flash" do + spree_post :create, payment: params, order_id: order.number + + redirects_to_list_of_payments_with_success_flash + expect(order.reload.payments.last.state).to eq "checkout" + end + end + + context "with Stripe payment where payment.process! errors out" do + let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) } + before { allow_any_instance_of(Spree::Payment).to receive(:process!).and_raise(Spree::Core::GatewayError.new("Payment Gateway Error")) } + + it "redirects to new payment page with flash error" do + spree_post :create, payment: params, order_id: order.number + + redirects_to_new_payment_page_with_flash_error("Payment Gateway Error") + expect(order.reload.payments.last.state).to eq "checkout" + end + end + + context "with StripeSCA payment" do + let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) } + + context "where payment.authorize! raises GatewayError" do + before { allow_any_instance_of(Spree::Payment).to receive(:authorize!).and_raise(Spree::Core::GatewayError.new("Stripe Authorization Failure")) } + + it "redirects to new payment page with flash error" do + spree_post :create, payment: params, order_id: order.number + + redirects_to_new_payment_page_with_flash_error("Stripe Authorization Failure") + expect(order.reload.payments.last.state).to eq "checkout" + end + end + + context "where payment.authorize! does not move payment to pending state" do + before do + allow_any_instance_of(Spree::Payment).to receive(:authorize!).and_return(true) + end + + it "redirects to new payment page with flash error" do + spree_post :create, payment: params, order_id: order.number + + redirects_to_new_payment_page_with_flash_error("Authorization Failure") + expect(order.reload.payments.last.state).to eq "checkout" + end + end + + context "where both payment.process! and payment.authorize! work" do + before do + allow_any_instance_of(Spree::Payment).to receive(:authorize!) do |payment| + payment.update_attribute :state, "pending" + end + allow_any_instance_of(Spree::Payment).to receive(:process!).and_return(true) + end + + it "redirects to list of payments with success flash" do + spree_post :create, payment: params, order_id: order.number + + redirects_to_list_of_payments_with_success_flash + expect(order.reload.payments.last.state).to eq "pending" + end + end + end + + def redirects_to_list_of_payments_with_success_flash + expect_redirect_to spree.admin_order_payments_url(order) + expect(flash[:success]).to eq "Payment has been successfully created!" + end + + def redirects_to_new_payment_page_with_flash_error(flash_error) + expect_redirect_to spree.new_admin_order_payment_url(order) + expect(flash[:error]).to eq flash_error + end + + def expect_redirect_to(path) + expect(response.status).to eq 302 + expect(response.location).to eq path + end end end From fcc746a1b7eb6895447963ab12b25a9663ccf061 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 15 Apr 2020 16:18:17 +0100 Subject: [PATCH 119/166] Fix long lines in payments_controller_spec --- .rubocop_manual_todo.yml | 1 - .../spree/admin/payments_controller_spec.rb | 33 ++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index de9861fa40..169cf59b04 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -156,7 +156,6 @@ Layout/LineLength: - spec/controllers/spree/admin/orders/customer_details_controller_spec.rb - spec/controllers/spree/admin/orders_controller_spec.rb - spec/controllers/spree/admin/payment_methods_controller_spec.rb - - spec/controllers/spree/admin/payments_controller_spec.rb - spec/controllers/spree/admin/products_controller_spec.rb - spec/controllers/spree/admin/reports_controller_spec.rb - spec/controllers/spree/admin/variants_controller_spec.rb diff --git a/spec/controllers/spree/admin/payments_controller_spec.rb b/spec/controllers/spree/admin/payments_controller_spec.rb index 115886ec7f..53dd604ebd 100644 --- a/spec/controllers/spree/admin/payments_controller_spec.rb +++ b/spec/controllers/spree/admin/payments_controller_spec.rb @@ -28,7 +28,9 @@ describe Spree::Admin::PaymentsController, type: :controller do context "order is complete" do let!(:order) do - create(:order_with_totals_and_distribution, distributor: shop, state: "complete", completed_at: Time.zone.now) + create(:order_with_totals_and_distribution, distributor: shop, + state: "complete", + completed_at: Time.zone.now) end context "with Check payment (payment.process! does nothing)" do @@ -42,7 +44,11 @@ describe Spree::Admin::PaymentsController, type: :controller do context "with Stripe payment where payment.process! errors out" do let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) } - before { allow_any_instance_of(Spree::Payment).to receive(:process!).and_raise(Spree::Core::GatewayError.new("Payment Gateway Error")) } + before do + allow_any_instance_of(Spree::Payment). + to receive(:process!). + and_raise(Spree::Core::GatewayError.new("Payment Gateway Error")) + end it "redirects to new payment page with flash error" do spree_post :create, payment: params, order_id: order.number @@ -56,7 +62,11 @@ describe Spree::Admin::PaymentsController, type: :controller do let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) } context "where payment.authorize! raises GatewayError" do - before { allow_any_instance_of(Spree::Payment).to receive(:authorize!).and_raise(Spree::Core::GatewayError.new("Stripe Authorization Failure")) } + before do + allow_any_instance_of(Spree::Payment). + to receive(:authorize!). + and_raise(Spree::Core::GatewayError.new("Stripe Authorization Failure")) + end it "redirects to new payment page with flash error" do spree_post :create, payment: params, order_id: order.number @@ -126,8 +136,10 @@ describe Spree::Admin::PaymentsController, type: :controller do context "that was processed by stripe" do let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) } - # let!(:credit_card) { create(:credit_card, gateway_customer_profile_id: "cus_1", gateway_payment_profile_id: 'card_2') } - let!(:payment) { create(:payment, order: order, state: 'completed', payment_method: payment_method, response_code: 'ch_1a2b3c', amount: order.total) } + let!(:payment) do + create(:payment, order: order, state: 'completed', payment_method: payment_method, + response_code: 'ch_1a2b3c', amount: order.total) + end before do allow(Stripe).to receive(:api_key) { "sk_test_12345" } @@ -137,7 +149,8 @@ describe Spree::Admin::PaymentsController, type: :controller do before do stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds"). with(basic_auth: ["sk_test_12345", ""]). - to_return(status: 200, body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') ) + to_return(status: 200, + body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') ) end it "voids the payment" do @@ -182,7 +195,10 @@ describe Spree::Admin::PaymentsController, type: :controller do context "that was processed by stripe" do let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) } - let!(:payment) { create(:payment, order: order, state: 'completed', payment_method: payment_method, response_code: 'ch_1a2b3c', amount: order.total + 5) } + let!(:payment) do + create(:payment, order: order, state: 'completed', payment_method: payment_method, + response_code: 'ch_1a2b3c', amount: order.total + 5) + end before do allow(Stripe).to receive(:api_key) { "sk_test_12345" } @@ -192,7 +208,8 @@ describe Spree::Admin::PaymentsController, type: :controller do before do stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds"). with(basic_auth: ["sk_test_12345", ""]). - to_return(status: 200, body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') ) + to_return(status: 200, + body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') ) end it "partially refunds the payment" do From c3f01be580b9a6f61506a74642be64c24b67cc72 Mon Sep 17 00:00:00 2001 From: chrishil1 Date: Mon, 6 Apr 2020 13:41:47 -0500 Subject: [PATCH 120/166] Fixed display all required tag --- app/views/spree/admin/products/_display_as.html.haml | 1 + app/views/spree/admin/products/new.html.haml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/views/spree/admin/products/_display_as.html.haml b/app/views/spree/admin/products/_display_as.html.haml index 04af12bdce..95636694c3 100644 --- a/app/views/spree/admin/products/_display_as.html.haml +++ b/app/views/spree/admin/products/_display_as.html.haml @@ -1,4 +1,5 @@ .three.columns.omega{ "ng-if" => "product.variant_unit_with_scale != 'items'" } = f.field_container :display_as do = f.label :product_display_as, t('.display_as') + %span.required * %input#product_display_as.fullwidth{name: "product[display_as]", placeholder: "{{ placeholder_text }}", type: "text"} diff --git a/app/views/spree/admin/products/new.html.haml b/app/views/spree/admin/products/new.html.haml index 6b3259c5e4..34665fbdcb 100644 --- a/app/views/spree/admin/products/new.html.haml +++ b/app/views/spree/admin/products/new.html.haml @@ -38,6 +38,7 @@ .three.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" } = f.field_container :unit_name do = f.label :product_variant_unit_name, t(".unit_name") + %span.required * %input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => t('admin.products.unit_name_placeholder'), :type => 'text' } .twelve.columns.alpha .six.columns.alpha From a9829ba5d9725944898cd0af3d65b467d89d1677 Mon Sep 17 00:00:00 2001 From: chrishil1 Date: Wed, 15 Apr 2020 17:01:22 -0500 Subject: [PATCH 121/166] Update _enterprise_relationship.html.haml --- .../enterprise_relationships/_enterprise_relationship.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml index 9264c90f01..c6f630ba48 100644 --- a/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml +++ b/app/views/admin/enterprise_relationships/_enterprise_relationship.html.haml @@ -7,6 +7,6 @@ %ul %li{"ng-repeat" => "permission in enterprise_relationship.permissions"} = t 'admin_enterprise_relationships_to' - {{ EnterpriseRelationships.permission_presentation(permission) }} + {{ EnterpriseRelationships.permission_presentation(permission.name) }} %td.actions %a.delete-enterprise-relationship.icon-trash.no-text{'ng-click' => 'delete(enterprise_relationship)'} From 2f7dc9a578078c66a5873e5b1dc4bc9579c98bcd Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 16 Apr 2020 17:09:44 +1000 Subject: [PATCH 122/166] Updating translations for config/locales/es.yml --- config/locales/es.yml | 182 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/config/locales/es.yml b/config/locales/es.yml index b7d30e1b8f..28cab71ad3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -31,6 +31,10 @@ es: taken: "Ya existe una cuenta con este email. Inicie sesión o restablezca tu contraseña." spree/order: no_card: No hay tarjetas de crédito autorizadas disponibles para cargar + spree/credit_card: + attributes: + base: + card_expired: "ha expirado" order_cycle: attributes: orders_close_at: @@ -52,6 +56,8 @@ es: shipping_method_ids: "Métodos de envío" payment_method_ids: "Métodos de Pago" errors: + messages: + inclusion: "no está incluido en la lista" models: order_management/subscriptions/validator: attributes: @@ -246,6 +252,8 @@ es: notes: Notas error: Error processing_payment: "Procesando el pago..." + no_pending_payments: "No tiene pagos pendientes" + invalid_payment_state: "Estado de pago no válido" filter_results: Filtrar resultados quantity: Cantidad pick_up: Recogida @@ -438,9 +446,12 @@ es: infinity: "infinito" to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda." back_to_products_list: "Volver a la lista de productos" + editing_product: "Editando producto" tabs: + product_details: "Detalles del Producto" group_buy_options: "Opciones de compra grupales" images: "Imágenes" + variants: "variaciones" product_properties: "Propiedades del producto" product_import: title: Importación de productos @@ -699,6 +710,11 @@ es: enable_subscriptions_false: "Deshabilitado" enable_subscriptions_true: "Habilitado" shopfront_message: "Mensaje de la Tienda" + shopfront_message_placeholder: > + Mensaje de bienvenida opcional para compradores, explica como comprar + en el sitio. si el texto se agrega en este campo, va a ser mostrado + en la pestaña de inicio cuando los clientes ingresen por primera vez + a la tienda. shopfront_message_link_tooltip: "Insertar / editar enlace" shopfront_message_link_prompt: "Por favor introduzca una URL para insertar" shopfront_closed_message: "Mensaje de tienda cerrada" @@ -836,25 +852,38 @@ es: new: create: "Crear" cancel: "Cancelar" + back_to_list: "Regresar a la lista" edit: advanced_settings: "Configuración Avanzada" save: "Guardar" + save_and_next: "Salvar y continuar" next: "Siguiente" cancel: "Cancelar" + back_to_list: "Regresar a la lista" + save_and_back_to_list: "Salvar y volver a lista" choose_products_from: "Escoger Productos desde:" incoming: save: "Guardar" + save_and_next: "Salvar y continuar" next: "Siguiente" cancel: "Cancelar" + back_to_list: "Regresar a la lista" outgoing: outgoing: "Saliente" distributor: "Distribuidora" products: "Productos" tags: "Tags" + delivery_details: "Detalles de entrega" fees: "Comisiones" previous: "Anterior" save: "Guardar" + save_and_back_to_list: "Salvar y volver a lista" cancel: "Cancelar" + back_to_list: "Regresar a la lista" + wizard_progress: + edit: "1. Configuración general" + incoming: "2. Productos entrantes" + outgoing: "3. Productos salientes" exchange_form: pickup_time_tip: Cuando los pedidos de este ciclo de pedido estarán listos para la consumidora pickup_instructions_placeholder: "Instrucciones de recogida" @@ -1092,10 +1121,13 @@ es: destroy_attachment_does_not_exist: "El logotipo no existe" enterprise_promo_image: destroy_attachment_does_not_exist: "La imagen promocional no existe" + orders: + failed_to_update: "Error al actualizar pedido" checkout: already_ordered: cart: "carrito" message_html: "Ya realizó un pedido para este ciclo de pedido. Compruebe el %{cart}para ver los artículos que pidió. También puede cancelar artículos mientras el ciclo de pedido siga abierto." + failed: "La finalización de compra falló, por favor comunicate con nosotros para procesar la orden." shops: hubs: show_closed_shops: "Mostrar tiendas cerradas" @@ -1266,6 +1298,7 @@ es: saving_credit_card: Guardando tarjeta de crédito... card_has_been_removed: "Su tarjeta ha sido eliminada (número: %{number})" card_could_not_be_removed: Lo sentimos, la tarjeta no se pudo quitar + invalid_credit_card: "Tarjeta de crédito inválida" ie_warning_headline: "Su navegador está desactualizado :-(" ie_warning_text: "Para la mejor esperiencia de Open Food Network, recomendamos actualizar su navegador:" ie_warning_chrome: Descargar Chrome @@ -1467,6 +1500,7 @@ es: shopping_oc_closed_description: "Por favor espere hasta que el próximo ciclo abra (o contactanos de forma directa para ver si podemos aceptar algunos pedidos tardíos)" shopping_oc_last_closed: "El último ciclo cerró hace %{distance_of_time}" shopping_oc_next_open: "El próximo ciclo abrirá en %{distance_of_time}" + shopping_oc_select: "Seleccionar" shopping_tabs_home: "Inicio" shopping_tabs_shop: "Tienda" shopping_tabs_about: "Acerca de" @@ -1840,6 +1874,7 @@ es: headline: "¡Terminado!" thanks: "Gracias por llenar los detalles de %{enterprise}." login: "Puede cambiar o actualizar su negocio en cualquier etapa iniciando sesión en Open Food Network y yendo a Admin." + action: "Ir al Panel de Organización" back: "Atrás" continue: "Continuar" action_or: "Ó" @@ -1925,6 +1960,7 @@ es: tax_category: "Categoría del impuesto" calculator: "Calculadora" calculator_values: "Calculadora de valores" + calculator_settings_warning: "Si está cambiando el tipo de calculadora, debe de salvar primero antes de editar las configuraciones de la calculadora" flat_percent_per_item: "Porcentaje fijo (por artículo)" flat_rate_per_item: "Tarifa plana (por artículo)" flat_rate_per_order: "Tarifa plana (por pedido)" @@ -2255,6 +2291,7 @@ es: enterprise_register_success_notice: "¡Felicidades! ¡Se ha completado el registro de %{enterprise}!" enterprise_bulk_update_success_notice: "Organizaciones actualizadas con éxito" enterprise_bulk_update_error: 'Error en la actualización' + enterprise_shop_show_error: "La tienda que busca no existe o esta inactiva en OFN. por favor visita otras tiendas." order_cycles_create_notice: 'Se ha creado el ciclo de pedido.' order_cycles_update_notice: 'Se ha actualizado su ciclo de pedido.' order_cycles_bulk_update_notice: 'Los ciclos de pedido han sido actualizados.' @@ -2410,6 +2447,12 @@ es: severity: Gravedad description: Descripción resolve: Resolver + exchange_products: + load_more_variants: "Cargar mas variantes" + load_all_variants: "cargar todas las variantes" + select_all_variants: "Seleccionar todo" + variants_loaded: "%{num_of_variants_loaded} de %{total_number_of_variants} variantes cargadas" + loading_variants: "Cargando variantes" tag_rules: shipping_method_tagged_top: "Métodos de envío etiquetados" shipping_method_tagged_bottom: "son:" @@ -2492,6 +2535,7 @@ es: customer_placeholder: "customer@example.org" valid_email_error: "Introduce un email válido" subscriptions: + error_saving: "Error al salvar suscripción " new: please_select_a_shop: "Por favor seleccione una tienda" insufficient_stock: "Stock insuficiente disponible, solo quedan %{on_hand}" @@ -2567,6 +2611,79 @@ es: signup_or_login: "Empieza registrándose (o iniciando sesión)" have_an_account: "¿Ya tiene una cuenta?" action_login: "Inicie sesión ahora." + inflections: + each: + one: "each" + other: "cada" + bunch: + one: "manojo" + other: "manojos" + pack: + one: "paquete" + other: "paquetes" + box: + one: "caja" + other: "cajas" + bottle: + one: "botella" + other: "botellas" + jar: + one: "frasco" + other: "frascos" + head: + one: "cabeza" + other: "cabezas" + bag: + one: "bolsa" + other: "bolsas" + loaf: + one: "hogaza" + other: "hogazas" + single: + one: "single" + other: "individuales" + tub: + one: "tub" + other: "recipientes" + punnet: + one: "canastilla" + other: "canastillas" + packet: + one: "paquete" + other: "paquetes" + item: + one: "elemento" + other: "elementos" + dozen: + one: "docena" + other: "docenas" + unit: + one: "unidad" + other: "unidades" + serve: + one: "serve" + other: "porción" + tray: + one: "bandeja" + other: "bandejas" + piece: + one: "pieza" + other: "piezas" + pot: + one: "maceta" + other: "contenedores" + bundle: + one: "haz" + other: "paquetes" + flask: + one: "flask" + other: "frascos" + basket: + one: "canasta" + other: "canastas" + sack: + one: "sacos" + other: "sacos" producers: signup: start_free_profile: "Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" @@ -2792,6 +2909,12 @@ es: minimal_amount: "Cantidad mínima" normal_amount: "Cantidad normal" discount_amount: "Importe de descuento" + no_images_found: "No se encontraron imágenes " + new_image: "Nueva Imagen" + filename: "Nombre de archivo" + alt_text: "Texto Alternativo" + thumbnail: "Miniatura" + back_to_images_list: "Volver a lista de imágenes " email: Email account_updated: "Cuenta actualizada!" email_updated: "La cuenta se actualizará una vez que se confirme el nuevo correo electrónico." @@ -2803,6 +2926,9 @@ es: zipcode: Código Postal weight: Peso (en kg) error_user_destroy_with_orders: "Los usuarios con pedidos completados no pueden ser eliminados" + cannot_create_payment_without_payment_methods: "No se puede crear un pago para una orden sin un medio de pago definido" + please_define_payment_methods: "por favor definir métodos de pago" + options: "Opciones" actions: update: "Actualizar" errors: @@ -2834,27 +2960,53 @@ es: product_properties: index: inherits_properties_checkbox_hint: "¿Heredar propiedades desde %{supplier}? (a menos que sea anulado arriba)" + add_product_properties: "Agregar Propiedades del producto" + select_from_prototype: "seleccionar de prototipo" properties: index: properties: "Propiedades" + new_property: "Nueva propiedad" name: "Nombre" + presentation: "presentación" + new: + new_property: "Nueva propiedad" + edit: + editing_property: "Editar Propiedad" + back_to_properties_list: "volver a lista de propiedades" form: name: "Nombre" + presentation: "presentación" return_authorizations: index: + new_return_authorization: "Nueva autorización de devolución" return_authorizations: "Autorizaciones de devolución" back_to_orders_list: "Volver a la lista de pedidos" + rma_number: "número RMA" status: "Estado" amount: "Cantidad" cannot_create_returns: "No se pueden crear devoluciones ya que este pedido no tiene unidades enviadas." continue: "Continuar" new: + new_return_authorization: "Nueva autorización de devolución" + back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continuar" edit: + receive: "recibir" are_you_sure: "¿Está seguro?" + return_authorization: "volver a autorización" form: product: "Producto" + quantity_shipped: "cantidad enviada" + quantity_returned: "Cantidad devuelta" + return_quantity: "cantidad a devolver" amount: "Cantidad" + rma_value: "Valor RMA" + reason: "razón" + stock_location: "localización de inventario" + states: + authorized: "autorizado" + received: "recibido" + canceled: "cancelado" orders: index: listing_orders: "Pedidos de listado" @@ -2862,6 +3014,7 @@ es: capture: "Captura" ship: "Envío" edit: "Editar" + order_not_updated: "El pedido no se pudo actualizar" note: "Nota" first: "primero" last: "Último" @@ -2884,6 +3037,8 @@ es: tax_invoice: "FACTURA DE IMPUESTOS" code: "Código" from: "De" + to: "Facturar a" + shipping: "envío" form: distribution_fields: title: "Distribución" @@ -3044,12 +3199,23 @@ es: index: sku: "SKU" price: "Precio" + options: "Opciones" no_results: "No hay resultados" + to_add_variants_you_must_first_define: "para agregar variantes, se debe primero definir" option_types: "Tipos de opciones" + option_values: "valores de opción" + and: "y" + new_variant: "Nueva Variante" + show_active: "mostrar activo" + show_deleted: "Mostrar eliminados" + new: + new_variant: "Nueva Variante" form: + cost_price: "Precio de costo" sku: "SKU" price: "Precio" display_as: "Mostrar como" + display_name: "Nombre para mostrar" autocomplete: producer_name: "Productora" unit: "Unidad" @@ -3195,3 +3361,19 @@ es: allow_charges?: "¿Permitir cargos?" localized_number: invalid_format: tiene un formato invalido. Por favor introduzca un numero. + api: + invalid_api_key: "La llave de API especificada (%{key}) es inválida." + unauthorized: "No tiene autorización para realizar esta acción." + invalid_resource: "Recurso inválido. Por favor corrija los errores e intente nuevamente." + resource_not_found: "El recurso que buscaba no puede ser encontrado." + access: "acceso al API" + key: "Llave" + clear_key: "valor vacío" + regenerate_key: "Regenerar llave" + no_key: "sin valor" + generate_key: "Generar llave de API" + key_generated: "Llave generada" + key_cleared: "valor borrado" + shipment: + cannot_ready: "No se puede completar envío" + invalid_taxonomy_id: "El identificador de taxonomía es inválido." From 71c7c356793f7e070ec27de7f0e5899aa5633478 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 16 Apr 2020 13:44:18 +0200 Subject: [PATCH 123/166] Remove old migrations! :tada: --- .../20120327000552_spree_zero_nine_zero.rb | 389 -------------- ...0553_create_indexes_for_inventory_units.rb | 6 - ..._count_on_hand_to_variants_and_products.rb | 49 -- ...20327000555_change_taxons_to_nested_set.rb | 46 -- ...327000556_move_to_configurable_gateways.rb | 54 -- ...0120327000557_product_groups_and_scopes.rb | 18 - ...00558_add_open_id_authentication_tables.rb | 15 - ...0120327000559_add_openid_field_to_users.rb | 24 - ...0327000560_change_preference_value_type.rb | 10 - ...20327000561_create_billing_integrations.rb | 12 - .../20120327000562_charge_refactoring.rb | 39 -- db/migrate/20120327000563_add_some_indexes.rb | 11 - .../20120327000564_checkout_state_machine.rb | 5 - .../20120327000565_state_for_shipments.rb | 5 - ...327000566_make_state_events_polymorphic.rb | 12 - ...327000567_ship_address_id_for_checkouts.rb | 5 - ...000568_shipping_method_id_for_checkouts.rb | 5 - ...20327000569_creditcard_last_four_digits.rb | 14 - ...27000570_populate_legacy_shipment_state.rb | 15 - db/migrate/20120327000571_add_cost_price.rb | 5 - ...7000572_shipment_id_for_inventory_units.rb | 25 - ...120327000573_cim_fields_for_creditcards.rb | 6 - ...0327000574_create_return_authorizations.rb | 12 - ...return_authorization_to_inventory_units.rb | 5 - db/migrate/20120327000576_create_trackers.rb | 10 - ...00577_creditcard_id_for_creditcard_txns.rb | 5 - ...l_creditcard_txn_id_for_creditcard_txns.rb | 5 - ...79_add_test_mode_to_billing_integration.rb | 6 - ...27000580_create_products_product_groups.rb | 8 - .../20120327000581_create_payment_methods.rb | 16 - .../20120327000582_polymorphic_payments.rb | 43 -- ...e_payments_payment_method_to_belongs_to.rb | 11 - ...00584_assign_creditcard_txns_to_payment.rb | 23 - .../20120327000585_sti_for_transactions.rb | 15 - ...0120327000586_drop_billing_integrations.rb | 16 - ...27000587_deleted_at_for_payment_methods.rb | 14 - .../20120327000588_add_adjustments_index.rb | 6 - .../20120327000589_fix_by_popularity.rb | 9 - .../20120327000590_add_alt_text_to_images.rb | 5 - ...20327000591_fix_existing_coupon_credits.rb | 13 - ...27000592_add_display_to_payment_methods.rb | 5 - ...7000593_add_addresses_checkouts_indexes.rb | 8 - .../20120327000594_add_icon_to_taxons.rb | 17 - ...0120327000595_add_description_to_taxons.rb | 11 - ...120327000596_index_for_shipments_number.rb | 5 - ...97_add_index_on_users_persistence_token.rb | 5 - ...327000598_add_default_to_tax_categories.rb | 5 - ...7000599_add_display_to_shipping_methods.rb | 5 - ...327000600_rename_payment_method_display.rb | 5 - ...20120327000601_rename_preferences_field.rb | 5 - db/migrate/20120327000602_add_guest_flag.rb | 5 - db/migrate/20120327000603_drop_order_token.rb | 9 - ...yments_state_and_assigned_to_order_only.rb | 14 - ...327000605_create_address_keys_for_order.rb | 6 - ...20120327000606_payment_total_for_orders.rb | 5 - ...327000607_shipping_method_id_for_orders.rb | 5 - ...27000608_add_shipment_and_payment_state.rb | 6 - .../20120327000609_refactor_adjustments.rb | 29 -- ...onse_code_and_avs_response_for_payments.rb | 6 - ...27000611_change_guest_flag_to_anonymous.rb | 5 - db/migrate/20120327000612_email_for_orders.rb | 5 - .../20120327000613_create_mail_methods.rb | 10 - .../20120327000614_rename_frozen_to_locked.rb | 5 - ...615_move_special_instructions_to_orders.rb | 10 - .../20120327000616_create_log_entries.rb | 11 - ...7_migrate_transactions_to_payment_state.rb | 98 ---- ...0120327000618_delete_in_progress_orders.rb | 19 - ...120327000619_migrate_checkout_to_orders.rb | 23 - .../20120327000620_remove_shipped_state.rb | 12 - ...0120327000621_prevent_nil_payment_total.rb | 8 - .../20120327000622_prevent_nil_email.rb | 9 - ...20120327000623_generate_anonymous_users.rb | 20 - .../20120327000624_update_order_state.rb | 12 - .../20120327000625_cleanup_legacy_tables.rb | 11 - ...26_remove_number_and_cvv_from_credicard.rb | 11 - ...327000627_drop_anonymous_field_for_user.rb | 9 - ...20327000628_renamed_rma_cancelled_state.rb | 9 - ...20327000629_fix_problematic_index_names.rb | 13 - ...20120327000630_add_position_to_variants.rb | 5 - ...27000631_add_next_state_to_state_events.rb | 5 - ...0327000632_add_position_to_option_types.rb | 5 - ...ve_trailing_slashes_in_taxon_permalinks.rb | 19 - .../20120327000634_create_activators.rb | 14 - ...20120327000635_eligible_for_adjustments.rb | 5 - ...120327000636_namespace_top_level_models.rb | 52 -- ...7_migrate_namespaced_polymorphic_models.rb | 52 -- ...0327000638_make_adjustments_polymorphic.rb | 9 - ...20120327000639_add_company_to_addresses.rb | 5 - ...20120327000640_add_inc_tax_to_tax_rates.rb | 5 - ...120327000641_rename_inc_price_attribute.rb | 5 - .../20120327000642_add_default_tax_zone.rb | 5 - ...hipping_methods_and_shipping_categories.rb | 7 - ...644_add_match_rules_to_shipping_methods.rb | 7 - db/migrate/20120327000645_new_preferences.rb | 81 --- ...27000646_add_deleted_at_to_tax_category.rb | 5 - ...0120327000647_rename_columns_for_devise.rb | 39 -- ...20327000648_convert_user_remember_field.rb | 11 - ...0327000649_create_tokenized_permissions.rb | 13 - ...20120327000650_tokens_for_legacy_orders.rb | 16 - ...27000651_namespace_tokenized_permission.rb | 5 - ...327000652_migrate_tokenized_permissions.rb | 24 - .../20120327000653_add_api_key_to_users.rb | 5 - ...0327000654_rename_coupons_to_promotions.rb | 10 - .../20120327000655_create_promotion_rules.rb | 24 - ...20327000656_match_policy_for_promotions.rb | 5 - ...0327000657_create_promotion_rules_users.rb | 14 - .../20120327000658_name_for_promotions.rb | 5 - ...9_update_calculable_type_for_promotions.rb | 9 - .../20120327000660_migrate_adjustments.rb | 9 - ...motion_changes_to_subclass_of_activator.rb | 22 - ...20120327000662_create_promotion_actions.rb | 9 - ...0663_create_promotion_action_line_items.rb | 10 - .../20120327000664_namespace_promo_tables.rb | 85 --- ...7000665_create_spree_pending_promotions.rb | 11 - .../20120327000666_content_visited_event.rb | 29 -- ...120327000667_create_skrill_transactions.rb | 14 - .../20120331051742_create_distributors.rb | 18 - ...20120407065132_add_distributor_to_order.rb | 5 - ...add_extra_address_fields_to_distributor.rb | 7 - ...20120409004831_add_state_to_distributor.rb | 5 - db/migrate/20120422042134_add_supplier.rb | 16 - .../20120425065453_add_supplier_to_product.rb | 5 - ...654_replace_spree_address_from_supplier.rb | 12 - ...ame_state_events_to_state_changes.spree.rb | 10 - ..._images_from_products_to_variants.spree.rb | 36 -- ...ment_size_to_attachment_file_size.spree.rb | 6 - ..._move_distributor_from_order_to_product.rb | 26 - ...20621064227_add_distributor_id_to_order.rb | 5 - ...r_and_supplier_address_to_spree_address.rb | 92 ---- ...utors_products_to_product_distributions.rb | 27 - ...increase_scale_of_tax_rate_amount.spree.rb | 10 - ...sword_sent_at_to_spree_users.spree_auth.rb | 6 - ...29043045_resize_api_key_field.spree_api.rb | 6 - ...te_paypal_accounts.spree_paypal_express.rb | 15 - ...ce_paypal_accounts.spree_paypal_express.rb | 6 - ..._add_next_collection_at_to_distributors.rb | 5 - .../20120802031147_add_group_buy_fields.rb | 6 - ..._convert_sales_tax_to_default_tax.spree.rb | 10 - ...eted_at_to_spree_shipping_methods.spree.rb | 6 - ...659_make_users_email_index_unique.spree.rb | 11 - ...add_counter_cache_to_zone_members.spree.rb | 15 - ...13335_add_shipping_method_to_line_items.rb | 20 - ..._populate_order_default_shipping_method.rb | 10 - db/migrate/20121009232513_create_cms.rb | 137 ----- ...scription_to_distributors_and_suppliers.rb | 6 - ...907_add_group_buy_unit_size_to_products.rb | 5 - ...liers_and_distributors_into_enterprises.rb | 69 --- ..._remove_pickup_address_from_enterprises.rb | 21 - ...roup_buy_unit_size_from_string_to_float.rb | 21 - ...22403_remove_suppliers_and_distributors.rb | 37 -- .../20121115010717_create_enterprise_fees.rb | 11 - .../20121125232613_create_order_cycles.rb | 35 -- ...0_change_exchange_pickup_time_to_string.rb | 9 - ...0130204355_add_order_cycle_id_to_orders.rb | 5 - ...reate_tokenized_permissions_table.spree.rb | 17 - ...ename_creditcards_to_credit_cards.spree.rb | 12 - ...8_remove_credit_total_from_orders.spree.rb | 6 - ...20130207043039_add_tax_rate_label.spree.rb | 6 - ...43040_add_toggle_tax_rate_display.spree.rb | 6 - ...43041_add_lock_version_to_variant.spree.rb | 6 - ..._constraint_from_products_on_hand.spree.rb | 12 - ...043043_add_position_to_taxonomies.spree.rb | 6 - ..._add_identifier_to_spree_payments.spree.rb | 6 - ...name_api_key_to_spree_api_key.spree_api.rb | 8 - .../20130207043047_create_users.spree_auth.rb | 30 -- .../20130207043541_spree_one_two.spree.rb | 482 ------------------ ..._remove_unused_preference_columns.spree.rb | 9 - ..._add_states_required_to_countries.spree.rb | 6 - ..._on_demand_to_product_and_variant.spree.rb | 7 - ...043545_split_prices_from_variants.spree.rb | 32 -- ...not_null_from_spree_prices_amount.spree.rb | 10 - ...043547_add_currency_to_line_items.spree.rb | 6 - ...0207043548_add_currency_to_orders.spree.rb | 6 - ...549_add_cost_currency_to_variants.spree.rb | 6 - ...e_display_on_from_payment_methods.spree.rb | 10 - ...43551_add_last_ip_to_spree_orders.spree.rb | 6 - ...splay_on_to_spree_payment_methods.spree.rb | 10 - ...dd_position_to_product_properties.spree.rb | 7 - ...54_add_api_key_to_spree_users.spree_api.rb | 8 - ...7043555_spree_promo_one_two.spree_promo.rb | 46 -- ...ises_distributor_info_rich_text_feature.rb | 6 - ...33_add_order_id_index_to_payments.spree.rb | 10 - ..._primary_to_spree_products_taxons.spree.rb | 6 - ...5_add_order_id_index_to_shipments.spree.rb | 6 - ...ription_on_spree_products_to_text.spree.rb | 6 - ..._variant_id_index_to_spree_prices.spree.rb | 6 - ...638_change_orders_total_precision.spree.rb | 9 - ...e_spree_payments_amount_precision.spree.rb | 8 - ...rn_authorization_amount_precision.spree.rb | 8 - ...ange_adjustments_amount_precision.spree.rb | 8 - ...629120642_add_seo_metas_to_taxons.spree.rb | 10 - ..._result_message_to_spree_payments.spree.rb | 7 - ...ex_to_permalink_on_spree_products.spree.rb | 6 - ...ers_shipments_and_stock_transfers.spree.rb | 7 - ...4_make_order_cycle_coordinator_fees_mtm.rb | 19 - .../20130729030515_add_enterprise_role.rb | 8 - ...130801005801_create_landing_page_images.rb | 7 - ..._attachment_photo_to_landing_page_image.rb | 15 - ...20130805050109_update_line_item_caching.rb | 47 -- ...enterprise_fee_to_product_distributions.rb | 5 - db/migrate/20130806055125_create_suburbs.rb | 11 - ...add_latitude_and_longitude_to_addresses.rb | 6 - ...57_add_distributor_id_to_payment_method.rb | 5 - db/migrate/20130807230834_add_cart.rb | 9 - ...e_fee_records_for_product_distributions.rb | 26 - ...130809075103_create_adjustment_metadata.rb | 13 - ...ipping_method_from_product_distribution.rb | 9 - ...pping_methods_using_itemwise_calculator.rb | 15 - ..._add_distributor_id_to_shipping_methods.rb | 6 - ...553_create_distributors_payment_methods.rb | 20 - ...move_distributor_id_from_payment_method.rb | 12 - ...sure_shipping_methods_have_distributors.rb | 20 - ..._shipping_methods_distributors_to_habtm.rb | 37 -- ...20131024005253_create_enterprise_groups.rb | 13 - ...31125_add_position_to_enterprise_groups.rb | 5 - ...28034556_setup_product_units_and_values.rb | 14 - ...238_make_unit_description_default_blank.rb | 10 - ...30500_add_attachment_logo_to_enterprise.rb | 15 - ...dd_attachment_promo_image_to_enterprise.rb | 15 - .../20140204011203_add_notes_to_products.rb | 5 - ...equire_ship_address_to_shipping_methods.rb | 6 - ...0140324025840_add_incoming_to_exchanges.rb | 25 - .../20140402032034_add_missing_indexes.rb | 38 -- db/migrate/20140402033428_add_foreign_keys.rb | 188 ------- ...25055718_add_active_flag_to_enterprises.rb | 5 - ...rename_active_to_visible_on_enterprises.rb | 5 - ...4044959_create_enterprise_relationships.rb | 16 - ...achment_promo_image_to_enterprise_group.rb | 15 - .../20140516044750_add_fields_to_groups.rb | 6 - ...add_attachment_logo_to_enterprise_group.rb | 15 - ...2015012_add_social_media_to_enterprises.rb | 7 - ...522044009_add_primary_taxon_to_products.rb | 20 - ...y_name_and_display_as_to_spree_variants.rb | 6 - ...move_deleted_variants_from_order_cycles.rb | 10 - ...140613004344_create_producer_properties.rb | 18 - ...230121_change_suburb_postcode_to_string.rb | 9 - ...fields_to_distributors_shipping_methods.rb | 23 - ...20140716051214_drop_landing_page_images.rb | 16 - ..._express_checkouts.spree_paypal_express.rb | 9 - ..._express_checkouts.spree_paypal_express.rb | 7 - ..._express_checkouts.spree_paypal_express.rb | 6 - ..._express_checkouts.spree_paypal_express.rb | 9 - .../20140723023713_switch_paypal_methods.rb | 13 - ...d_unique_constraint_to_enterprise_roles.rb | 5 - .../20140815065014_add_type_to_enterprises.rb | 10 - ...ate_enterprise_relationship_permissions.rb | 11 - ...3521_prevent_duplicate_enterprise_roles.rb | 5 - .../20140828023619_add_owner_to_enterprise.rb | 22 - ...026_add_enterprise_limit_to_spree_users.rb | 18 - ...0927005000_add_dummy_for_missing_emails.rb | 7 - ...140927005043_enterprise_config_refactor.rb | 57 --- ...060622_add_standard_variant_to_products.rb | 63 --- ...010043405_add_confirmable_to_enterprise.rb | 16 - ...dd_shop_trial_start_date_to_enterprises.rb | 5 - ...dd_producer_profile_only_to_enterprises.rb | 5 - ...20141113053004_create_variant_overrides.rb | 15 - ..._not_null_to_variant_override_relations.rb | 11 - ...1219034321_add_permalink_to_enterprises.rb | 25 - ...229094516_add_receival_time_to_exchange.rb | 6 - ..._add_addresses_ref_to_enterprise_groups.rb | 6 - ...instances_to_existing_enterprise_groups.rb | 19 - ...27_add_web_contact_to_enterprise_groups.rb | 10 - db/migrate/20150122145607_create_customers.rb | 18 - ...02000203_add_owner_to_enterprise_groups.rb | 6 - ...controlled_to_spree_shipping_categories.rb | 5 - ...42_add_owner_index_to_enterprise_groups.rb | 5 - ...d_address_id_index_to_enterprise_groups.rb | 5 - ...1538_add_tax_category_to_enterprise_fee.rb | 7 - ...5232938_add_included_tax_to_adjustments.rb | 5 - ...20150305004846_add_weight_to_line_items.rb | 5 - ...39_add_charges_sales_tax_to_enterprises.rb | 5 - .../20150410043302_create_delayed_jobs.rb | 22 - ...4819_add_inherits_properties_to_product.rb | 5 - ...ot_null_to_producer_properties_position.rb | 9 - ...424151117_populate_line_item_unit_value.rb | 9 - ...on_migration.acts_as_taggable_on_engine.rb | 31 -- ...ique_indices.acts_as_taggable_on_engine.rb | 20 - ...ache_to_tags.acts_as_taggable_on_engine.rb | 15 - ...ggable_index.acts_as_taggable_on_engine.rb | 10 - ...or_tag_names.acts_as_taggable_on_engine.rb | 10 - ...emove_customer_code_not_null_constraint.rb | 9 - .../20150508072938_add_customer_to_orders.rb | 16 - .../20150527004427_add_permalink_to_groups.rb | 26 - ...dd_unique_index_to_enterprise_permalink.rb | 16 - .../20150604045725_add_sessions_table.rb | 12 - ...16_dependent_delete_adjustment_metadata.rb | 11 - ...0612045544_make_enterprises_name_unique.rb | 20 - db/migrate/20150619020711_create_versions.rb | 13 - .../20150619100137_create_bill_items.rb | 15 - ...8_rename_bill_items_to_billable_periods.rb | 9 - ...4055_add_timestamps_to_billable_periods.rb | 8 - ..._add_default_stock_to_variant_overrides.rb | 5 - ...50719153136_rename_line_item_unit_value.rb | 5 - ...cision_on_line_item_final_weight_volume.rb | 11 - ...ate_spree_line_item_final_weight_volume.rb | 9 - ...2_add_enable_reset_to_variant_overrides.rb | 5 - .../20150916012814_create_account_invoices.rb | 18 - ...add_account_invoice_to_billable_periods.rb | 7 - ...add_option_values_line_items_join_table.rb | 14 - ...sure_address_for_account_invoice_orders.rb | 15 - ...nge_receival_time_receival_instructions.rb | 9 - ..._on_demand_and_sku_to_variant_overrides.rb | 6 - ...85900_rename_enable_reset_to_resettable.rb | 3 - .../20160114001844_create_inventory_items.rb | 13 - ...0160116024333_create_column_preferences.rb | 13 - ...160204013914_add_id_to_coordinator_fees.rb | 5 - ...nherits_tax_category_to_enterprise_fees.rb | 5 - ...044930_add_email_address_to_enterprises.rb | 5 - ...0212092908_set_enterprise_email_address.rb | 8 - .../20160218235221_populate_inventories.rb | 22 - ...t_explicit_variant_override_permissions.rb | 30 -- ...mission_revoked_at_to_variant_overrides.rb | 21 - .../20160302044850_repopulate_inventories.rb | 30 -- db/migrate/20160303004210_create_tag_rules.rb | 10 - ...6051131_add_require_login_to_enterprise.rb | 5 - ...7_change_value_type_of_paypal_passwords.rb | 15 - ...160520065217_add_is_default_to_tag_rule.rb | 5 - ...20160527012603_add_priority_to_tag_rule.rb | 5 - db/migrate/20160630052453_create_schedules.rb | 8 - ...0630055825_create_order_cycle_schedules.rb | 14 - db/migrate/20160707023818_drop_cms.rb | 154 ------ ...ll_address_and_ship_address_to_customer.rb | 12 - .../20160713013358_add_name_to_customer.rb | 5 - .../20160819045727_create_standing_orders.rb | 25 - ...wap_calculator_to_flat_percent_per_item.rb | 29 -- ...160824013751_create_standing_line_items.rb | 16 - .../20160828115018_create_stripe_accounts.rb | 12 - ...35_add_state_to_spree_adjustments.spree.rb | 7 - ...42_add_allow_guest_orders_to_enterprise.rb | 5 - ...2_add_allow_order_changes_to_enterprise.rb | 5 - ...hip_and_bill_address_to_standing_orders.rb | 12 - ...1020012017_create_standing_order_orders.rb | 16 - ...anding_orders_placed_at_to_order_cycles.rb | 5 - ...d_price_estimate_to_standing_line_items.rb | 5 - ...2009_add_canceled_at_to_standing_orders.rb | 5 - ...name_standing_order_orders_cancelled_at.rb | 7 - ...042153_add_paused_at_to_standing_orders.rb | 5 - ...ing_orders_confirmed_at_to_order_cycles.rb | 5 - ...e_standing_order_orders_to_proxy_orders.rb | 9 - ...5939_add_order_cycle_id_to_proxy_orders.rb | 20 - ...e_proxy_order_order_not_null_constraint.rb | 9 - ...d_enable_standing_orders_to_enterprises.rb | 5 - ...ce_text_and_invoice_logo_to_enterprises.rb | 6 - ...ced_at_and_confirmed_at_to_proxy_orders.rb | 6 - ...03658_add_user_id_to_spree_credit_cards.rb | 8 - ...dd_payment_method_to_spree_credit_cards.rb | 8 - ...31746_add_import_date_to_spree_variants.rb | 5 - ...01_add_import_date_to_variant_overrides.rb | 5 - ...me_payment_methods.spree_paypal_express.rb | 14 - ...ing_url_to_spree_shipping_methods.spree.rb | 6 - ...0170512115519_add_locale_to_spree_users.rb | 5 - .../20170710145821_add_confirmable_to_user.rb | 16 - ...120_remove_confirmable_from_enterprises.rb | 16 - ...eives_notifications_to_enterprise_roles.rb | 5 - ...728140134_remove_email_from_enterprises.rb | 48 -- ...t_value_of_spree_users_enterprise_limit.rb | 9 - ...21065259_update_adjustment_states.spree.rb | 17 - ...5930_add_credit_card_to_standing_orders.rb | 7 - ...rename_standing_orders_to_subscriptions.rb | 99 ---- ...g_line_items_to_subscription_line_items.rb | 27 - ...nd_payment_fee_estimate_to_subscription.rb | 6 - ...d_at_and_confirmed_at_from_order_cycles.rb | 11 - ...045821_add_charges_allowed_to_customers.rb | 5 - ...418025217_add_is_default_to_credit_card.rb | 5 - ...26145630_create_spree_stock_items.spree.rb | 15 - ...5631_create_spree_stock_locations.spree.rb | 12 - ...180426145632_create_default_stock.spree.rb | 34 -- ...ck_location_id_to_spree_shipments.spree.rb | 6 - ...634_add_pending_to_inventory_unit.spree.rb | 7 - ...n_demand_from_product_and_variant.spree.rb | 7 - ...45636_create_shipping_method_zone.spree.rb | 23 - ..._category_id_from_shipping_method.spree.rb | 6 - ...create_shipping_method_categories.spree.rb | 14 - ...45639_create_spree_shipping_rates.spree.rb | 25 - ...h_attributes_from_shipping_method.spree.rb | 8 - ...0426145641_create_stock_movements.spree.rb | 13 - ..._address_fields_to_stock_location.spree.rb | 23 - ...d_active_field_to_stock_locations.spree.rb | 6 - ...4_add_backorderable_to_stock_item.spree.rb | 6 - ...efault_quantity_to_stock_movement.spree.rb | 6 - ...nd_destination_to_stock_movements.spree.rb | 9 - ..._add_originator_to_stock_movement.spree.rb | 8 - ...d_destination_from_stock_movement.spree.rb | 16 - ...te_inventory_unit_sold_to_on_hand.spree.rb | 10 - ...6145650_add_stock_location_to_rma.spree.rb | 6 - ...hipment_state_for_canceled_orders.spree.rb | 16 - ...emove_stock_item_and_variant_lock.spree.rb | 15 - ...3_add_shipping_rates_to_shipments.spree.rb | 16 - ...5654_create_spree_stock_transfers.spree.rb | 15 - ...45655_drop_products_count_on_hand.spree.rb | 6 - ...56_set_default_shipping_rate_cost.spree.rb | 6 - ...5657_add_number_to_stock_transfer.spree.rb | 24 - ...8_add_sku_index_to_spree_variants.spree.rb | 6 - ...e_default_to_spree_stock_location.spree.rb | 6 - ..._variants_to_spree_stock_location.spree.rb | 6 - ...s_to_spree_shipping_methods_zones.spree.rb | 6 - ...add_deleted_at_to_spree_tax_rates.spree.rb | 6 - ...lock_version_from_inventory_units.spree.rb | 7 - ...45664_add_cost_price_to_line_item.spree.rb | 6 - ...backorderable_to_default_to_false.spree.rb | 7 - ...add_created_by_id_to_spree_orders.spree.rb | 6 - ...ndex_completed_at_on_spree_orders.spree.rb | 6 - ...x_category_id_to_spree_line_items.spree.rb | 6 - ...rate_tax_categories_to_line_items.spree.rb | 14 - ...0_remove_credit_card_from_subscriptions.rb | 13 - db/migrate/20180812214434_drop_carts.rb | 7 - ...ness_of_variant_id_to_spree_stock_items.rb | 8 - ...iqueness_of_order_id_to_spree_shipments.rb | 92 ---- ...pping_method_name_from_spree_line_items.rb | 9 - .../20181008201815_update_instagram_data.rb | 8 - ...0093850_fix_variants_missing_unit_value.rb | 49 -- ...ke_variant_overrideswithout_permissions.rb | 17 - ...low_all_suppliers_own_variant_overrides.rb | 12 - ...pdate_weight_calculator_type_class_name.rb | 9 - ...1123012635_associate_customers_to_users.rb | 42 -- .../20181128054803_old_migrations_removed.rb | 11 + ...implify_variant_override_stock_settings.rb | 165 ------ 417 files changed, 11 insertions(+), 7125 deletions(-) delete mode 100644 db/migrate/20120327000552_spree_zero_nine_zero.rb delete mode 100644 db/migrate/20120327000553_create_indexes_for_inventory_units.rb delete mode 100644 db/migrate/20120327000554_add_count_on_hand_to_variants_and_products.rb delete mode 100644 db/migrate/20120327000555_change_taxons_to_nested_set.rb delete mode 100644 db/migrate/20120327000556_move_to_configurable_gateways.rb delete mode 100644 db/migrate/20120327000557_product_groups_and_scopes.rb delete mode 100644 db/migrate/20120327000558_add_open_id_authentication_tables.rb delete mode 100644 db/migrate/20120327000559_add_openid_field_to_users.rb delete mode 100644 db/migrate/20120327000560_change_preference_value_type.rb delete mode 100644 db/migrate/20120327000561_create_billing_integrations.rb delete mode 100644 db/migrate/20120327000562_charge_refactoring.rb delete mode 100644 db/migrate/20120327000563_add_some_indexes.rb delete mode 100644 db/migrate/20120327000564_checkout_state_machine.rb delete mode 100644 db/migrate/20120327000565_state_for_shipments.rb delete mode 100644 db/migrate/20120327000566_make_state_events_polymorphic.rb delete mode 100644 db/migrate/20120327000567_ship_address_id_for_checkouts.rb delete mode 100644 db/migrate/20120327000568_shipping_method_id_for_checkouts.rb delete mode 100644 db/migrate/20120327000569_creditcard_last_four_digits.rb delete mode 100644 db/migrate/20120327000570_populate_legacy_shipment_state.rb delete mode 100644 db/migrate/20120327000571_add_cost_price.rb delete mode 100644 db/migrate/20120327000572_shipment_id_for_inventory_units.rb delete mode 100644 db/migrate/20120327000573_cim_fields_for_creditcards.rb delete mode 100644 db/migrate/20120327000574_create_return_authorizations.rb delete mode 100644 db/migrate/20120327000575_add_return_authorization_to_inventory_units.rb delete mode 100644 db/migrate/20120327000576_create_trackers.rb delete mode 100644 db/migrate/20120327000577_creditcard_id_for_creditcard_txns.rb delete mode 100644 db/migrate/20120327000578_original_creditcard_txn_id_for_creditcard_txns.rb delete mode 100644 db/migrate/20120327000579_add_test_mode_to_billing_integration.rb delete mode 100644 db/migrate/20120327000580_create_products_product_groups.rb delete mode 100644 db/migrate/20120327000581_create_payment_methods.rb delete mode 100644 db/migrate/20120327000582_polymorphic_payments.rb delete mode 100644 db/migrate/20120327000583_change_payments_payment_method_to_belongs_to.rb delete mode 100644 db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb delete mode 100644 db/migrate/20120327000585_sti_for_transactions.rb delete mode 100644 db/migrate/20120327000586_drop_billing_integrations.rb delete mode 100644 db/migrate/20120327000587_deleted_at_for_payment_methods.rb delete mode 100644 db/migrate/20120327000588_add_adjustments_index.rb delete mode 100644 db/migrate/20120327000589_fix_by_popularity.rb delete mode 100644 db/migrate/20120327000590_add_alt_text_to_images.rb delete mode 100644 db/migrate/20120327000591_fix_existing_coupon_credits.rb delete mode 100644 db/migrate/20120327000592_add_display_to_payment_methods.rb delete mode 100644 db/migrate/20120327000593_add_addresses_checkouts_indexes.rb delete mode 100644 db/migrate/20120327000594_add_icon_to_taxons.rb delete mode 100644 db/migrate/20120327000595_add_description_to_taxons.rb delete mode 100644 db/migrate/20120327000596_index_for_shipments_number.rb delete mode 100644 db/migrate/20120327000597_add_index_on_users_persistence_token.rb delete mode 100644 db/migrate/20120327000598_add_default_to_tax_categories.rb delete mode 100644 db/migrate/20120327000599_add_display_to_shipping_methods.rb delete mode 100644 db/migrate/20120327000600_rename_payment_method_display.rb delete mode 100644 db/migrate/20120327000601_rename_preferences_field.rb delete mode 100644 db/migrate/20120327000602_add_guest_flag.rb delete mode 100644 db/migrate/20120327000603_drop_order_token.rb delete mode 100644 db/migrate/20120327000604_payments_state_and_assigned_to_order_only.rb delete mode 100644 db/migrate/20120327000605_create_address_keys_for_order.rb delete mode 100644 db/migrate/20120327000606_payment_total_for_orders.rb delete mode 100644 db/migrate/20120327000607_shipping_method_id_for_orders.rb delete mode 100644 db/migrate/20120327000608_add_shipment_and_payment_state.rb delete mode 100644 db/migrate/20120327000609_refactor_adjustments.rb delete mode 100644 db/migrate/20120327000610_response_code_and_avs_response_for_payments.rb delete mode 100644 db/migrate/20120327000611_change_guest_flag_to_anonymous.rb delete mode 100644 db/migrate/20120327000612_email_for_orders.rb delete mode 100644 db/migrate/20120327000613_create_mail_methods.rb delete mode 100644 db/migrate/20120327000614_rename_frozen_to_locked.rb delete mode 100644 db/migrate/20120327000615_move_special_instructions_to_orders.rb delete mode 100644 db/migrate/20120327000616_create_log_entries.rb delete mode 100644 db/migrate/20120327000617_migrate_transactions_to_payment_state.rb delete mode 100644 db/migrate/20120327000618_delete_in_progress_orders.rb delete mode 100644 db/migrate/20120327000619_migrate_checkout_to_orders.rb delete mode 100644 db/migrate/20120327000620_remove_shipped_state.rb delete mode 100644 db/migrate/20120327000621_prevent_nil_payment_total.rb delete mode 100644 db/migrate/20120327000622_prevent_nil_email.rb delete mode 100644 db/migrate/20120327000623_generate_anonymous_users.rb delete mode 100644 db/migrate/20120327000624_update_order_state.rb delete mode 100644 db/migrate/20120327000625_cleanup_legacy_tables.rb delete mode 100644 db/migrate/20120327000626_remove_number_and_cvv_from_credicard.rb delete mode 100644 db/migrate/20120327000627_drop_anonymous_field_for_user.rb delete mode 100644 db/migrate/20120327000628_renamed_rma_cancelled_state.rb delete mode 100644 db/migrate/20120327000629_fix_problematic_index_names.rb delete mode 100644 db/migrate/20120327000630_add_position_to_variants.rb delete mode 100644 db/migrate/20120327000631_add_next_state_to_state_events.rb delete mode 100644 db/migrate/20120327000632_add_position_to_option_types.rb delete mode 100644 db/migrate/20120327000633_remove_trailing_slashes_in_taxon_permalinks.rb delete mode 100644 db/migrate/20120327000634_create_activators.rb delete mode 100644 db/migrate/20120327000635_eligible_for_adjustments.rb delete mode 100644 db/migrate/20120327000636_namespace_top_level_models.rb delete mode 100644 db/migrate/20120327000637_migrate_namespaced_polymorphic_models.rb delete mode 100644 db/migrate/20120327000638_make_adjustments_polymorphic.rb delete mode 100644 db/migrate/20120327000639_add_company_to_addresses.rb delete mode 100644 db/migrate/20120327000640_add_inc_tax_to_tax_rates.rb delete mode 100644 db/migrate/20120327000641_rename_inc_price_attribute.rb delete mode 100644 db/migrate/20120327000642_add_default_tax_zone.rb delete mode 100644 db/migrate/20120327000643_associate_shipping_methods_and_shipping_categories.rb delete mode 100644 db/migrate/20120327000644_add_match_rules_to_shipping_methods.rb delete mode 100644 db/migrate/20120327000645_new_preferences.rb delete mode 100644 db/migrate/20120327000646_add_deleted_at_to_tax_category.rb delete mode 100644 db/migrate/20120327000647_rename_columns_for_devise.rb delete mode 100644 db/migrate/20120327000648_convert_user_remember_field.rb delete mode 100644 db/migrate/20120327000649_create_tokenized_permissions.rb delete mode 100644 db/migrate/20120327000650_tokens_for_legacy_orders.rb delete mode 100644 db/migrate/20120327000651_namespace_tokenized_permission.rb delete mode 100644 db/migrate/20120327000652_migrate_tokenized_permissions.rb delete mode 100644 db/migrate/20120327000653_add_api_key_to_users.rb delete mode 100644 db/migrate/20120327000654_rename_coupons_to_promotions.rb delete mode 100644 db/migrate/20120327000655_create_promotion_rules.rb delete mode 100644 db/migrate/20120327000656_match_policy_for_promotions.rb delete mode 100644 db/migrate/20120327000657_create_promotion_rules_users.rb delete mode 100644 db/migrate/20120327000658_name_for_promotions.rb delete mode 100644 db/migrate/20120327000659_update_calculable_type_for_promotions.rb delete mode 100644 db/migrate/20120327000660_migrate_adjustments.rb delete mode 100644 db/migrate/20120327000661_promotion_changes_to_subclass_of_activator.rb delete mode 100644 db/migrate/20120327000662_create_promotion_actions.rb delete mode 100644 db/migrate/20120327000663_create_promotion_action_line_items.rb delete mode 100644 db/migrate/20120327000664_namespace_promo_tables.rb delete mode 100644 db/migrate/20120327000665_create_spree_pending_promotions.rb delete mode 100644 db/migrate/20120327000666_content_visited_event.rb delete mode 100644 db/migrate/20120327000667_create_skrill_transactions.rb delete mode 100644 db/migrate/20120331051742_create_distributors.rb delete mode 100644 db/migrate/20120407065132_add_distributor_to_order.rb delete mode 100644 db/migrate/20120408081918_add_extra_address_fields_to_distributor.rb delete mode 100644 db/migrate/20120409004831_add_state_to_distributor.rb delete mode 100644 db/migrate/20120422042134_add_supplier.rb delete mode 100644 db/migrate/20120425065453_add_supplier_to_product.rb delete mode 100644 db/migrate/20120429071654_replace_spree_address_from_supplier.rb delete mode 100644 db/migrate/20120520062059_rename_state_events_to_state_changes.spree.rb delete mode 100644 db/migrate/20120520062060_migrate_images_from_products_to_variants.spree.rb delete mode 100644 db/migrate/20120520062061_rename_attachment_size_to_attachment_file_size.spree.rb delete mode 100644 db/migrate/20120618061537_move_distributor_from_order_to_product.rb delete mode 100644 db/migrate/20120621064227_add_distributor_id_to_order.rb delete mode 100644 db/migrate/20120626013846_extract_distributor_and_supplier_address_to_spree_address.rb delete mode 100644 db/migrate/20120626233350_rename_distributors_products_to_product_distributions.rb delete mode 100644 db/migrate/20120629043042_increase_scale_of_tax_rate_amount.spree.rb delete mode 100644 db/migrate/20120629043043_add_reset_password_sent_at_to_spree_users.spree_auth.rb delete mode 100644 db/migrate/20120629043045_resize_api_key_field.spree_api.rb delete mode 100644 db/migrate/20120629043647_create_paypal_accounts.spree_paypal_express.rb delete mode 100644 db/migrate/20120629043648_namespace_paypal_accounts.spree_paypal_express.rb delete mode 100644 db/migrate/20120702020402_add_next_collection_at_to_distributors.rb delete mode 100644 db/migrate/20120802031147_add_group_buy_fields.rb delete mode 100644 db/migrate/20120913054657_convert_sales_tax_to_default_tax.spree.rb delete mode 100644 db/migrate/20120913054658_add_deleted_at_to_spree_shipping_methods.spree.rb delete mode 100644 db/migrate/20120913054659_make_users_email_index_unique.spree.rb delete mode 100644 db/migrate/20120913054660_add_counter_cache_to_zone_members.spree.rb delete mode 100644 db/migrate/20120919013335_add_shipping_method_to_line_items.rb delete mode 100644 db/migrate/20121005015852_populate_order_default_shipping_method.rb delete mode 100644 db/migrate/20121009232513_create_cms.rb delete mode 100644 db/migrate/20121010004400_add_long_description_to_distributors_and_suppliers.rb delete mode 100644 db/migrate/20121018002907_add_group_buy_unit_size_to_products.rb delete mode 100644 db/migrate/20121025012233_combine_suppliers_and_distributors_into_enterprises.rb delete mode 100644 db/migrate/20121028070200_remove_pickup_address_from_enterprises.rb delete mode 100644 db/migrate/20121031203807_change_group_buy_unit_size_from_string_to_float.rb delete mode 100644 db/migrate/20121031222403_remove_suppliers_and_distributors.rb delete mode 100644 db/migrate/20121115010717_create_enterprise_fees.rb delete mode 100644 db/migrate/20121125232613_create_order_cycles.rb delete mode 100644 db/migrate/20130118031610_change_exchange_pickup_time_to_string.rb delete mode 100644 db/migrate/20130130204355_add_order_cycle_id_to_orders.rb delete mode 100644 db/migrate/20130207043036_create_tokenized_permissions_table.spree.rb delete mode 100644 db/migrate/20130207043037_rename_creditcards_to_credit_cards.spree.rb delete mode 100644 db/migrate/20130207043038_remove_credit_total_from_orders.spree.rb delete mode 100644 db/migrate/20130207043039_add_tax_rate_label.spree.rb delete mode 100644 db/migrate/20130207043040_add_toggle_tax_rate_display.spree.rb delete mode 100644 db/migrate/20130207043041_add_lock_version_to_variant.spree.rb delete mode 100644 db/migrate/20130207043042_remove_not_null_constraint_from_products_on_hand.spree.rb delete mode 100644 db/migrate/20130207043043_add_position_to_taxonomies.spree.rb delete mode 100644 db/migrate/20130207043044_add_identifier_to_spree_payments.spree.rb delete mode 100644 db/migrate/20130207043046_rename_api_key_to_spree_api_key.spree_api.rb delete mode 100644 db/migrate/20130207043047_create_users.spree_auth.rb delete mode 100644 db/migrate/20130207043541_spree_one_two.spree.rb delete mode 100644 db/migrate/20130207043542_remove_unused_preference_columns.spree.rb delete mode 100644 db/migrate/20130207043543_add_states_required_to_countries.spree.rb delete mode 100644 db/migrate/20130207043544_add_on_demand_to_product_and_variant.spree.rb delete mode 100644 db/migrate/20130207043545_split_prices_from_variants.spree.rb delete mode 100644 db/migrate/20130207043546_remove_not_null_from_spree_prices_amount.spree.rb delete mode 100644 db/migrate/20130207043547_add_currency_to_line_items.spree.rb delete mode 100644 db/migrate/20130207043548_add_currency_to_orders.spree.rb delete mode 100644 db/migrate/20130207043549_add_cost_currency_to_variants.spree.rb delete mode 100644 db/migrate/20130207043550_remove_display_on_from_payment_methods.spree.rb delete mode 100644 db/migrate/20130207043551_add_last_ip_to_spree_orders.spree.rb delete mode 100644 db/migrate/20130207043552_add_display_on_to_spree_payment_methods.spree.rb delete mode 100644 db/migrate/20130207043553_add_position_to_product_properties.spree.rb delete mode 100644 db/migrate/20130207043554_add_api_key_to_spree_users.spree_api.rb delete mode 100644 db/migrate/20130207043555_spree_promo_one_two.spree_promo.rb delete mode 100644 db/migrate/20130426023034_add_distributor_info_to_enterprises.enterprises_distributor_info_rich_text_feature.rb delete mode 100644 db/migrate/20130629120633_add_order_id_index_to_payments.spree.rb delete mode 100644 db/migrate/20130629120634_add_primary_to_spree_products_taxons.spree.rb delete mode 100644 db/migrate/20130629120635_add_order_id_index_to_shipments.spree.rb delete mode 100644 db/migrate/20130629120636_change_meta_description_on_spree_products_to_text.spree.rb delete mode 100644 db/migrate/20130629120637_add_variant_id_index_to_spree_prices.spree.rb delete mode 100644 db/migrate/20130629120638_change_orders_total_precision.spree.rb delete mode 100644 db/migrate/20130629120639_change_spree_payments_amount_precision.spree.rb delete mode 100644 db/migrate/20130629120640_change_spree_return_authorization_amount_precision.spree.rb delete mode 100644 db/migrate/20130629120641_change_adjustments_amount_precision.spree.rb delete mode 100644 db/migrate/20130629120642_add_seo_metas_to_taxons.spree.rb delete mode 100644 db/migrate/20130629120643_add_cvv_result_code_and_cvv_result_message_to_spree_payments.spree.rb delete mode 100644 db/migrate/20130629120644_add_unique_index_to_permalink_on_spree_products.spree.rb delete mode 100644 db/migrate/20130629120645_add_unique_index_to_orders_shipments_and_stock_transfers.spree.rb delete mode 100644 db/migrate/20130729021924_make_order_cycle_coordinator_fees_mtm.rb delete mode 100644 db/migrate/20130729030515_add_enterprise_role.rb delete mode 100644 db/migrate/20130801005801_create_landing_page_images.rb delete mode 100644 db/migrate/20130801012854_add_attachment_photo_to_landing_page_image.rb delete mode 100644 db/migrate/20130805050109_update_line_item_caching.rb delete mode 100644 db/migrate/20130805232516_add_enterprise_fee_to_product_distributions.rb delete mode 100644 db/migrate/20130806055125_create_suburbs.rb delete mode 100644 db/migrate/20130807002915_add_latitude_and_longitude_to_addresses.rb delete mode 100644 db/migrate/20130807062657_add_distributor_id_to_payment_method.rb delete mode 100644 db/migrate/20130807230834_add_cart.rb delete mode 100644 db/migrate/20130809045637_create_enterprise_fee_records_for_product_distributions.rb delete mode 100644 db/migrate/20130809075103_create_adjustment_metadata.rb delete mode 100644 db/migrate/20130812233634_remove_shipping_method_from_product_distribution.rb delete mode 100644 db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb delete mode 100644 db/migrate/20130830012138_add_distributor_id_to_shipping_methods.rb delete mode 100644 db/migrate/20130912021553_create_distributors_payment_methods.rb delete mode 100644 db/migrate/20130912021938_remove_distributor_id_from_payment_method.rb delete mode 100644 db/migrate/20130919010513_ensure_shipping_methods_have_distributors.rb delete mode 100644 db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb delete mode 100644 db/migrate/20131024005253_create_enterprise_groups.rb delete mode 100644 db/migrate/20131030031125_add_position_to_enterprise_groups.rb delete mode 100644 db/migrate/20131128034556_setup_product_units_and_values.rb delete mode 100644 db/migrate/20140110040238_make_unit_description_default_blank.rb delete mode 100644 db/migrate/20140116030500_add_attachment_logo_to_enterprise.rb delete mode 100644 db/migrate/20140121050239_add_attachment_promo_image_to_enterprise.rb delete mode 100644 db/migrate/20140204011203_add_notes_to_products.rb delete mode 100644 db/migrate/20140213003443_add_require_ship_address_to_shipping_methods.rb delete mode 100644 db/migrate/20140324025840_add_incoming_to_exchanges.rb delete mode 100644 db/migrate/20140402032034_add_missing_indexes.rb delete mode 100644 db/migrate/20140402033428_add_foreign_keys.rb delete mode 100644 db/migrate/20140425055718_add_active_flag_to_enterprises.rb delete mode 100644 db/migrate/20140430020639_rename_active_to_visible_on_enterprises.rb delete mode 100644 db/migrate/20140514044959_create_enterprise_relationships.rb delete mode 100644 db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb delete mode 100644 db/migrate/20140516044750_add_fields_to_groups.rb delete mode 100644 db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb delete mode 100644 db/migrate/20140522015012_add_social_media_to_enterprises.rb delete mode 100644 db/migrate/20140522044009_add_primary_taxon_to_products.rb delete mode 100644 db/migrate/20140604051248_add_display_name_and_display_as_to_spree_variants.rb delete mode 100644 db/migrate/20140612020206_remove_deleted_variants_from_order_cycles.rb delete mode 100644 db/migrate/20140613004344_create_producer_properties.rb delete mode 100644 db/migrate/20140621230121_change_suburb_postcode_to_string.rb delete mode 100644 db/migrate/20140702053145_add_fields_to_distributors_shipping_methods.rb delete mode 100644 db/migrate/20140716051214_drop_landing_page_images.rb delete mode 100644 db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb delete mode 100644 db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb delete mode 100644 db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb delete mode 100644 db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb delete mode 100644 db/migrate/20140723023713_switch_paypal_methods.rb delete mode 100644 db/migrate/20140815053659_add_unique_constraint_to_enterprise_roles.rb delete mode 100644 db/migrate/20140815065014_add_type_to_enterprises.rb delete mode 100644 db/migrate/20140825023227_create_enterprise_relationship_permissions.rb delete mode 100644 db/migrate/20140826043521_prevent_duplicate_enterprise_roles.rb delete mode 100644 db/migrate/20140828023619_add_owner_to_enterprise.rb delete mode 100644 db/migrate/20140904003026_add_enterprise_limit_to_spree_users.rb delete mode 100644 db/migrate/20140927005000_add_dummy_for_missing_emails.rb delete mode 100644 db/migrate/20140927005043_enterprise_config_refactor.rb delete mode 100644 db/migrate/20141003060622_add_standard_variant_to_products.rb delete mode 100644 db/migrate/20141010043405_add_confirmable_to_enterprise.rb delete mode 100644 db/migrate/20141022050659_add_shop_trial_start_date_to_enterprises.rb delete mode 100644 db/migrate/20141023050324_add_producer_profile_only_to_enterprises.rb delete mode 100644 db/migrate/20141113053004_create_variant_overrides.rb delete mode 100644 db/migrate/20141210233407_add_not_null_to_variant_override_relations.rb delete mode 100644 db/migrate/20141219034321_add_permalink_to_enterprises.rb delete mode 100644 db/migrate/20141229094516_add_receival_time_to_exchange.rb delete mode 100644 db/migrate/20150115050935_add_addresses_ref_to_enterprise_groups.rb delete mode 100644 db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb delete mode 100644 db/migrate/20150121030627_add_web_contact_to_enterprise_groups.rb delete mode 100644 db/migrate/20150122145607_create_customers.rb delete mode 100644 db/migrate/20150202000203_add_owner_to_enterprise_groups.rb delete mode 100644 db/migrate/20150216075336_add_temperature_controlled_to_spree_shipping_categories.rb delete mode 100644 db/migrate/20150219021742_add_owner_index_to_enterprise_groups.rb delete mode 100644 db/migrate/20150220035501_add_address_id_index_to_enterprise_groups.rb delete mode 100644 db/migrate/20150225111538_add_tax_category_to_enterprise_fee.rb delete mode 100644 db/migrate/20150225232938_add_included_tax_to_adjustments.rb delete mode 100644 db/migrate/20150305004846_add_weight_to_line_items.rb delete mode 100644 db/migrate/20150407234739_add_charges_sales_tax_to_enterprises.rb delete mode 100644 db/migrate/20150410043302_create_delayed_jobs.rb delete mode 100644 db/migrate/20150422014819_add_inherits_properties_to_product.rb delete mode 100644 db/migrate/20150424025907_add_default_and_not_null_to_producer_properties_position.rb delete mode 100644 db/migrate/20150424151117_populate_line_item_unit_value.rb delete mode 100644 db/migrate/20150508030520_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb delete mode 100644 db/migrate/20150508030521_add_missing_unique_indices.acts_as_taggable_on_engine.rb delete mode 100644 db/migrate/20150508030522_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb delete mode 100644 db/migrate/20150508030523_add_missing_taggable_index.acts_as_taggable_on_engine.rb delete mode 100644 db/migrate/20150508030524_change_collation_for_tag_names.acts_as_taggable_on_engine.rb delete mode 100644 db/migrate/20150508072454_remove_customer_code_not_null_constraint.rb delete mode 100644 db/migrate/20150508072938_add_customer_to_orders.rb delete mode 100644 db/migrate/20150527004427_add_permalink_to_groups.rb delete mode 100644 db/migrate/20150603001843_add_unique_index_to_enterprise_permalink.rb delete mode 100644 db/migrate/20150604045725_add_sessions_table.rb delete mode 100644 db/migrate/20150605052516_dependent_delete_adjustment_metadata.rb delete mode 100644 db/migrate/20150612045544_make_enterprises_name_unique.rb delete mode 100644 db/migrate/20150619020711_create_versions.rb delete mode 100644 db/migrate/20150619100137_create_bill_items.rb delete mode 100644 db/migrate/20150626090338_rename_bill_items_to_billable_periods.rb delete mode 100644 db/migrate/20150701034055_add_timestamps_to_billable_periods.rb delete mode 100644 db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb delete mode 100644 db/migrate/20150719153136_rename_line_item_unit_value.rb delete mode 100644 db/migrate/20150719153732_update_precision_on_line_item_final_weight_volume.rb delete mode 100644 db/migrate/20150730160010_update_spree_line_item_final_weight_volume.rb delete mode 100644 db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb delete mode 100644 db/migrate/20150916012814_create_account_invoices.rb delete mode 100644 db/migrate/20150916061809_add_account_invoice_to_billable_periods.rb delete mode 100644 db/migrate/20150924054538_add_option_values_line_items_join_table.rb delete mode 100644 db/migrate/20151002020537_ensure_address_for_account_invoice_orders.rb delete mode 100644 db/migrate/20151125051510_combine_exchange_receival_time_receival_instructions.rb delete mode 100644 db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb delete mode 100644 db/migrate/20151128185900_rename_enable_reset_to_resettable.rb delete mode 100644 db/migrate/20160114001844_create_inventory_items.rb delete mode 100644 db/migrate/20160116024333_create_column_preferences.rb delete mode 100644 db/migrate/20160204013914_add_id_to_coordinator_fees.rb delete mode 100644 db/migrate/20160204031816_add_inherits_tax_category_to_enterprise_fees.rb delete mode 100644 db/migrate/20160205044930_add_email_address_to_enterprises.rb delete mode 100644 db/migrate/20160212092908_set_enterprise_email_address.rb delete mode 100644 db/migrate/20160218235221_populate_inventories.rb delete mode 100644 db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb delete mode 100644 db/migrate/20160224230143_add_permission_revoked_at_to_variant_overrides.rb delete mode 100644 db/migrate/20160302044850_repopulate_inventories.rb delete mode 100644 db/migrate/20160303004210_create_tag_rules.rb delete mode 100644 db/migrate/20160316051131_add_require_login_to_enterprise.rb delete mode 100644 db/migrate/20160401043927_change_value_type_of_paypal_passwords.rb delete mode 100644 db/migrate/20160520065217_add_is_default_to_tag_rule.rb delete mode 100644 db/migrate/20160527012603_add_priority_to_tag_rule.rb delete mode 100644 db/migrate/20160630052453_create_schedules.rb delete mode 100644 db/migrate/20160630055825_create_order_cycle_schedules.rb delete mode 100644 db/migrate/20160707023818_drop_cms.rb delete mode 100644 db/migrate/20160713003535_add_bill_address_and_ship_address_to_customer.rb delete mode 100644 db/migrate/20160713013358_add_name_to_customer.rb delete mode 100644 db/migrate/20160819045727_create_standing_orders.rb delete mode 100644 db/migrate/20160819065331_swap_calculator_to_flat_percent_per_item.rb delete mode 100644 db/migrate/20160824013751_create_standing_line_items.rb delete mode 100644 db/migrate/20160828115018_create_stripe_accounts.rb delete mode 100644 db/migrate/20160916024535_add_state_to_spree_adjustments.spree.rb delete mode 100644 db/migrate/20160921060442_add_allow_guest_orders_to_enterprise.rb delete mode 100644 db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb delete mode 100644 db/migrate/20161014000216_add_ship_and_bill_address_to_standing_orders.rb delete mode 100644 db/migrate/20161020012017_create_standing_order_orders.rb delete mode 100644 db/migrate/20161110002554_add_standing_orders_placed_at_to_order_cycles.rb delete mode 100644 db/migrate/20161130001339_add_price_estimate_to_standing_line_items.rb delete mode 100644 db/migrate/20161206232009_add_canceled_at_to_standing_orders.rb delete mode 100644 db/migrate/20161207040232_rename_standing_order_orders_cancelled_at.rb delete mode 100644 db/migrate/20161207042153_add_paused_at_to_standing_orders.rb delete mode 100644 db/migrate/20161208233703_add_standing_orders_confirmed_at_to_order_cycles.rb delete mode 100644 db/migrate/20161210225156_rename_standing_order_orders_to_proxy_orders.rb delete mode 100644 db/migrate/20161210235939_add_order_cycle_id_to_proxy_orders.rb delete mode 100644 db/migrate/20161211210859_remove_proxy_order_order_not_null_constraint.rb delete mode 100644 db/migrate/20161215032136_add_enable_standing_orders_to_enterprises.rb delete mode 100644 db/migrate/20161215230219_add_invoice_text_and_invoice_logo_to_enterprises.rb delete mode 100644 db/migrate/20161222022340_add_placed_at_and_confirmed_at_to_proxy_orders.rb delete mode 100644 db/migrate/20170225203658_add_user_id_to_spree_credit_cards.rb delete mode 100644 db/migrate/20170304151129_add_payment_method_to_spree_credit_cards.rb delete mode 100644 db/migrate/20170310231746_add_import_date_to_spree_variants.rb delete mode 100644 db/migrate/20170314132401_add_import_date_to_variant_overrides.rb delete mode 100644 db/migrate/20170413074528_rename_payment_methods.spree_paypal_express.rb delete mode 100644 db/migrate/20170413083148_add_tracking_url_to_spree_shipping_methods.spree.rb delete mode 100644 db/migrate/20170512115519_add_locale_to_spree_users.rb delete mode 100644 db/migrate/20170710145821_add_confirmable_to_user.rb delete mode 100644 db/migrate/20170719125120_remove_confirmable_from_enterprises.rb delete mode 100644 db/migrate/20170727104900_add_receives_notifications_to_enterprise_roles.rb delete mode 100644 db/migrate/20170728140134_remove_email_from_enterprises.rb delete mode 100644 db/migrate/20170913205345_change_default_value_of_spree_users_enterprise_limit.rb delete mode 100644 db/migrate/20170921065259_update_adjustment_states.spree.rb delete mode 100644 db/migrate/20171027005930_add_credit_card_to_standing_orders.rb delete mode 100644 db/migrate/20180202024104_rename_standing_orders_to_subscriptions.rb delete mode 100644 db/migrate/20180204235108_rename_standing_line_items_to_subscription_line_items.rb delete mode 100644 db/migrate/20180222231639_add_shipping_fee_estimate_and_payment_fee_estimate_to_subscription.rb delete mode 100644 db/migrate/20180316034336_remove_placed_at_and_confirmed_at_from_order_cycles.rb delete mode 100644 db/migrate/20180406045821_add_charges_allowed_to_customers.rb delete mode 100644 db/migrate/20180418025217_add_is_default_to_credit_card.rb delete mode 100644 db/migrate/20180426145630_create_spree_stock_items.spree.rb delete mode 100644 db/migrate/20180426145631_create_spree_stock_locations.spree.rb delete mode 100644 db/migrate/20180426145632_create_default_stock.spree.rb delete mode 100644 db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb delete mode 100644 db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb delete mode 100644 db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb delete mode 100644 db/migrate/20180426145636_create_shipping_method_zone.spree.rb delete mode 100644 db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb delete mode 100644 db/migrate/20180426145638_create_shipping_method_categories.spree.rb delete mode 100644 db/migrate/20180426145639_create_spree_shipping_rates.spree.rb delete mode 100644 db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb delete mode 100644 db/migrate/20180426145641_create_stock_movements.spree.rb delete mode 100644 db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb delete mode 100644 db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb delete mode 100644 db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb delete mode 100644 db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb delete mode 100644 db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb delete mode 100644 db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb delete mode 100644 db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb delete mode 100644 db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb delete mode 100644 db/migrate/20180426145650_add_stock_location_to_rma.spree.rb delete mode 100644 db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb delete mode 100644 db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb delete mode 100644 db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb delete mode 100644 db/migrate/20180426145654_create_spree_stock_transfers.spree.rb delete mode 100644 db/migrate/20180426145655_drop_products_count_on_hand.spree.rb delete mode 100644 db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb delete mode 100644 db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb delete mode 100644 db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb delete mode 100644 db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb delete mode 100644 db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb delete mode 100644 db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb delete mode 100644 db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb delete mode 100644 db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb delete mode 100644 db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb delete mode 100644 db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb delete mode 100644 db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb delete mode 100644 db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb delete mode 100644 db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb delete mode 100644 db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb delete mode 100644 db/migrate/20180510083800_remove_credit_card_from_subscriptions.rb delete mode 100644 db/migrate/20180812214434_drop_carts.rb delete mode 100644 db/migrate/20180906094641_add_uniqueness_of_variant_id_to_spree_stock_items.rb delete mode 100644 db/migrate/20180910155506_add_uniqueness_of_order_id_to_spree_shipments.rb delete mode 100644 db/migrate/20180919102548_remove_shipping_method_name_from_spree_line_items.rb delete mode 100644 db/migrate/20181008201815_update_instagram_data.rb delete mode 100644 db/migrate/20181010093850_fix_variants_missing_unit_value.rb delete mode 100644 db/migrate/20181020103501_revoke_variant_overrideswithout_permissions.rb delete mode 100644 db/migrate/20181031105158_allow_all_suppliers_own_variant_overrides.rb delete mode 100644 db/migrate/20181106162211_update_weight_calculator_type_class_name.rb delete mode 100644 db/migrate/20181123012635_associate_customers_to_users.rb create mode 100644 db/migrate/20181128054803_old_migrations_removed.rb delete mode 100644 db/migrate/20181128054803_simplify_variant_override_stock_settings.rb diff --git a/db/migrate/20120327000552_spree_zero_nine_zero.rb b/db/migrate/20120327000552_spree_zero_nine_zero.rb deleted file mode 100644 index bd40ead315..0000000000 --- a/db/migrate/20120327000552_spree_zero_nine_zero.rb +++ /dev/null @@ -1,389 +0,0 @@ -class SpreeZeroNineZero < ActiveRecord::Migration - # This is a legacy migration consolidating all of the database changes needed as of Spree 0.9.0 - # (See http://railsdog.lighthouseapp.com/projects/31096-spree/tickets/772) - - def change - create_table :addresses, :force => true do |t| - t.string :firstname, :lastname, :address1, :address2, :city, - :zipcode, :phone, :state_name, :alternative_phone - t.references :state - t.references :country - - t.timestamps - end - - create_table :adjustments, :force => true do |t| - t.integer :position, :adjustment_source_id - t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.string :type, :description, :adjustment_source_type, :secondary_type - t.references :order - - t.timestamps - end - - create_table :assets, :force => true do |t| - t.integer :viewable_id, :attachment_width, :attachment_height, - :attachment_size, :position - t.string :viewable_type, :limit => 50 - t.string :attachment_content_type, :attachment_file_name - t.string :type, :limit => 75 - t.datetime :attachment_updated_at - end - - create_table :calculators, :force => true do |t| - t.string :type - t.integer :calculable_id, :null => false - t.string :calculable_type, :null => false - - t.timestamps - end - - create_table :checkouts, :force => true do |t| - t.references :order - t.string :email, :ip_address - t.text :special_instructions - t.integer :bill_address_id - t.datetime :completed_at - - t.timestamps - end - - create_table :configurations, :force => true do |t| - t.string :name - t.string :type, :limit => 50 - - t.timestamps - end - - add_index :configurations, [:name, :type], :name => 'index_configurations_on_name_and_type' - - create_table :countries, :force => true do |t| - t.string :iso_name, :iso, :iso3, :name - t.integer :numcode - end - - create_table :coupons, :force => true do |t| - t.string :code, :description - t.integer :usage_limit - t.boolean :combine - t.datetime :expires_at, :starts_at - - t.timestamps - end - - create_table :creditcard_txns, :force => true do |t| - t.integer :creditcard_payment_id, :txn_type - t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.string :response_code - t.text :avs_response, :cvv_response - - t.timestamps - end - - create_table :creditcards, :force => true do |t| - t.text :number, :verification_value - t.string :month, :year, :cc_type, :display_number, :first_name, - :last_name, :start_month, :start_year, :issue_number - t.references :address - t.references :checkout - - t.timestamps - end - - create_table :gateway_configurations, :force => true do |t| - t.references :gateway - - t.timestamps - end - - create_table :gateway_option_values, :force => true do |t| - t.references :gateway_configuration - t.references :gateway_option - t.text :value - - t.timestamps - end - - create_table :gateway_options, :force => true do |t| - t.string :name - t.text :description - t.boolean :textarea, :default => false - t.references :gateway - - t.timestamps - end - - create_table :gateways, :force => true do |t| - t.string :clazz, :name - t.text :description - t.boolean :active - - t.timestamps - end - - create_table :inventory_units, :force => true do |t| - t.integer :lock_version, :default => 0 - t.string :state - t.references :variant - t.references :order - - t.timestamps - end - - create_table :line_items, :force => true do |t| - t.references :order - t.references :variant - t.integer :quantity, :null => false - t.decimal :price, :precision => 8, :scale => 2, :null => false - - t.timestamps - end - - add_index :line_items, :order_id, :name => 'index_line_items_on_order_id' - add_index :line_items, :variant_id, :name => 'index_line_items_on_variant_id' - - create_table :option_types, :force => true do |t| - t.string :name, :limit => 100 - t.string :presentation, :limit => 100 - - t.timestamps - end - - create_table :option_types_prototypes, :id => false, :force => true do |t| - t.references :prototype - t.references :option_type - end - - create_table :option_values, :force => true do |t| - t.integer :position - t.string :name, :presentation - t.references :option_type - - t.timestamps - end - - create_table :option_values_variants, :id => false, :force => true do |t| - t.integer :variant_id - t.integer :option_value_id - end - - add_index :option_values_variants, :variant_id, :name => 'index_option_values_variants_on_variant_id' - - create_table :orders, :force => true do |t| - t.string :number, :limit => 15 - t.decimal :item_total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.decimal :total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.string :state - t.string :token - t.decimal :adjustment_total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.decimal :credit_total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.references :user - - t.timestamps - end - - add_index :orders, :number, :name => 'index_orders_on_number' - - create_table :payments, :force => true do |t| - t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.string :type - t.references :order - t.references :creditcard - - t.timestamps - end - - create_table :preferences, :force => true do |t| - t.string :attribute, :null => false, :limit => 100 - t.integer :owner_id, :null => false, :limit => 30 - t.string :owner_type, :null => false, :limit => 50 - t.integer :group_id - t.string :group_type, :limit => 50 - t.string :value - - t.timestamps - end - - add_index :preferences, [:owner_id, :owner_type, :attribute, :group_id, :group_type], :name => 'index_preferences_on_owner_and_attribute_and_preference', :unique => true - - create_table :product_option_types, :force => true do |t| - t.integer :position - t.references :product - t.references :option_type - - t.timestamps - end - - create_table :product_properties, :force => true do |t| - t.string :value - t.references :product - t.references :property - - t.timestamps - end - - create_table :products, :force => true do |t| - t.string :name, :default => '', :null => false - t.text :description - t.datetime :available_on, :deleted_at - t.string :permalink, :meta_description, :meta_keywords - t.references :tax_category - t.references :shipping_category - - t.timestamps - end - - add_index :products, :available_on, :name => 'index_products_on_available_on' - add_index :products, :deleted_at, :name => 'index_products_on_deleted_at' - add_index :products, :name, :name => 'index_products_on_name' - add_index :products, :permalink, :name => 'index_products_on_permalink' - - create_table :products_taxons, :id => false, :force => true do |t| - t.references :product - t.references :taxon - end - - add_index :products_taxons, :product_id, :name => 'index_products_taxons_on_product_id' - add_index :products_taxons, :taxon_id, :name => 'index_products_taxons_on_taxon_id' - - create_table :properties, :force => true do |t| - t.string :name - t.string :presentation, :null => false - - t.timestamps - end - - create_table :properties_prototypes, :id => false, :force => true do |t| - t.references :prototype - t.references :property - end - - create_table :prototypes, :force => true do |t| - t.string :name - - t.timestamps - end - - create_table :roles, :force => true do |t| - t.string :name - end - - create_table :roles_users, :id => false, :force => true do |t| - t.references :role - t.references :user - end - - add_index :roles_users, :role_id, :name => 'index_roles_users_on_role_id' - add_index :roles_users, :user_id, :name => 'index_roles_users_on_user_id' - - create_table :shipments, :force => true do |t| - t.string :tracking, :number - t.decimal :cost, :precision => 8, :scale => 2 - t.datetime :shipped_at - t.references :order - t.references :shipping_method - t.references :address - - t.timestamps - end - - create_table :shipping_categories, :force => true do |t| - t.string :name - - t.timestamps - end - - create_table :shipping_methods, :force => true do |t| - t.string :name - t.references :zone - - t.timestamps - end - - create_table :state_events, :force => true do |t| - t.string :name, :previous_state - t.references :order - t.references :user - - t.timestamps - end - - create_table :states, :force => true do |t| - t.string :name - t.string :abbr - t.references :country - end - - create_table :tax_categories, :force => true do |t| - t.string :name, :description - - t.timestamps - end - - create_table :tax_rates, :force => true do |t| - t.decimal :amount, :precision => 8, :scale => 4 - t.references :zone - t.references :tax_category - - t.timestamps - end - - create_table :taxonomies, :force => true do |t| - t.string :name, :null => false - - t.timestamps - end - - create_table :taxons, :force => true do |t| - t.integer :parent_id - t.integer :position, :default => 0 - t.string :name, :null => false - t.string :permalink - t.references :taxonomy - - t.timestamps - end - - create_table :users, :force => true do |t| - t.string :crypted_password, :limit => 128, :default => '', :null => false - t.string :salt, :limit => 128, :default => '', :null => false - t.string :email, :remember_token, :remember_token_expires_at, - :persistence_token, :single_access_token, :perishable_token - t.integer :login_count, :default => 0, :null => false - t.integer :failed_login_count, :default => 0, :null => false - t.datetime :last_request_at, :current_login_at, :last_login_at - t.string :current_login_ip, :last_login_ip, :login - t.integer :ship_address_id, :bill_address_id - - t.timestamps - end - - create_table :variants, :force => true do |t| - t.string :sku, :default => '', :null => false - t.decimal :price, :precision => 8, :scale => 2, :null => false - t.decimal :weight, :precision => 8, :scale => 2 - t.decimal :height, :precision => 8, :scale => 2 - t.decimal :width, :precision => 8, :scale => 2 - t.decimal :depth, :precision => 8, :scale => 2 - t.datetime :deleted_at - t.boolean :is_master, :default => false - t.references :product - end - - add_index :variants, :product_id, :name => 'index_variants_on_product_id' - - create_table :zone_members, :force => true do |t| - t.integer :zoneable_id - t.string :zoneable_type - t.references :zone - - t.timestamps - end - - create_table :zones, :force => true do |t| - t.string :name, :description - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000553_create_indexes_for_inventory_units.rb b/db/migrate/20120327000553_create_indexes_for_inventory_units.rb deleted file mode 100644 index 6ce5048610..0000000000 --- a/db/migrate/20120327000553_create_indexes_for_inventory_units.rb +++ /dev/null @@ -1,6 +0,0 @@ -class CreateIndexesForInventoryUnits < ActiveRecord::Migration - def change - add_index :inventory_units, :variant_id - add_index :inventory_units, :order_id - end -end diff --git a/db/migrate/20120327000554_add_count_on_hand_to_variants_and_products.rb b/db/migrate/20120327000554_add_count_on_hand_to_variants_and_products.rb deleted file mode 100644 index 7341e5e268..0000000000 --- a/db/migrate/20120327000554_add_count_on_hand_to_variants_and_products.rb +++ /dev/null @@ -1,49 +0,0 @@ -class AddCountOnHandToVariantsAndProducts < ActiveRecord::Migration - def up - add_column :variants, :count_on_hand, :integer, :default => 0, :null => false - add_column :products, :count_on_hand, :integer, :default => 0, :null => false - - # Due to our namespacing changes, this migration (from earlier Spree versions) is broken - # To fix it, temporarily set table name on each of the models involved - # And then... - Spree::Variant.table_name = 'variants' - Spree::Product.table_name = 'products' - Spree::InventoryUnit.table_name = 'inventory_units' - - # In some cases needed to reflect changes in table structure - Spree::Variant.reset_column_information - Spree::Product.reset_column_information - - say_with_time 'Transfering inventory units with status on_hand to variants table...' do - Spree::Variant.all.each do |v| - v.update_attribute(:count_on_hand, v.inventory_units.with_state('on_hand').size) - Spree::InventoryUnit.destroy_all(:variant_id => v.id, :state => 'on_hand') - end - end - - say_with_time 'Updating products count on hand' do - Spree::Product.all.each do |p| - product_count_on_hand = p.has_variants? ? - p.variants.inject(0) { |acc, v| acc + v.count_on_hand } : - (p.master ? p.master.count_on_hand : 0) - p.update_attribute(:count_on_hand, product_count_on_hand) - end - end - - # ... Switch things back at the end of the migration - Spree::Variant.table_name = 'spree_variants' - Spree::Product.table_name = 'spree_products' - Spree::InventoryUnit.table_name = 'spree_inventory_units' - end - - def down - Spree::Variant.all.each do |v| - v.count_on_hand.times do - Spree::InventoryUnit.create(:variant => variant, :state => 'on_hand') - end - end - - remove_column :variants, :count_on_hand - remove_column :products, :count_on_hand - end -end diff --git a/db/migrate/20120327000555_change_taxons_to_nested_set.rb b/db/migrate/20120327000555_change_taxons_to_nested_set.rb deleted file mode 100644 index d00944142c..0000000000 --- a/db/migrate/20120327000555_change_taxons_to_nested_set.rb +++ /dev/null @@ -1,46 +0,0 @@ -class ChangeTaxonsToNestedSet < ActiveRecord::Migration - def up - add_column :taxons, :lft, :integer - add_column :taxons, :rgt, :integer - - Spree::Taxon.reset_column_information # So the new root ids get saved - - # Temporarily set the table back to taxons - Spree::Taxon.table_name = 'taxons' - - Spree::Taxon.class_eval do - # adapted from awesome nested set to use 'position' information - indices = {} - - left_column_name = 'lft' - right_column_name = 'rgt' - quoted_parent_column_name = 'parent_id' - scope = lambda{|node|} - - set_left_and_rights = lambda do |node| - # set left - node[left_column_name] = indices[scope.call(node)] += 1 - # find - where("#{quoted_parent_column_name} = ?", node).order('position ASC').each{ |n| set_left_and_rights.call(n) } - # set right - node[right_column_name] = indices[scope.call(node)] += 1 - node.save! - end - - # Find root node(s) - where("#{quoted_parent_column_name}" => nil).order('position ASC').each do |root_node| - # setup index for this scope - indices[scope.call(root_node)] ||= 0 - set_left_and_rights.call(root_node) - end - end - - # Set it back after the migration - Spree::Taxon.table_name = 'spree_taxons' - end - - def down - remove_column :taxons, :lft - remove_column :taxons, :rgt - end -end diff --git a/db/migrate/20120327000556_move_to_configurable_gateways.rb b/db/migrate/20120327000556_move_to_configurable_gateways.rb deleted file mode 100644 index a598cce828..0000000000 --- a/db/migrate/20120327000556_move_to_configurable_gateways.rb +++ /dev/null @@ -1,54 +0,0 @@ -class MoveToConfigurableGateways < ActiveRecord::Migration - def up - drop_table :gateways - drop_table :gateway_options - drop_table :gateway_option_values - drop_table :gateway_configurations - - create_table :gateways, :force => true do |t| - t.string :type, :name - t.text :description - t.boolean :active, :default => true - t.string :environment, :default => 'development' - t.string :server, :default => 'test' - t.boolean :test_mode, :default => true - - t.timestamps - end - end - - def down - drop_table :gateways - - create_table :gateway_configurations, :force => true do |t| - t.references :gateway - - t.timestamps - end - - create_table :gateway_option_values, :force => true do |t| - t.text :value - t.references :gateway_configuration - t.references :gateway_option - - t.timestamps - end - - create_table :gateway_options, :force => true do |t| - t.string :name - t.text :description - t.boolean :textarea, :default => false - t.references :gateway - - t.timestamps - end - - create_table :gateways, :force => true do |t| - t.string :clazz, :name - t.text :description - t.boolean :active - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000557_product_groups_and_scopes.rb b/db/migrate/20120327000557_product_groups_and_scopes.rb deleted file mode 100644 index 00a82d0a2b..0000000000 --- a/db/migrate/20120327000557_product_groups_and_scopes.rb +++ /dev/null @@ -1,18 +0,0 @@ -class ProductGroupsAndScopes < ActiveRecord::Migration - def change - create_table :product_groups do |t| - t.string :name, :permalink, :order - end - - create_table :product_scopes do |t| - t.string :name - t.text :arguments - t.references :product_group - end - - add_index :product_groups, :name - add_index :product_groups, :permalink - add_index :product_scopes, :name - add_index :product_scopes, :product_group_id - end -end diff --git a/db/migrate/20120327000558_add_open_id_authentication_tables.rb b/db/migrate/20120327000558_add_open_id_authentication_tables.rb deleted file mode 100644 index fe20ab3ec2..0000000000 --- a/db/migrate/20120327000558_add_open_id_authentication_tables.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddOpenIdAuthenticationTables < ActiveRecord::Migration - def change - create_table :open_id_authentication_associations, :force => true do |t| - t.integer :issued, :lifetime - t.string :handle, :assoc_type - t.binary :server_url, :secret - end - - create_table :open_id_authentication_nonces, :force => true do |t| - t.integer :timestamp, :null => false - t.string :server_url, :null => true - t.string :salt, :null => false - end - end -end diff --git a/db/migrate/20120327000559_add_openid_field_to_users.rb b/db/migrate/20120327000559_add_openid_field_to_users.rb deleted file mode 100644 index 3ee6288692..0000000000 --- a/db/migrate/20120327000559_add_openid_field_to_users.rb +++ /dev/null @@ -1,24 +0,0 @@ -class AddOpenidFieldToUsers < ActiveRecord::Migration - def up - add_column :users, :openid_identifier, :string - add_index :users, :openid_identifier - - change_column :users, :login, :string, :default => nil, :null => true - change_column :users, :crypted_password, :string, :default => nil, :null => true - change_column :users, :salt, :string, :default => nil, :null => true - end - - def down - remove_column :users, :openid_identifier - - # Due to namespacing change, temporarily set the table back to users - Spree::User.table_name = 'users' - - [:login, :crypted_password, :salt].each do |field| - Spree::User.where(field => nil).each { |user| user.update_attribute(field, '') if user.send(field).nil? } - change_column :users, field, :string, :default => '', :null => false - end - - Spree::User.table_name = 'spree_users' - end -end diff --git a/db/migrate/20120327000560_change_preference_value_type.rb b/db/migrate/20120327000560_change_preference_value_type.rb deleted file mode 100644 index b0e1d07bab..0000000000 --- a/db/migrate/20120327000560_change_preference_value_type.rb +++ /dev/null @@ -1,10 +0,0 @@ -class ChangePreferenceValueType < ActiveRecord::Migration - def up - remove_index :preferences, :name => 'index_preferences_on_owner_and_attribute_and_preference' - change_column :preferences, :value, :text - end - - def down - change_column :preferences, :value, :string - end -end diff --git a/db/migrate/20120327000561_create_billing_integrations.rb b/db/migrate/20120327000561_create_billing_integrations.rb deleted file mode 100644 index c61e2e8932..0000000000 --- a/db/migrate/20120327000561_create_billing_integrations.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateBillingIntegrations < ActiveRecord::Migration - def change - create_table :billing_integrations do |t| - t.string :type, :name - t.text :description - t.boolean :active, :default => true - t.string :environment, :default => 'development' - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000562_charge_refactoring.rb b/db/migrate/20120327000562_charge_refactoring.rb deleted file mode 100644 index fdcd31abb0..0000000000 --- a/db/migrate/20120327000562_charge_refactoring.rb +++ /dev/null @@ -1,39 +0,0 @@ -class Checkout < ActiveRecord::Base; end; - -# Hack to prevent issues with legacy migrations -class Order < ActiveRecord::Base - has_one :checkout -end - -class ChargeRefactoring < ActiveRecord::Migration - def up - # Temporarily set table name for legacy support - Spree::Adjustment.table_name = 'adjustments' - - add_column :orders, :completed_at, :timestamp - Order.reset_column_information - Order.all.each { |o| o.update_attribute(:completed_at, o.checkout && o.checkout.read_attribute(:completed_at)) } - remove_column :checkouts, :completed_at - - change_column :adjustments, :amount, :decimal, :null => true, :default => nil, :precision => 8, :scale => 2 - Spree::Adjustment.update_all :type => 'secondary_type' - Spree::Adjustment.where(:type => 'Credit').update_all(:type => 'CouponCredit') - remove_column :adjustments, :secondary_type - - # Reset table name - Spree::Adjustment.table_name = 'spree_adjustments' - end - - def down - add_column :checkouts, :completed_at, :timestamp - Spree::Checkout.reset_column_information - Spree::Checkout.all.each { |c| c.update_attribute(:completed_at, c.order && c.order.completed_at) } - remove_column :orders, :completed_at - - add_column :adjustments, :secondary_type, :string - Spree::Adjustment.update_all :secondary_type => 'type' - Spree::Adjustment.where('type LIKE ?', '%Charge').update_all(:type => 'Charge') - Spree::Adjustment.where('type LIKE ?', '%Credit').update_all(:type => 'Credit') - change_column :adjustments, :amount, :decimal, :null => false, :default => 0, :precision => 8, :scale => 2 - end -end diff --git a/db/migrate/20120327000563_add_some_indexes.rb b/db/migrate/20120327000563_add_some_indexes.rb deleted file mode 100644 index ffb8495876..0000000000 --- a/db/migrate/20120327000563_add_some_indexes.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddSomeIndexes < ActiveRecord::Migration - def change - add_index :taxons, :permalink - add_index :taxons, :parent_id - add_index :taxons, :taxonomy_id - add_index :assets, :viewable_id - add_index :assets, [:viewable_type, :type] - add_index :product_properties, :product_id - add_index :option_values_variants, [:variant_id, :option_value_id] - end -end diff --git a/db/migrate/20120327000564_checkout_state_machine.rb b/db/migrate/20120327000564_checkout_state_machine.rb deleted file mode 100644 index c80323b30e..0000000000 --- a/db/migrate/20120327000564_checkout_state_machine.rb +++ /dev/null @@ -1,5 +0,0 @@ -class CheckoutStateMachine < ActiveRecord::Migration - def change - add_column :checkouts, :state, :string - end -end diff --git a/db/migrate/20120327000565_state_for_shipments.rb b/db/migrate/20120327000565_state_for_shipments.rb deleted file mode 100644 index b7a3bc4bba..0000000000 --- a/db/migrate/20120327000565_state_for_shipments.rb +++ /dev/null @@ -1,5 +0,0 @@ -class StateForShipments < ActiveRecord::Migration - def change - add_column :shipments, :state, :string - end -end diff --git a/db/migrate/20120327000566_make_state_events_polymorphic.rb b/db/migrate/20120327000566_make_state_events_polymorphic.rb deleted file mode 100644 index ed8cef3659..0000000000 --- a/db/migrate/20120327000566_make_state_events_polymorphic.rb +++ /dev/null @@ -1,12 +0,0 @@ -class MakeStateEventsPolymorphic < ActiveRecord::Migration - def up - rename_column :state_events, :order_id, :stateful_id - add_column :state_events, :stateful_type, :string - execute "UPDATE state_events SET stateful_type = 'Order'" - end - - def down - rename_column :state_events, :stateful_id, :order_id - remove_column :state_events, :stateful_type - end -end diff --git a/db/migrate/20120327000567_ship_address_id_for_checkouts.rb b/db/migrate/20120327000567_ship_address_id_for_checkouts.rb deleted file mode 100644 index c16f4c82c0..0000000000 --- a/db/migrate/20120327000567_ship_address_id_for_checkouts.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ShipAddressIdForCheckouts < ActiveRecord::Migration - def change - add_column :checkouts, :ship_address_id, :integer - end -end diff --git a/db/migrate/20120327000568_shipping_method_id_for_checkouts.rb b/db/migrate/20120327000568_shipping_method_id_for_checkouts.rb deleted file mode 100644 index 6f8edd588a..0000000000 --- a/db/migrate/20120327000568_shipping_method_id_for_checkouts.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ShippingMethodIdForCheckouts < ActiveRecord::Migration - def change - add_column :checkouts, :shipping_method_id, :integer - end -end diff --git a/db/migrate/20120327000569_creditcard_last_four_digits.rb b/db/migrate/20120327000569_creditcard_last_four_digits.rb deleted file mode 100644 index 922df48f8d..0000000000 --- a/db/migrate/20120327000569_creditcard_last_four_digits.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreditcardLastFourDigits < ActiveRecord::Migration - def up - rename_column :creditcards, :display_number, :last_digits - - creditcards = select_all "SELECT * FROM creditcards" - creditcards.each do |card| - execute "UPDATE creditcards SET last_digits = '#{card['last_digits'].gsub('XXXX-XXXX-XXXX-', '')}' WHERE id = #{card['id']}" if card['last_digits'].present? - end - end - - def down - rename_column :creditcards, :last_digits, :display_number - end -end diff --git a/db/migrate/20120327000570_populate_legacy_shipment_state.rb b/db/migrate/20120327000570_populate_legacy_shipment_state.rb deleted file mode 100644 index 2008e38817..0000000000 --- a/db/migrate/20120327000570_populate_legacy_shipment_state.rb +++ /dev/null @@ -1,15 +0,0 @@ -class PopulateLegacyShipmentState < ActiveRecord::Migration - def up - shipments = select_all "SELECT * FROM shipments" - shipments.each do |shipment| - if shipment['shipped_at'] - execute "UPDATE shipments SET state = 'shipped'" - else - execute "UPDATE shipments SET state = 'pending'" - end - end - end - - def down - end -end diff --git a/db/migrate/20120327000571_add_cost_price.rb b/db/migrate/20120327000571_add_cost_price.rb deleted file mode 100644 index 81dc8d25cb..0000000000 --- a/db/migrate/20120327000571_add_cost_price.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddCostPrice < ActiveRecord::Migration - def change - add_column :variants, :cost_price, :decimal, :null => true, :default => nil, :precision => 8, :scale => 2 - end -end diff --git a/db/migrate/20120327000572_shipment_id_for_inventory_units.rb b/db/migrate/20120327000572_shipment_id_for_inventory_units.rb deleted file mode 100644 index 93aec53f7e..0000000000 --- a/db/migrate/20120327000572_shipment_id_for_inventory_units.rb +++ /dev/null @@ -1,25 +0,0 @@ -class ShipmentIdForInventoryUnits < ActiveRecord::Migration - def up - add_column :inventory_units, :shipment_id, :integer - add_index :inventory_units, :shipment_id - - # migrate legacy shipments - Spree::Shipment.table_name = 'shipments' - - Spree::Shipment.all.each do |shipment| - unless shipment.order - puts "Warning: shipment has invalid order - #{shipment.id}" - next - end - shipment.order.inventory_units.each do |unit| - unit.update_attribute('shipment_id', shipment.id) - end - end - - Spree::Shipment.table_name = 'spree_shipments' - end - - def down - remove_column :inventory_units, :shipment_id - end -end diff --git a/db/migrate/20120327000573_cim_fields_for_creditcards.rb b/db/migrate/20120327000573_cim_fields_for_creditcards.rb deleted file mode 100644 index 417a9613c0..0000000000 --- a/db/migrate/20120327000573_cim_fields_for_creditcards.rb +++ /dev/null @@ -1,6 +0,0 @@ -class CimFieldsForCreditcards < ActiveRecord::Migration - def change - add_column :creditcards, :gateway_customer_profile_id, :string - add_column :creditcards, :gateway_payment_profile_id, :string - end -end diff --git a/db/migrate/20120327000574_create_return_authorizations.rb b/db/migrate/20120327000574_create_return_authorizations.rb deleted file mode 100644 index bb9fed3e00..0000000000 --- a/db/migrate/20120327000574_create_return_authorizations.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateReturnAuthorizations < ActiveRecord::Migration - def change - create_table :return_authorizations do |t| - t.string :number, :state - t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.references :order - t.text :reason - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000575_add_return_authorization_to_inventory_units.rb b/db/migrate/20120327000575_add_return_authorization_to_inventory_units.rb deleted file mode 100644 index 49a55bc026..0000000000 --- a/db/migrate/20120327000575_add_return_authorization_to_inventory_units.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddReturnAuthorizationToInventoryUnits < ActiveRecord::Migration - def change - add_column :inventory_units, :return_authorization_id, :integer - end -end diff --git a/db/migrate/20120327000576_create_trackers.rb b/db/migrate/20120327000576_create_trackers.rb deleted file mode 100644 index e4e216213b..0000000000 --- a/db/migrate/20120327000576_create_trackers.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreateTrackers < ActiveRecord::Migration - def change - create_table :trackers do |t| - t.string :environment, :analytics_id - t.boolean :active, :default => true - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000577_creditcard_id_for_creditcard_txns.rb b/db/migrate/20120327000577_creditcard_id_for_creditcard_txns.rb deleted file mode 100644 index 7190e0e711..0000000000 --- a/db/migrate/20120327000577_creditcard_id_for_creditcard_txns.rb +++ /dev/null @@ -1,5 +0,0 @@ -class CreditcardIdForCreditcardTxns < ActiveRecord::Migration - def change - add_column :creditcard_txns, :creditcard_id, :integer - end -end diff --git a/db/migrate/20120327000578_original_creditcard_txn_id_for_creditcard_txns.rb b/db/migrate/20120327000578_original_creditcard_txn_id_for_creditcard_txns.rb deleted file mode 100644 index 54160feac4..0000000000 --- a/db/migrate/20120327000578_original_creditcard_txn_id_for_creditcard_txns.rb +++ /dev/null @@ -1,5 +0,0 @@ -class OriginalCreditcardTxnIdForCreditcardTxns < ActiveRecord::Migration - def change - add_column :creditcard_txns, :original_creditcard_txn_id, :integer - end -end diff --git a/db/migrate/20120327000579_add_test_mode_to_billing_integration.rb b/db/migrate/20120327000579_add_test_mode_to_billing_integration.rb deleted file mode 100644 index aa1be7912b..0000000000 --- a/db/migrate/20120327000579_add_test_mode_to_billing_integration.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddTestModeToBillingIntegration < ActiveRecord::Migration - def change - add_column :billing_integrations, :test_mode, :boolean, :default => true - add_column :billing_integrations, :server, :string, :default => 'test' - end -end diff --git a/db/migrate/20120327000580_create_products_product_groups.rb b/db/migrate/20120327000580_create_products_product_groups.rb deleted file mode 100644 index aaa6533732..0000000000 --- a/db/migrate/20120327000580_create_products_product_groups.rb +++ /dev/null @@ -1,8 +0,0 @@ -class CreateProductsProductGroups < ActiveRecord::Migration - def change - create_table :product_groups_products, :id => false do |t| - t.references :product - t.references :product_group - end - end -end diff --git a/db/migrate/20120327000581_create_payment_methods.rb b/db/migrate/20120327000581_create_payment_methods.rb deleted file mode 100644 index 41145056e7..0000000000 --- a/db/migrate/20120327000581_create_payment_methods.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreatePaymentMethods < ActiveRecord::Migration - def change - create_table :payment_methods do |t| - t.string :type, :name - t.text :description - t.boolean :active, :default => true - t.string :environment, :default => 'development' - - t.timestamps - end - # TODO - also migrate any legacy configurations for gateways and billing integrations before dropping the old tables - # we probably also need to do this inside the payment_gateway extension b/c table won't exist yet in fresh bootstrap - #drop_table :billing_integrations - #drop_table :gateways - end -end diff --git a/db/migrate/20120327000582_polymorphic_payments.rb b/db/migrate/20120327000582_polymorphic_payments.rb deleted file mode 100644 index 33787c3d26..0000000000 --- a/db/migrate/20120327000582_polymorphic_payments.rb +++ /dev/null @@ -1,43 +0,0 @@ -# Legacy table support -class Checkout < ActiveRecord::Base; end; -class Spree::Creditcard < ActiveRecord::Base; end; - -class PolymorphicPayments < ActiveRecord::Migration - def up - remove_column :payments, :type - remove_column :payments, :creditcard_id - rename_column :payments, :order_id, :payable_id - change_table :payments do |t| - t.string :payable_type, :payment_method - t.references :source, :polymorphic => true - end - execute "UPDATE payments SET payable_type = 'Order'" - - Spree::Creditcard.table_name = 'creditcards' - - Spree::Creditcard.all.each do |creditcard| - if checkout = Checkout.find_by_id(creditcard.checkout_id) and checkout.order - if payment = checkout.order.payments.first - execute "UPDATE payments SET source_type = 'Creditcard', source_id = #{creditcard.id} WHERE id = #{payment.id}" - end - end - end - - Spree::Creditcard.table_name = 'spree_creditcards' - - remove_column :creditcards, :checkout_id - end - - def down - add_column :creditcards, :checkout_id, :integer - change_table :payments do |t| - t.remove :payable_type - t.remove :payment_method - t.remove :source_id - t.remove :source_type - end - rename_column :payments, :payable_id, :order_id - add_column :payments, :creditcard_id, :integer - add_column :payments, :type, :string - end -end diff --git a/db/migrate/20120327000583_change_payments_payment_method_to_belongs_to.rb b/db/migrate/20120327000583_change_payments_payment_method_to_belongs_to.rb deleted file mode 100644 index 456dace6e2..0000000000 --- a/db/migrate/20120327000583_change_payments_payment_method_to_belongs_to.rb +++ /dev/null @@ -1,11 +0,0 @@ -class ChangePaymentsPaymentMethodToBelongsTo < ActiveRecord::Migration - def up - remove_column :payments, :payment_method - add_column :payments, :payment_method_id, :integer - end - - def down - add_column :payments, :payment_method, :string - remove_column :payments, :payment_method_id - end -end diff --git a/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb b/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb deleted file mode 100644 index 562f60c7b0..0000000000 --- a/db/migrate/20120327000584_assign_creditcard_txns_to_payment.rb +++ /dev/null @@ -1,23 +0,0 @@ -class AssignCreditcardTxnsToPayment < ActiveRecord::Migration - def up - add_column :creditcard_txns, :payment_id, :integer - - # Temporarily set back to creditcards - Spree::Creditcard.table_name = 'creditcards' - - ActiveRecord::Base.connection.select_all('SELECT * FROM creditcard_txns').each do |txn_attrs| - if creditcard = Spree::Creditcard.find_by_id(txn_attrs['creditcard_id']) and creditcard.payments.first - execute "UPDATE creditcard_txns SET payment_id = #{creditcard.payments.first.id} WHERE id = #{txn_attrs['id']}" - end - end - - Spree::Creditcard.table_name = 'spree_creditcards' - - remove_column :creditcard_txns, :creditcard_payment_id - end - - def down - remove_column :creditcard_txns, :payment_id - add_column :creditcard_txns, :creditcard_payment_id, :integer - end -end diff --git a/db/migrate/20120327000585_sti_for_transactions.rb b/db/migrate/20120327000585_sti_for_transactions.rb deleted file mode 100644 index 5d44f725e9..0000000000 --- a/db/migrate/20120327000585_sti_for_transactions.rb +++ /dev/null @@ -1,15 +0,0 @@ -class StiForTransactions < ActiveRecord::Migration - def up - rename_table :creditcard_txns, :transactions - add_column :transactions, :type, :string - remove_column :transactions, :creditcard_id - - execute "UPDATE transactions SET type = 'CreditcardTxn'" - end - - def down - rename_table :transactions, :creditcard_txns - remove_column :transactions, :type - add_column :transactions, :creditcard_id, :integer - end -end diff --git a/db/migrate/20120327000586_drop_billing_integrations.rb b/db/migrate/20120327000586_drop_billing_integrations.rb deleted file mode 100644 index 362a4f6904..0000000000 --- a/db/migrate/20120327000586_drop_billing_integrations.rb +++ /dev/null @@ -1,16 +0,0 @@ -class DropBillingIntegrations < ActiveRecord::Migration - def up - drop_table :billing_integrations - end - - def down - create_table :billing_integrations do |t| - t.string :type, :name - t.text :description - t.boolean :active, :default => true - t.string :environment, :default => 'development' - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000587_deleted_at_for_payment_methods.rb b/db/migrate/20120327000587_deleted_at_for_payment_methods.rb deleted file mode 100644 index 6283733f58..0000000000 --- a/db/migrate/20120327000587_deleted_at_for_payment_methods.rb +++ /dev/null @@ -1,14 +0,0 @@ -class DeletedAtForPaymentMethods < ActiveRecord::Migration - def up - change_table :payment_methods do |t| - t.timestamp :deleted_at, :default => nil - end - end - - def down - remove_column :payments_methods, :column_name - change_table :payment_methods do |t| - t.remove :deleted_at - end - end -end \ No newline at end of file diff --git a/db/migrate/20120327000588_add_adjustments_index.rb b/db/migrate/20120327000588_add_adjustments_index.rb deleted file mode 100644 index 559766d9bd..0000000000 --- a/db/migrate/20120327000588_add_adjustments_index.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddAdjustmentsIndex < ActiveRecord::Migration - def change - add_index :adjustments, :order_id - end -end - diff --git a/db/migrate/20120327000589_fix_by_popularity.rb b/db/migrate/20120327000589_fix_by_popularity.rb deleted file mode 100644 index 756b725bbe..0000000000 --- a/db/migrate/20120327000589_fix_by_popularity.rb +++ /dev/null @@ -1,9 +0,0 @@ -class FixByPopularity < ActiveRecord::Migration - def up - execute("UPDATE product_scopes SET name='descend_by_popularity' WHERE name='by_popularity'") - end - - def down - execute("UPDATE product_scopes SET name='by_popularity' WHERE name='descend_by_popularity'") - end -end diff --git a/db/migrate/20120327000590_add_alt_text_to_images.rb b/db/migrate/20120327000590_add_alt_text_to_images.rb deleted file mode 100644 index 69b9ce2e72..0000000000 --- a/db/migrate/20120327000590_add_alt_text_to_images.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddAltTextToImages < ActiveRecord::Migration - def change - add_column :assets, :alt, :text - end -end diff --git a/db/migrate/20120327000591_fix_existing_coupon_credits.rb b/db/migrate/20120327000591_fix_existing_coupon_credits.rb deleted file mode 100644 index 1f04087051..0000000000 --- a/db/migrate/20120327000591_fix_existing_coupon_credits.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Adjustment < ActiveRecord::Base; end; - -class FixExistingCouponCredits < ActiveRecord::Migration - def up - execute("UPDATE adjustments SET type='PromotionCredit' WHERE type='CouponCredit'") - execute("UPDATE adjustments SET adjustment_source_type='Promotion' WHERE adjustment_source_type='Coupon'") - end - - def down - execute("UPDATE adjustments SET adjustment_source_type='Coupon' WHERE adjustment_source_type='Promotion'") - execute("UPDATE adjustments SET type='CouponCredit' WHERE type='PromotionCredit'") - end -end diff --git a/db/migrate/20120327000592_add_display_to_payment_methods.rb b/db/migrate/20120327000592_add_display_to_payment_methods.rb deleted file mode 100644 index a7097add2f..0000000000 --- a/db/migrate/20120327000592_add_display_to_payment_methods.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDisplayToPaymentMethods < ActiveRecord::Migration - def change - add_column :payment_methods, :display, :string, :default => nil - end -end diff --git a/db/migrate/20120327000593_add_addresses_checkouts_indexes.rb b/db/migrate/20120327000593_add_addresses_checkouts_indexes.rb deleted file mode 100644 index 4a1c460bae..0000000000 --- a/db/migrate/20120327000593_add_addresses_checkouts_indexes.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddAddressesCheckoutsIndexes < ActiveRecord::Migration - def change - add_index :addresses, :firstname - add_index :addresses, :lastname - add_index :checkouts, :order_id - add_index :checkouts, :bill_address_id - end -end diff --git a/db/migrate/20120327000594_add_icon_to_taxons.rb b/db/migrate/20120327000594_add_icon_to_taxons.rb deleted file mode 100644 index 625c253779..0000000000 --- a/db/migrate/20120327000594_add_icon_to_taxons.rb +++ /dev/null @@ -1,17 +0,0 @@ -class AddIconToTaxons < ActiveRecord::Migration - def up - # skip this migration if the attribute already exists because of advanced taxon extension - return if column_exists?(:taxons, :icon_file_name) - add_column :taxons, :icon_file_name, :string - add_column :taxons, :icon_content_type, :string - add_column :taxons, :icon_file_size, :integer - add_column :taxons, :icon_updated_at, :datetime - end - - def down - remove_column :taxons, :icon_file_name - remove_column :taxons, :icon_content_type - remove_column :taxons, :icon_file_size - remove_column :taxons, :icon_updated_at - end -end diff --git a/db/migrate/20120327000595_add_description_to_taxons.rb b/db/migrate/20120327000595_add_description_to_taxons.rb deleted file mode 100644 index 287daad048..0000000000 --- a/db/migrate/20120327000595_add_description_to_taxons.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddDescriptionToTaxons < ActiveRecord::Migration - def up - # skip this migration if the attribute already exists because of advanced taxon extension - return if column_exists?(:taxons, :description) - add_column :taxons, :description, :text - end - - def down - remove_column :taxons, :description - end -end diff --git a/db/migrate/20120327000596_index_for_shipments_number.rb b/db/migrate/20120327000596_index_for_shipments_number.rb deleted file mode 100644 index c1a85d1d23..0000000000 --- a/db/migrate/20120327000596_index_for_shipments_number.rb +++ /dev/null @@ -1,5 +0,0 @@ -class IndexForShipmentsNumber < ActiveRecord::Migration - def change - add_index :shipments, :number - end -end diff --git a/db/migrate/20120327000597_add_index_on_users_persistence_token.rb b/db/migrate/20120327000597_add_index_on_users_persistence_token.rb deleted file mode 100644 index 9b4d65cb63..0000000000 --- a/db/migrate/20120327000597_add_index_on_users_persistence_token.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIndexOnUsersPersistenceToken < ActiveRecord::Migration - def change - add_index :users, :persistence_token - end -end diff --git a/db/migrate/20120327000598_add_default_to_tax_categories.rb b/db/migrate/20120327000598_add_default_to_tax_categories.rb deleted file mode 100644 index 9845b90449..0000000000 --- a/db/migrate/20120327000598_add_default_to_tax_categories.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDefaultToTaxCategories < ActiveRecord::Migration - def change - add_column :tax_categories, :is_default, :boolean, :default => false - end -end diff --git a/db/migrate/20120327000599_add_display_to_shipping_methods.rb b/db/migrate/20120327000599_add_display_to_shipping_methods.rb deleted file mode 100644 index ba3aa011ac..0000000000 --- a/db/migrate/20120327000599_add_display_to_shipping_methods.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDisplayToShippingMethods < ActiveRecord::Migration - def change - add_column :shipping_methods, :display_on, :string, :default => nil - end -end diff --git a/db/migrate/20120327000600_rename_payment_method_display.rb b/db/migrate/20120327000600_rename_payment_method_display.rb deleted file mode 100644 index 1cc727bf9f..0000000000 --- a/db/migrate/20120327000600_rename_payment_method_display.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenamePaymentMethodDisplay < ActiveRecord::Migration - def change - rename_column :payment_methods, :display, :display_on - end -end diff --git a/db/migrate/20120327000601_rename_preferences_field.rb b/db/migrate/20120327000601_rename_preferences_field.rb deleted file mode 100644 index 19d67680c1..0000000000 --- a/db/migrate/20120327000601_rename_preferences_field.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenamePreferencesField < ActiveRecord::Migration - def change - rename_column :preferences, :attribute, :name - end -end diff --git a/db/migrate/20120327000602_add_guest_flag.rb b/db/migrate/20120327000602_add_guest_flag.rb deleted file mode 100644 index ec8cbf1156..0000000000 --- a/db/migrate/20120327000602_add_guest_flag.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddGuestFlag < ActiveRecord::Migration - def change - add_column :users, :guest, :boolean - end -end diff --git a/db/migrate/20120327000603_drop_order_token.rb b/db/migrate/20120327000603_drop_order_token.rb deleted file mode 100644 index 5738228ac0..0000000000 --- a/db/migrate/20120327000603_drop_order_token.rb +++ /dev/null @@ -1,9 +0,0 @@ -class DropOrderToken < ActiveRecord::Migration - def up - remove_column :orders, :token - end - - def down - add_column :orders, :token, :string - end -end diff --git a/db/migrate/20120327000604_payments_state_and_assigned_to_order_only.rb b/db/migrate/20120327000604_payments_state_and_assigned_to_order_only.rb deleted file mode 100644 index 69ee291859..0000000000 --- a/db/migrate/20120327000604_payments_state_and_assigned_to_order_only.rb +++ /dev/null @@ -1,14 +0,0 @@ -class PaymentsStateAndAssignedToOrderOnly < ActiveRecord::Migration - def up - # TODO: migrate existing payments - rename_column :payments, :payable_id, :order_id - remove_column :payments, :payable_type - add_column :payments, :state, :string - end - - def down - remove_column :payments, :state - add_column :payments, :payable_type, :string - rename_column :payments, :order_id, :payable_id - end -end diff --git a/db/migrate/20120327000605_create_address_keys_for_order.rb b/db/migrate/20120327000605_create_address_keys_for_order.rb deleted file mode 100644 index ee794c3e50..0000000000 --- a/db/migrate/20120327000605_create_address_keys_for_order.rb +++ /dev/null @@ -1,6 +0,0 @@ -class CreateAddressKeysForOrder < ActiveRecord::Migration - def change - add_column :orders, :bill_address_id, :integer - add_column :orders, :ship_address_id, :integer - end -end \ No newline at end of file diff --git a/db/migrate/20120327000606_payment_total_for_orders.rb b/db/migrate/20120327000606_payment_total_for_orders.rb deleted file mode 100644 index 9190e090af..0000000000 --- a/db/migrate/20120327000606_payment_total_for_orders.rb +++ /dev/null @@ -1,5 +0,0 @@ -class PaymentTotalForOrders < ActiveRecord::Migration - def change - add_column :orders, :payment_total, :decimal, :precision => 8, :scale => 2, :default => 0.0 - end -end diff --git a/db/migrate/20120327000607_shipping_method_id_for_orders.rb b/db/migrate/20120327000607_shipping_method_id_for_orders.rb deleted file mode 100644 index ec0bafb1be..0000000000 --- a/db/migrate/20120327000607_shipping_method_id_for_orders.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ShippingMethodIdForOrders < ActiveRecord::Migration - def change - add_column :orders, :shipping_method_id, :integer - end -end diff --git a/db/migrate/20120327000608_add_shipment_and_payment_state.rb b/db/migrate/20120327000608_add_shipment_and_payment_state.rb deleted file mode 100644 index 240dc95776..0000000000 --- a/db/migrate/20120327000608_add_shipment_and_payment_state.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddShipmentAndPaymentState < ActiveRecord::Migration - def change - add_column :orders, :shipment_state, :string - add_column :orders, :payment_state, :string - end -end \ No newline at end of file diff --git a/db/migrate/20120327000609_refactor_adjustments.rb b/db/migrate/20120327000609_refactor_adjustments.rb deleted file mode 100644 index 77e01fc904..0000000000 --- a/db/migrate/20120327000609_refactor_adjustments.rb +++ /dev/null @@ -1,29 +0,0 @@ -class RefactorAdjustments < ActiveRecord::Migration - def up - change_table :adjustments do |t| - t.boolean :mandatory - t.boolean :frozen - t.rename :adjustment_source_id, :source_id - t.rename :adjustment_source_type, :source_type - t.references :originator - t.string :originator_type - t.remove :type - t.rename :description, :label - t.remove :position - end - end - - def down - change_table :adjustments do |t| - t.integer :position - t.rename :label, :description - t.string :type - t.remove :originator_type - t.remove :originator_id - t.rename :source_type, :adjustment_source_type - t.rename :source_id, :adjustment_source_id - t.remove :frozen - t.remove :mandatory - end - end -end diff --git a/db/migrate/20120327000610_response_code_and_avs_response_for_payments.rb b/db/migrate/20120327000610_response_code_and_avs_response_for_payments.rb deleted file mode 100644 index cc0f6c4164..0000000000 --- a/db/migrate/20120327000610_response_code_and_avs_response_for_payments.rb +++ /dev/null @@ -1,6 +0,0 @@ -class ResponseCodeAndAvsResponseForPayments < ActiveRecord::Migration - def change - add_column :payments, :response_code, :string - add_column :payments, :avs_response, :string - end -end diff --git a/db/migrate/20120327000611_change_guest_flag_to_anonymous.rb b/db/migrate/20120327000611_change_guest_flag_to_anonymous.rb deleted file mode 100644 index ca8ae7a3f7..0000000000 --- a/db/migrate/20120327000611_change_guest_flag_to_anonymous.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ChangeGuestFlagToAnonymous < ActiveRecord::Migration - def change - rename_column :users, :guest, :anonymous - end -end diff --git a/db/migrate/20120327000612_email_for_orders.rb b/db/migrate/20120327000612_email_for_orders.rb deleted file mode 100644 index f766dca878..0000000000 --- a/db/migrate/20120327000612_email_for_orders.rb +++ /dev/null @@ -1,5 +0,0 @@ -class EmailForOrders < ActiveRecord::Migration - def change - add_column :orders, :email, :string - end -end diff --git a/db/migrate/20120327000613_create_mail_methods.rb b/db/migrate/20120327000613_create_mail_methods.rb deleted file mode 100644 index 0860607aa7..0000000000 --- a/db/migrate/20120327000613_create_mail_methods.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreateMailMethods < ActiveRecord::Migration - def change - create_table :mail_methods do |t| - t.string :environment - t.boolean :active, :default => true - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000614_rename_frozen_to_locked.rb b/db/migrate/20120327000614_rename_frozen_to_locked.rb deleted file mode 100644 index fef534ab16..0000000000 --- a/db/migrate/20120327000614_rename_frozen_to_locked.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameFrozenToLocked < ActiveRecord::Migration - def change - rename_column :adjustments, :frozen, :locked - end -end diff --git a/db/migrate/20120327000615_move_special_instructions_to_orders.rb b/db/migrate/20120327000615_move_special_instructions_to_orders.rb deleted file mode 100644 index 4d6b1f4aba..0000000000 --- a/db/migrate/20120327000615_move_special_instructions_to_orders.rb +++ /dev/null @@ -1,10 +0,0 @@ -class MoveSpecialInstructionsToOrders < ActiveRecord::Migration - def up - add_column :orders, :special_instructions, :text - execute "UPDATE orders SET special_instructions = (SELECT special_instructions FROM checkouts WHERE order_id = orders.id)" - end - - def down - remove_column :orders, :special_instructions, :text - end -end diff --git a/db/migrate/20120327000616_create_log_entries.rb b/db/migrate/20120327000616_create_log_entries.rb deleted file mode 100644 index 8a0d7f8d8a..0000000000 --- a/db/migrate/20120327000616_create_log_entries.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateLogEntries < ActiveRecord::Migration - def change - create_table :log_entries do |t| - t.integer :source_id - t.string :source_type - t.text :details - - t.timestamps - end - end -end diff --git a/db/migrate/20120327000617_migrate_transactions_to_payment_state.rb b/db/migrate/20120327000617_migrate_transactions_to_payment_state.rb deleted file mode 100644 index 185953157b..0000000000 --- a/db/migrate/20120327000617_migrate_transactions_to_payment_state.rb +++ /dev/null @@ -1,98 +0,0 @@ -class Transaction < ActiveRecord::Base; end -class CreditcardTxn < Transaction; end - -class MigrateTransactionsToPaymentState < ActiveRecord::Migration - - AUTHORIZED=1 - COMPLETED=2 - PURCHASED=3 - VOIDED = 4 - CREDITED =5 - - PAYMENT_COMPLETE = 'completed' - PAYMENT_VOID = 'void' - PAYMENT_PENDING = 'pending' - - # Temporarily set the table back to payments - Spree::Payment.table_name = 'payments' - - def up - migrate_authorized_only_transactions - migrate_voided_transactions - migrate_completed_transactions - migrate_purchased_transactions - migrate_credited_transactions - - Spree::Payment.table_name = 'spree_payments' - end - - def migrate_credited_transactions - credited = Transaction.find_by_sql("SELECT * FROM transactions WHERE txn_type = #{CREDITED}") - credited.each do |tx| - payment = Spree::Payment.find(tx) - order = payment.order - order.create_payment( - :amount => tx.amount, - :source_id => payment.source_id, :source_type => 'Creditcard', - :payment_method_id => payment.payment_method_id, :state => PAYMENT_COMPLETE, - :avs_response => tx.avs_response, :response_code => tx.response_code - ) - end - credited.each { |rec| rec.destroy } - end - - def migrate_voided_transactions - voided = Transaction.find_by_sql("SELECT * FROM transactions WHERE txn_type = #{VOIDED}") - voided.each do |tx| - update_payment(tx, PAYMENT_VOID) - end - unless voided.empty? - all_but_credited = [AUTHORIZED, COMPLETED, PURCHASED, VOIDED] - voided_and_subsequent_transactions = Transaction.find_by_sql("SELECT * FROM transactions WHERE payment_id IN (#{voided.map(&:payment_id).join(',')}) AND txn_type IN (#{all_but_credited.join(',')})") - voided_and_subsequent_transactions.each { |rec| rec.destroy } - end - end - - def migrate_purchased_transactions - migrate_transactions(PURCHASED) - end - - def migrate_completed_transactions - migrate_transactions(COMPLETED) - end - - def migrate_transactions(type) - txs = Transaction.find_by_sql("SELECT * FROM transactions WHERE txn_type = #{type}") - txs.each do |tx| - update_payment(tx, PAYMENT_COMPLETE) - end - txs.each { |rec| rec.destroy } - end - - def migrate_authorized_only_transactions - if (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL') - group_by_clause = 'GROUP BY transactions.' + Transaction.column_names.join(', transactions.') - else - group_by_clause = 'GROUP BY payment_id' - end - authorized_only = Transaction.find_by_sql("SELECT * FROM transactions #{group_by_clause} HAVING COUNT(payment_id) = 1 AND txn_type = #{AUTHORIZED}") - authorized_only.each do |tx| - update_payment(tx, PAYMENT_PENDING) - end - authorized_only.each { |rec| rec.destroy } - end - - def update_payment(tx, state) - payment = Spree::Payment.find(tx.payment_id) - payment.update_attributes_without_callbacks({ - :state => state, - :source_type => 'Creditcard', - :amount => tx.amount, - :response_code => tx.response_code, - :avs_response => tx.avs_response - }) - end - - def down - end -end diff --git a/db/migrate/20120327000618_delete_in_progress_orders.rb b/db/migrate/20120327000618_delete_in_progress_orders.rb deleted file mode 100644 index 3a32449b9c..0000000000 --- a/db/migrate/20120327000618_delete_in_progress_orders.rb +++ /dev/null @@ -1,19 +0,0 @@ -class DeleteInProgressOrders < ActiveRecord::Migration - def up - execute("DELETE FROM orders WHERE orders.state = 'in_progress'") - delete_orphans('adjustments') - delete_orphans('checkouts') - delete_orphans('shipments') - delete_orphans('payments') - delete_orphans('line_items') - delete_orphans('inventory_units') - end - - def down - end - - private - def delete_orphans(table_name) - execute "DELETE FROM #{table_name} WHERE order_id NOT IN (SELECT id FROM orders)" - end -end diff --git a/db/migrate/20120327000619_migrate_checkout_to_orders.rb b/db/migrate/20120327000619_migrate_checkout_to_orders.rb deleted file mode 100644 index 16963fa046..0000000000 --- a/db/migrate/20120327000619_migrate_checkout_to_orders.rb +++ /dev/null @@ -1,23 +0,0 @@ -class MigrateCheckoutToOrders < ActiveRecord::Migration - def up - orders = select_all "SELECT * FROM orders" - - orders.each do |order| - checkout = update_order(order) - execute "DELETE FROM checkouts WHERE id = #{checkout['id']}" if checkout - end - end - - def down - end - - private - def update_order(order) - checkout = select_one "SELECT * FROM checkouts WHERE order_id = #{order['id']}" - - if checkout - execute "UPDATE orders SET email='#{checkout['email']}', bill_address_id = #{checkout['bill_address_id']}, ship_address_id = #{checkout['ship_address_id']} WHERE id = #{checkout['id']}" - end - checkout - end -end diff --git a/db/migrate/20120327000620_remove_shipped_state.rb b/db/migrate/20120327000620_remove_shipped_state.rb deleted file mode 100644 index 2da2eee433..0000000000 --- a/db/migrate/20120327000620_remove_shipped_state.rb +++ /dev/null @@ -1,12 +0,0 @@ -class RemoveShippedState < ActiveRecord::Migration - def up - execute "UPDATE orders SET state = 'complete' WHERE state = 'shipped'" - shipments = select_all "SELECT shipments.id FROM shipments WHERE order_id IN (SELECT orders.id FROM orders WHERE orders.state = 'shipped')" - shipments.each do |shipment| - execute "UPDATE shipments SET state='shipped' WHERE id = #{shipment[:id]}" - end - end - - def down - end -end diff --git a/db/migrate/20120327000621_prevent_nil_payment_total.rb b/db/migrate/20120327000621_prevent_nil_payment_total.rb deleted file mode 100644 index 101a26dc1b..0000000000 --- a/db/migrate/20120327000621_prevent_nil_payment_total.rb +++ /dev/null @@ -1,8 +0,0 @@ -class PreventNilPaymentTotal < ActiveRecord::Migration - def up - execute "UPDATE orders SET payment_total = 0.0 WHERE payment_total IS NULL" - end - - def down - end -end diff --git a/db/migrate/20120327000622_prevent_nil_email.rb b/db/migrate/20120327000622_prevent_nil_email.rb deleted file mode 100644 index 6bb09984c2..0000000000 --- a/db/migrate/20120327000622_prevent_nil_email.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PreventNilEmail < ActiveRecord::Migration - def up - execute "UPDATE orders SET email = 'guest@example.com' WHERE email IS NULL" - execute "UPDATE orders SET email = 'guest@example.com' WHERE email = ''" - end - - def down - end -end diff --git a/db/migrate/20120327000623_generate_anonymous_users.rb b/db/migrate/20120327000623_generate_anonymous_users.rb deleted file mode 100644 index 47509d8778..0000000000 --- a/db/migrate/20120327000623_generate_anonymous_users.rb +++ /dev/null @@ -1,20 +0,0 @@ -class GenerateAnonymousUsers < ActiveRecord::Migration - def up - Spree::User.table_name = 'users' - Spree::Order.table_name = 'orders' - - Spree::User.reset_column_information - Spree::Order.where(:user_id => nil).each do |order| - user = Spree::User.anonymous! - user.email ||= order.email - order.user = user - order.save! - end - - Spree::User.table_name = 'spree_users' - Spree::Order.table_name = 'spree_orders' - end - - def down - end -end diff --git a/db/migrate/20120327000624_update_order_state.rb b/db/migrate/20120327000624_update_order_state.rb deleted file mode 100644 index 174adbc565..0000000000 --- a/db/migrate/20120327000624_update_order_state.rb +++ /dev/null @@ -1,12 +0,0 @@ -class UpdateOrderState < ActiveRecord::Migration - def up - Spree::Order.table_name = 'orders' - - Spree::Order.all.map(&:update!) - - Spree::Order.table_name = 'spree_orders' - end - - def down - end -end diff --git a/db/migrate/20120327000625_cleanup_legacy_tables.rb b/db/migrate/20120327000625_cleanup_legacy_tables.rb deleted file mode 100644 index 7979409209..0000000000 --- a/db/migrate/20120327000625_cleanup_legacy_tables.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CleanupLegacyTables < ActiveRecord::Migration - def up - drop_table :checkouts - drop_table :transactions - drop_table :open_id_authentication_associations - drop_table :open_id_authentication_nonces - end - - def down - end -end diff --git a/db/migrate/20120327000626_remove_number_and_cvv_from_credicard.rb b/db/migrate/20120327000626_remove_number_and_cvv_from_credicard.rb deleted file mode 100644 index 9bfcf2bd7d..0000000000 --- a/db/migrate/20120327000626_remove_number_and_cvv_from_credicard.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RemoveNumberAndCvvFromCredicard < ActiveRecord::Migration - def up - remove_column :creditcards, :number - remove_column :creditcards, :verification_value - end - - def down - add_column :creditcards, :verification_value, :text - add_column :creditcards, :number, :text - end -end diff --git a/db/migrate/20120327000627_drop_anonymous_field_for_user.rb b/db/migrate/20120327000627_drop_anonymous_field_for_user.rb deleted file mode 100644 index 6aadea72ff..0000000000 --- a/db/migrate/20120327000627_drop_anonymous_field_for_user.rb +++ /dev/null @@ -1,9 +0,0 @@ -class DropAnonymousFieldForUser < ActiveRecord::Migration - def up - remove_column :users, :anonymous - end - - def down - add_column :users, :anonymous, :boolean - end -end diff --git a/db/migrate/20120327000628_renamed_rma_cancelled_state.rb b/db/migrate/20120327000628_renamed_rma_cancelled_state.rb deleted file mode 100644 index 1675568cf2..0000000000 --- a/db/migrate/20120327000628_renamed_rma_cancelled_state.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RenamedRmaCancelledState < ActiveRecord::Migration - def up - execute "UPDATE return_authorizations SET state = 'canceled' WHERE state = 'cancelled'" - end - - def down - execute "UPDATE return_authorizations SET state = 'cancelled' WHERE state = 'canceled'" - end -end diff --git a/db/migrate/20120327000629_fix_problematic_index_names.rb b/db/migrate/20120327000629_fix_problematic_index_names.rb deleted file mode 100644 index ec6eb98f57..0000000000 --- a/db/migrate/20120327000629_fix_problematic_index_names.rb +++ /dev/null @@ -1,13 +0,0 @@ -class FixProblematicIndexNames < ActiveRecord::Migration - def up - begin - remove_index :preferences, :name => 'index_preferences_on_owner_and_attribute_and_preference' - rescue ArgumentError - # ignore - already remove then - end - add_index :preferences, [:owner_id, :owner_type, :name, :group_id, :group_type], :name => 'ix_prefs_on_owner_attr_pref', :unique => true - end - - def down - end -end diff --git a/db/migrate/20120327000630_add_position_to_variants.rb b/db/migrate/20120327000630_add_position_to_variants.rb deleted file mode 100644 index 84a4ab5972..0000000000 --- a/db/migrate/20120327000630_add_position_to_variants.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPositionToVariants < ActiveRecord::Migration - def change - add_column :variants, :position, :integer - end -end diff --git a/db/migrate/20120327000631_add_next_state_to_state_events.rb b/db/migrate/20120327000631_add_next_state_to_state_events.rb deleted file mode 100644 index 4ea7479a72..0000000000 --- a/db/migrate/20120327000631_add_next_state_to_state_events.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNextStateToStateEvents < ActiveRecord::Migration - def change - add_column :state_events, :next_state, :string - end -end diff --git a/db/migrate/20120327000632_add_position_to_option_types.rb b/db/migrate/20120327000632_add_position_to_option_types.rb deleted file mode 100644 index 61cdf87344..0000000000 --- a/db/migrate/20120327000632_add_position_to_option_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPositionToOptionTypes < ActiveRecord::Migration - def change - add_column :option_types, :position, :integer, :null => false, :default => 0 - end -end diff --git a/db/migrate/20120327000633_remove_trailing_slashes_in_taxon_permalinks.rb b/db/migrate/20120327000633_remove_trailing_slashes_in_taxon_permalinks.rb deleted file mode 100644 index cb2a016fbb..0000000000 --- a/db/migrate/20120327000633_remove_trailing_slashes_in_taxon_permalinks.rb +++ /dev/null @@ -1,19 +0,0 @@ -class RemoveTrailingSlashesInTaxonPermalinks < ActiveRecord::Migration - def up - taxons = select_all "SELECT * FROM taxons" - taxons.each do |taxon| - if taxon['permalink'] && taxon['permalink'][-1..-1] == '/' - execute "UPDATE taxons SET permalink = '#{taxon['permalink'][0...-1]}' WHERE id = #{taxon['id']}" - end - end - end - - def down - taxons = select_all "SELECT * FROM taxons" - taxons.each do |taxon| - if taxon['permalink'] && taxon['permalink'][-1..-1] != '/' - execute "UPDATE taxons SET permalink = '#{taxon['permalink'] + '/'}' WHERE id = #{taxon['id']}" - end - end - end -end diff --git a/db/migrate/20120327000634_create_activators.rb b/db/migrate/20120327000634_create_activators.rb deleted file mode 100644 index 81448f3025..0000000000 --- a/db/migrate/20120327000634_create_activators.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateActivators < ActiveRecord::Migration - def change - create_table :activators, :force => true do |t| - t.string :description - t.datetime :expires_at - t.datetime :created_at - t.datetime :updated_at - t.datetime :starts_at - t.string :name - t.string :event_name - t.string :type - end - end -end diff --git a/db/migrate/20120327000635_eligible_for_adjustments.rb b/db/migrate/20120327000635_eligible_for_adjustments.rb deleted file mode 100644 index 0f669ed30e..0000000000 --- a/db/migrate/20120327000635_eligible_for_adjustments.rb +++ /dev/null @@ -1,5 +0,0 @@ -class EligibleForAdjustments < ActiveRecord::Migration - def change - add_column :adjustments, :eligible, :boolean, :default => true - end -end diff --git a/db/migrate/20120327000636_namespace_top_level_models.rb b/db/migrate/20120327000636_namespace_top_level_models.rb deleted file mode 100644 index 88abe8a139..0000000000 --- a/db/migrate/20120327000636_namespace_top_level_models.rb +++ /dev/null @@ -1,52 +0,0 @@ -class NamespaceTopLevelModels < ActiveRecord::Migration - def change - rename_table :activators, :spree_activators - rename_table :addresses, :spree_addresses - rename_table :adjustments, :spree_adjustments - rename_table :configurations, :spree_configurations - rename_table :assets, :spree_assets - rename_table :calculators, :spree_calculators - rename_table :countries, :spree_countries - rename_table :creditcards, :spree_creditcards - rename_table :gateways, :spree_gateways - rename_table :inventory_units, :spree_inventory_units - rename_table :line_items, :spree_line_items - rename_table :log_entries, :spree_log_entries - rename_table :mail_methods, :spree_mail_methods - rename_table :option_types, :spree_option_types - rename_table :option_values, :spree_option_values - rename_table :option_types_prototypes, :spree_option_types_prototypes - rename_table :option_values_variants, :spree_option_values_variants - rename_table :orders, :spree_orders - rename_table :payments, :spree_payments - rename_table :payment_methods, :spree_payment_methods - rename_table :preferences, :spree_preferences - rename_table :products, :spree_products - rename_table :product_groups, :spree_product_groups - rename_table :product_groups_products, :spree_product_groups_products - rename_table :product_option_types, :spree_product_option_types - rename_table :product_properties, :spree_product_properties - rename_table :product_scopes, :spree_product_scopes - rename_table :products_taxons, :spree_products_taxons - rename_table :properties, :spree_properties - rename_table :prototypes, :spree_prototypes - rename_table :properties_prototypes, :spree_properties_prototypes - rename_table :return_authorizations, :spree_return_authorizations - rename_table :roles, :spree_roles - rename_table :roles_users, :spree_roles_users - rename_table :shipments, :spree_shipments - rename_table :shipping_categories, :spree_shipping_categories - rename_table :shipping_methods, :spree_shipping_methods - rename_table :states, :spree_states - rename_table :state_events, :spree_state_events - rename_table :tax_categories, :spree_tax_categories - rename_table :tax_rates, :spree_tax_rates - rename_table :taxons, :spree_taxons - rename_table :taxonomies, :spree_taxonomies - rename_table :trackers, :spree_trackers - rename_table :users, :spree_users - rename_table :variants, :spree_variants - rename_table :zones, :spree_zones - rename_table :zone_members, :spree_zone_members - end -end diff --git a/db/migrate/20120327000637_migrate_namespaced_polymorphic_models.rb b/db/migrate/20120327000637_migrate_namespaced_polymorphic_models.rb deleted file mode 100644 index ec82863a4f..0000000000 --- a/db/migrate/20120327000637_migrate_namespaced_polymorphic_models.rb +++ /dev/null @@ -1,52 +0,0 @@ -class MigrateNamespacedPolymorphicModels < ActiveRecord::Migration - def concat(str1, str2) - dbtype = Rails.configuration.database_configuration[Rails.env]['adapter'].to_sym - - case dbtype - when :mysql, :mysql2 - "CONCAT(#{str1}, #{str2})" - when :sqlserver - "(#{str1} + #{str2})" - else - "(#{str1} || #{str2})" - end - end - - def update_column_data(table_names, column_name) - tables = Array.wrap(table_names) - tables.each do |table| - execute "UPDATE #{table} SET #{column_name} = #{concat("'Spree::'", column_name)}" + - " where #{column_name} NOT LIKE 'Spree::%' AND #{column_name} IS NOT NULL" - end - end - - def replace_column_data(table_names, column_name) - tables = Array.wrap(table_names) - tables.each do |table| - execute "UPDATE #{table} SET #{column_name} = REPLACE(#{column_name}, 'Spree::', '') " + - " where #{column_name} LIKE 'Spree::%'" - end - end - - def up - update_column_data(['spree_payments', 'spree_adjustments', 'spree_log_entries'], 'source_type') - update_column_data('spree_adjustments', 'originator_type') - update_column_data('spree_calculators', 'calculable_type') - update_column_data('spree_preferences', 'owner_type') - update_column_data('spree_state_events', 'stateful_type') - update_column_data(['spree_activators', 'spree_assets', 'spree_calculators', 'spree_configurations', 'spree_gateways', 'spree_payment_methods'], 'type') - update_column_data('spree_assets', 'viewable_type') - update_column_data('spree_zone_members', 'zoneable_type') - end - - def down - replace_column_data(['spree_payments', 'spree_adjustments', 'spree_log_entries'], 'source_type') - replace_column_data('spree_adjustments', 'originator_type') - replace_column_data('spree_calculators', 'calculable_type') - replace_column_data('spree_preferences', 'owner_type') - replace_column_data('spree_state_events', 'stateful_type') - replace_column_data(['spree_activators', 'spree_assets', 'spree_calculators', 'spree_configurations', 'spree_gateways', 'spree_payment_methods'], 'type') - replace_column_data('spree_assets', 'viewable_type') - replace_column_data('spree_zone_members', 'zoneable_type') - end -end diff --git a/db/migrate/20120327000638_make_adjustments_polymorphic.rb b/db/migrate/20120327000638_make_adjustments_polymorphic.rb deleted file mode 100644 index 62ba67cb64..0000000000 --- a/db/migrate/20120327000638_make_adjustments_polymorphic.rb +++ /dev/null @@ -1,9 +0,0 @@ -class MakeAdjustmentsPolymorphic < ActiveRecord::Migration - - def change - add_column :spree_adjustments, :adjustable_type, :string - rename_column :spree_adjustments, :order_id, :adjustable_id - execute "UPDATE spree_adjustments SET adjustable_type = 'Spree::Order'" - end - -end diff --git a/db/migrate/20120327000639_add_company_to_addresses.rb b/db/migrate/20120327000639_add_company_to_addresses.rb deleted file mode 100644 index 60a819ea70..0000000000 --- a/db/migrate/20120327000639_add_company_to_addresses.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddCompanyToAddresses < ActiveRecord::Migration - def change - add_column :spree_addresses, :company, :string - end -end diff --git a/db/migrate/20120327000640_add_inc_tax_to_tax_rates.rb b/db/migrate/20120327000640_add_inc_tax_to_tax_rates.rb deleted file mode 100644 index 715b0b4357..0000000000 --- a/db/migrate/20120327000640_add_inc_tax_to_tax_rates.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIncTaxToTaxRates < ActiveRecord::Migration - def change - add_column :spree_tax_rates, :inc_tax, :boolean, :default => false - end -end diff --git a/db/migrate/20120327000641_rename_inc_price_attribute.rb b/db/migrate/20120327000641_rename_inc_price_attribute.rb deleted file mode 100644 index 8657f63a58..0000000000 --- a/db/migrate/20120327000641_rename_inc_price_attribute.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameIncPriceAttribute < ActiveRecord::Migration - def change - rename_column :spree_tax_rates, :inc_tax, :included_in_price - end -end diff --git a/db/migrate/20120327000642_add_default_tax_zone.rb b/db/migrate/20120327000642_add_default_tax_zone.rb deleted file mode 100644 index d0e831800f..0000000000 --- a/db/migrate/20120327000642_add_default_tax_zone.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDefaultTaxZone < ActiveRecord::Migration - def change - add_column :spree_zones, :default_tax, :boolean, :default => false - end -end diff --git a/db/migrate/20120327000643_associate_shipping_methods_and_shipping_categories.rb b/db/migrate/20120327000643_associate_shipping_methods_and_shipping_categories.rb deleted file mode 100644 index f7f62b7201..0000000000 --- a/db/migrate/20120327000643_associate_shipping_methods_and_shipping_categories.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AssociateShippingMethodsAndShippingCategories < ActiveRecord::Migration - def change - change_table :spree_shipping_methods do |t| - t.references :shipping_category - end - end -end diff --git a/db/migrate/20120327000644_add_match_rules_to_shipping_methods.rb b/db/migrate/20120327000644_add_match_rules_to_shipping_methods.rb deleted file mode 100644 index e5b5ea32a2..0000000000 --- a/db/migrate/20120327000644_add_match_rules_to_shipping_methods.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddMatchRulesToShippingMethods < ActiveRecord::Migration - def change - add_column :spree_shipping_methods, :match_none, :boolean - add_column :spree_shipping_methods, :match_all, :boolean - add_column :spree_shipping_methods, :match_one, :boolean - end -end diff --git a/db/migrate/20120327000645_new_preferences.rb b/db/migrate/20120327000645_new_preferences.rb deleted file mode 100644 index 86e5dbbf57..0000000000 --- a/db/migrate/20120327000645_new_preferences.rb +++ /dev/null @@ -1,81 +0,0 @@ -# Spree 1.3.6.beta preference rescue implementation, required for the new -# preferences migration, which is broken since commit ab707cf due to the -# absence of this file. -# -# Migration: db/migrate/20120327000645_new_preferences.rb -# Source: https://raw.githubusercontent.com/spree/spree/1-3-stable/core/lib/spree/core/preference_rescue.rb -# -# rubocop:disable all -module Spree - class OldPrefs < ActiveRecord::Base - self.table_name = "spree_preferences" - belongs_to :owner, :polymorphic => true - attr_accessor :owner_klass - end - - class PreferenceRescue - def self.try - OldPrefs.where(:key => nil).each do |old_pref| - next unless owner = (old_pref.owner rescue nil) - unless old_pref.owner_type == "Spree::Activator" || old_pref.owner_type == "Spree::Configuration" - begin - old_pref.key = [owner.class.name, old_pref.name, owner.id].join('::').underscore - old_pref.value_type = owner.preference_type(old_pref.name) - puts "Migrating Preference: #{old_pref.key}" - old_pref.save - rescue NoMethodError => ex - puts ex.message - end - end - end - end - end -end -# rubocop:enable all - -class NewPreferences < ActiveRecord::Migration - - def up - add_column :spree_preferences, :key, :string - add_column :spree_preferences, :value_type, :string - add_index :spree_preferences, :key, :unique => true - - remove_index :spree_preferences, :name => 'ix_prefs_on_owner_attr_pref' - - # remove old constraints for migration - change_column :spree_preferences, :name, :string, :null => true - change_column :spree_preferences, :owner_id, :integer, :null => true - change_column :spree_preferences, :owner_type, :string, :null => true - change_column :spree_preferences, :group_id, :integer, :null => true - change_column :spree_preferences, :group_type, :string, :null => true - - cfgs = execute("select id, type from spree_configurations").to_a - execute("select id, owner_id, name from spree_preferences where owner_type = 'Spree::Configuration'").each do |pref| - configuration = cfgs.detect { |c| c[0].to_s == pref[1].to_s } - - value_type = configuration[1].constantize.new.send "preferred_#{pref[2]}_type" rescue 'string' - - execute "UPDATE spree_preferences set `key` = '#{configuration[1].underscore}/#{pref[2]}', `value_type` = '#{value_type}' where id = #{pref[0]}" rescue nil - end - - # remove orphaned calculator preferences - Spree::Preference.where(:owner_type => 'Spree::Calculator').each do |preference| - preference.destroy unless Spree::Calculator.exists? preference.owner_id - end - - Spree::PreferenceRescue.try - - Spree::Preference.where(:value_type => nil).update_all(:value_type => 'string') - end - - def down - remove_column :spree_preferences, :key - remove_column :spree_preferences, :value_type - - add_column :spree_preferences, :name, :string - add_column :spree_preferences, :owner_id, :integer - add_column :spree_preferences, :owner_type, :string - add_column :spree_preferences, :group_id, :integer - add_column :spree_preferences, :group_type, :string - end -end diff --git a/db/migrate/20120327000646_add_deleted_at_to_tax_category.rb b/db/migrate/20120327000646_add_deleted_at_to_tax_category.rb deleted file mode 100644 index be24f6b4d0..0000000000 --- a/db/migrate/20120327000646_add_deleted_at_to_tax_category.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDeletedAtToTaxCategory < ActiveRecord::Migration - def change - add_column :spree_tax_categories, :deleted_at, :datetime - end -end diff --git a/db/migrate/20120327000647_rename_columns_for_devise.rb b/db/migrate/20120327000647_rename_columns_for_devise.rb deleted file mode 100644 index cfd893edee..0000000000 --- a/db/migrate/20120327000647_rename_columns_for_devise.rb +++ /dev/null @@ -1,39 +0,0 @@ -class RenameColumnsForDevise < ActiveRecord::Migration - def up - return if column_exists?(:spree_users, :password_salt) - rename_column :spree_users, :crypted_password, :encrypted_password - rename_column :spree_users, :salt, :password_salt - rename_column :spree_users, :remember_token_expires_at, :remember_created_at - rename_column :spree_users, :login_count, :sign_in_count - rename_column :spree_users, :failed_login_count, :failed_attempts - rename_column :spree_users, :single_access_token, :reset_password_token - rename_column :spree_users, :current_login_at, :current_sign_in_at - rename_column :spree_users, :last_login_at, :last_sign_in_at - rename_column :spree_users, :current_login_ip, :current_sign_in_ip - rename_column :spree_users, :last_login_ip, :last_sign_in_ip - add_column :spree_users, :authentication_token, :string - add_column :spree_users, :unlock_token, :string - add_column :spree_users, :locked_at, :datetime - remove_column :spree_users, :api_key if column_exists?(:spree_users, :api_key) - remove_column :spree_users, :openid_identifier - end - - def down - remove_column :spree_users, :authentication_token - remove_column :spree_users, :locked_at - remove_column :spree_users, :unlock_token - rename_column :table_name, :new_column_name, :column_name - rename_column :spree_users, :last_sign_in_ip, :last_login_ip - rename_column :spree_users, :current_sign_in_ip, :current_login_ip - rename_column :spree_users, :last_sign_in_at, :last_login_at - rename_column :spree_users, :current_sign_in_at, :current_login_at - rename_column :spree_users, :reset_password_token, :single_access_token - rename_column :spree_users, :failed_attempts, :failed_login_count - rename_column :spree_users, :sign_in_count, :login_count - rename_column :spree_users, :remember_created_at, :remember_token_expires_at - rename_column :spree_users, :password_salt, :salt - rename_column :spree_users, :encrypted_password, :crypted_password - add_column :spree_users, :unlock_token, :string - add_column :spree_users, :openid_identifier, :string - end -end diff --git a/db/migrate/20120327000648_convert_user_remember_field.rb b/db/migrate/20120327000648_convert_user_remember_field.rb deleted file mode 100644 index 4514fc5b47..0000000000 --- a/db/migrate/20120327000648_convert_user_remember_field.rb +++ /dev/null @@ -1,11 +0,0 @@ -class ConvertUserRememberField < ActiveRecord::Migration - def up - remove_column :spree_users, :remember_created_at - add_column :spree_users, :remember_created_at, :datetime - end - - def down - remove_column :spree_users, :remember_created_at - add_column :spree_users, :remember_created_at, :string - end -end diff --git a/db/migrate/20120327000649_create_tokenized_permissions.rb b/db/migrate/20120327000649_create_tokenized_permissions.rb deleted file mode 100644 index e7d8df4d60..0000000000 --- a/db/migrate/20120327000649_create_tokenized_permissions.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateTokenizedPermissions < ActiveRecord::Migration - def change - create_table :tokenized_permissions do |t| - t.integer :permissable_id - t.string :permissable_type - t.string :token - - t.timestamps - end - - add_index :tokenized_permissions, [:permissable_id, :permissable_type], :name => 'index_tokenized_name_and_type' - end -end diff --git a/db/migrate/20120327000650_tokens_for_legacy_orders.rb b/db/migrate/20120327000650_tokens_for_legacy_orders.rb deleted file mode 100644 index 009177b4e8..0000000000 --- a/db/migrate/20120327000650_tokens_for_legacy_orders.rb +++ /dev/null @@ -1,16 +0,0 @@ -class TokensForLegacyOrders < ActiveRecord::Migration - def up - Spree::TokenizedPermission.table_name = 'tokenized_permissions' - - # add token permissions for legacy orders (stop relying on user persistence token) - Spree::Order.all.each do |order| - next unless order.user - order.create_tokenized_permission(:token => order.user.persistence_token) - end - - Spree::TokenizedPermission.table_name = 'spree_tokenized_permissions' - end - - def down - end -end diff --git a/db/migrate/20120327000651_namespace_tokenized_permission.rb b/db/migrate/20120327000651_namespace_tokenized_permission.rb deleted file mode 100644 index 3eb8baa7b0..0000000000 --- a/db/migrate/20120327000651_namespace_tokenized_permission.rb +++ /dev/null @@ -1,5 +0,0 @@ -class NamespaceTokenizedPermission < ActiveRecord::Migration - def change - rename_table :tokenized_permissions, :spree_tokenized_permissions - end -end diff --git a/db/migrate/20120327000652_migrate_tokenized_permissions.rb b/db/migrate/20120327000652_migrate_tokenized_permissions.rb deleted file mode 100644 index 2fb4e6e155..0000000000 --- a/db/migrate/20120327000652_migrate_tokenized_permissions.rb +++ /dev/null @@ -1,24 +0,0 @@ -class MigrateTokenizedPermissions < ActiveRecord::Migration - def concat(str1, str2) - dbtype = Rails.configuration.database_configuration[Rails.env]['adapter'].to_sym - - case dbtype - when :mysql, :mysql2 - "CONCAT(#{str1}, #{str2})" - when :sqlserver - "(#{str1} + #{str2})" - else - "(#{str1} || #{str2})" - end - end - - def up - execute "UPDATE spree_tokenized_permissions SET permissable_type = #{concat("'Spree::'", "permissable_type")}" + - " WHERE permissable_type NOT LIKE 'Spree::%' AND permissable_type IS NOT NULL" - end - - def down - execute "UPDATE spree_tokenized_permissions SET permissable_type = REPLACE(permissable_type, 'Spree::', '')" + - " WHERE permissable_type LIKE 'Spree::%'" - end -end diff --git a/db/migrate/20120327000653_add_api_key_to_users.rb b/db/migrate/20120327000653_add_api_key_to_users.rb deleted file mode 100644 index 32d98fabba..0000000000 --- a/db/migrate/20120327000653_add_api_key_to_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddApiKeyToUsers < ActiveRecord::Migration - def change - add_column :spree_users, :api_key, :string, :limit => 40 - end -end diff --git a/db/migrate/20120327000654_rename_coupons_to_promotions.rb b/db/migrate/20120327000654_rename_coupons_to_promotions.rb deleted file mode 100644 index a5d6bb39e5..0000000000 --- a/db/migrate/20120327000654_rename_coupons_to_promotions.rb +++ /dev/null @@ -1,10 +0,0 @@ -class RenameCouponsToPromotions < ActiveRecord::Migration - def up - drop_table :promotions if table_exists?(:promotions) - rename_table :coupons, :promotions - end - - def down - rename_table :promotions, :coupons - end -end diff --git a/db/migrate/20120327000655_create_promotion_rules.rb b/db/migrate/20120327000655_create_promotion_rules.rb deleted file mode 100644 index f94030b7a4..0000000000 --- a/db/migrate/20120327000655_create_promotion_rules.rb +++ /dev/null @@ -1,24 +0,0 @@ -class CreatePromotionRules < ActiveRecord::Migration - def up - create_table :promotion_rules do |t| - t.references :promotion, :user, :product_group - t.string :type - - t.timestamps - end - add_index :promotion_rules, :product_group_id - add_index :promotion_rules, :user_id - - create_table :products_promotion_rules do |t| - t.integer :product_id, :promotion_rule_id - end - remove_column :products_promotion_rules, :id - add_index :products_promotion_rules, :product_id - add_index :products_promotion_rules, :promotion_rule_id - end - - def down - drop_table :promotion_rules - drop_table :products_promotion_rules - end -end diff --git a/db/migrate/20120327000656_match_policy_for_promotions.rb b/db/migrate/20120327000656_match_policy_for_promotions.rb deleted file mode 100644 index f6c580e452..0000000000 --- a/db/migrate/20120327000656_match_policy_for_promotions.rb +++ /dev/null @@ -1,5 +0,0 @@ -class MatchPolicyForPromotions < ActiveRecord::Migration - def change - add_column :promotions, :match_policy, :string, :default => 'all' - end -end diff --git a/db/migrate/20120327000657_create_promotion_rules_users.rb b/db/migrate/20120327000657_create_promotion_rules_users.rb deleted file mode 100644 index f6c33350e6..0000000000 --- a/db/migrate/20120327000657_create_promotion_rules_users.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreatePromotionRulesUsers < ActiveRecord::Migration - def up - create_table :promotion_rules_users do |t| - t.integer :user_id, :promotion_rule_id - end - remove_column :promotion_rules_users, :id - add_index :promotion_rules_users, :user_id - add_index :promotion_rules_users, :promotion_rule_id - end - - def down - drop_table :promotion_rules_users - end -end diff --git a/db/migrate/20120327000658_name_for_promotions.rb b/db/migrate/20120327000658_name_for_promotions.rb deleted file mode 100644 index 1a26126e9b..0000000000 --- a/db/migrate/20120327000658_name_for_promotions.rb +++ /dev/null @@ -1,5 +0,0 @@ -class NameForPromotions < ActiveRecord::Migration - def change - add_column :promotions, :name, :string - end -end diff --git a/db/migrate/20120327000659_update_calculable_type_for_promotions.rb b/db/migrate/20120327000659_update_calculable_type_for_promotions.rb deleted file mode 100644 index ccdb8bef84..0000000000 --- a/db/migrate/20120327000659_update_calculable_type_for_promotions.rb +++ /dev/null @@ -1,9 +0,0 @@ -class UpdateCalculableTypeForPromotions < ActiveRecord::Migration - def up - execute "UPDATE spree_calculators SET calculable_type = 'Promotion' WHERE calculable_type = 'Coupon'" - end - - def down - execute "UPDATE spree_calculators SET calculable_type = 'Coupon' WHERE calculable_type = 'Promotion'" - end -end diff --git a/db/migrate/20120327000660_migrate_adjustments.rb b/db/migrate/20120327000660_migrate_adjustments.rb deleted file mode 100644 index 398d23bbc8..0000000000 --- a/db/migrate/20120327000660_migrate_adjustments.rb +++ /dev/null @@ -1,9 +0,0 @@ -class MigrateAdjustments < ActiveRecord::Migration - def up - execute "UPDATE spree_adjustments SET amount = 0.0 WHERE amount IS NULL" - execute "UPDATE spree_adjustments SET mandatory = 't' WHERE locked = 't'" - end - - def down - end -end diff --git a/db/migrate/20120327000661_promotion_changes_to_subclass_of_activator.rb b/db/migrate/20120327000661_promotion_changes_to_subclass_of_activator.rb deleted file mode 100644 index feee9c754e..0000000000 --- a/db/migrate/20120327000661_promotion_changes_to_subclass_of_activator.rb +++ /dev/null @@ -1,22 +0,0 @@ -class PromotionChangesToSubclassOfActivator < ActiveRecord::Migration - def up - drop_table :promotions - rename_column :promotion_rules, :promotion_id, :activator_id - end - - def down - create_table :promotions, :force => true do |t| - t.string :name - t.string :code - t.string :description - t.integer :usage_limit - t.boolean :combine - t.datetime :expires_at - t.datetime :starts_at - t.string :match_policy, :default => 'all' - - t.timestamps - end - rename_column :promotion_rules, :activator_id, :promotion_id - end -end diff --git a/db/migrate/20120327000662_create_promotion_actions.rb b/db/migrate/20120327000662_create_promotion_actions.rb deleted file mode 100644 index 2283154611..0000000000 --- a/db/migrate/20120327000662_create_promotion_actions.rb +++ /dev/null @@ -1,9 +0,0 @@ -class CreatePromotionActions < ActiveRecord::Migration - def change - create_table :promotion_actions do |t| - t.integer :activator_id - t.integer :position - t.string :type - end - end -end diff --git a/db/migrate/20120327000663_create_promotion_action_line_items.rb b/db/migrate/20120327000663_create_promotion_action_line_items.rb deleted file mode 100644 index 9241d58fc3..0000000000 --- a/db/migrate/20120327000663_create_promotion_action_line_items.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreatePromotionActionLineItems < ActiveRecord::Migration - def change - create_table :promotion_action_line_items do |t| - t.integer :promotion_action_id, :variant_id - t.integer :quantity, :default => 1 - t.references :promotion_action - t.references :variant - end - end -end diff --git a/db/migrate/20120327000664_namespace_promo_tables.rb b/db/migrate/20120327000664_namespace_promo_tables.rb deleted file mode 100644 index 398e65ae16..0000000000 --- a/db/migrate/20120327000664_namespace_promo_tables.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'spree/core/preference_rescue' - -class NamespacePromoTables < ActiveRecord::Migration - - def concat(str1, str2) - dbtype = Rails.configuration.database_configuration[Rails.env]['adapter'].to_sym - - case dbtype - when :mysql, :mysql2 - "CONCAT(#{str1}, #{str2})" - when :sqlserver - "(#{str1} + #{str2})" - else - "(#{str1} || #{str2})" - end - end - - def update_column_data(table_names, column_name) - tables = Array.wrap(table_names) - tables.each do |table| - execute "UPDATE #{table} SET #{column_name} = #{concat("'Spree::'", column_name)}" + - " where #{column_name} NOT LIKE 'Spree::%' AND #{column_name} IS NOT NULL" - end - end - - def replace_column_data(table_names, column_name) - tables = Array.wrap(table_names) - tables.each do |table| - execute "UPDATE #{table} SET #{column_name} = REPLACE(#{column_name}, 'Spree::', '') " + - " where #{column_name} LIKE 'Spree::%'" - end - end - - def self.up - # namespace promo tables - rename_table :promotion_actions, :spree_promotion_actions - rename_table :promotion_rules, :spree_promotion_rules - rename_table :promotion_rules_users, :spree_promotion_rules_users - rename_table :promotion_action_line_items, :spree_promotion_action_line_items - rename_table :products_promotion_rules, :spree_products_promotion_rules - - update_column_data('spree_promotion_actions', 'type') - update_column_data('spree_promotion_rules', 'type') - - # add old promo preferences as columns - add_column :spree_activators, :usage_limit, :integer - add_column :spree_activators, :match_policy, :string, :default => 'all' - add_column :spree_activators, :code, :string - add_column :spree_activators, :advertise, :boolean, :default => false - - Spree::Activator.reset_column_information - - Spree::Preference.where(:owner_type => 'Spree::Activator').each do |preference| - unless Spree::Activator.exists? preference.owner_id - preference.destroy - next - end - - @activator = Spree::Activator.find(preference.owner_id) - @activator.update_attribute(preference.name, preference.raw_value) - preference.destroy - end - - Spree::PreferenceRescue.try - - # This *should* be in the new_preferences migration inside of Core but... - # This is migration needs to have these keys around so that - # we can convert the promotions over correctly. - # So they hang around until we're *finally* done with them, since promo's - # migrations are copied over *after* core, and then we ditch them. - remove_column :spree_preferences, :group_id - remove_column :spree_preferences, :group_type - end - - def self.down - replace_column_data('spree_promotion_actions', 'type') - replace_column_data('spree_promotion_rules', 'type') - - rename_table :spree_promotion_actions, :promotion_actions - rename_table :spree_promotion_rules, :promotion_rules - rename_table :spree_promotion_rules_users, :promotion_rules_users - rename_table :spree_promotion_action_line_items, :promotion_action_line_items - rename_table :spree_products_promotion_rules, :products_promotion_rules - end -end \ No newline at end of file diff --git a/db/migrate/20120327000665_create_spree_pending_promotions.rb b/db/migrate/20120327000665_create_spree_pending_promotions.rb deleted file mode 100644 index e6de8afdeb..0000000000 --- a/db/migrate/20120327000665_create_spree_pending_promotions.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateSpreePendingPromotions < ActiveRecord::Migration - def change - create_table :spree_pending_promotions do |t| - t.references :user - t.references :promotion - end - - add_index :spree_pending_promotions, :user_id - add_index :spree_pending_promotions, :promotion_id - end -end diff --git a/db/migrate/20120327000666_content_visited_event.rb b/db/migrate/20120327000666_content_visited_event.rb deleted file mode 100644 index ea853b2c9b..0000000000 --- a/db/migrate/20120327000666_content_visited_event.rb +++ /dev/null @@ -1,29 +0,0 @@ -# LandingPage used to support static pages, we've moved to a static -# event. This adds path to promotions then migrates the old LandingPage rules -class ContentVisitedEvent < ActiveRecord::Migration - - # Removed Class for Migrations - class Spree::Promotion::Rules::LandingPage < Spree::PromotionRule - preference :path, :string - def eligible?(order, options = {}) - true - end - end - - def up - add_column :spree_activators, :path, :string - - Spree::Promotion::Rules::LandingPage.all.each do |promotion_rule| - promotion = promotion_rule.promotion - say "migrating #{promotion.name} promotion to use 'spree.content.visited' event" - promotion.event_name = 'spree.content.visited' - promotion.path = promotion_rule.preferred_path - promotion.promotion_rules.delete promotion_rule - promotion.save(:validate => false) - end - end - - def down - remove_column :spree_activators, :path - end -end \ No newline at end of file diff --git a/db/migrate/20120327000667_create_skrill_transactions.rb b/db/migrate/20120327000667_create_skrill_transactions.rb deleted file mode 100644 index 0af9924a0b..0000000000 --- a/db/migrate/20120327000667_create_skrill_transactions.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateSkrillTransactions < ActiveRecord::Migration - def change - create_table :spree_skrill_transactions do |t| - t.string :email - t.float :amount - t.string :currency - t.integer :transaction_id - t.integer :customer_id - t.string :payment_type - t.timestamps - end - end -end - diff --git a/db/migrate/20120331051742_create_distributors.rb b/db/migrate/20120331051742_create_distributors.rb deleted file mode 100644 index f9096b4fb8..0000000000 --- a/db/migrate/20120331051742_create_distributors.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateDistributors < ActiveRecord::Migration - def change - create_table :distributors do |t| - t.string :name - t.string :contact - t.string :phone - t.string :email - t.string :pickup_address - t.string :pickup_times - t.string :url - t.string :abn - t.string :acn - t.string :description - - t.timestamps - end - end -end diff --git a/db/migrate/20120407065132_add_distributor_to_order.rb b/db/migrate/20120407065132_add_distributor_to_order.rb deleted file mode 100644 index 9dd239d214..0000000000 --- a/db/migrate/20120407065132_add_distributor_to_order.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDistributorToOrder < ActiveRecord::Migration - def change - add_column :spree_orders, :distributor_id, :integer - end -end diff --git a/db/migrate/20120408081918_add_extra_address_fields_to_distributor.rb b/db/migrate/20120408081918_add_extra_address_fields_to_distributor.rb deleted file mode 100644 index 91b65333d6..0000000000 --- a/db/migrate/20120408081918_add_extra_address_fields_to_distributor.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddExtraAddressFieldsToDistributor < ActiveRecord::Migration - def change - add_column :distributors, :city, :string - add_column :distributors, :post_code, :string - add_column :distributors, :country_id, :integer - end -end diff --git a/db/migrate/20120409004831_add_state_to_distributor.rb b/db/migrate/20120409004831_add_state_to_distributor.rb deleted file mode 100644 index 5480039a1a..0000000000 --- a/db/migrate/20120409004831_add_state_to_distributor.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStateToDistributor < ActiveRecord::Migration - def change - add_column :distributors, :state_id, :integer - end -end diff --git a/db/migrate/20120422042134_add_supplier.rb b/db/migrate/20120422042134_add_supplier.rb deleted file mode 100644 index 85add9901a..0000000000 --- a/db/migrate/20120422042134_add_supplier.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddSupplier < ActiveRecord::Migration - def change - create_table :suppliers do |t| - t.string :name - t.string :description - t.string :url - t.string :email - t.string :twitter - t.string :website - - t.integer :address_id - - t.timestamps - end - end -end diff --git a/db/migrate/20120425065453_add_supplier_to_product.rb b/db/migrate/20120425065453_add_supplier_to_product.rb deleted file mode 100644 index 41653e7857..0000000000 --- a/db/migrate/20120425065453_add_supplier_to_product.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddSupplierToProduct < ActiveRecord::Migration - def change - add_column :spree_products, :supplier_id, :integer - end -end diff --git a/db/migrate/20120429071654_replace_spree_address_from_supplier.rb b/db/migrate/20120429071654_replace_spree_address_from_supplier.rb deleted file mode 100644 index e910b373c6..0000000000 --- a/db/migrate/20120429071654_replace_spree_address_from_supplier.rb +++ /dev/null @@ -1,12 +0,0 @@ -class ReplaceSpreeAddressFromSupplier < ActiveRecord::Migration - def change - remove_column :suppliers, :address_id - remove_column :suppliers, :url - - add_column :suppliers, :address, :string - add_column :suppliers, :city, :string - add_column :suppliers, :postcode, :string - add_column :suppliers, :state_id, :integer - add_column :suppliers, :country_id, :integer - end -end diff --git a/db/migrate/20120520062059_rename_state_events_to_state_changes.spree.rb b/db/migrate/20120520062059_rename_state_events_to_state_changes.spree.rb deleted file mode 100644 index 469e730d62..0000000000 --- a/db/migrate/20120520062059_rename_state_events_to_state_changes.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20120203001428) -class RenameStateEventsToStateChanges < ActiveRecord::Migration - def up - rename_table :spree_state_events, :spree_state_changes - end - - def down - rename_table :spree_state_changes, :spree_state_events - end -end diff --git a/db/migrate/20120520062060_migrate_images_from_products_to_variants.spree.rb b/db/migrate/20120520062060_migrate_images_from_products_to_variants.spree.rb deleted file mode 100644 index 5199cbd49d..0000000000 --- a/db/migrate/20120520062060_migrate_images_from_products_to_variants.spree.rb +++ /dev/null @@ -1,36 +0,0 @@ -# This migration comes from spree (originally 20120315064358) -class MigrateImagesFromProductsToVariants < ActiveRecord::Migration - def up - images = select_all("SELECT spree_assets.* FROM spree_assets - WHERE spree_assets.type IN ('Spree::Image') - AND spree_assets.viewable_type = 'Spree::Product'") - - images.each do |image| - master_variant_id = select_value("SELECT id FROM spree_variants - WHERE product_id = #{image['viewable_id']} - AND is_master = #{quoted_true}") - - execute("UPDATE spree_assets SET viewable_type = 'Spree::Variant', viewable_id = #{master_variant_id} - WHERE id = #{image['id']}") if master_variant_id - end - end - - def down - images = select_all("SELECT spree_assets.* FROM spree_assets - JOIN spree_variants - ON spree_variants.id = spree_assets.viewable_id - AND spree_variants.is_master = #{quoted_true} - WHERE spree_assets.type IN ('Spree::Image') - AND spree_assets.viewable_type = 'Spree::Variant'") - - images.each do |image| - product_id = select_value("SELECT spree_products.id FROM spree_products - JOIN spree_variants - ON spree_variants.id = #{image['viewable_id']} - AND spree_products.id = spree_variants.product_id") - - execute("UPDATE spree_assets SET viewable_type = 'Spree::Product', viewable_id = #{product_id} - WHERE id = #{image['id']}") if product_id - end - end -end diff --git a/db/migrate/20120520062061_rename_attachment_size_to_attachment_file_size.spree.rb b/db/migrate/20120520062061_rename_attachment_size_to_attachment_file_size.spree.rb deleted file mode 100644 index 2dec8f2115..0000000000 --- a/db/migrate/20120520062061_rename_attachment_size_to_attachment_file_size.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20120416233427) -class RenameAttachmentSizeToAttachmentFileSize < ActiveRecord::Migration - def change - rename_column :spree_assets, :attachment_size, :attachment_file_size - end -end diff --git a/db/migrate/20120618061537_move_distributor_from_order_to_product.rb b/db/migrate/20120618061537_move_distributor_from_order_to_product.rb deleted file mode 100644 index c5f0b18a59..0000000000 --- a/db/migrate/20120618061537_move_distributor_from_order_to_product.rb +++ /dev/null @@ -1,26 +0,0 @@ -class MoveDistributorFromOrderToProduct < ActiveRecord::Migration - class Distributor < ActiveRecord::Base; end - class Spree::Product < ActiveRecord::Base; end - - def up - remove_column :spree_orders, :distributor_id - - create_table :distributors_products, :id => false do |t| - t.references :product - t.references :distributor - end - - # Associate all products with the first distributor - distributor = Distributor.first - if distributor - Spree::Product.all.each do |product| - product.distributors << distributor - end - end - end - - def down - drop_table :distributors_products - add_column :spree_orders, :distributor_id, :integer - end -end diff --git a/db/migrate/20120621064227_add_distributor_id_to_order.rb b/db/migrate/20120621064227_add_distributor_id_to_order.rb deleted file mode 100644 index 3f6bb57acf..0000000000 --- a/db/migrate/20120621064227_add_distributor_id_to_order.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDistributorIdToOrder < ActiveRecord::Migration - def change - add_column :spree_orders, :distributor_id, :integer - end -end diff --git a/db/migrate/20120626013846_extract_distributor_and_supplier_address_to_spree_address.rb b/db/migrate/20120626013846_extract_distributor_and_supplier_address_to_spree_address.rb deleted file mode 100644 index 89480427ea..0000000000 --- a/db/migrate/20120626013846_extract_distributor_and_supplier_address_to_spree_address.rb +++ /dev/null @@ -1,92 +0,0 @@ -class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migration - class Supplier < ActiveRecord::Base; end - class Distributor < ActiveRecord::Base; end - class Spree::Address < ActiveRecord::Base; end - - - def up - # -- Distributors - add_column :distributors, :pickup_address_id, :integer - Distributor.reset_column_information - - Distributor.all.each do |distributor| - pickup_address = Spree::Address.create!(:firstname => 'unused', - :lastname => 'unused', - :phone => 'unused', - :address1 => distributor[:pickup_address], - :city => distributor.city, - :zipcode => distributor.post_code, - :state_id => distributor.state_id, - :country_id => distributor.country_id) - distributor.pickup_address = pickup_address - distributor.save! - end - - %w(pickup_address city post_code state_id country_id).each do |column| - remove_column :distributors, column - end - - - # -- Suppliers - add_column :suppliers, :address_id, :integer - Supplier.reset_column_information - - Supplier.all.each do |supplier| - address = Spree::Address.create!(:firstname => 'unused', - :lastname => 'unused', - :phone => 'unused', - :address1 => supplier[:address], - :city => supplier.city, - :zipcode => supplier.postcode, - :state_id => supplier.state_id, - :country_id => supplier.country_id) - supplier.address = address - supplier.save! - end - - %w(address city postcode state_id country_id).each do |column| - remove_column :suppliers, column - end - end - - def down - # -- Distributors - add_column :distributors, :pickup_address, :string - add_column :distributors, :city, :string - add_column :distributors, :post_code, :string - add_column :distributors, :state_id, :integer - add_column :distributors, :country_id, :integer - Distributor.reset_column_information - - Distributor.all.each do |distributor| - distributor[:pickup_address] = distributor.pickup_address.address1 - distributor.city = distributor.pickup_address.city - distributor.post_code = distributor.pickup_address.zipcode - distributor.state_id = distributor.pickup_address.state_id - distributor.country_id = distributor.pickup_address.country_id - distributor.save! - end - - remove_column :distributors, :pickup_address_id - - - # -- Suppliers - add_column :suppliers, :address, :string - add_column :suppliers, :city, :string - add_column :suppliers, :postcode, :string - add_column :suppliers, :state_id, :integer - add_column :suppliers, :country_id, :integer - Supplier.reset_column_information - - Supplier.all.each do |supplier| - supplier[:address] = supplier.address.address1 - supplier.city = supplier.address.city - supplier.post_code = supplier.address.zipcode - supplier.state_id = supplier.address.state_id - supplier.country_id = supplier.address.country_id - supplier.save! - end - - remove_column :suppliers, :address_id - end -end diff --git a/db/migrate/20120626233350_rename_distributors_products_to_product_distributions.rb b/db/migrate/20120626233350_rename_distributors_products_to_product_distributions.rb deleted file mode 100644 index c2ecd94457..0000000000 --- a/db/migrate/20120626233350_rename_distributors_products_to_product_distributions.rb +++ /dev/null @@ -1,27 +0,0 @@ -class RenameDistributorsProductsToProductDistributions < ActiveRecord::Migration - class Spree::ShippingMethod < ActiveRecord::Base; end - class ProductDistribution < ActiveRecord::Base; end - - def up - # Convert m2m join table into explicit join model, and add a shipping method relation and timestamps - rename_table :distributors_products, :product_distributions - add_column :product_distributions, :id, :primary_key - change_table :product_distributions do |t| - t.references :shipping_method - t.timestamps - end - - # Set default shipping method on all product distributions - sm = Spree::ShippingMethod.unscoped.first - ProductDistribution.update_all(:shipping_method_id => sm.id) if sm - end - - def down - change_table :product_distributions do |t| - t.remove :id - t.remove :shipping_method_id - t.remove :created_at, :updated_at - end - rename_table :product_distributions, :distributors_products - end -end diff --git a/db/migrate/20120629043042_increase_scale_of_tax_rate_amount.spree.rb b/db/migrate/20120629043042_increase_scale_of_tax_rate_amount.spree.rb deleted file mode 100644 index f4725b09d9..0000000000 --- a/db/migrate/20120629043042_increase_scale_of_tax_rate_amount.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20120507232704) -class IncreaseScaleOfTaxRateAmount < ActiveRecord::Migration - def up - change_column :spree_tax_rates, :amount, :decimal, { :scale => 5, :precision => 8 } - end - - def down - change_column :spree_tax_rates, :amount, :decimal, { :scale => 4, :precision => 8 } - end -end diff --git a/db/migrate/20120629043043_add_reset_password_sent_at_to_spree_users.spree_auth.rb b/db/migrate/20120629043043_add_reset_password_sent_at_to_spree_users.spree_auth.rb deleted file mode 100644 index 7632ac3417..0000000000 --- a/db/migrate/20120629043043_add_reset_password_sent_at_to_spree_users.spree_auth.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree_auth (originally 20120203010234) -class AddResetPasswordSentAtToSpreeUsers < ActiveRecord::Migration - def change - add_column :spree_users, :reset_password_sent_at, :datetime - end -end diff --git a/db/migrate/20120629043045_resize_api_key_field.spree_api.rb b/db/migrate/20120629043045_resize_api_key_field.spree_api.rb deleted file mode 100644 index cdd4430364..0000000000 --- a/db/migrate/20120629043045_resize_api_key_field.spree_api.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree_api (originally 20120411123334) -class ResizeApiKeyField < ActiveRecord::Migration - def change - change_column :spree_users, :api_key, :string, :limit => 48 - end -end diff --git a/db/migrate/20120629043647_create_paypal_accounts.spree_paypal_express.rb b/db/migrate/20120629043647_create_paypal_accounts.spree_paypal_express.rb deleted file mode 100644 index 89ee02159b..0000000000 --- a/db/migrate/20120629043647_create_paypal_accounts.spree_paypal_express.rb +++ /dev/null @@ -1,15 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20100224133156) -class CreatePaypalAccounts < ActiveRecord::Migration - def self.up - create_table :paypal_accounts do |t| - t.string :email - t.string :payer_id - t.string :payer_country - t.string :payer_status - end - end - - def self.down - drop_table :paypal_accounts - end -end diff --git a/db/migrate/20120629043648_namespace_paypal_accounts.spree_paypal_express.rb b/db/migrate/20120629043648_namespace_paypal_accounts.spree_paypal_express.rb deleted file mode 100644 index 12a2f0cc83..0000000000 --- a/db/migrate/20120629043648_namespace_paypal_accounts.spree_paypal_express.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20120117182027) -class NamespacePaypalAccounts < ActiveRecord::Migration - def change - rename_table :paypal_accounts, :spree_paypal_accounts - end -end diff --git a/db/migrate/20120702020402_add_next_collection_at_to_distributors.rb b/db/migrate/20120702020402_add_next_collection_at_to_distributors.rb deleted file mode 100644 index 1e30199de8..0000000000 --- a/db/migrate/20120702020402_add_next_collection_at_to_distributors.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNextCollectionAtToDistributors < ActiveRecord::Migration - def change - add_column :distributors, :next_collection_at, :string - end -end diff --git a/db/migrate/20120802031147_add_group_buy_fields.rb b/db/migrate/20120802031147_add_group_buy_fields.rb deleted file mode 100644 index 5cc9efe857..0000000000 --- a/db/migrate/20120802031147_add_group_buy_fields.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddGroupBuyFields < ActiveRecord::Migration - def change - add_column :spree_products, :group_buy, :boolean - add_column :spree_line_items, :max_quantity, :integer - end -end diff --git a/db/migrate/20120913054657_convert_sales_tax_to_default_tax.spree.rb b/db/migrate/20120913054657_convert_sales_tax_to_default_tax.spree.rb deleted file mode 100644 index a15416d63c..0000000000 --- a/db/migrate/20120913054657_convert_sales_tax_to_default_tax.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20120523061241) -class ConvertSalesTaxToDefaultTax < ActiveRecord::Migration - def up - execute "UPDATE spree_calculators SET type='Spree::Calculator::DefaultTax' WHERE type='Spree::Calculator::SalesTax'" - end - - def down - execute "UPDATE spree_calculators SET type='Spree::Calculator::SalesTax' WHERE type='Spree::Calculator::DefaultTax'" - end -end diff --git a/db/migrate/20120913054658_add_deleted_at_to_spree_shipping_methods.spree.rb b/db/migrate/20120913054658_add_deleted_at_to_spree_shipping_methods.spree.rb deleted file mode 100644 index 54c5978c24..0000000000 --- a/db/migrate/20120913054658_add_deleted_at_to_spree_shipping_methods.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20120604030249) -class AddDeletedAtToSpreeShippingMethods < ActiveRecord::Migration - def change - add_column :spree_shipping_methods, :deleted_at, :datetime - end -end diff --git a/db/migrate/20120913054659_make_users_email_index_unique.spree.rb b/db/migrate/20120913054659_make_users_email_index_unique.spree.rb deleted file mode 100644 index 4fd43f21d2..0000000000 --- a/db/migrate/20120913054659_make_users_email_index_unique.spree.rb +++ /dev/null @@ -1,11 +0,0 @@ -# This migration comes from spree (originally 20120605211305) -class MakeUsersEmailIndexUnique < ActiveRecord::Migration - def up - add_index "spree_users", ["email"], :name => "email_idx_unique", :unique => true - end - - def down - remove_index "spree_users", :name => "email_idx_unique" - add_index "spree_users", ["email"], :name => "email_idx_unique" - end -end diff --git a/db/migrate/20120913054660_add_counter_cache_to_zone_members.spree.rb b/db/migrate/20120913054660_add_counter_cache_to_zone_members.spree.rb deleted file mode 100644 index 669434e34d..0000000000 --- a/db/migrate/20120913054660_add_counter_cache_to_zone_members.spree.rb +++ /dev/null @@ -1,15 +0,0 @@ -# This migration comes from spree (originally 20120712172620) -class AddCounterCacheToZoneMembers < ActiveRecord::Migration - def up - add_column :spree_zones, :zone_members_count, :integer, :default => 0 - - Spree::Zone.reset_column_information - Spree::Zone.find(:all).each do |zone| - Spree::Zone.update_counters zone.id, :zone_members_count => zone.zone_members.length - end - end - - def down - remove_column :spree_zones, :zone_members_count - end -end diff --git a/db/migrate/20120919013335_add_shipping_method_to_line_items.rb b/db/migrate/20120919013335_add_shipping_method_to_line_items.rb deleted file mode 100644 index fd5974992d..0000000000 --- a/db/migrate/20120919013335_add_shipping_method_to_line_items.rb +++ /dev/null @@ -1,20 +0,0 @@ -class AddShippingMethodToLineItems < ActiveRecord::Migration - def up - add_column :spree_line_items, :shipping_method_id, :integer - - Spree::LineItem.all.each do |li| - begin - shipping_method = li.product.shipping_method_for_distributor(li.order.distributor) - rescue ArgumentError - shipping_method = Spree::ShippingMethod.find_by_name 'Producer Delivery' - say "Line item #{li.id} does not have a valid shipping method, setting to '#{shipping_method.name}'" - end - - Spree::LineItem.update_all("shipping_method_id = #{shipping_method.id}", "id = #{li.id}") - end - end - - def down - remove_column :spree_line_items, :shipping_method_id - end -end diff --git a/db/migrate/20121005015852_populate_order_default_shipping_method.rb b/db/migrate/20121005015852_populate_order_default_shipping_method.rb deleted file mode 100644 index 2184ee18b0..0000000000 --- a/db/migrate/20121005015852_populate_order_default_shipping_method.rb +++ /dev/null @@ -1,10 +0,0 @@ -class PopulateOrderDefaultShippingMethod < ActiveRecord::Migration - def up - Spree::Order.where(shipping_method_id: nil).each do |order| - order.send(:set_default_shipping_method) - end - end - - def down - end -end diff --git a/db/migrate/20121009232513_create_cms.rb b/db/migrate/20121009232513_create_cms.rb deleted file mode 100644 index d1c1700a5e..0000000000 --- a/db/migrate/20121009232513_create_cms.rb +++ /dev/null @@ -1,137 +0,0 @@ -class CreateCms < ActiveRecord::Migration - - def self.up - - text_limit = case ActiveRecord::Base.connection.adapter_name - when 'PostgreSQL' - { } - else - { :limit => 16777215 } - end - - # -- Sites -------------------------------------------------------------- - create_table :cms_sites do |t| - t.string :label, :null => false - t.string :identifier, :null => false - t.string :hostname, :null => false - t.string :path - t.string :locale, :null => false, :default => 'en' - t.boolean :is_mirrored, :null => false, :default => false - end - add_index :cms_sites, :hostname - add_index :cms_sites, :is_mirrored - - # -- Layouts ------------------------------------------------------------ - create_table :cms_layouts do |t| - t.integer :site_id, :null => false - t.integer :parent_id - t.string :app_layout - t.string :label, :null => false - t.string :identifier, :null => false - t.text :content, text_limit - t.text :css, text_limit - t.text :js, text_limit - t.integer :position, :null => false, :default => 0 - t.boolean :is_shared, :null => false, :default => false - t.timestamps - end - add_index :cms_layouts, [:parent_id, :position] - add_index :cms_layouts, [:site_id, :identifier], :unique => true - - # -- Pages -------------------------------------------------------------- - create_table :cms_pages do |t| - t.integer :site_id, :null => false - t.integer :layout_id - t.integer :parent_id - t.integer :target_page_id - t.string :label, :null => false - t.string :slug - t.string :full_path, :null => false - t.text :content, text_limit - t.integer :position, :null => false, :default => 0 - t.integer :children_count, :null => false, :default => 0 - t.boolean :is_published, :null => false, :default => true - t.boolean :is_shared, :null => false, :default => false - t.timestamps - end - add_index :cms_pages, [:site_id, :full_path] - add_index :cms_pages, [:parent_id, :position] - - # -- Page Blocks -------------------------------------------------------- - create_table :cms_blocks do |t| - t.integer :page_id, :null => false - t.string :identifier, :null => false - t.text :content - t.timestamps - end - add_index :cms_blocks, [:page_id, :identifier] - - # -- Snippets ----------------------------------------------------------- - create_table :cms_snippets do |t| - t.integer :site_id, :null => false - t.string :label, :null => false - t.string :identifier, :null => false - t.text :content, text_limit - t.integer :position, :null => false, :default => 0 - t.boolean :is_shared, :null => false, :default => false - t.timestamps - end - add_index :cms_snippets, [:site_id, :identifier], :unique => true - add_index :cms_snippets, [:site_id, :position] - - # -- Files -------------------------------------------------------------- - create_table :cms_files do |t| - t.integer :site_id, :null => false - t.integer :block_id - t.string :label, :null => false - t.string :file_file_name, :null => false - t.string :file_content_type, :null => false - t.integer :file_file_size, :null => false - t.string :description, :limit => 2048 - t.integer :position, :null => false, :default => 0 - t.timestamps - end - add_index :cms_files, [:site_id, :label] - add_index :cms_files, [:site_id, :file_file_name] - add_index :cms_files, [:site_id, :position] - add_index :cms_files, [:site_id, :block_id] - - # -- Revisions ----------------------------------------------------------- - create_table :cms_revisions, :force => true do |t| - t.string :record_type, :null => false - t.integer :record_id, :null => false - t.text :data, text_limit - t.datetime :created_at - end - add_index :cms_revisions, [:record_type, :record_id, :created_at] - - # -- Categories --------------------------------------------------------- - create_table :cms_categories, :force => true do |t| - t.integer :site_id, :null => false - t.string :label, :null => false - t.string :categorized_type, :null => false - end - add_index :cms_categories, [:site_id, :categorized_type, :label], :unique => true - - create_table :cms_categorizations, :force => true do |t| - t.integer :category_id, :null => false - t.string :categorized_type, :null => false - t.integer :categorized_id, :null => false - end - add_index :cms_categorizations, [:category_id, :categorized_type, :categorized_id], :unique => true, - :name => 'index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id' - end - - def self.down - drop_table :cms_sites - drop_table :cms_layouts - drop_table :cms_pages - drop_table :cms_snippets - drop_table :cms_blocks - drop_table :cms_files - drop_table :cms_revisions - drop_table :cms_categories - drop_table :cms_categorizations - end -end - diff --git a/db/migrate/20121010004400_add_long_description_to_distributors_and_suppliers.rb b/db/migrate/20121010004400_add_long_description_to_distributors_and_suppliers.rb deleted file mode 100644 index 7b3e2aa9f1..0000000000 --- a/db/migrate/20121010004400_add_long_description_to_distributors_and_suppliers.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddLongDescriptionToDistributorsAndSuppliers < ActiveRecord::Migration - def change - add_column :distributors, :long_description, :text - add_column :suppliers, :long_description, :text - end -end diff --git a/db/migrate/20121018002907_add_group_buy_unit_size_to_products.rb b/db/migrate/20121018002907_add_group_buy_unit_size_to_products.rb deleted file mode 100644 index 4abc9e5923..0000000000 --- a/db/migrate/20121018002907_add_group_buy_unit_size_to_products.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddGroupBuyUnitSizeToProducts < ActiveRecord::Migration - def change - add_column :spree_products, :group_buy_unit_size, :string - end -end diff --git a/db/migrate/20121025012233_combine_suppliers_and_distributors_into_enterprises.rb b/db/migrate/20121025012233_combine_suppliers_and_distributors_into_enterprises.rb deleted file mode 100644 index 7eff3e6961..0000000000 --- a/db/migrate/20121025012233_combine_suppliers_and_distributors_into_enterprises.rb +++ /dev/null @@ -1,69 +0,0 @@ -class CombineSuppliersAndDistributorsIntoEnterprises < ActiveRecord::Migration - class Supplier < ActiveRecord::Base; end - class Distributor < ActiveRecord::Base; end - class Enterprise < ActiveRecord::Base; end - class ProductDistribution < ActiveRecord::Base; end - class Spree::Product < ActiveRecord::Base; end - class Spree::Order < ActiveRecord::Base; end - - - def up - # Create enterprises table - create_table :enterprises do |t| - t.string :name - t.string :description - t.text :long_description - t.boolean :is_primary_producer - t.boolean :is_distributor - t.string :contact - t.string :phone - t.string :email - t.string :website - t.string :twitter - t.string :abn - t.string :acn - t.integer :address_id - t.string :pickup_times - t.integer :pickup_address_id - t.string :next_collection_at - t.timestamps - end - - # Copy suppliers to enterprises table with primary producer flag set - updated_product_ids = [-1] - Supplier.all.each do |s| - attrs = s.attributes - attrs.reject! { |k| k == 'id' } - attrs.merge! is_primary_producer: true, is_distributor: false - e = Enterprise.create! attrs - - # Update supplier_id on product to point at the new enterprise - product_ids = Spree::Product.where(:supplier_id => s.id).pluck(:id) - Spree::Product.update_all("supplier_id=#{e.id}", "supplier_id=#{s.id} AND id NOT IN (#{updated_product_ids.join(', ')})") - updated_product_ids += product_ids - end - - # Copy distributors to enterprises table with distributor flag set - updated_product_distribution_ids = [-1] - updated_order_ids = [-1] - Distributor.all.each do |d| - attrs = d.attributes - attrs['website'] = attrs['url'] - attrs.reject! { |k| ['id', 'url'].include? k } - attrs.merge! is_primary_producer: false, is_distributor: true - e = Enterprise.create! attrs - - # Update distributor_id on product distribution and order to point at the new enterprise - product_distribution_ids = ProductDistribution.where(:distributor_id => d.id).pluck(:id) - order_ids = Spree::Order.where(:distributor_id => d.id).pluck(:id) - ProductDistribution.update_all("distributor_id=#{e.id}", "distributor_id=#{d.id} AND id NOT IN (#{updated_product_distribution_ids.join(', ')})") - Spree::Order.update_all("distributor_id=#{e.id}", "distributor_id=#{d.id} AND id NOT IN (#{updated_order_ids.join(', ')})") - updated_product_distribution_ids += product_distribution_ids - updated_order_ids += order_ids - end - end - - def down - drop_table :enterprises - end -end diff --git a/db/migrate/20121028070200_remove_pickup_address_from_enterprises.rb b/db/migrate/20121028070200_remove_pickup_address_from_enterprises.rb deleted file mode 100644 index d1c7fd0d56..0000000000 --- a/db/migrate/20121028070200_remove_pickup_address_from_enterprises.rb +++ /dev/null @@ -1,21 +0,0 @@ -class RemovePickupAddressFromEnterprises < ActiveRecord::Migration - class Enterprise < ActiveRecord::Base; end - - def up - Enterprise.all.each do |e| - e.address_id ||= e.pickup_address_id - e.save! - end - - remove_column :enterprises, :pickup_address_id - end - - def down - add_column :enterprises, :pickup_address_id, :integer - - Enterprise.all.each do |e| - e.pickup_address_id ||= e.address_id - e.save! - end - end -end diff --git a/db/migrate/20121031203807_change_group_buy_unit_size_from_string_to_float.rb b/db/migrate/20121031203807_change_group_buy_unit_size_from_string_to_float.rb deleted file mode 100644 index 44caf3beaa..0000000000 --- a/db/migrate/20121031203807_change_group_buy_unit_size_from_string_to_float.rb +++ /dev/null @@ -1,21 +0,0 @@ -class ChangeGroupBuyUnitSizeFromStringToFloat < ActiveRecord::Migration - class Spree::Product < ActiveRecord::Base; end - - def up - add_column :spree_products, :group_buy_unit_size_f, :float - Spree::Product.reset_column_information - - Spree::Product.all.each do |product| - product.group_buy_unit_size_f = product.group_buy_unit_size.to_f - product.save! - end - - remove_column :spree_products, :group_buy_unit_size - rename_column :spree_products, :group_buy_unit_size_f, :group_buy_unit_size - end - - def down - change_column :spree_products, :group_buy_unit_size, :string - end - -end diff --git a/db/migrate/20121031222403_remove_suppliers_and_distributors.rb b/db/migrate/20121031222403_remove_suppliers_and_distributors.rb deleted file mode 100644 index ece31be171..0000000000 --- a/db/migrate/20121031222403_remove_suppliers_and_distributors.rb +++ /dev/null @@ -1,37 +0,0 @@ -class RemoveSuppliersAndDistributors < ActiveRecord::Migration - def up - drop_table :suppliers - drop_table :distributors - end - - def down - create_table "distributors" do |t| - t.string :name - t.string :contact - t.string :phone - t.string :email - t.string :pickup_times - t.string :url - t.string :abn - t.string :acn - t.string :description - t.datetime :created_at - t.datetime :updated_at - t.integer :pickup_address_id - t.string :next_collection_at - t.text :long_description - end - - create_table "suppliers" do |t| - t.string :name - t.string :description - t.string :email - t.string :twitter - t.string :website - t.datetime :created_at - t.datetime :updated_at - t.integer :address_id - t.text :long_description - end - end -end diff --git a/db/migrate/20121115010717_create_enterprise_fees.rb b/db/migrate/20121115010717_create_enterprise_fees.rb deleted file mode 100644 index 00c3057bfb..0000000000 --- a/db/migrate/20121115010717_create_enterprise_fees.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateEnterpriseFees < ActiveRecord::Migration - def change - create_table :enterprise_fees do |t| - t.references :enterprise - t.string :fee_type - t.string :name - - t.timestamps - end - end -end diff --git a/db/migrate/20121125232613_create_order_cycles.rb b/db/migrate/20121125232613_create_order_cycles.rb deleted file mode 100644 index 9d0e4bab90..0000000000 --- a/db/migrate/20121125232613_create_order_cycles.rb +++ /dev/null @@ -1,35 +0,0 @@ -class CreateOrderCycles < ActiveRecord::Migration - def change - create_table :order_cycles do |t| - t.string :name - t.datetime :orders_open_at - t.datetime :orders_close_at - t.references :coordinator - t.references :coordinator_admin_fee - t.references :coordinator_sales_fee - t.timestamps - end - - create_table :exchanges do |t| - t.references :order_cycle - t.references :sender - t.references :receiver - t.references :payment_enterprise - t.datetime :pickup_time - t.string :pickup_instructions - t.timestamps - end - - create_table :exchange_variants do |t| - t.references :exchange - t.references :variant - t.timestamps - end - - create_table :exchange_fees do |t| - t.references :exchange - t.references :enterprise_fee - t.timestamps - end - end -end diff --git a/db/migrate/20130118031610_change_exchange_pickup_time_to_string.rb b/db/migrate/20130118031610_change_exchange_pickup_time_to_string.rb deleted file mode 100644 index 1fca44c81b..0000000000 --- a/db/migrate/20130118031610_change_exchange_pickup_time_to_string.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ChangeExchangePickupTimeToString < ActiveRecord::Migration - def up - change_column :exchanges, :pickup_time, :string - end - - def down - change_column :exchanges, :pickup_time, :datetime - end -end diff --git a/db/migrate/20130130204355_add_order_cycle_id_to_orders.rb b/db/migrate/20130130204355_add_order_cycle_id_to_orders.rb deleted file mode 100644 index 871cb2b2f7..0000000000 --- a/db/migrate/20130130204355_add_order_cycle_id_to_orders.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddOrderCycleIdToOrders < ActiveRecord::Migration - def change - add_column :spree_orders, :order_cycle_id, :integer - end -end diff --git a/db/migrate/20130207043036_create_tokenized_permissions_table.spree.rb b/db/migrate/20130207043036_create_tokenized_permissions_table.spree.rb deleted file mode 100644 index 91c8ad18ab..0000000000 --- a/db/migrate/20130207043036_create_tokenized_permissions_table.spree.rb +++ /dev/null @@ -1,17 +0,0 @@ -# This migration comes from spree (originally 20120509055454) -class CreateTokenizedPermissionsTable < ActiveRecord::Migration - def change - unless Spree::TokenizedPermission.table_exists? - create_table :spree_tokenized_permissions do |t| - t.integer :permissable_id - t.string :permissable_type - t.string :token - - t.timestamps - end - - add_index :spree_tokenized_permissions, [:permissable_id, :permissable_type], :name => 'index_tokenized_name_and_type' - end - end -end - diff --git a/db/migrate/20130207043037_rename_creditcards_to_credit_cards.spree.rb b/db/migrate/20130207043037_rename_creditcards_to_credit_cards.spree.rb deleted file mode 100644 index b6d61a8a8c..0000000000 --- a/db/migrate/20130207043037_rename_creditcards_to_credit_cards.spree.rb +++ /dev/null @@ -1,12 +0,0 @@ -# This migration comes from spree (originally 20120530012000) -class RenameCreditcardsToCreditCards < ActiveRecord::Migration - def change - rename_table :spree_creditcards, :spree_credit_cards - execute("UPDATE spree_payments SET source_type = 'Spree::CreditCard' WHERE source_type = 'Spree::Creditcard'") - end - - def down - execute("UPDATE spree_payments SET source_type = 'Spree::Creditcard' WHERE source_type = 'Spree::CreditCard'") - rename_table :spree_credit_cards, :spree_creditcards - end -end diff --git a/db/migrate/20130207043038_remove_credit_total_from_orders.spree.rb b/db/migrate/20130207043038_remove_credit_total_from_orders.spree.rb deleted file mode 100644 index 09559d50fa..0000000000 --- a/db/migrate/20130207043038_remove_credit_total_from_orders.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20120604203654) -class RemoveCreditTotalFromOrders < ActiveRecord::Migration - def change - remove_column :spree_orders, :credit_total - end -end diff --git a/db/migrate/20130207043039_add_tax_rate_label.spree.rb b/db/migrate/20130207043039_add_tax_rate_label.spree.rb deleted file mode 100644 index c39a83c5ee..0000000000 --- a/db/migrate/20130207043039_add_tax_rate_label.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20120905145253) -class AddTaxRateLabel < ActiveRecord::Migration - def change - add_column :spree_tax_rates, :name, :string - end -end diff --git a/db/migrate/20130207043040_add_toggle_tax_rate_display.spree.rb b/db/migrate/20130207043040_add_toggle_tax_rate_display.spree.rb deleted file mode 100644 index 83da18b4f4..0000000000 --- a/db/migrate/20130207043040_add_toggle_tax_rate_display.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20120905151823) -class AddToggleTaxRateDisplay < ActiveRecord::Migration - def change - add_column :spree_tax_rates, :show_rate_in_label, :boolean, :default => true - end -end diff --git a/db/migrate/20130207043041_add_lock_version_to_variant.spree.rb b/db/migrate/20130207043041_add_lock_version_to_variant.spree.rb deleted file mode 100644 index 0e8cc92328..0000000000 --- a/db/migrate/20130207043041_add_lock_version_to_variant.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121009142519) -class AddLockVersionToVariant < ActiveRecord::Migration - def change - add_column :spree_variants, :lock_version, :integer, :default => 0 - end -end diff --git a/db/migrate/20130207043042_remove_not_null_constraint_from_products_on_hand.spree.rb b/db/migrate/20130207043042_remove_not_null_constraint_from_products_on_hand.spree.rb deleted file mode 100644 index acbebfc6cb..0000000000 --- a/db/migrate/20130207043042_remove_not_null_constraint_from_products_on_hand.spree.rb +++ /dev/null @@ -1,12 +0,0 @@ -# This migration comes from spree (originally 20121017010007) -class RemoveNotNullConstraintFromProductsOnHand < ActiveRecord::Migration - def up - change_column :spree_products, :count_on_hand, :integer, :null => true - change_column :spree_variants, :count_on_hand, :integer, :null => true - end - - def down - change_column :spree_products, :count_on_hand, :integer, :null => false - change_column :spree_variants, :count_on_hand, :integer, :null => false - end -end diff --git a/db/migrate/20130207043043_add_position_to_taxonomies.spree.rb b/db/migrate/20130207043043_add_position_to_taxonomies.spree.rb deleted file mode 100644 index 177870b42a..0000000000 --- a/db/migrate/20130207043043_add_position_to_taxonomies.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121124203911) -class AddPositionToTaxonomies < ActiveRecord::Migration - def change - add_column :spree_taxonomies, :position, :integer, :default => 0 - end -end diff --git a/db/migrate/20130207043044_add_identifier_to_spree_payments.spree.rb b/db/migrate/20130207043044_add_identifier_to_spree_payments.spree.rb deleted file mode 100644 index 91a65d92cb..0000000000 --- a/db/migrate/20130207043044_add_identifier_to_spree_payments.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130203232234) -class AddIdentifierToSpreePayments < ActiveRecord::Migration - def change - add_column :spree_payments, :identifier, :string - end -end diff --git a/db/migrate/20130207043046_rename_api_key_to_spree_api_key.spree_api.rb b/db/migrate/20130207043046_rename_api_key_to_spree_api_key.spree_api.rb deleted file mode 100644 index 7fd09d3b11..0000000000 --- a/db/migrate/20130207043046_rename_api_key_to_spree_api_key.spree_api.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree_api (originally 20120530054546) -class RenameApiKeyToSpreeApiKey < ActiveRecord::Migration - def change - unless defined?(User) - rename_column :spree_users, :api_key, :spree_api_key - end - end -end diff --git a/db/migrate/20130207043047_create_users.spree_auth.rb b/db/migrate/20130207043047_create_users.spree_auth.rb deleted file mode 100644 index a4e8e602d2..0000000000 --- a/db/migrate/20130207043047_create_users.spree_auth.rb +++ /dev/null @@ -1,30 +0,0 @@ -# This migration comes from spree_auth (originally 20101026184949) -class CreateUsers < ActiveRecord::Migration - def up - unless table_exists?("spree_users") - create_table "spree_users", :force => true do |t| - t.string "crypted_password", :limit => 128 - t.string "salt", :limit => 128 - t.string "email" - t.string "remember_token" - t.string "remember_token_expires_at" - t.string "persistence_token" - t.string "single_access_token" - t.string "perishable_token" - t.integer "login_count", :default => 0, :null => false - t.integer "failed_login_count", :default => 0, :null => false - t.datetime "last_request_at" - t.datetime "current_login_at" - t.datetime "last_login_at" - t.string "current_login_ip" - t.string "last_login_ip" - t.string "login" - t.integer "ship_address_id" - t.integer "bill_address_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "openid_identifier" - end - end - end -end diff --git a/db/migrate/20130207043541_spree_one_two.spree.rb b/db/migrate/20130207043541_spree_one_two.spree.rb deleted file mode 100644 index ad81bfeabe..0000000000 --- a/db/migrate/20130207043541_spree_one_two.spree.rb +++ /dev/null @@ -1,482 +0,0 @@ -# This migration comes from spree (originally 20120831092320) -class SpreeOneTwo < ActiveRecord::Migration - def up - # This migration is just a compressed version of all the previous - # migrations for spree_core. Do not run it if one of the core tables - # already exists. Assume the best. - return if table_exists?(:spree_addresses) - - - create_table :spree_activators do |t| - t.string :description - t.datetime :expires_at - t.datetime :starts_at - t.string :name - t.string :event_name - t.string :type - t.integer :usage_limit - t.string :match_policy, :default => 'all' - t.string :code - t.boolean :advertise, :default => false - t.string :path - t.timestamps - end - - create_table :spree_addresses do |t| - t.string :firstname - t.string :lastname - t.string :address1 - t.string :address2 - t.string :city - t.string :zipcode - t.string :phone - t.string :state_name - t.string :alternative_phone - t.string :company - t.references :state - t.references :country - t.timestamps - end - - add_index :spree_addresses, [:firstname], :name => 'index_addresses_on_firstname' - add_index :spree_addresses, [:lastname], :name => 'index_addresses_on_lastname' - - create_table :spree_adjustments do |t| - t.references :source, :polymorphic => true - t.references :adjustable, :polymorphic => true - t.references :originator, :polymorphic => true - t.decimal :amount, :precision => 8, :scale => 2 - t.string :label - t.boolean :mandatory - t.boolean :locked - t.boolean :eligible, :default => true - t.timestamps - end - - add_index :spree_adjustments, [:adjustable_id], :name => 'index_adjustments_on_order_id' - - create_table :spree_assets do |t| - t.references :viewable, :polymorphic => true - t.integer :attachment_width - t.integer :attachment_height - t.integer :attachment_file_size - t.integer :position - t.string :attachment_content_type - t.string :attachment_file_name - t.string :type, :limit => 75 - t.datetime :attachment_updated_at - t.text :alt - end - - add_index :spree_assets, [:viewable_id], :name => 'index_assets_on_viewable_id' - add_index :spree_assets, [:viewable_type, :type], :name => 'index_assets_on_viewable_type_and_type' - - create_table :spree_calculators do |t| - t.string :type - t.references :calculable, :polymorphic => true - t.timestamps - end - - create_table :spree_configurations do |t| - t.string :name - t.string :type, :limit => 50 - t.timestamps - end - - add_index :spree_configurations, [:name, :type], :name => 'index_spree_configurations_on_name_and_type' - - create_table :spree_countries do |t| - t.string :iso_name - t.string :iso - t.string :iso3 - t.string :name - t.integer :numcode - end - - create_table :spree_credit_cards do |t| - t.string :month - t.string :year - t.string :cc_type - t.string :last_digits - t.string :first_name - t.string :last_name - t.string :start_month - t.string :start_year - t.string :issue_number - t.references :address - t.string :gateway_customer_profile_id - t.string :gateway_payment_profile_id - t.timestamps - end - - create_table :spree_gateways do |t| - t.string :type - t.string :name - t.text :description - t.boolean :active, :default => true - t.string :environment, :default => 'development' - t.string :server, :default => 'test' - t.boolean :test_mode, :default => true - t.timestamps - end - - create_table :spree_inventory_units do |t| - t.integer :lock_version, :default => 0 - t.string :state - t.references :variant - t.references :order - t.references :shipment - t.references :return_authorization - t.timestamps - end - - add_index :spree_inventory_units, [:order_id], :name => 'index_inventory_units_on_order_id' - add_index :spree_inventory_units, [:shipment_id], :name => 'index_inventory_units_on_shipment_id' - add_index :spree_inventory_units, [:variant_id], :name => 'index_inventory_units_on_variant_id' - - create_table :spree_line_items do |t| - t.references :variant - t.references :order - t.integer :quantity, :null => false - t.decimal :price, :precision => 8, :scale => 2, :null => false - t.timestamps - end - - add_index :spree_line_items, [:order_id], :name => 'index_spree_line_items_on_order_id' - add_index :spree_line_items, [:variant_id], :name => 'index_spree_line_items_on_variant_id' - - create_table :spree_log_entries do |t| - t.references :source, :polymorphic => true - t.text :details - t.timestamps - end - - create_table :spree_mail_methods do |t| - t.string :environment - t.boolean :active, :default => true - t.timestamps - end - - create_table :spree_option_types do |t| - t.string :name, :limit => 100 - t.string :presentation, :limit => 100 - t.integer :position, :default => 0, :null => false - t.timestamps - end - - create_table :spree_option_types_prototypes, :id => false do |t| - t.references :prototype - t.references :option_type - end - - create_table :spree_option_values do |t| - t.integer :position - t.string :name - t.string :presentation - t.references :option_type - t.timestamps - end - - create_table :spree_option_values_variants, :id => false do |t| - t.references :variant - t.references :option_value - end - - add_index :spree_option_values_variants, [:variant_id, :option_value_id], :name => 'index_option_values_variants_on_variant_id_and_option_value_id' - add_index :spree_option_values_variants, [:variant_id], :name => 'index_spree_option_values_variants_on_variant_id' - - create_table :spree_orders do |t| - t.string :number, :limit => 15 - t.decimal :item_total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.decimal :total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.string :state - t.decimal :adjustment_total, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.references :user - t.datetime :completed_at - t.references :bill_address - t.references :ship_address - t.decimal :payment_total, :precision => 8, :scale => 2, :default => 0.0 - t.references :shipping_method - t.string :shipment_state - t.string :payment_state - t.string :email - t.text :special_instructions - t.timestamps - end - - add_index :spree_orders, [:number], :name => 'index_spree_orders_on_number' - - create_table :spree_payment_methods do |t| - t.string :type - t.string :name - t.text :description - t.boolean :active, :default => true - t.string :environment, :default => 'development' - t.datetime :deleted_at - t.string :display_on - t.timestamps - end - - create_table :spree_payments do |t| - t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.references :order - t.references :source, :polymorphic => true - t.references :payment_method - t.string :state - t.string :response_code - t.string :avs_response - t.timestamps - end - - create_table :spree_preferences do |t| - t.string :name, :limit => 100 - t.references :owner, :polymorphic => true - t.text :value - t.string :key - t.string :value_type - t.timestamps - end - - add_index :spree_preferences, [:key], :name => 'index_spree_preferences_on_key', :unique => true - - create_table :spree_product_option_types do |t| - t.integer :position - t.references :product - t.references :option_type - t.timestamps - end - - create_table :spree_product_properties do |t| - t.string :value - t.references :product - t.references :property - t.timestamps - end - - add_index :spree_product_properties, [:product_id], :name => 'index_product_properties_on_product_id' - - create_table :spree_products do |t| - t.string :name, :default => '', :null => false - t.text :description - t.datetime :available_on - t.datetime :deleted_at - t.string :permalink - t.string :meta_description - t.string :meta_keywords - t.references :tax_category - t.references :shipping_category - t.integer :count_on_hand, :default => 0, :null => false - t.timestamps - end - - add_index :spree_products, [:available_on], :name => 'index_spree_products_on_available_on' - add_index :spree_products, [:deleted_at], :name => 'index_spree_products_on_deleted_at' - add_index :spree_products, [:name], :name => 'index_spree_products_on_name' - add_index :spree_products, [:permalink], :name => 'index_spree_products_on_permalink' - - create_table :spree_products_taxons, :id => false do |t| - t.references :product - t.references :taxon - end - - add_index :spree_products_taxons, [:product_id], :name => 'index_spree_products_taxons_on_product_id' - add_index :spree_products_taxons, [:taxon_id], :name => 'index_spree_products_taxons_on_taxon_id' - - create_table :spree_properties do |t| - t.string :name - t.string :presentation, :null => false - t.timestamps - end - - create_table :spree_properties_prototypes, :id => false do |t| - t.references :prototype - t.references :property - end - - create_table :spree_prototypes do |t| - t.string :name - t.timestamps - end - - create_table :spree_return_authorizations do |t| - t.string :number - t.string :state - t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false - t.references :order - t.text :reason - t.timestamps - end - - create_table :spree_roles do |t| - t.string :name - end - - create_table :spree_roles_users, :id => false do |t| - t.references :role - t.references :user - end - - add_index :spree_roles_users, [:role_id], :name => 'index_spree_roles_users_on_role_id' - add_index :spree_roles_users, [:user_id], :name => 'index_spree_roles_users_on_user_id' - - create_table :spree_shipments do |t| - t.string :tracking - t.string :number - t.decimal :cost, :precision => 8, :scale => 2 - t.datetime :shipped_at - t.references :order - t.references :shipping_method - t.references :address - t.string :state - t.timestamps - end - - add_index :spree_shipments, [:number], :name => 'index_shipments_on_number' - - create_table :spree_shipping_categories do |t| - t.string :name - t.timestamps - end - - create_table :spree_shipping_methods do |t| - t.string :name - t.references :zone - t.string :display_on - t.references :shipping_category - t.boolean :match_none - t.boolean :match_all - t.boolean :match_one - t.datetime :deleted_at - t.timestamps - end - - create_table :spree_state_changes do |t| - t.string :name - t.string :previous_state - t.references :stateful - t.references :user - t.string :stateful_type - t.string :next_state - t.timestamps - end - - create_table :spree_states do |t| - t.string :name - t.string :abbr - t.references :country - end - - create_table :spree_tax_categories do |t| - t.string :name - t.string :description - t.boolean :is_default, :default => false - t.datetime :deleted_at - t.timestamps - end - - create_table :spree_tax_rates do |t| - t.decimal :amount, :precision => 8, :scale => 5 - t.references :zone - t.references :tax_category - t.boolean :included_in_price, :default => false - t.timestamps - end - - create_table :spree_taxonomies do |t| - t.string :name, :null => false - t.timestamps - end - - create_table :spree_taxons do |t| - t.references :parent - t.integer :position, :default => 0 - t.string :name, :null => false - t.string :permalink - t.references :taxonomy - t.integer :lft - t.integer :rgt - t.string :icon_file_name - t.string :icon_content_type - t.integer :icon_file_size - t.datetime :icon_updated_at - t.text :description - t.timestamps - end - - add_index :spree_taxons, [:parent_id], :name => 'index_taxons_on_parent_id' - add_index :spree_taxons, [:permalink], :name => 'index_taxons_on_permalink' - add_index :spree_taxons, [:taxonomy_id], :name => 'index_taxons_on_taxonomy_id' - - create_table :spree_tokenized_permissions, :force => true do |t| - t.references :permissable, :polymorphic => true - t.string :token - t.timestamps - end - - add_index :spree_tokenized_permissions, [:permissable_id, :permissable_type], :name => 'index_tokenized_name_and_type' - - create_table :spree_trackers do |t| - t.string :environment - t.string :analytics_id - t.boolean :active, :default => true - t.timestamps - end - - create_table :spree_users do |t| - t.string :encrypted_password, :limit => 128 - t.string :password_salt, :limit => 128 - t.string :email - t.string :remember_token - t.string :persistence_token - t.string :reset_password_token - t.string :perishable_token - t.integer :sign_in_count, :default => 0, :null => false - t.integer :failed_attempts, :default => 0, :null => false - t.datetime :last_request_at - t.datetime :current_sign_in_at - t.datetime :last_sign_in_at - t.string :current_sign_in_ip - t.string :last_sign_in_ip - t.string :login - t.references :ship_address - t.references :bill_address - t.string :authentication_token - t.string :unlock_token - t.datetime :locked_at - t.datetime :remember_created_at - t.datetime :reset_password_sent_at - t.timestamps - end - - create_table :spree_variants do |t| - t.string :sku, :default => '', :null => false - t.decimal :price, :precision => 8, :scale => 2, :null => false - t.decimal :weight, :precision => 8, :scale => 2 - t.decimal :height, :precision => 8, :scale => 2 - t.decimal :width, :precision => 8, :scale => 2 - t.decimal :depth, :precision => 8, :scale => 2 - t.datetime :deleted_at - t.boolean :is_master, :default => false - t.references :product - t.integer :count_on_hand, :default => 0, :null => false - t.decimal :cost_price, :precision => 8, :scale => 2 - t.integer :position - end - - add_index :spree_variants, [:product_id], :name => 'index_spree_variants_on_product_id' - - create_table :spree_zone_members do |t| - t.references :zoneable, :polymorphic => true - t.references :zone - t.timestamps - end - - create_table :spree_zones do |t| - t.string :name - t.string :description - t.boolean :default_tax, :default => false - t.integer :zone_members_count, :default => 0 - t.timestamps - end - end -end diff --git a/db/migrate/20130207043542_remove_unused_preference_columns.spree.rb b/db/migrate/20130207043542_remove_unused_preference_columns.spree.rb deleted file mode 100644 index 6c049daa22..0000000000 --- a/db/migrate/20130207043542_remove_unused_preference_columns.spree.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This migration comes from spree (originally 20120929093553) -class RemoveUnusedPreferenceColumns < ActiveRecord::Migration - def change - # Columns have already been removed if the application was upgraded from an older version, but must be removed from new apps. - remove_column :spree_preferences, :name if ActiveRecord::Base.connection.column_exists?(:spree_preferences, :name) - remove_column :spree_preferences, :owner_id if ActiveRecord::Base.connection.column_exists?(:spree_preferences, :owner_id) - remove_column :spree_preferences, :owner_type if ActiveRecord::Base.connection.column_exists?(:spree_preferences, :owner_type) - end -end diff --git a/db/migrate/20130207043543_add_states_required_to_countries.spree.rb b/db/migrate/20130207043543_add_states_required_to_countries.spree.rb deleted file mode 100644 index 415001d170..0000000000 --- a/db/migrate/20130207043543_add_states_required_to_countries.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121010142909) -class AddStatesRequiredToCountries < ActiveRecord::Migration - def change - add_column :spree_countries, :states_required, :boolean,:default => true - end -end diff --git a/db/migrate/20130207043544_add_on_demand_to_product_and_variant.spree.rb b/db/migrate/20130207043544_add_on_demand_to_product_and_variant.spree.rb deleted file mode 100644 index ba258ebf26..0000000000 --- a/db/migrate/20130207043544_add_on_demand_to_product_and_variant.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20121012071449) -class AddOnDemandToProductAndVariant < ActiveRecord::Migration - def change - add_column :spree_products, :on_demand, :boolean, :default => false - add_column :spree_variants, :on_demand, :boolean, :default => false - end -end diff --git a/db/migrate/20130207043545_split_prices_from_variants.spree.rb b/db/migrate/20130207043545_split_prices_from_variants.spree.rb deleted file mode 100644 index f22753470f..0000000000 --- a/db/migrate/20130207043545_split_prices_from_variants.spree.rb +++ /dev/null @@ -1,32 +0,0 @@ -# This migration comes from spree (originally 20121031162139) -class SplitPricesFromVariants < ActiveRecord::Migration - def up - create_table :spree_prices do |t| - t.integer :variant_id, :null => false - t.decimal :amount, :precision => 8, :scale => 2, :null => false - t.string :currency - end - - Spree::Variant.all.each do |variant| - Spree::Price.create!( - :variant_id => variant.id, - :amount => variant[:price], - :currency => Spree::Config[:currency] - ) - end - - remove_column :spree_variants, :price - end - - def down - prices = ActiveRecord::Base.connection.execute("select variant_id, amount from spree_prices") - add_column :spree_variants, :price, :decimal, :after => :sku, :scale => 2, :precision => 8 - - prices.each do |price| - ActiveRecord::Base.connection.execute("update spree_variants set price = #{price['amount']} where id = #{price['variant_id']}") - end - - change_column :spree_variants, :price, :decimal, :after => :sku, :scale => 2, :precision => 8, :null => false - drop_table :spree_prices - end -end diff --git a/db/migrate/20130207043546_remove_not_null_from_spree_prices_amount.spree.rb b/db/migrate/20130207043546_remove_not_null_from_spree_prices_amount.spree.rb deleted file mode 100644 index beb5f7a85f..0000000000 --- a/db/migrate/20130207043546_remove_not_null_from_spree_prices_amount.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20121107003422) -class RemoveNotNullFromSpreePricesAmount < ActiveRecord::Migration - def up - change_column :spree_prices, :amount, :decimal, :precision => 8, :scale => 2, :null => true - end - - def down - change_column :spree_prices, :amount, :decimal, :precision => 8, :scale => 2, :null => false - end -end diff --git a/db/migrate/20130207043547_add_currency_to_line_items.spree.rb b/db/migrate/20130207043547_add_currency_to_line_items.spree.rb deleted file mode 100644 index b0732ee630..0000000000 --- a/db/migrate/20130207043547_add_currency_to_line_items.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121107184631) -class AddCurrencyToLineItems < ActiveRecord::Migration - def change - add_column :spree_line_items, :currency, :string - end -end diff --git a/db/migrate/20130207043548_add_currency_to_orders.spree.rb b/db/migrate/20130207043548_add_currency_to_orders.spree.rb deleted file mode 100644 index d84bc3b7cc..0000000000 --- a/db/migrate/20130207043548_add_currency_to_orders.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121107194006) -class AddCurrencyToOrders < ActiveRecord::Migration - def change - add_column :spree_orders, :currency, :string - end -end diff --git a/db/migrate/20130207043549_add_cost_currency_to_variants.spree.rb b/db/migrate/20130207043549_add_cost_currency_to_variants.spree.rb deleted file mode 100644 index a31b96499d..0000000000 --- a/db/migrate/20130207043549_add_cost_currency_to_variants.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121109173623) -class AddCostCurrencyToVariants < ActiveRecord::Migration - def change - add_column :spree_variants, :cost_currency, :string, :after => :cost_price - end -end diff --git a/db/migrate/20130207043550_remove_display_on_from_payment_methods.spree.rb b/db/migrate/20130207043550_remove_display_on_from_payment_methods.spree.rb deleted file mode 100644 index a763d823e9..0000000000 --- a/db/migrate/20130207043550_remove_display_on_from_payment_methods.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20121111231553) -class RemoveDisplayOnFromPaymentMethods < ActiveRecord::Migration - def up - remove_column :spree_payment_methods, :display_on - end - - def down - add_column :spree_payment_methods, :display_on, :string - end -end diff --git a/db/migrate/20130207043551_add_last_ip_to_spree_orders.spree.rb b/db/migrate/20130207043551_add_last_ip_to_spree_orders.spree.rb deleted file mode 100644 index e85fc41ffe..0000000000 --- a/db/migrate/20130207043551_add_last_ip_to_spree_orders.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20121126040517) -class AddLastIpToSpreeOrders < ActiveRecord::Migration - def change - add_column :spree_orders, :last_ip_address, :string - end -end diff --git a/db/migrate/20130207043552_add_display_on_to_spree_payment_methods.spree.rb b/db/migrate/20130207043552_add_display_on_to_spree_payment_methods.spree.rb deleted file mode 100644 index 240870bbb6..0000000000 --- a/db/migrate/20130207043552_add_display_on_to_spree_payment_methods.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20130114053446) -class AddDisplayOnToSpreePaymentMethods < ActiveRecord::Migration - def self.up - add_column :spree_payment_methods, :display_on, :string - end - - def self.down - remove_column :spree_payment_methods, :display_on - end -end diff --git a/db/migrate/20130207043553_add_position_to_product_properties.spree.rb b/db/migrate/20130207043553_add_position_to_product_properties.spree.rb deleted file mode 100644 index 93da5d87b1..0000000000 --- a/db/migrate/20130207043553_add_position_to_product_properties.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130120201805) -class AddPositionToProductProperties < ActiveRecord::Migration - def change - add_column :spree_product_properties, :position, :integer, :default => 0 - end -end - diff --git a/db/migrate/20130207043554_add_api_key_to_spree_users.spree_api.rb b/db/migrate/20130207043554_add_api_key_to_spree_users.spree_api.rb deleted file mode 100644 index b9e3fe3884..0000000000 --- a/db/migrate/20130207043554_add_api_key_to_spree_users.spree_api.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree_api (originally 20100107141738) -class AddApiKeyToSpreeUsers < ActiveRecord::Migration - def change - unless defined?(User) - add_column :spree_users, :api_key, :string, :limit => 40 - end - end -end diff --git a/db/migrate/20130207043555_spree_promo_one_two.spree_promo.rb b/db/migrate/20130207043555_spree_promo_one_two.spree_promo.rb deleted file mode 100644 index 7e808c800b..0000000000 --- a/db/migrate/20130207043555_spree_promo_one_two.spree_promo.rb +++ /dev/null @@ -1,46 +0,0 @@ -# This migration comes from spree_promo (originally 20120831092359) -class SpreePromoOneTwo < ActiveRecord::Migration - def up - # This migration is just a compressed migration for all previous versions of spree_promo - return if table_exists?(:spree_products_promotion_rules) - - create_table :spree_products_promotion_rules, :id => false, :force => true do |t| - t.references :product - t.references :promotion_rule - end - - add_index :spree_products_promotion_rules, [:product_id], :name => 'index_products_promotion_rules_on_product_id' - add_index :spree_products_promotion_rules, [:promotion_rule_id], :name => 'index_products_promotion_rules_on_promotion_rule_id' - - create_table :spree_promotion_action_line_items, :force => true do |t| - t.references :promotion_action - t.references :variant - t.integer :quantity, :default => 1 - end - - create_table :spree_promotion_actions, :force => true do |t| - t.references :activator - t.integer :position - t.string :type - end - - create_table :spree_promotion_rules, :force => true do |t| - t.references :activator - t.references :user - t.references :product_group - t.string :type - t.timestamps - end - - add_index :spree_promotion_rules, [:product_group_id], :name => 'index_promotion_rules_on_product_group_id' - add_index :spree_promotion_rules, [:user_id], :name => 'index_promotion_rules_on_user_id' - - create_table :spree_promotion_rules_users, :id => false, :force => true do |t| - t.references :user - t.references :promotion_rule - end - - add_index :spree_promotion_rules_users, [:promotion_rule_id], :name => 'index_promotion_rules_users_on_promotion_rule_id' - add_index :spree_promotion_rules_users, [:user_id], :name => 'index_promotion_rules_users_on_user_id' - end -end diff --git a/db/migrate/20130426023034_add_distributor_info_to_enterprises.enterprises_distributor_info_rich_text_feature.rb b/db/migrate/20130426023034_add_distributor_info_to_enterprises.enterprises_distributor_info_rich_text_feature.rb deleted file mode 100644 index 69a6b9981e..0000000000 --- a/db/migrate/20130426023034_add_distributor_info_to_enterprises.enterprises_distributor_info_rich_text_feature.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from enterprises_distributor_info_rich_text_feature (originally 20130426022945) -class AddDistributorInfoToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :distributor_info, :text - end -end diff --git a/db/migrate/20130629120633_add_order_id_index_to_payments.spree.rb b/db/migrate/20130629120633_add_order_id_index_to_payments.spree.rb deleted file mode 100644 index 49b378abb3..0000000000 --- a/db/migrate/20130629120633_add_order_id_index_to_payments.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20130207155350) -class AddOrderIdIndexToPayments < ActiveRecord::Migration - def self.up - add_index :spree_payments, :order_id - end - - def self.down - remove_index :spree_payments, :order_id - end -end diff --git a/db/migrate/20130629120634_add_primary_to_spree_products_taxons.spree.rb b/db/migrate/20130629120634_add_primary_to_spree_products_taxons.spree.rb deleted file mode 100644 index fd438d5c83..0000000000 --- a/db/migrate/20130629120634_add_primary_to_spree_products_taxons.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130208032954) -class AddPrimaryToSpreeProductsTaxons < ActiveRecord::Migration - def change - add_column :spree_products_taxons, :id, :primary_key - end -end diff --git a/db/migrate/20130629120635_add_order_id_index_to_shipments.spree.rb b/db/migrate/20130629120635_add_order_id_index_to_shipments.spree.rb deleted file mode 100644 index 5d0ebdbc78..0000000000 --- a/db/migrate/20130629120635_add_order_id_index_to_shipments.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130222032153) -class AddOrderIdIndexToShipments < ActiveRecord::Migration - def change - add_index :spree_shipments, :order_id - end -end diff --git a/db/migrate/20130629120636_change_meta_description_on_spree_products_to_text.spree.rb b/db/migrate/20130629120636_change_meta_description_on_spree_products_to_text.spree.rb deleted file mode 100644 index 66fff52115..0000000000 --- a/db/migrate/20130629120636_change_meta_description_on_spree_products_to_text.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130226032817) -class ChangeMetaDescriptionOnSpreeProductsToText < ActiveRecord::Migration - def change - change_column :spree_products, :meta_description, :text, :limit => nil - end -end diff --git a/db/migrate/20130629120637_add_variant_id_index_to_spree_prices.spree.rb b/db/migrate/20130629120637_add_variant_id_index_to_spree_prices.spree.rb deleted file mode 100644 index 0a362f2ee8..0000000000 --- a/db/migrate/20130629120637_add_variant_id_index_to_spree_prices.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130226054936) -class AddVariantIdIndexToSpreePrices < ActiveRecord::Migration - def change - add_index :spree_prices, :variant_id - end -end diff --git a/db/migrate/20130629120638_change_orders_total_precision.spree.rb b/db/migrate/20130629120638_change_orders_total_precision.spree.rb deleted file mode 100644 index cfb1c81e6a..0000000000 --- a/db/migrate/20130629120638_change_orders_total_precision.spree.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This migration comes from spree (originally 20130319062004) -class ChangeOrdersTotalPrecision < ActiveRecord::Migration - def change - change_column :spree_orders, :item_total, :decimal, :precision => 10, :scale => 2, :default => 0.0, :null => false - change_column :spree_orders, :total, :decimal, :precision => 10, :scale => 2, :default => 0.0, :null => false - change_column :spree_orders, :adjustment_total, :decimal, :precision => 10, :scale => 2, :default => 0.0, :null => false - change_column :spree_orders, :payment_total, :decimal, :precision => 10, :scale => 2, :default => 0.0 - end -end diff --git a/db/migrate/20130629120639_change_spree_payments_amount_precision.spree.rb b/db/migrate/20130629120639_change_spree_payments_amount_precision.spree.rb deleted file mode 100644 index 2ac4630836..0000000000 --- a/db/migrate/20130629120639_change_spree_payments_amount_precision.spree.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree (originally 20130319063911) -class ChangeSpreePaymentsAmountPrecision < ActiveRecord::Migration - def change - - change_column :spree_payments, :amount, :decimal, :precision => 10, :scale => 2, :default => 0.0, :null => false - - end -end diff --git a/db/migrate/20130629120640_change_spree_return_authorization_amount_precision.spree.rb b/db/migrate/20130629120640_change_spree_return_authorization_amount_precision.spree.rb deleted file mode 100644 index cf6cc4b3c2..0000000000 --- a/db/migrate/20130629120640_change_spree_return_authorization_amount_precision.spree.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree (originally 20130319064308) -class ChangeSpreeReturnAuthorizationAmountPrecision < ActiveRecord::Migration - def change - - change_column :spree_return_authorizations, :amount, :decimal, :precision => 10, :scale => 2, :default => 0.0, :null => false - - end -end diff --git a/db/migrate/20130629120641_change_adjustments_amount_precision.spree.rb b/db/migrate/20130629120641_change_adjustments_amount_precision.spree.rb deleted file mode 100644 index f391987c40..0000000000 --- a/db/migrate/20130629120641_change_adjustments_amount_precision.spree.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree (originally 20130319082943) -class ChangeAdjustmentsAmountPrecision < ActiveRecord::Migration - def change - - change_column :spree_adjustments, :amount, :decimal, :precision => 10, :scale => 2 - - end -end diff --git a/db/migrate/20130629120642_add_seo_metas_to_taxons.spree.rb b/db/migrate/20130629120642_add_seo_metas_to_taxons.spree.rb deleted file mode 100644 index a947764a27..0000000000 --- a/db/migrate/20130629120642_add_seo_metas_to_taxons.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20130328195253) -class AddSeoMetasToTaxons < ActiveRecord::Migration - def change - change_table :spree_taxons do |t| - t.string :meta_title - t.string :meta_description - t.string :meta_keywords - end - end -end diff --git a/db/migrate/20130629120643_add_cvv_result_code_and_cvv_result_message_to_spree_payments.spree.rb b/db/migrate/20130629120643_add_cvv_result_code_and_cvv_result_message_to_spree_payments.spree.rb deleted file mode 100644 index 0f611c6336..0000000000 --- a/db/migrate/20130629120643_add_cvv_result_code_and_cvv_result_message_to_spree_payments.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130626232741) -class AddCvvResultCodeAndCvvResultMessageToSpreePayments < ActiveRecord::Migration - def change - add_column :spree_payments, :cvv_response_code, :string - add_column :spree_payments, :cvv_response_message, :string - end -end diff --git a/db/migrate/20130629120644_add_unique_index_to_permalink_on_spree_products.spree.rb b/db/migrate/20130629120644_add_unique_index_to_permalink_on_spree_products.spree.rb deleted file mode 100644 index 310d487116..0000000000 --- a/db/migrate/20130629120644_add_unique_index_to_permalink_on_spree_products.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130628021056) -class AddUniqueIndexToPermalinkOnSpreeProducts < ActiveRecord::Migration - def change - add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true - end -end diff --git a/db/migrate/20130629120645_add_unique_index_to_orders_shipments_and_stock_transfers.spree.rb b/db/migrate/20130629120645_add_unique_index_to_orders_shipments_and_stock_transfers.spree.rb deleted file mode 100644 index 054cc7402e..0000000000 --- a/db/migrate/20130629120645_add_unique_index_to_orders_shipments_and_stock_transfers.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130628022817) -class AddUniqueIndexToOrdersShipmentsAndStockTransfers < ActiveRecord::Migration - def add - add_index "spree_orders", ["number"], :name => "number_idx_unique", :unique => true - add_index "spree_shipments", ["number"], :name => "number_idx_unique", :unique => true - end -end diff --git a/db/migrate/20130729021924_make_order_cycle_coordinator_fees_mtm.rb b/db/migrate/20130729021924_make_order_cycle_coordinator_fees_mtm.rb deleted file mode 100644 index ff88d3f493..0000000000 --- a/db/migrate/20130729021924_make_order_cycle_coordinator_fees_mtm.rb +++ /dev/null @@ -1,19 +0,0 @@ -class MakeOrderCycleCoordinatorFeesMtm < ActiveRecord::Migration - def up - remove_column :order_cycles, :coordinator_admin_fee_id - remove_column :order_cycles, :coordinator_sales_fee_id - - create_table :coordinator_fees, id: false do |t| - t.references :order_cycle - t.references :enterprise_fee - end - end - - def down - drop_table :coordinator_fees - - add_column :order_cycles, :coordinator_admin_fee_id, :integer - add_column :order_cycles, :coordinator_sales_fee_id, :integer - end - -end diff --git a/db/migrate/20130729030515_add_enterprise_role.rb b/db/migrate/20130729030515_add_enterprise_role.rb deleted file mode 100644 index 25a1deeeac..0000000000 --- a/db/migrate/20130729030515_add_enterprise_role.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddEnterpriseRole < ActiveRecord::Migration - def change - create_table :enterprise_roles do |t| - t.references :user, index: true - t.references :enterprise, index: true - end - end -end diff --git a/db/migrate/20130801005801_create_landing_page_images.rb b/db/migrate/20130801005801_create_landing_page_images.rb deleted file mode 100644 index 6b48464d0a..0000000000 --- a/db/migrate/20130801005801_create_landing_page_images.rb +++ /dev/null @@ -1,7 +0,0 @@ -class CreateLandingPageImages < ActiveRecord::Migration - def change - create_table :landing_page_images do |t| - t.timestamps - end - end -end diff --git a/db/migrate/20130801012854_add_attachment_photo_to_landing_page_image.rb b/db/migrate/20130801012854_add_attachment_photo_to_landing_page_image.rb deleted file mode 100644 index 72a4c40de9..0000000000 --- a/db/migrate/20130801012854_add_attachment_photo_to_landing_page_image.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddAttachmentPhotoToLandingPageImage < ActiveRecord::Migration - def self.up - add_column :landing_page_images, :photo_file_name, :string - add_column :landing_page_images, :photo_content_type, :string - add_column :landing_page_images, :photo_file_size, :integer - add_column :landing_page_images, :photo_updated_at, :datetime - end - - def self.down - remove_column :landing_page_images, :photo_file_name - remove_column :landing_page_images, :photo_content_type - remove_column :landing_page_images, :photo_file_size - remove_column :landing_page_images, :photo_updated_at - end -end diff --git a/db/migrate/20130805050109_update_line_item_caching.rb b/db/migrate/20130805050109_update_line_item_caching.rb deleted file mode 100644 index 42760e7c02..0000000000 --- a/db/migrate/20130805050109_update_line_item_caching.rb +++ /dev/null @@ -1,47 +0,0 @@ -class UpdateLineItemCaching < ActiveRecord::Migration - - class SpreeLineItem < ActiveRecord::Base - belongs_to :shipping_method, class_name: 'Spree::ShippingMethod' - belongs_to :variant, :class_name => "Spree::Variant" - - def itemwise_shipping_cost - order = OpenStruct.new :line_items => [self] - shipping_method.compute_amount(order) - end - - def amount - price * quantity - end - alias total amount - end - - - def up - add_column :spree_line_items, :distribution_fee, :decimal, precision: 10, scale: 2 - add_column :spree_line_items, :shipping_method_name, :string - - SpreeLineItem.all.each do |line_item| - line_item.update_column(:distribution_fee, line_item.itemwise_shipping_cost) - line_item.update_column(:shipping_method_name, line_item.shipping_method.name) - end - - remove_column :spree_line_items, :shipping_method_id - end - - def down - add_column :spree_line_items, :shipping_method_id, :integer - - SpreeLineItem.all.each do |line_item| - shipping_method = Spree::ShippingMethod.find_by_name(line_item.shipping_method_name) - unless shipping_method - say "Shipping method #{line_item.shipping_method_name} not found, using the first available shipping method for LineItem #{line_item.id}" - shipping_method = Spree::ShippingMethod.where("name != 'Delivery'").first - end - - line_item.update_column(:shipping_method_id, shipping_method.id) - end - - remove_column :spree_line_items, :distribution_fee - remove_column :spree_line_items, :shipping_method_name - end -end diff --git a/db/migrate/20130805232516_add_enterprise_fee_to_product_distributions.rb b/db/migrate/20130805232516_add_enterprise_fee_to_product_distributions.rb deleted file mode 100644 index b6154c1dd1..0000000000 --- a/db/migrate/20130805232516_add_enterprise_fee_to_product_distributions.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddEnterpriseFeeToProductDistributions < ActiveRecord::Migration - def change - add_column :product_distributions, :enterprise_fee_id, :integer - end -end diff --git a/db/migrate/20130806055125_create_suburbs.rb b/db/migrate/20130806055125_create_suburbs.rb deleted file mode 100644 index bb09b8522b..0000000000 --- a/db/migrate/20130806055125_create_suburbs.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateSuburbs < ActiveRecord::Migration - def change - create_table :suburbs do |t| - t.string :name - t.integer :postcode - t.float :latitude - t.float :longitude - t.integer :state_id - end - end -end diff --git a/db/migrate/20130807002915_add_latitude_and_longitude_to_addresses.rb b/db/migrate/20130807002915_add_latitude_and_longitude_to_addresses.rb deleted file mode 100644 index 7fbfe9c30e..0000000000 --- a/db/migrate/20130807002915_add_latitude_and_longitude_to_addresses.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddLatitudeAndLongitudeToAddresses < ActiveRecord::Migration - def change - add_column :spree_addresses, :latitude, :float - add_column :spree_addresses, :longitude, :float - end -end diff --git a/db/migrate/20130807062657_add_distributor_id_to_payment_method.rb b/db/migrate/20130807062657_add_distributor_id_to_payment_method.rb deleted file mode 100644 index 26ea241019..0000000000 --- a/db/migrate/20130807062657_add_distributor_id_to_payment_method.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDistributorIdToPaymentMethod < ActiveRecord::Migration - def change - add_column :spree_payment_methods, :distributor_id, :integer - end -end diff --git a/db/migrate/20130807230834_add_cart.rb b/db/migrate/20130807230834_add_cart.rb deleted file mode 100644 index 38d94a7c8e..0000000000 --- a/db/migrate/20130807230834_add_cart.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddCart < ActiveRecord::Migration - def change - create_table :carts do |t| - t.integer :user_id - end - - add_column :spree_orders, :cart_id, :integer - end -end diff --git a/db/migrate/20130809045637_create_enterprise_fee_records_for_product_distributions.rb b/db/migrate/20130809045637_create_enterprise_fee_records_for_product_distributions.rb deleted file mode 100644 index b826f51fdb..0000000000 --- a/db/migrate/20130809045637_create_enterprise_fee_records_for_product_distributions.rb +++ /dev/null @@ -1,26 +0,0 @@ -class CreateEnterpriseFeeRecordsForProductDistributions < ActiveRecord::Migration - - class ProductDistribution < ActiveRecord::Base - belongs_to :shipping_method, :class_name => 'Spree::ShippingMethod' - belongs_to :distributor, :class_name => 'Enterprise' - belongs_to :enterprise_fee - end - - def up - ProductDistribution.all.each do |pd| - calculator = pd.shipping_method.calculator.dup - calculator.save! - - ef = EnterpriseFee.new enterprise_id: pd.distributor.id, fee_type: 'packing', name: pd.shipping_method.name - ef.calculator = calculator - ef.save! - - pd.enterprise_fee = ef - pd.save! - end - end - - def down - ProductDistribution.update_all :enterprise_fee_id => nil - end -end diff --git a/db/migrate/20130809075103_create_adjustment_metadata.rb b/db/migrate/20130809075103_create_adjustment_metadata.rb deleted file mode 100644 index 4d1c6579eb..0000000000 --- a/db/migrate/20130809075103_create_adjustment_metadata.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateAdjustmentMetadata < ActiveRecord::Migration - def change - create_table :adjustment_metadata do |t| - t.integer :adjustment_id - t.integer :enterprise_id - t.string :fee_name - t.string :fee_type - t.string :enterprise_role - end - - add_index :adjustment_metadata, :adjustment_id - end -end diff --git a/db/migrate/20130812233634_remove_shipping_method_from_product_distribution.rb b/db/migrate/20130812233634_remove_shipping_method_from_product_distribution.rb deleted file mode 100644 index cf3fee3020..0000000000 --- a/db/migrate/20130812233634_remove_shipping_method_from_product_distribution.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveShippingMethodFromProductDistribution < ActiveRecord::Migration - def up - remove_column :product_distributions, :shipping_method_id - end - - def down - add_column :product_distributions, :shipping_method_id, :integer - end -end diff --git a/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb b/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb deleted file mode 100644 index 52351065dd..0000000000 --- a/db/migrate/20130814010857_remove_shipping_methods_using_itemwise_calculator.rb +++ /dev/null @@ -1,15 +0,0 @@ -class RemoveShippingMethodsUsingItemwiseCalculator < ActiveRecord::Migration - class OpenFoodNetwork::Calculator::Itemwise < Spree::Calculator; end - - def up - Spree::ShippingMethod.all.select { |sm| sm.calculator.type == 'OpenFoodNetwork::Calculator::Itemwise' }.each do |sm| - - say "Destroying itemwise shipping method with id #{sm.id}" - sm.destroy - end - end - - def down - Spree::ShippingMethod.create!({name: 'Delivery', zone: Spree::Zone.last, calculator: OpenFoodNetwork::Calculator::Itemwise.new}, without_protection: true) - end -end diff --git a/db/migrate/20130830012138_add_distributor_id_to_shipping_methods.rb b/db/migrate/20130830012138_add_distributor_id_to_shipping_methods.rb deleted file mode 100644 index 3039475a10..0000000000 --- a/db/migrate/20130830012138_add_distributor_id_to_shipping_methods.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddDistributorIdToShippingMethods < ActiveRecord::Migration - def change - add_column :spree_shipping_methods, :distributor_id, :integer - add_index :spree_shipping_methods, :distributor_id - end -end diff --git a/db/migrate/20130912021553_create_distributors_payment_methods.rb b/db/migrate/20130912021553_create_distributors_payment_methods.rb deleted file mode 100644 index a9e2ed1738..0000000000 --- a/db/migrate/20130912021553_create_distributors_payment_methods.rb +++ /dev/null @@ -1,20 +0,0 @@ -class CreateDistributorsPaymentMethods < ActiveRecord::Migration - class Spree::PaymentMethod < ActiveRecord::Base - belongs_to :distributor, class_name: 'Enterprise' - has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id' - end - - def up - create_table :distributors_payment_methods, :id => false do |t| - t.references :distributor - t.references :payment_method - end - Spree::PaymentMethod.all.each do |pm| - pm.distributors << pm.distributor if pm.distributor_id - end - end - - def down - drop_table :distributors_payment_methods - end -end diff --git a/db/migrate/20130912021938_remove_distributor_id_from_payment_method.rb b/db/migrate/20130912021938_remove_distributor_id_from_payment_method.rb deleted file mode 100644 index 58bece17cd..0000000000 --- a/db/migrate/20130912021938_remove_distributor_id_from_payment_method.rb +++ /dev/null @@ -1,12 +0,0 @@ -class RemoveDistributorIdFromPaymentMethod < ActiveRecord::Migration - def up - remove_column :spree_payment_methods, :distributor_id - end - - def down - add_column :spree_payment_methods, :distributor_id, :integer - Spree::PaymentMethod.each do |pm| - pm.distributor_id = pm.distributors.first.distributor_id if pm.distributors.first - end - end -end diff --git a/db/migrate/20130919010513_ensure_shipping_methods_have_distributors.rb b/db/migrate/20130919010513_ensure_shipping_methods_have_distributors.rb deleted file mode 100644 index 09017609eb..0000000000 --- a/db/migrate/20130919010513_ensure_shipping_methods_have_distributors.rb +++ /dev/null @@ -1,20 +0,0 @@ -class EnsureShippingMethodsHaveDistributors < ActiveRecord::Migration - class Enterprise < ActiveRecord::Base - scope :is_distributor, -> { where(is_distributor: true) } - end - - def up - d = Enterprise.is_distributor.first - sms = Spree::ShippingMethod.where('distributor_id IS NULL') - - if d - say "Assigning an arbitrary distributor (#{d.name}) to all shipping methods without one (#{sms.count} total)" - sms.update_all(distributor_id: d) - else - say "There are #{sms.count} shipping methods without distributors, but there are no distributors to assign to them" - end - end - - def down - end -end diff --git a/db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb b/db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb deleted file mode 100644 index 8d26c88d9b..0000000000 --- a/db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb +++ /dev/null @@ -1,37 +0,0 @@ -class ConvertShippingMethodsDistributorsToHabtm < ActiveRecord::Migration - class Spree::ShippingMethod < ActiveRecord::Base - belongs_to :distributor, class_name: 'Enterprise' - has_and_belongs_to_many :distributors, join_table: 'distributors_shipping_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id' - end - - def up - create_table :distributors_shipping_methods, id: false do |t| - t.references :distributor - t.references :shipping_method - end - add_index :distributors_shipping_methods, :distributor_id - add_index :distributors_shipping_methods, :shipping_method_id - - Spree::ShippingMethod.all.each do |sm| - sm.distributors << sm.distributor if sm.distributor_id - end - - remove_column :spree_shipping_methods, :distributor_id - end - - def down - add_column :spree_shipping_methods, :distributor_id, :integer - add_index :spree_shipping_methods, :distributor_id - - Spree::ShippingMethod.all.each do |sm| - if sm.distributors.present? - sm.distributor = sm.distributors.first - sm.save! - - say "WARNING: Discarding #{sm.distributors.count-1} distributors while flattening HABTM relation to belongs_to" if sm.distributors.count > 1 - end - end - - drop_table :distributors_shipping_methods - end -end diff --git a/db/migrate/20131024005253_create_enterprise_groups.rb b/db/migrate/20131024005253_create_enterprise_groups.rb deleted file mode 100644 index 4a8d01fd0a..0000000000 --- a/db/migrate/20131024005253_create_enterprise_groups.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateEnterpriseGroups < ActiveRecord::Migration - def change - create_table :enterprise_groups do |t| - t.string :name - t.boolean :on_front_page - end - - create_table :enterprise_groups_enterprises, id: false do |t| - t.references :enterprise_group - t.references :enterprise - end - end -end diff --git a/db/migrate/20131030031125_add_position_to_enterprise_groups.rb b/db/migrate/20131030031125_add_position_to_enterprise_groups.rb deleted file mode 100644 index 199a045784..0000000000 --- a/db/migrate/20131030031125_add_position_to_enterprise_groups.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPositionToEnterpriseGroups < ActiveRecord::Migration - def change - add_column :enterprise_groups, :position, :integer - end -end diff --git a/db/migrate/20131128034556_setup_product_units_and_values.rb b/db/migrate/20131128034556_setup_product_units_and_values.rb deleted file mode 100644 index d6cf779aed..0000000000 --- a/db/migrate/20131128034556_setup_product_units_and_values.rb +++ /dev/null @@ -1,14 +0,0 @@ -class SetupProductUnitsAndValues < ActiveRecord::Migration - def change - change_table :spree_products do |t| - t.string :variant_unit - t.float :variant_unit_scale - t.string :variant_unit_name - end - - change_table :spree_variants do |t| - t.float :unit_value - t.string :unit_description - end - end -end diff --git a/db/migrate/20140110040238_make_unit_description_default_blank.rb b/db/migrate/20140110040238_make_unit_description_default_blank.rb deleted file mode 100644 index 58254259ab..0000000000 --- a/db/migrate/20140110040238_make_unit_description_default_blank.rb +++ /dev/null @@ -1,10 +0,0 @@ -class MakeUnitDescriptionDefaultBlank < ActiveRecord::Migration - def up - execute "UPDATE spree_variants SET unit_description='' WHERE unit_description IS NULL" - change_column :spree_variants, :unit_description, :string, default: '' - end - - def down - change_column :spree_variants, :unit_description, :string, default: nil - end -end diff --git a/db/migrate/20140116030500_add_attachment_logo_to_enterprise.rb b/db/migrate/20140116030500_add_attachment_logo_to_enterprise.rb deleted file mode 100644 index 0f3c6e114f..0000000000 --- a/db/migrate/20140116030500_add_attachment_logo_to_enterprise.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddAttachmentLogoToEnterprise < ActiveRecord::Migration - def self.up - add_column :enterprises, :logo_file_name, :string - add_column :enterprises, :logo_content_type, :string - add_column :enterprises, :logo_file_size, :integer - add_column :enterprises, :logo_updated_at, :datetime - end - - def self.down - remove_column :enterprises, :logo_file_name - remove_column :enterprises, :logo_content_type - remove_column :enterprises, :logo_file_size - remove_column :enterprises, :logo_updated_at - end -end diff --git a/db/migrate/20140121050239_add_attachment_promo_image_to_enterprise.rb b/db/migrate/20140121050239_add_attachment_promo_image_to_enterprise.rb deleted file mode 100644 index d875f111b2..0000000000 --- a/db/migrate/20140121050239_add_attachment_promo_image_to_enterprise.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddAttachmentPromoImageToEnterprise < ActiveRecord::Migration - def self.up - add_column :enterprises, :promo_image_file_name, :string - add_column :enterprises, :promo_image_content_type, :string - add_column :enterprises, :promo_image_file_size, :integer - add_column :enterprises, :promo_image_updated_at, :datetime - end - - def self.down - remove_column :enterprises, :promo_image_file_name - remove_column :enterprises, :promo_image_content_type - remove_column :enterprises, :promo_image_file_size - remove_column :enterprises, :promo_image_updated_at - end -end diff --git a/db/migrate/20140204011203_add_notes_to_products.rb b/db/migrate/20140204011203_add_notes_to_products.rb deleted file mode 100644 index 5ec603a85c..0000000000 --- a/db/migrate/20140204011203_add_notes_to_products.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNotesToProducts < ActiveRecord::Migration - def change - add_column :spree_products, :notes, :text - end -end diff --git a/db/migrate/20140213003443_add_require_ship_address_to_shipping_methods.rb b/db/migrate/20140213003443_add_require_ship_address_to_shipping_methods.rb deleted file mode 100644 index a38ad29242..0000000000 --- a/db/migrate/20140213003443_add_require_ship_address_to_shipping_methods.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddRequireShipAddressToShippingMethods < ActiveRecord::Migration - def change - add_column :spree_shipping_methods, :require_ship_address, :boolean, :default => true - add_column :spree_shipping_methods, :description, :text - end -end diff --git a/db/migrate/20140324025840_add_incoming_to_exchanges.rb b/db/migrate/20140324025840_add_incoming_to_exchanges.rb deleted file mode 100644 index 37df0a48db..0000000000 --- a/db/migrate/20140324025840_add_incoming_to_exchanges.rb +++ /dev/null @@ -1,25 +0,0 @@ -class AddIncomingToExchanges < ActiveRecord::Migration - class Exchange < ActiveRecord::Base - belongs_to :order_cycle - belongs_to :receiver, :class_name => 'Enterprise' - - def incoming? - receiver == order_cycle.coordinator - end - end - - - def up - add_column :exchanges, :incoming, :boolean, null: false, default: false - - # Initialise based on whether the exchange is going to or coming - # from the order cycle coordinator - Exchange.all.each do |exchange| - exchange.update_attribute :incoming, exchange.incoming? - end - end - - def down - remove_column :exchanges, :incoming - end -end diff --git a/db/migrate/20140402032034_add_missing_indexes.rb b/db/migrate/20140402032034_add_missing_indexes.rb deleted file mode 100644 index 5c7713d3b6..0000000000 --- a/db/migrate/20140402032034_add_missing_indexes.rb +++ /dev/null @@ -1,38 +0,0 @@ -class AddMissingIndexes < ActiveRecord::Migration - def change - add_index :adjustment_metadata, :enterprise_id - - add_index :carts, :user_id - - add_index :coordinator_fees, :order_cycle_id - add_index :coordinator_fees, :enterprise_fee_id - - add_index :distributors_payment_methods, :distributor_id - add_index :distributors_payment_methods, :payment_method_id - - add_index :enterprise_fees, :enterprise_id - - add_index :enterprise_groups_enterprises, :enterprise_group_id - add_index :enterprise_groups_enterprises, :enterprise_id - - add_index :enterprise_roles, :user_id - add_index :enterprise_roles, :enterprise_id - - add_index :enterprises, :address_id - - add_index :exchange_fees, :exchange_id - add_index :exchange_fees, :enterprise_fee_id - - add_index :exchange_variants, :exchange_id - add_index :exchange_variants, :variant_id - - add_index :exchanges, :order_cycle_id - add_index :exchanges, :sender_id - add_index :exchanges, :receiver_id - add_index :exchanges, :payment_enterprise_id - - add_index :product_distributions, :product_id - add_index :product_distributions, :distributor_id - add_index :product_distributions, :enterprise_fee_id - end -end diff --git a/db/migrate/20140402033428_add_foreign_keys.rb b/db/migrate/20140402033428_add_foreign_keys.rb deleted file mode 100644 index 1535f4f3f9..0000000000 --- a/db/migrate/20140402033428_add_foreign_keys.rb +++ /dev/null @@ -1,188 +0,0 @@ -class AddForeignKeys < ActiveRecord::Migration - class AdjustmentMetadata < ActiveRecord::Base; end - class CoordinatorFee < ActiveRecord::Base; end - class Enterprise < ActiveRecord::Base - belongs_to :address, :class_name => 'Spree::Address' - end - class ExchangeVariant < ActiveRecord::Base; end - class Spree::InventoryUnit < ActiveRecord::Base; end - class Spree::LineItem < ActiveRecord::Base; end - class Spree::Address < ActiveRecord::Base; end - class Spree::Order < ActiveRecord::Base; end - class Spree::Taxon < ActiveRecord::Base; end - - def change - setup_foreign_keys - end - - # http://stackoverflow.com/a/7679513/2720566 - def migrate(direction) - sanitise_data if direction == :up - super - end - - - private - - def sanitise_data - # Remove orphaned AdjustmentMetadata records - orphaned_adjustment_metadata = AdjustmentMetadata.joins('LEFT OUTER JOIN spree_adjustments ON spree_adjustments.id = adjustment_metadata.adjustment_id').where('spree_adjustments.id IS NULL') - say "Destroying #{orphaned_adjustment_metadata.count} orphaned AdjustmentMetadata (of total #{AdjustmentMetadata.count})" - orphaned_adjustment_metadata.destroy_all - - # Remove orphaned ExchangeVariants - orphaned_exchange_variants = ExchangeVariant.joins('LEFT OUTER JOIN spree_variants ON spree_variants.id=exchange_variants.variant_id').where('spree_variants.id IS NULL') - say "Destroying #{orphaned_exchange_variants.count} orphaned ExchangeVariants (of total #{ExchangeVariant.count})" - orphaned_exchange_variants.destroy_all - - # Remove orphaned ExchangeFee records - orphaned_exchange_fees = ExchangeFee.joins('LEFT OUTER JOIN enterprise_fees ON enterprise_fees.id=exchange_fees.enterprise_fee_id').where('enterprise_fees.id IS NULL') - say "Destroying #{orphaned_exchange_fees.count} orphaned ExchangeFees (of total #{ExchangeFee.count})" - orphaned_exchange_fees.destroy_all - - # Remove orphaned Spree::InventoryUnits - orphaned_inventory_units = Spree::InventoryUnit.joins('LEFT OUTER JOIN spree_variants ON spree_variants.id=spree_inventory_units.variant_id').where('spree_variants.id IS NULL') - say "Destroying #{orphaned_inventory_units.count} orphaned InventoryUnits (of total #{Spree::InventoryUnit.count})" - orphaned_inventory_units.destroy_all - - # Remove orphaned Spree::LineItems - orphaned_line_items = Spree::LineItem. - joins('LEFT OUTER JOIN spree_variants ON spree_variants.id=spree_line_items.variant_id'). - joins('LEFT OUTER JOIN spree_orders ON spree_orders.id=spree_line_items.order_id'). - where('spree_variants.id IS NULL OR spree_orders.id IS NULL') - say "Destroying #{orphaned_line_items.count} orphaned LineItems (of total #{Spree::LineItem.count})" - orphaned_line_items.each { |li| li.delete } - - # Update orders without a distributor with a dummy distributor - state = Spree::State.first - country = state.andand.country - unless country && state - country = Spree::Country.create! name: 'Australia', iso_name: 'AU' - state = country.states.create! name: 'Victoria' - end - - address = Spree::Address.create!(firstname: 'Dummy distributor', lastname: 'Dummy distributor', phone: '12345678', state: state, - address1: 'Dummy distributor', city: 'Dummy distributor', zipcode: '1234', country: country) - Enterprise.reset_column_information - deleted_distributor = Enterprise.create!(name: "Deleted distributor", address: address) - - orphaned_orders = Spree::Order.joins('LEFT OUTER JOIN enterprises ON enterprises.id=spree_orders.distributor_id').where('enterprises.id IS NULL') - say "Assigning a dummy distributor to #{orphaned_orders.count} orders with a deleted distributor (of total #{Spree::Order.count})" - orphaned_orders.update_all distributor_id: deleted_distributor.id - - # Remove orphaned Spree::Taxons - orphaned_taxons = Spree::Taxon.joins('LEFT OUTER JOIN spree_taxonomies ON spree_taxonomies.id=spree_taxons.taxonomy_id').where('spree_taxonomies.id IS NULL') - say "Destroying #{orphaned_taxons.count} orphaned Taxons (of total #{Spree::Taxon.count})" - orphaned_taxons.destroy_all - - # Remove orphaned CoordinatorFee records - orphaned_coordinator_fees = CoordinatorFee.joins('LEFT OUTER JOIN enterprise_fees ON enterprise_fees.id = coordinator_fees.enterprise_fee_id').where('enterprise_fees.id IS NULL') - say "Destroying #{orphaned_coordinator_fees.count} orphaned CoordinatorFees (of total #{CoordinatorFee.count})" - orphaned_coordinator_fees.each do |cf| - CoordinatorFee.connection.execute("DELETE FROM coordinator_fees WHERE coordinator_fees.order_cycle_id=#{cf.order_cycle_id} AND coordinator_fees.enterprise_fee_id=#{cf.enterprise_fee_id}") - end - end - - - def setup_foreign_keys - add_foreign_key "adjustment_metadata", "spree_adjustments", name: "adjustment_metadata_adjustment_id_fk", column: "adjustment_id" - add_foreign_key "adjustment_metadata", "enterprises", name: "adjustment_metadata_enterprise_id_fk" - add_foreign_key "carts", "spree_users", name: "carts_user_id_fk", column: "user_id" - add_foreign_key "cms_blocks", "cms_pages", name: "cms_blocks_page_id_fk", column: "page_id" - add_foreign_key "cms_categories", "cms_sites", name: "cms_categories_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "cms_categorizations", "cms_categories", name: "cms_categorizations_category_id_fk", column: "category_id" - add_foreign_key "cms_files", "cms_blocks", name: "cms_files_block_id_fk", column: "block_id" - add_foreign_key "cms_files", "cms_sites", name: "cms_files_site_id_fk", column: "site_id" - add_foreign_key "cms_layouts", "cms_layouts", name: "cms_layouts_parent_id_fk", column: "parent_id" - add_foreign_key "cms_layouts", "cms_sites", name: "cms_layouts_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "cms_pages", "cms_layouts", name: "cms_pages_layout_id_fk", column: "layout_id" - add_foreign_key "cms_pages", "cms_pages", name: "cms_pages_parent_id_fk", column: "parent_id" - add_foreign_key "cms_pages", "cms_sites", name: "cms_pages_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "cms_pages", "cms_pages", name: "cms_pages_target_page_id_fk", column: "target_page_id" - add_foreign_key "cms_snippets", "cms_sites", name: "cms_snippets_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "coordinator_fees", "enterprise_fees", name: "coordinator_fees_enterprise_fee_id_fk" - add_foreign_key "coordinator_fees", "order_cycles", name: "coordinator_fees_order_cycle_id_fk" - add_foreign_key "distributors_payment_methods", "enterprises", name: "distributors_payment_methods_distributor_id_fk", column: "distributor_id" - add_foreign_key "distributors_payment_methods", "spree_payment_methods", name: "distributors_payment_methods_payment_method_id_fk", column: "payment_method_id" - add_foreign_key "distributors_shipping_methods", "enterprises", name: "distributors_shipping_methods_distributor_id_fk", column: "distributor_id" - add_foreign_key "distributors_shipping_methods", "spree_shipping_methods", name: "distributors_shipping_methods_shipping_method_id_fk", column: "shipping_method_id" - add_foreign_key "enterprise_fees", "enterprises", name: "enterprise_fees_enterprise_id_fk" - add_foreign_key "enterprise_groups_enterprises", "enterprise_groups", name: "enterprise_groups_enterprises_enterprise_group_id_fk" - add_foreign_key "enterprise_groups_enterprises", "enterprises", name: "enterprise_groups_enterprises_enterprise_id_fk" - add_foreign_key "enterprise_roles", "enterprises", name: "enterprise_roles_enterprise_id_fk" - add_foreign_key "enterprise_roles", "spree_users", name: "enterprise_roles_user_id_fk", column: "user_id" - add_foreign_key "enterprises", "spree_addresses", name: "enterprises_address_id_fk", column: "address_id" - add_foreign_key "exchange_fees", "enterprise_fees", name: "exchange_fees_enterprise_fee_id_fk" - add_foreign_key "exchange_fees", "exchanges", name: "exchange_fees_exchange_id_fk" - add_foreign_key "exchange_variants", "exchanges", name: "exchange_variants_exchange_id_fk" - add_foreign_key "exchange_variants", "spree_variants", name: "exchange_variants_variant_id_fk", column: "variant_id" - add_foreign_key "exchanges", "order_cycles", name: "exchanges_order_cycle_id_fk" - add_foreign_key "exchanges", "enterprises", name: "exchanges_payment_enterprise_id_fk", column: "payment_enterprise_id" - add_foreign_key "exchanges", "enterprises", name: "exchanges_receiver_id_fk", column: "receiver_id" - add_foreign_key "exchanges", "enterprises", name: "exchanges_sender_id_fk", column: "sender_id" - add_foreign_key "order_cycles", "enterprises", name: "order_cycles_coordinator_id_fk", column: "coordinator_id" - add_foreign_key "product_distributions", "enterprises", name: "product_distributions_distributor_id_fk", column: "distributor_id" - add_foreign_key "product_distributions", "enterprise_fees", name: "product_distributions_enterprise_fee_id_fk" - add_foreign_key "product_distributions", "spree_products", name: "product_distributions_product_id_fk", column: "product_id" - add_foreign_key "spree_addresses", "spree_countries", name: "spree_addresses_country_id_fk", column: "country_id" - add_foreign_key "spree_addresses", "spree_states", name: "spree_addresses_state_id_fk", column: "state_id" - add_foreign_key "spree_inventory_units", "spree_orders", name: "spree_inventory_units_order_id_fk", column: "order_id" - add_foreign_key "spree_inventory_units", "spree_return_authorizations", name: "spree_inventory_units_return_authorization_id_fk", column: "return_authorization_id" - add_foreign_key "spree_inventory_units", "spree_shipments", name: "spree_inventory_units_shipment_id_fk", column: "shipment_id" - add_foreign_key "spree_inventory_units", "spree_variants", name: "spree_inventory_units_variant_id_fk", column: "variant_id" - add_foreign_key "spree_line_items", "spree_orders", name: "spree_line_items_order_id_fk", column: "order_id" - add_foreign_key "spree_line_items", "spree_variants", name: "spree_line_items_variant_id_fk", column: "variant_id" - add_foreign_key "spree_option_types_prototypes", "spree_option_types", name: "spree_option_types_prototypes_option_type_id_fk", column: "option_type_id" - add_foreign_key "spree_option_types_prototypes", "spree_prototypes", name: "spree_option_types_prototypes_prototype_id_fk", column: "prototype_id" - add_foreign_key "spree_option_values", "spree_option_types", name: "spree_option_values_option_type_id_fk", column: "option_type_id" - add_foreign_key "spree_option_values_variants", "spree_option_values", name: "spree_option_values_variants_option_value_id_fk", column: "option_value_id" - add_foreign_key "spree_option_values_variants", "spree_variants", name: "spree_option_values_variants_variant_id_fk", column: "variant_id" - add_foreign_key "spree_orders", "spree_addresses", name: "spree_orders_bill_address_id_fk", column: "bill_address_id" - add_foreign_key "spree_orders", "carts", name: "spree_orders_cart_id_fk" - add_foreign_key "spree_orders", "enterprises", name: "spree_orders_distributor_id_fk", column: "distributor_id" - add_foreign_key "spree_orders", "order_cycles", name: "spree_orders_order_cycle_id_fk" - add_foreign_key "spree_orders", "spree_addresses", name: "spree_orders_ship_address_id_fk", column: "ship_address_id" - #add_foreign_key "spree_orders", "spree_shipping_methods", name: "spree_orders_shipping_method_id_fk", column: "shipping_method_id" - add_foreign_key "spree_orders", "spree_users", name: "spree_orders_user_id_fk", column: "user_id" - add_foreign_key "spree_payments", "spree_orders", name: "spree_payments_order_id_fk", column: "order_id" - add_foreign_key "spree_payments", "spree_payment_methods", name: "spree_payments_payment_method_id_fk", column: "payment_method_id" - #add_foreign_key "spree_payments", "spree_payments", name: "spree_payments_source_id_fk", column: "source_id" - add_foreign_key "spree_prices", "spree_variants", name: "spree_prices_variant_id_fk", column: "variant_id" - add_foreign_key "spree_product_option_types", "spree_option_types", name: "spree_product_option_types_option_type_id_fk", column: "option_type_id" - add_foreign_key "spree_product_option_types", "spree_products", name: "spree_product_option_types_product_id_fk", column: "product_id" - add_foreign_key "spree_product_properties", "spree_products", name: "spree_product_properties_product_id_fk", column: "product_id" - add_foreign_key "spree_product_properties", "spree_properties", name: "spree_product_properties_property_id_fk", column: "property_id" - add_foreign_key "spree_products_promotion_rules", "spree_products", name: "spree_products_promotion_rules_product_id_fk", column: "product_id" - add_foreign_key "spree_products_promotion_rules", "spree_promotion_rules", name: "spree_products_promotion_rules_promotion_rule_id_fk", column: "promotion_rule_id" - add_foreign_key "spree_products", "spree_shipping_categories", name: "spree_products_shipping_category_id_fk", column: "shipping_category_id" - add_foreign_key "spree_products", "enterprises", name: "spree_products_supplier_id_fk", column: "supplier_id" - add_foreign_key "spree_products", "spree_tax_categories", name: "spree_products_tax_category_id_fk", column: "tax_category_id" - add_foreign_key "spree_products_taxons", "spree_products", name: "spree_products_taxons_product_id_fk", column: "product_id", dependent: :delete - add_foreign_key "spree_products_taxons", "spree_taxons", name: "spree_products_taxons_taxon_id_fk", column: "taxon_id", dependent: :delete - add_foreign_key "spree_promotion_action_line_items", "spree_promotion_actions", name: "spree_promotion_action_line_items_promotion_action_id_fk", column: "promotion_action_id" - add_foreign_key "spree_promotion_action_line_items", "spree_variants", name: "spree_promotion_action_line_items_variant_id_fk", column: "variant_id" - add_foreign_key "spree_promotion_actions", "spree_activators", name: "spree_promotion_actions_activator_id_fk", column: "activator_id" - add_foreign_key "spree_promotion_rules", "spree_activators", name: "spree_promotion_rules_activator_id_fk", column: "activator_id" - add_foreign_key "spree_properties_prototypes", "spree_properties", name: "spree_properties_prototypes_property_id_fk", column: "property_id" - add_foreign_key "spree_properties_prototypes", "spree_prototypes", name: "spree_properties_prototypes_prototype_id_fk", column: "prototype_id" - add_foreign_key "spree_return_authorizations", "spree_orders", name: "spree_return_authorizations_order_id_fk", column: "order_id" - add_foreign_key "spree_roles_users", "spree_roles", name: "spree_roles_users_role_id_fk", column: "role_id" - add_foreign_key "spree_roles_users", "spree_users", name: "spree_roles_users_user_id_fk", column: "user_id" - add_foreign_key "spree_shipments", "spree_addresses", name: "spree_shipments_address_id_fk", column: "address_id" - add_foreign_key "spree_shipments", "spree_orders", name: "spree_shipments_order_id_fk", column: "order_id" - #add_foreign_key "spree_shipments", "spree_shipping_methods", name: "spree_shipments_shipping_method_id_fk", column: "shipping_method_id" - add_foreign_key "spree_shipping_methods", "spree_shipping_categories", name: "spree_shipping_methods_shipping_category_id_fk", column: "shipping_category_id" - add_foreign_key "spree_shipping_methods", "spree_zones", name: "spree_shipping_methods_zone_id_fk", column: "zone_id" - add_foreign_key "spree_state_changes", "spree_users", name: "spree_state_changes_user_id_fk", column: "user_id" - add_foreign_key "spree_states", "spree_countries", name: "spree_states_country_id_fk", column: "country_id" - add_foreign_key "spree_tax_rates", "spree_tax_categories", name: "spree_tax_rates_tax_category_id_fk", column: "tax_category_id" - add_foreign_key "spree_tax_rates", "spree_zones", name: "spree_tax_rates_zone_id_fk", column: "zone_id" - add_foreign_key "spree_taxons", "spree_taxons", name: "spree_taxons_parent_id_fk", column: "parent_id" - add_foreign_key "spree_taxons", "spree_taxonomies", name: "spree_taxons_taxonomy_id_fk", column: "taxonomy_id" - add_foreign_key "spree_users", "spree_addresses", name: "spree_users_bill_address_id_fk", column: "bill_address_id" - add_foreign_key "spree_users", "spree_addresses", name: "spree_users_ship_address_id_fk", column: "ship_address_id" - add_foreign_key "spree_variants", "spree_products", name: "spree_variants_product_id_fk", column: "product_id" - add_foreign_key "spree_zone_members", "spree_zones", name: "spree_zone_members_zone_id_fk", column: "zone_id" - add_foreign_key "suburbs", "spree_states", name: "suburbs_state_id_fk", column: "state_id" - end -end diff --git a/db/migrate/20140425055718_add_active_flag_to_enterprises.rb b/db/migrate/20140425055718_add_active_flag_to_enterprises.rb deleted file mode 100644 index b0bcc2f3ed..0000000000 --- a/db/migrate/20140425055718_add_active_flag_to_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddActiveFlagToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :active, :boolean, default: true - end -end diff --git a/db/migrate/20140430020639_rename_active_to_visible_on_enterprises.rb b/db/migrate/20140430020639_rename_active_to_visible_on_enterprises.rb deleted file mode 100644 index 99b011304a..0000000000 --- a/db/migrate/20140430020639_rename_active_to_visible_on_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameActiveToVisibleOnEnterprises < ActiveRecord::Migration - def change - rename_column :enterprises, :active, :visible - end -end diff --git a/db/migrate/20140514044959_create_enterprise_relationships.rb b/db/migrate/20140514044959_create_enterprise_relationships.rb deleted file mode 100644 index 0467d6e560..0000000000 --- a/db/migrate/20140514044959_create_enterprise_relationships.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreateEnterpriseRelationships < ActiveRecord::Migration - def change - create_table :enterprise_relationships do |t| - t.integer :parent_id - t.integer :child_id - end - - add_index :enterprise_relationships, :parent_id - add_index :enterprise_relationships, :child_id - - add_index :enterprise_relationships, [:parent_id, :child_id], unique: true - - add_foreign_key :enterprise_relationships, :enterprises, column: :parent_id - add_foreign_key :enterprise_relationships, :enterprises, column: :child_id - end -end diff --git a/db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb b/db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb deleted file mode 100644 index bd67cb92f0..0000000000 --- a/db/migrate/20140516042552_add_attachment_promo_image_to_enterprise_group.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddAttachmentPromoImageToEnterpriseGroup < ActiveRecord::Migration - def self.up - add_column :enterprise_groups, :promo_image_file_name, :string - add_column :enterprise_groups, :promo_image_content_type, :string - add_column :enterprise_groups, :promo_image_file_size, :integer - add_column :enterprise_groups, :promo_image_updated_at, :datetime - end - - def self.down - remove_column :enterprise_groups, :promo_image_file_name - remove_column :enterprise_groups, :promo_image_content_type - remove_column :enterprise_groups, :promo_image_file_size - remove_column :enterprise_groups, :promo_image_updated_at - end -end diff --git a/db/migrate/20140516044750_add_fields_to_groups.rb b/db/migrate/20140516044750_add_fields_to_groups.rb deleted file mode 100644 index a50ef1db14..0000000000 --- a/db/migrate/20140516044750_add_fields_to_groups.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddFieldsToGroups < ActiveRecord::Migration - def change - add_column :enterprise_groups, :description, :text - add_column :enterprise_groups, :long_description, :text - end -end diff --git a/db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb b/db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb deleted file mode 100644 index 525bccb63e..0000000000 --- a/db/migrate/20140516045323_add_attachment_logo_to_enterprise_group.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddAttachmentLogoToEnterpriseGroup < ActiveRecord::Migration - def self.up - add_column :enterprise_groups, :logo_file_name, :string - add_column :enterprise_groups, :logo_content_type, :string - add_column :enterprise_groups, :logo_file_size, :integer - add_column :enterprise_groups, :logo_updated_at, :datetime - end - - def self.down - remove_column :enterprise_groups, :logo_file_name - remove_column :enterprise_groups, :logo_content_type - remove_column :enterprise_groups, :logo_file_size - remove_column :enterprise_groups, :logo_updated_at - end -end diff --git a/db/migrate/20140522015012_add_social_media_to_enterprises.rb b/db/migrate/20140522015012_add_social_media_to_enterprises.rb deleted file mode 100644 index 9ca88cf0dc..0000000000 --- a/db/migrate/20140522015012_add_social_media_to_enterprises.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddSocialMediaToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :facebook, :string - add_column :enterprises, :instagram, :string - add_column :enterprises, :linkedin, :string - end -end diff --git a/db/migrate/20140522044009_add_primary_taxon_to_products.rb b/db/migrate/20140522044009_add_primary_taxon_to_products.rb deleted file mode 100644 index d985d7f1b8..0000000000 --- a/db/migrate/20140522044009_add_primary_taxon_to_products.rb +++ /dev/null @@ -1,20 +0,0 @@ -class AddPrimaryTaxonToProducts < ActiveRecord::Migration - def up - add_column :spree_products, :primary_taxon_id, :integer - - add_index :spree_products, :primary_taxon_id - add_foreign_key :spree_products, :spree_taxons, column: :primary_taxon_id - - Spree::Product.all.each do |p| - primary_taxon = p.taxons.where('spree_taxons.name != ?', 'specials').first - first_taxon = Spree::Taxonomy.find_by_name('Products').andand.root || Spree::Taxon.first - p.update_column :primary_taxon_id, (primary_taxon || first_taxon) - end - - change_column :spree_products, :primary_taxon_id, :integer, null: false - end - - def down - remove_column :spree_products, :primary_taxon_id - end -end diff --git a/db/migrate/20140604051248_add_display_name_and_display_as_to_spree_variants.rb b/db/migrate/20140604051248_add_display_name_and_display_as_to_spree_variants.rb deleted file mode 100644 index a2c1080b31..0000000000 --- a/db/migrate/20140604051248_add_display_name_and_display_as_to_spree_variants.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddDisplayNameAndDisplayAsToSpreeVariants < ActiveRecord::Migration - def change - add_column :spree_variants, :display_name, :string - add_column :spree_variants, :display_as, :string - end -end diff --git a/db/migrate/20140612020206_remove_deleted_variants_from_order_cycles.rb b/db/migrate/20140612020206_remove_deleted_variants_from_order_cycles.rb deleted file mode 100644 index cb03abe09a..0000000000 --- a/db/migrate/20140612020206_remove_deleted_variants_from_order_cycles.rb +++ /dev/null @@ -1,10 +0,0 @@ -class RemoveDeletedVariantsFromOrderCycles < ActiveRecord::Migration - def up - evs = ExchangeVariant.joins(:variant).where('spree_variants.deleted_at IS NOT NULL') - say "Removing #{evs.count} deleted variants from order cycles..." - evs.destroy_all - end - - def down - end -end diff --git a/db/migrate/20140613004344_create_producer_properties.rb b/db/migrate/20140613004344_create_producer_properties.rb deleted file mode 100644 index b45b3bed5d..0000000000 --- a/db/migrate/20140613004344_create_producer_properties.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateProducerProperties < ActiveRecord::Migration - def change - create_table :producer_properties do |t| - t.string :value - t.references :producer - t.references :property - t.integer :position - t.timestamps - end - - add_index :producer_properties, :producer_id - add_index :producer_properties, :property_id - add_index :producer_properties, :position - - add_foreign_key :producer_properties, :enterprises, column: :producer_id - add_foreign_key :producer_properties, :spree_properties, column: :property_id - end -end diff --git a/db/migrate/20140621230121_change_suburb_postcode_to_string.rb b/db/migrate/20140621230121_change_suburb_postcode_to_string.rb deleted file mode 100644 index 4756c71c59..0000000000 --- a/db/migrate/20140621230121_change_suburb_postcode_to_string.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ChangeSuburbPostcodeToString < ActiveRecord::Migration - def up - change_column :suburbs, :postcode, :string - end - - def down - change_column :suburbs, :postcode, 'integer USING (postcode::integer)' - end -end diff --git a/db/migrate/20140702053145_add_fields_to_distributors_shipping_methods.rb b/db/migrate/20140702053145_add_fields_to_distributors_shipping_methods.rb deleted file mode 100644 index 75fa60e7b7..0000000000 --- a/db/migrate/20140702053145_add_fields_to_distributors_shipping_methods.rb +++ /dev/null @@ -1,23 +0,0 @@ -class AddFieldsToDistributorsShippingMethods < ActiveRecord::Migration - class DistributorShippingMethod < ActiveRecord::Base - self.table_name = "distributors_shipping_methods" - end - - def up - add_column :distributors_shipping_methods, :id, :primary_key - add_column :distributors_shipping_methods, :created_at, :datetime - add_column :distributors_shipping_methods, :updated_at, :datetime - - DistributorShippingMethod.reset_column_information - DistributorShippingMethod.update_all created_at: Time.zone.now, updated_at: Time.zone.now - - change_column :distributors_shipping_methods, :created_at, :datetime, null: false - change_column :distributors_shipping_methods, :updated_at, :datetime, null: false - end - - def down - remove_column :distributors_shipping_methods, :id - remove_column :distributors_shipping_methods, :created_at - remove_column :distributors_shipping_methods, :updated_at - end -end diff --git a/db/migrate/20140716051214_drop_landing_page_images.rb b/db/migrate/20140716051214_drop_landing_page_images.rb deleted file mode 100644 index d7324ed94b..0000000000 --- a/db/migrate/20140716051214_drop_landing_page_images.rb +++ /dev/null @@ -1,16 +0,0 @@ -class DropLandingPageImages < ActiveRecord::Migration - def up - drop_table :landing_page_images - end - - def down - create_table :landing_page_images do |t| - t.string :photo_file_name - t.string :photo_content_type - t.integer :photo_file_size - t.datetime :photo_updated_at - - t.timestamps - end - end -end diff --git a/db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb deleted file mode 100644 index 1f30b68bff..0000000000 --- a/db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20130723042610) -class CreateSpreePaypalExpressCheckouts < ActiveRecord::Migration - def change - create_table :spree_paypal_express_checkouts do |t| - t.string :token - t.string :payer_id - end - end -end diff --git a/db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb deleted file mode 100644 index 3603e8887a..0000000000 --- a/db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20130808030836) -class AddTransactionIdToSpreePaypalExpressCheckouts < ActiveRecord::Migration - def change - add_column :spree_paypal_express_checkouts, :transaction_id, :string - add_index :spree_paypal_express_checkouts, :transaction_id - end -end diff --git a/db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb deleted file mode 100644 index 56a35ae307..0000000000 --- a/db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20130809013846) -class AddStateToSpreePaypalExpressCheckouts < ActiveRecord::Migration - def change - add_column :spree_paypal_express_checkouts, :state, :string, :default => "complete" - end -end diff --git a/db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb deleted file mode 100644 index eb2d10e7f7..0000000000 --- a/db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20130809014319) -class AddRefundedFieldsToSpreePaypalExpressCheckouts < ActiveRecord::Migration - def change - add_column :spree_paypal_express_checkouts, :refund_transaction_id, :string - add_column :spree_paypal_express_checkouts, :refunded_at, :datetime - add_column :spree_paypal_express_checkouts, :refund_type, :string - add_column :spree_paypal_express_checkouts, :created_at, :datetime - end -end diff --git a/db/migrate/20140723023713_switch_paypal_methods.rb b/db/migrate/20140723023713_switch_paypal_methods.rb deleted file mode 100644 index 5b5509cb94..0000000000 --- a/db/migrate/20140723023713_switch_paypal_methods.rb +++ /dev/null @@ -1,13 +0,0 @@ -class SwitchPaypalMethods < ActiveRecord::Migration - def up - Spree::PaymentMethod.connection.execute < 1 - e_limit = 100 - e_limit = 1000 if u.admin? - u.update_column :enterprise_limit, e_limit - end - end - end - - def down - remove_column :spree_users, :enterprise_limit - end -end diff --git a/db/migrate/20140927005000_add_dummy_for_missing_emails.rb b/db/migrate/20140927005000_add_dummy_for_missing_emails.rb deleted file mode 100644 index 08f638e2a3..0000000000 --- a/db/migrate/20140927005000_add_dummy_for_missing_emails.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddDummyForMissingEmails < ActiveRecord::Migration - def up - Enterprise.all.each do |enterprise| - enterprise.update_column(:email, "missing@example.com") if enterprise.read_attribute(:email).blank? - end - end -end diff --git a/db/migrate/20140927005043_enterprise_config_refactor.rb b/db/migrate/20140927005043_enterprise_config_refactor.rb deleted file mode 100644 index 6b51ac6e50..0000000000 --- a/db/migrate/20140927005043_enterprise_config_refactor.rb +++ /dev/null @@ -1,57 +0,0 @@ -class EnterpriseConfigRefactor < ActiveRecord::Migration - class Enterprise < ActiveRecord::Base - self.inheritance_column = nil - end - - def up - add_column :enterprises, :sells, :string, null: false, default: 'none' - add_index :enterprises, :sells - add_index :enterprises, [:is_primary_producer, :sells] - - Enterprise.reset_column_information - - Enterprise.all.each do |enterprise| - enterprise.update_attributes!({:sells => sells_what?(enterprise)}) - end - - remove_column :enterprises, :type - remove_column :enterprises, :is_distributor - end - - def down - # This process is lossy. Producer profiles wont exist. - add_column :enterprises, :type, :string, null: false, default: 'profile' - add_column :enterprises, :is_distributor, :boolean - - Enterprise.reset_column_information - - Enterprise.all.each do |enterprise| - enterprise.update_attributes!({ - :type => type?(enterprise), - :is_distributor => distributes?(enterprise) - }) - end - - remove_column :enterprises, :sells - end - - def sells_what?(enterprise) - is_distributor = enterprise.read_attribute(:is_distributor) - is_primary_producer = enterprise.read_attribute(:is_primary_producer) - type = enterprise.read_attribute(:type) - return "own" if type == "single" && (is_distributor || is_primary_producer) - return "none" if !is_distributor || type == "profile" - return "any" - end - - def distributes?(enterprise) - enterprise.read_attribute(:sells) != "none" - end - - def type?(enterprise) - sells = enterprise.read_attribute(:sells) - return "profile" if sells == "none" - return "single" if sells == "own" - return "full" - end -end diff --git a/db/migrate/20141003060622_add_standard_variant_to_products.rb b/db/migrate/20141003060622_add_standard_variant_to_products.rb deleted file mode 100644 index 5242f86686..0000000000 --- a/db/migrate/20141003060622_add_standard_variant_to_products.rb +++ /dev/null @@ -1,63 +0,0 @@ -class AddStandardVariantToProducts < ActiveRecord::Migration - def up - # Make sure that all products have a variant_unit - Spree::Product.where("variant_unit IS NULL OR variant_unit = ''").update_all(variant_unit: "items", variant_unit_name: "each") - - # Find products without any standard variants - products_with_only_master = Spree::Product.includes(:variants).where('spree_variants.id IS NULL').select('DISTINCT spree_products.*') - - products_with_only_master.each do |product| - # Add a unit_value to the master variant if it doesn't have one - if product.unit_value.blank? - if product.variant_unit == "weight" && match = product.unit_description.andand.match(/^(\d+(\.\d*)?)(k?g) ?(.*)$/) - scale = (match[3] == "kg" ? 1000 : 1) - product.unit_value = (match[1].to_i*scale) - product.unit_description = match[4] - product.save! - else - unless product.variant_unit == "items" && product.unit_description.present? - product.unit_value = 1 - product.save! - end - end - end - - # Run the callback to add a copy of the master variant as a standard variant - product.send(:ensure_standard_variant) - - existing_master = product.master - new_variant = product.variants.first - - # Replace any relevant references to the master variant with the new standard variant - - # Inventory Units - # Strategy: do nothing to inventory units pertaining to existing_master, - # new inventory units will be created with reference to new_variant - - # Line Items - # Strategy: do nothing to line items pertaining to existing_master, - # new line items will be created with reference to new_variant - - # Option Values - # Strategy: add all option values on existing_master to new_variant, and keep on existing_master - option_values = existing_master.option_values - option_values.each do |option_value| - variant_ids = option_value.variant_ids - variant_ids << new_variant.id - option_value.update_attributes(variant_ids: variant_ids) - end - - # Prices - # Strategy: duplicate all prices on existing_master and assign them to new_variant - existing_prices = existing_master.prices - existing_prices.each do |price| - new_variant.prices << price.dup - end - - # Exchange Variants - # Strategy: Replace all references to existing master in exchanges with new_variant - exchange_variants = ExchangeVariant.where(variant_id: existing_master.id) - exchange_variants.update_all(variant_id: new_variant.id) - end - end -end diff --git a/db/migrate/20141010043405_add_confirmable_to_enterprise.rb b/db/migrate/20141010043405_add_confirmable_to_enterprise.rb deleted file mode 100644 index 9c29bd5f2c..0000000000 --- a/db/migrate/20141010043405_add_confirmable_to_enterprise.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddConfirmableToEnterprise < ActiveRecord::Migration - def up - add_column :enterprises, :confirmation_token, :string - add_column :enterprises, :confirmed_at, :datetime - add_column :enterprises, :confirmation_sent_at, :datetime - add_column :enterprises, :unconfirmed_email, :string - add_index :enterprises, :confirmation_token, :unique => true - - # Existing enterprises are assumed to be confirmed - Enterprise.update_all(:confirmed_at => Time.zone.now) - end - - def down - remove_columns :enterprises, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email - end -end diff --git a/db/migrate/20141022050659_add_shop_trial_start_date_to_enterprises.rb b/db/migrate/20141022050659_add_shop_trial_start_date_to_enterprises.rb deleted file mode 100644 index c9680f4e40..0000000000 --- a/db/migrate/20141022050659_add_shop_trial_start_date_to_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddShopTrialStartDateToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :shop_trial_start_date, :datetime, default: nil - end -end diff --git a/db/migrate/20141023050324_add_producer_profile_only_to_enterprises.rb b/db/migrate/20141023050324_add_producer_profile_only_to_enterprises.rb deleted file mode 100644 index fb73d123f8..0000000000 --- a/db/migrate/20141023050324_add_producer_profile_only_to_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddProducerProfileOnlyToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :producer_profile_only, :boolean, default: false - end -end diff --git a/db/migrate/20141113053004_create_variant_overrides.rb b/db/migrate/20141113053004_create_variant_overrides.rb deleted file mode 100644 index ae3746f828..0000000000 --- a/db/migrate/20141113053004_create_variant_overrides.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateVariantOverrides < ActiveRecord::Migration - def change - create_table :variant_overrides do |t| - t.references :variant - t.references :hub - t.decimal :price, precision: 8, scale: 2 - t.integer :count_on_hand - end - - add_foreign_key :variant_overrides, :spree_variants, column: :variant_id - add_foreign_key :variant_overrides, :enterprises, column: :hub_id - - add_index :variant_overrides, [:variant_id, :hub_id] - end -end diff --git a/db/migrate/20141210233407_add_not_null_to_variant_override_relations.rb b/db/migrate/20141210233407_add_not_null_to_variant_override_relations.rb deleted file mode 100644 index b2f50167c9..0000000000 --- a/db/migrate/20141210233407_add_not_null_to_variant_override_relations.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddNotNullToVariantOverrideRelations < ActiveRecord::Migration - def up - change_column :variant_overrides, :hub_id, :integer, null: false - change_column :variant_overrides, :variant_id, :integer, null: false - end - - def down - change_column :variant_overrides, :hub_id, :integer, null: true - change_column :variant_overrides, :variant_id, :integer, null: true - end -end diff --git a/db/migrate/20141219034321_add_permalink_to_enterprises.rb b/db/migrate/20141219034321_add_permalink_to_enterprises.rb deleted file mode 100644 index b912180ba7..0000000000 --- a/db/migrate/20141219034321_add_permalink_to_enterprises.rb +++ /dev/null @@ -1,25 +0,0 @@ -class AddPermalinkToEnterprises < ActiveRecord::Migration - def up - add_column :enterprises, :permalink, :string - - Enterprise.reset_column_information - - Enterprise.all.each do |enterprise| - counter = 1 - permalink = enterprise.name.parameterize - permalink = "my-enterprise-name" if permalink == "" - while Enterprise.find_by_permalink(permalink) do - permalink = enterprise.name.parameterize + counter.to_s - counter += 1 - end - - enterprise.update_column :permalink, permalink - end - - change_column :enterprises, :permalink, :string, null: false - end - - def down - remove_column :enterprises, :permalink - end -end diff --git a/db/migrate/20141229094516_add_receival_time_to_exchange.rb b/db/migrate/20141229094516_add_receival_time_to_exchange.rb deleted file mode 100644 index 06933ed051..0000000000 --- a/db/migrate/20141229094516_add_receival_time_to_exchange.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddReceivalTimeToExchange < ActiveRecord::Migration - def change - add_column :exchanges, :receival_time, :string - add_column :exchanges, :receival_instructions, :string - end -end diff --git a/db/migrate/20150115050935_add_addresses_ref_to_enterprise_groups.rb b/db/migrate/20150115050935_add_addresses_ref_to_enterprise_groups.rb deleted file mode 100644 index 566b35bb88..0000000000 --- a/db/migrate/20150115050935_add_addresses_ref_to_enterprise_groups.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddAddressesRefToEnterpriseGroups < ActiveRecord::Migration - def change - add_column :enterprise_groups, :address_id, :integer - add_foreign_key :enterprise_groups, :spree_addresses, column: "address_id" - end -end diff --git a/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb b/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb deleted file mode 100644 index 3b93ee6386..0000000000 --- a/db/migrate/20150115050936_add_address_instances_to_existing_enterprise_groups.rb +++ /dev/null @@ -1,19 +0,0 @@ -class AddAddressInstancesToExistingEnterpriseGroups < ActiveRecord::Migration - def change - country = Spree::Country.find_by_iso(ENV['DEFAULT_COUNTRY_CODE']) - state = country.states.first - EnterpriseGroup.all.each do |g| - next if g.address.present? - address = Spree::Address.new(firstname: 'unused', lastname: 'unused', address1: 'undefined', city: 'undefined', zipcode: 'undefined', state: state, country: country, phone: 'undefined') - g.address = address - # some groups are invalid, because of a missing description - g.save!(validate: false) - end - end - - def self.down - # we can't know which addresses were already there and which weren't - # and we can't remove addresses as long as they are referenced and - # required by the model - end -end diff --git a/db/migrate/20150121030627_add_web_contact_to_enterprise_groups.rb b/db/migrate/20150121030627_add_web_contact_to_enterprise_groups.rb deleted file mode 100644 index afea2dbeea..0000000000 --- a/db/migrate/20150121030627_add_web_contact_to_enterprise_groups.rb +++ /dev/null @@ -1,10 +0,0 @@ -class AddWebContactToEnterpriseGroups < ActiveRecord::Migration - def change - add_column :enterprise_groups, :email, :string, null: false, default: '' - add_column :enterprise_groups, :website, :string, null: false, default: '' - add_column :enterprise_groups, :facebook, :string, null: false, default: '' - add_column :enterprise_groups, :instagram, :string, null: false, default: '' - add_column :enterprise_groups, :linkedin, :string, null: false, default: '' - add_column :enterprise_groups, :twitter, :string, null: false, default: '' - end -end diff --git a/db/migrate/20150122145607_create_customers.rb b/db/migrate/20150122145607_create_customers.rb deleted file mode 100644 index 12e5a721e8..0000000000 --- a/db/migrate/20150122145607_create_customers.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateCustomers < ActiveRecord::Migration - def change - create_table :customers do |t| - t.string :email, null: false - t.references :enterprise, null: false - t.string :code, null: false - t.references :user - - t.timestamps - end - add_index :customers, [:enterprise_id, :code], unique: true - add_index :customers, :email - add_index :customers, :user_id - - add_foreign_key :customers, :enterprises, column: :enterprise_id - add_foreign_key :customers, :spree_users, column: :user_id - end -end diff --git a/db/migrate/20150202000203_add_owner_to_enterprise_groups.rb b/db/migrate/20150202000203_add_owner_to_enterprise_groups.rb deleted file mode 100644 index f2e46452df..0000000000 --- a/db/migrate/20150202000203_add_owner_to_enterprise_groups.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddOwnerToEnterpriseGroups < ActiveRecord::Migration - def change - add_column :enterprise_groups, :owner_id, :integer - add_foreign_key :enterprise_groups, :spree_users, column: "owner_id" - end -end diff --git a/db/migrate/20150216075336_add_temperature_controlled_to_spree_shipping_categories.rb b/db/migrate/20150216075336_add_temperature_controlled_to_spree_shipping_categories.rb deleted file mode 100644 index 89035fc16f..0000000000 --- a/db/migrate/20150216075336_add_temperature_controlled_to_spree_shipping_categories.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTemperatureControlledToSpreeShippingCategories < ActiveRecord::Migration - def change - add_column :spree_shipping_categories, :temperature_controlled, :boolean, null: false, default: false - end -end diff --git a/db/migrate/20150219021742_add_owner_index_to_enterprise_groups.rb b/db/migrate/20150219021742_add_owner_index_to_enterprise_groups.rb deleted file mode 100644 index 062e9523e6..0000000000 --- a/db/migrate/20150219021742_add_owner_index_to_enterprise_groups.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddOwnerIndexToEnterpriseGroups < ActiveRecord::Migration - def change - add_index :enterprise_groups, :owner_id - end -end diff --git a/db/migrate/20150220035501_add_address_id_index_to_enterprise_groups.rb b/db/migrate/20150220035501_add_address_id_index_to_enterprise_groups.rb deleted file mode 100644 index 32094cbde7..0000000000 --- a/db/migrate/20150220035501_add_address_id_index_to_enterprise_groups.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddAddressIdIndexToEnterpriseGroups < ActiveRecord::Migration - def change - add_index :enterprise_groups, :address_id - end -end diff --git a/db/migrate/20150225111538_add_tax_category_to_enterprise_fee.rb b/db/migrate/20150225111538_add_tax_category_to_enterprise_fee.rb deleted file mode 100644 index 05b5410587..0000000000 --- a/db/migrate/20150225111538_add_tax_category_to_enterprise_fee.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddTaxCategoryToEnterpriseFee < ActiveRecord::Migration - def change - add_column :enterprise_fees, :tax_category_id, :integer - add_foreign_key :enterprise_fees, :spree_tax_categories, column: :tax_category_id - add_index :enterprise_fees, :tax_category_id - end -end diff --git a/db/migrate/20150225232938_add_included_tax_to_adjustments.rb b/db/migrate/20150225232938_add_included_tax_to_adjustments.rb deleted file mode 100644 index f3815dec2a..0000000000 --- a/db/migrate/20150225232938_add_included_tax_to_adjustments.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIncludedTaxToAdjustments < ActiveRecord::Migration - def change - add_column :spree_adjustments, :included_tax, :decimal, precision: 10, scale: 2, null: false, default: 0 - end -end diff --git a/db/migrate/20150305004846_add_weight_to_line_items.rb b/db/migrate/20150305004846_add_weight_to_line_items.rb deleted file mode 100644 index a4df1a12f0..0000000000 --- a/db/migrate/20150305004846_add_weight_to_line_items.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddWeightToLineItems < ActiveRecord::Migration - def change - add_column :spree_line_items, :unit_value, :decimal, :precision => 8, :scale => 2 - end -end diff --git a/db/migrate/20150407234739_add_charges_sales_tax_to_enterprises.rb b/db/migrate/20150407234739_add_charges_sales_tax_to_enterprises.rb deleted file mode 100644 index ba8dfa7a08..0000000000 --- a/db/migrate/20150407234739_add_charges_sales_tax_to_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddChargesSalesTaxToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :charges_sales_tax, :boolean, null: false, default: false - end -end diff --git a/db/migrate/20150410043302_create_delayed_jobs.rb b/db/migrate/20150410043302_create_delayed_jobs.rb deleted file mode 100644 index f7de70bdc5..0000000000 --- a/db/migrate/20150410043302_create_delayed_jobs.rb +++ /dev/null @@ -1,22 +0,0 @@ -class CreateDelayedJobs < ActiveRecord::Migration - def self.up - create_table :delayed_jobs, :force => true do |table| - table.integer :priority, :default => 0, :null => false # Allows some jobs to jump to the front of the queue - table.integer :attempts, :default => 0, :null => false # Provides for retries, but still fail eventually. - table.text :handler, :null => false # YAML-encoded string of the object that will do work - table.text :last_error # reason for last failure (See Note below) - table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. - table.datetime :locked_at # Set when a client is working on this object - table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) - table.string :locked_by # Who is working on this object (if locked) - table.string :queue # The name of the queue this job is in - table.timestamps - end - - add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority' - end - - def self.down - drop_table :delayed_jobs - end -end diff --git a/db/migrate/20150422014819_add_inherits_properties_to_product.rb b/db/migrate/20150422014819_add_inherits_properties_to_product.rb deleted file mode 100644 index aba8bbbe45..0000000000 --- a/db/migrate/20150422014819_add_inherits_properties_to_product.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddInheritsPropertiesToProduct < ActiveRecord::Migration - def change - add_column :spree_products, :inherits_properties, :boolean, null: false, default: true - end -end diff --git a/db/migrate/20150424025907_add_default_and_not_null_to_producer_properties_position.rb b/db/migrate/20150424025907_add_default_and_not_null_to_producer_properties_position.rb deleted file mode 100644 index 8c5a2d1f2c..0000000000 --- a/db/migrate/20150424025907_add_default_and_not_null_to_producer_properties_position.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddDefaultAndNotNullToProducerPropertiesPosition < ActiveRecord::Migration - def change - ProducerProperty.where(position: nil).each do |producer_property| - producer_property.update_attribute(:position, 0) - end - - change_column :producer_properties, :position, :integer, null: false, default: 0 - end -end diff --git a/db/migrate/20150424151117_populate_line_item_unit_value.rb b/db/migrate/20150424151117_populate_line_item_unit_value.rb deleted file mode 100644 index 2122b84472..0000000000 --- a/db/migrate/20150424151117_populate_line_item_unit_value.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PopulateLineItemUnitValue < ActiveRecord::Migration - def up - execute "UPDATE spree_line_items SET unit_value = spree_variants.unit_value FROM spree_variants WHERE spree_line_items.variant_id = spree_variants.id" - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20150508030520_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb b/db/migrate/20150508030520_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb deleted file mode 100644 index 6bbd5594ea..0000000000 --- a/db/migrate/20150508030520_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb +++ /dev/null @@ -1,31 +0,0 @@ -# This migration comes from acts_as_taggable_on_engine (originally 1) -class ActsAsTaggableOnMigration < ActiveRecord::Migration - def self.up - create_table :tags do |t| - t.string :name - end - - create_table :taggings do |t| - t.references :tag - - # You should make sure that the column created is - # long enough to store the required class names. - t.references :taggable, polymorphic: true - t.references :tagger, polymorphic: true - - # Limit is created to prevent MySQL error on index - # length for MyISAM table type: http://bit.ly/vgW2Ql - t.string :context, limit: 128 - - t.datetime :created_at - end - - add_index :taggings, :tag_id - add_index :taggings, [:taggable_id, :taggable_type, :context] - end - - def self.down - drop_table :taggings - drop_table :tags - end -end diff --git a/db/migrate/20150508030521_add_missing_unique_indices.acts_as_taggable_on_engine.rb b/db/migrate/20150508030521_add_missing_unique_indices.acts_as_taggable_on_engine.rb deleted file mode 100644 index 4ca676f6c7..0000000000 --- a/db/migrate/20150508030521_add_missing_unique_indices.acts_as_taggable_on_engine.rb +++ /dev/null @@ -1,20 +0,0 @@ -# This migration comes from acts_as_taggable_on_engine (originally 2) -class AddMissingUniqueIndices < ActiveRecord::Migration - def self.up - add_index :tags, :name, unique: true - - remove_index :taggings, :tag_id - remove_index :taggings, [:taggable_id, :taggable_type, :context] - add_index :taggings, - [:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type], - unique: true, name: 'taggings_idx' - end - - def self.down - remove_index :tags, :name - - remove_index :taggings, name: 'taggings_idx' - add_index :taggings, :tag_id - add_index :taggings, [:taggable_id, :taggable_type, :context] - end -end diff --git a/db/migrate/20150508030522_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb b/db/migrate/20150508030522_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb deleted file mode 100644 index 8edb508078..0000000000 --- a/db/migrate/20150508030522_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +++ /dev/null @@ -1,15 +0,0 @@ -# This migration comes from acts_as_taggable_on_engine (originally 3) -class AddTaggingsCounterCacheToTags < ActiveRecord::Migration - def self.up - add_column :tags, :taggings_count, :integer, default: 0 - - ActsAsTaggableOn::Tag.reset_column_information - ActsAsTaggableOn::Tag.find_each do |tag| - ActsAsTaggableOn::Tag.reset_counters(tag.id, :taggings) - end - end - - def self.down - remove_column :tags, :taggings_count - end -end diff --git a/db/migrate/20150508030523_add_missing_taggable_index.acts_as_taggable_on_engine.rb b/db/migrate/20150508030523_add_missing_taggable_index.acts_as_taggable_on_engine.rb deleted file mode 100644 index 71f2d7f433..0000000000 --- a/db/migrate/20150508030523_add_missing_taggable_index.acts_as_taggable_on_engine.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from acts_as_taggable_on_engine (originally 4) -class AddMissingTaggableIndex < ActiveRecord::Migration - def self.up - add_index :taggings, [:taggable_id, :taggable_type, :context] - end - - def self.down - remove_index :taggings, [:taggable_id, :taggable_type, :context] - end -end diff --git a/db/migrate/20150508030524_change_collation_for_tag_names.acts_as_taggable_on_engine.rb b/db/migrate/20150508030524_change_collation_for_tag_names.acts_as_taggable_on_engine.rb deleted file mode 100644 index bfb06bc7cd..0000000000 --- a/db/migrate/20150508030524_change_collation_for_tag_names.acts_as_taggable_on_engine.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from acts_as_taggable_on_engine (originally 5) -# This migration is added to circumvent issue #623 and have special characters -# work properly -class ChangeCollationForTagNames < ActiveRecord::Migration - def up - if ActsAsTaggableOn::Utils.using_mysql? - execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;") - end - end -end diff --git a/db/migrate/20150508072454_remove_customer_code_not_null_constraint.rb b/db/migrate/20150508072454_remove_customer_code_not_null_constraint.rb deleted file mode 100644 index deeacbc608..0000000000 --- a/db/migrate/20150508072454_remove_customer_code_not_null_constraint.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveCustomerCodeNotNullConstraint < ActiveRecord::Migration - def up - change_column :customers, :code, :string, null: true - end - - def down - change_column :customers, :code, :string, null: false - end -end diff --git a/db/migrate/20150508072938_add_customer_to_orders.rb b/db/migrate/20150508072938_add_customer_to_orders.rb deleted file mode 100644 index 79d69baf49..0000000000 --- a/db/migrate/20150508072938_add_customer_to_orders.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddCustomerToOrders < ActiveRecord::Migration - def change - add_column :spree_orders, :customer_id, :integer - add_index :spree_orders, :customer_id - add_foreign_key :spree_orders, :customers, column: :customer_id - - Spree::Order.where("spree_orders.email IS NOT NULL AND distributor_id IS NOT NULL AND customer_id IS NULL").each do |order| - customer = Customer.find_by_email_and_enterprise_id(order.email, order.distributor_id) - unless customer.present? - user = Spree::User.find_by_email(order.email) - customer = Customer.create!(email: order.email, enterprise_id: order.distributor_id, user_id: user.andand.id ) - end - order.update_attribute(:customer, customer) - end - end -end diff --git a/db/migrate/20150527004427_add_permalink_to_groups.rb b/db/migrate/20150527004427_add_permalink_to_groups.rb deleted file mode 100644 index ab6886cff4..0000000000 --- a/db/migrate/20150527004427_add_permalink_to_groups.rb +++ /dev/null @@ -1,26 +0,0 @@ -class AddPermalinkToGroups < ActiveRecord::Migration - def up - add_column :enterprise_groups, :permalink, :string - - EnterpriseGroup.reset_column_information - - EnterpriseGroup.all.each do |group| - counter = 1 - permalink = group.name.parameterize - permalink = "my-group-name" if permalink == "" - while EnterpriseGroup.find_by_permalink(permalink) do - permalink = group.name.parameterize + counter.to_s - counter += 1 - end - - group.update_column :permalink, permalink - end - - change_column :enterprise_groups, :permalink, :string, null: false - add_index :enterprise_groups, :permalink, :unique => true - end - - def down - remove_column :enterprise_groups, :permalink - end -end diff --git a/db/migrate/20150603001843_add_unique_index_to_enterprise_permalink.rb b/db/migrate/20150603001843_add_unique_index_to_enterprise_permalink.rb deleted file mode 100644 index e8841b2c5f..0000000000 --- a/db/migrate/20150603001843_add_unique_index_to_enterprise_permalink.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddUniqueIndexToEnterprisePermalink < ActiveRecord::Migration - def change - duplicates = Enterprise.group(:permalink).having('count(*) > 1').pluck(:permalink) - duplicates.each { |p| resolve_permalink(p) }; - add_index :enterprises, :permalink, :unique => true - end - - def resolve_permalink(permalink) - conflicting = Enterprise.where(permalink: permalink) - while conflicting.size > 1 do - enterprise = conflicting.pop - enterprise.permalink = nil - enterprise.save - end - end -end diff --git a/db/migrate/20150604045725_add_sessions_table.rb b/db/migrate/20150604045725_add_sessions_table.rb deleted file mode 100644 index 4c879564a5..0000000000 --- a/db/migrate/20150604045725_add_sessions_table.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddSessionsTable < ActiveRecord::Migration - def change - create_table :sessions do |t| - t.string :session_id, :null => false - t.text :data - t.timestamps - end - - add_index :sessions, :session_id - add_index :sessions, :updated_at - end -end diff --git a/db/migrate/20150605052516_dependent_delete_adjustment_metadata.rb b/db/migrate/20150605052516_dependent_delete_adjustment_metadata.rb deleted file mode 100644 index ee9d8d4af8..0000000000 --- a/db/migrate/20150605052516_dependent_delete_adjustment_metadata.rb +++ /dev/null @@ -1,11 +0,0 @@ -class DependentDeleteAdjustmentMetadata < ActiveRecord::Migration - def up - remove_foreign_key "adjustment_metadata", name: "adjustment_metadata_adjustment_id_fk" - add_foreign_key "adjustment_metadata", "spree_adjustments", name: "adjustment_metadata_adjustment_id_fk", column: "adjustment_id", dependent: :delete - end - - def down - remove_foreign_key "adjustment_metadata", name: "adjustment_metadata_adjustment_id_fk" - add_foreign_key "adjustment_metadata", "spree_adjustments", name: "adjustment_metadata_adjustment_id_fk", column: "adjustment_id" - end -end diff --git a/db/migrate/20150612045544_make_enterprises_name_unique.rb b/db/migrate/20150612045544_make_enterprises_name_unique.rb deleted file mode 100644 index 5722284d94..0000000000 --- a/db/migrate/20150612045544_make_enterprises_name_unique.rb +++ /dev/null @@ -1,20 +0,0 @@ -class MakeEnterprisesNameUnique < ActiveRecord::Migration - def up - dup_names = Enterprise.group('name').select('name, COUNT(*) AS num_enterprises') - - dup_names.each do |data| - (data.num_enterprises.to_i - 1).times do |i| - e = Enterprise.find_by_name data.name - new_name = "#{data.name}-#{i+1}" - e.update_column :name, new_name - say "Renamed enterprise #{data.name} to #{new_name}" - end - end - - add_index :enterprises, :name, unique: true - end - - def down - remove_index :enterprises, :name - end -end diff --git a/db/migrate/20150619020711_create_versions.rb b/db/migrate/20150619020711_create_versions.rb deleted file mode 100644 index 23be970c66..0000000000 --- a/db/migrate/20150619020711_create_versions.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateVersions < ActiveRecord::Migration - def change - create_table :versions do |t| - t.string :item_type, :null => false - t.integer :item_id, :null => false - t.string :event, :null => false - t.string :whodunnit - t.text :object - t.datetime :created_at - end - add_index :versions, [:item_type, :item_id] - end -end diff --git a/db/migrate/20150619100137_create_bill_items.rb b/db/migrate/20150619100137_create_bill_items.rb deleted file mode 100644 index fec80692b1..0000000000 --- a/db/migrate/20150619100137_create_bill_items.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateBillItems < ActiveRecord::Migration - def change - create_table :bill_items do |t| - t.references :enterprise, nil: false - t.references :owner, nil: false - t.datetime :begins_at, default: nil - t.datetime :ends_at, default: nil - t.string :sells, default: nil - t.boolean :trial, default: false - t.decimal :turnover, default: 0.0 - t.foreign_key :enterprises - t.foreign_key :spree_users, column: :owner_id - end - end -end diff --git a/db/migrate/20150626090338_rename_bill_items_to_billable_periods.rb b/db/migrate/20150626090338_rename_bill_items_to_billable_periods.rb deleted file mode 100644 index caa2fb9a4d..0000000000 --- a/db/migrate/20150626090338_rename_bill_items_to_billable_periods.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RenameBillItemsToBillablePeriods < ActiveRecord::Migration - def up - rename_table :bill_items, :billable_periods - end - - def down - rename_table :billable_periods, :bill_items - end -end diff --git a/db/migrate/20150701034055_add_timestamps_to_billable_periods.rb b/db/migrate/20150701034055_add_timestamps_to_billable_periods.rb deleted file mode 100644 index 6c3ea52356..0000000000 --- a/db/migrate/20150701034055_add_timestamps_to_billable_periods.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddTimestampsToBillablePeriods < ActiveRecord::Migration - def change - change_table(:billable_periods) do |t| - t.datetime :deleted_at, default: nil - t.timestamps - end - end -end diff --git a/db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb b/db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb deleted file mode 100644 index 880a1b8349..0000000000 --- a/db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDefaultStockToVariantOverrides < ActiveRecord::Migration - def change - add_column :variant_overrides, :default_stock, :integer - end -end diff --git a/db/migrate/20150719153136_rename_line_item_unit_value.rb b/db/migrate/20150719153136_rename_line_item_unit_value.rb deleted file mode 100644 index 9dbdce75c5..0000000000 --- a/db/migrate/20150719153136_rename_line_item_unit_value.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameLineItemUnitValue < ActiveRecord::Migration - def change - rename_column :spree_line_items, :unit_value, :final_weight_volume - end -end diff --git a/db/migrate/20150719153732_update_precision_on_line_item_final_weight_volume.rb b/db/migrate/20150719153732_update_precision_on_line_item_final_weight_volume.rb deleted file mode 100644 index c1b3482c0f..0000000000 --- a/db/migrate/20150719153732_update_precision_on_line_item_final_weight_volume.rb +++ /dev/null @@ -1,11 +0,0 @@ -class UpdatePrecisionOnLineItemFinalWeightVolume < ActiveRecord::Migration - def up - change_column :spree_line_items, :final_weight_volume, :decimal, :precision => 10, :scale => 2 - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end - - diff --git a/db/migrate/20150730160010_update_spree_line_item_final_weight_volume.rb b/db/migrate/20150730160010_update_spree_line_item_final_weight_volume.rb deleted file mode 100644 index 4d51a7160b..0000000000 --- a/db/migrate/20150730160010_update_spree_line_item_final_weight_volume.rb +++ /dev/null @@ -1,9 +0,0 @@ -class UpdateSpreeLineItemFinalWeightVolume < ActiveRecord::Migration - def up - execute "UPDATE spree_line_items SET final_weight_volume = final_weight_volume * quantity" - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb b/db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb deleted file mode 100644 index 172cce6588..0000000000 --- a/db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddEnableResetToVariantOverrides < ActiveRecord::Migration - def change - add_column :variant_overrides, :enable_reset, :boolean - end -end diff --git a/db/migrate/20150916012814_create_account_invoices.rb b/db/migrate/20150916012814_create_account_invoices.rb deleted file mode 100644 index 7e92a53593..0000000000 --- a/db/migrate/20150916012814_create_account_invoices.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateAccountInvoices < ActiveRecord::Migration - def change - create_table :account_invoices do |t| - t.references :user, null: false - t.references :order - t.integer :year, null: false - t.integer :month, null: false - t.datetime :issued_at - - t.timestamps - end - add_index :account_invoices, :user_id - add_index :account_invoices, :order_id - - add_foreign_key :account_invoices, :spree_orders, column: :order_id - add_foreign_key :account_invoices, :spree_users, column: :user_id - end -end diff --git a/db/migrate/20150916061809_add_account_invoice_to_billable_periods.rb b/db/migrate/20150916061809_add_account_invoice_to_billable_periods.rb deleted file mode 100644 index ee1d9d5d93..0000000000 --- a/db/migrate/20150916061809_add_account_invoice_to_billable_periods.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddAccountInvoiceToBillablePeriods < ActiveRecord::Migration - def change - add_column :billable_periods, :account_invoice_id, :integer, null: false - add_index :billable_periods, :account_invoice_id - add_foreign_key :billable_periods, :account_invoices, column: :account_invoice_id - end -end diff --git a/db/migrate/20150924054538_add_option_values_line_items_join_table.rb b/db/migrate/20150924054538_add_option_values_line_items_join_table.rb deleted file mode 100644 index 7a51c851ec..0000000000 --- a/db/migrate/20150924054538_add_option_values_line_items_join_table.rb +++ /dev/null @@ -1,14 +0,0 @@ -class AddOptionValuesLineItemsJoinTable < ActiveRecord::Migration - def change - create_table :spree_option_values_line_items, :id => false, :force => true do |t| - t.integer :line_item_id - t.integer :option_value_id - end - - Spree::LineItem.all.each do |line_item| - line_item.update_units - end - - add_index :spree_option_values_line_items, :line_item_id, :name => 'index_option_values_line_items_on_line_item_id' - end -end diff --git a/db/migrate/20151002020537_ensure_address_for_account_invoice_orders.rb b/db/migrate/20151002020537_ensure_address_for_account_invoice_orders.rb deleted file mode 100644 index 6d2c7d45c5..0000000000 --- a/db/migrate/20151002020537_ensure_address_for_account_invoice_orders.rb +++ /dev/null @@ -1,15 +0,0 @@ -class EnsureAddressForAccountInvoiceOrders < ActiveRecord::Migration - def up - AccountInvoice.where('order_id IS NOT NULL').each do |account_invoice| - billable_periods = account_invoice.billable_periods.order(:enterprise_id).reject{ |bp| bp.turnover == 0 } - - if billable_periods.any? - address = billable_periods.first.enterprise.address - account_invoice.order.update_attributes(bill_address: address, ship_address: address) - end - end - end - - def down - end -end diff --git a/db/migrate/20151125051510_combine_exchange_receival_time_receival_instructions.rb b/db/migrate/20151125051510_combine_exchange_receival_time_receival_instructions.rb deleted file mode 100644 index 434a2053ab..0000000000 --- a/db/migrate/20151125051510_combine_exchange_receival_time_receival_instructions.rb +++ /dev/null @@ -1,9 +0,0 @@ -class CombineExchangeReceivalTimeReceivalInstructions < ActiveRecord::Migration - def up - remove_column :exchanges, :receival_time - end - - def down - add_column :exchanges, :receival_time, :string - end -end diff --git a/db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb b/db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb deleted file mode 100644 index 9c47bfbc27..0000000000 --- a/db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddOnDemandAndSkuToVariantOverrides < ActiveRecord::Migration - def change - add_column :variant_overrides, :sku, :string, :default => nil, :after => :hub_id - add_column :variant_overrides, :on_demand, :boolean, :default => nil, :after => :count_on_hand - end -end diff --git a/db/migrate/20151128185900_rename_enable_reset_to_resettable.rb b/db/migrate/20151128185900_rename_enable_reset_to_resettable.rb deleted file mode 100644 index 461e2efe25..0000000000 --- a/db/migrate/20151128185900_rename_enable_reset_to_resettable.rb +++ /dev/null @@ -1,3 +0,0 @@ -class RenameEnableResetToResettable < ActiveRecord::Migration - rename_column :variant_overrides, :enable_reset, :resettable -end diff --git a/db/migrate/20160114001844_create_inventory_items.rb b/db/migrate/20160114001844_create_inventory_items.rb deleted file mode 100644 index 2ca54dce4d..0000000000 --- a/db/migrate/20160114001844_create_inventory_items.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateInventoryItems < ActiveRecord::Migration - def change - create_table :inventory_items do |t| - t.references :enterprise, null: false, index: true - t.references :variant, null: false, index: true - t.boolean :visible, default: true, null: false - - t.timestamps - end - - add_index "inventory_items", [:enterprise_id, :variant_id], unique: true - end -end diff --git a/db/migrate/20160116024333_create_column_preferences.rb b/db/migrate/20160116024333_create_column_preferences.rb deleted file mode 100644 index e38c51d858..0000000000 --- a/db/migrate/20160116024333_create_column_preferences.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateColumnPreferences < ActiveRecord::Migration - def change - create_table :column_preferences do |t| - t.references :user, null: false, index: true - t.string :action_name, null: false, index: true - t.string :column_name, null: false - t.boolean :visible, null: false - - t.timestamps - end - add_index :column_preferences, [:user_id, :action_name, :column_name], unique: true, name: 'index_column_prefs_on_user_id_and_action_name_and_column_name' - end -end diff --git a/db/migrate/20160204013914_add_id_to_coordinator_fees.rb b/db/migrate/20160204013914_add_id_to_coordinator_fees.rb deleted file mode 100644 index 74326a6006..0000000000 --- a/db/migrate/20160204013914_add_id_to_coordinator_fees.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIdToCoordinatorFees < ActiveRecord::Migration - def change - add_column :coordinator_fees, :id, :primary_key - end -end diff --git a/db/migrate/20160204031816_add_inherits_tax_category_to_enterprise_fees.rb b/db/migrate/20160204031816_add_inherits_tax_category_to_enterprise_fees.rb deleted file mode 100644 index 49751cc479..0000000000 --- a/db/migrate/20160204031816_add_inherits_tax_category_to_enterprise_fees.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddInheritsTaxCategoryToEnterpriseFees < ActiveRecord::Migration - def change - add_column :enterprise_fees, :inherits_tax_category, :boolean, null: false, default: false - end -end diff --git a/db/migrate/20160205044930_add_email_address_to_enterprises.rb b/db/migrate/20160205044930_add_email_address_to_enterprises.rb deleted file mode 100644 index b1047fe4b8..0000000000 --- a/db/migrate/20160205044930_add_email_address_to_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddEmailAddressToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :email_address, :string - end -end diff --git a/db/migrate/20160212092908_set_enterprise_email_address.rb b/db/migrate/20160212092908_set_enterprise_email_address.rb deleted file mode 100644 index a43591624a..0000000000 --- a/db/migrate/20160212092908_set_enterprise_email_address.rb +++ /dev/null @@ -1,8 +0,0 @@ -class SetEnterpriseEmailAddress < ActiveRecord::Migration - def up - Enterprise.all.each do |enterprise| - enterprise.email_address = enterprise.email - enterprise.save - end - end -end diff --git a/db/migrate/20160218235221_populate_inventories.rb b/db/migrate/20160218235221_populate_inventories.rb deleted file mode 100644 index 2b9d1be8b6..0000000000 --- a/db/migrate/20160218235221_populate_inventories.rb +++ /dev/null @@ -1,22 +0,0 @@ -class PopulateInventories < ActiveRecord::Migration - def up - # If hubs are actively using overrides, populate their inventories with all variants they have permission to override - # Otherwise leave their inventories empty - - hubs_using_overrides = Enterprise.joins("LEFT OUTER JOIN variant_overrides ON variant_overrides.hub_id = enterprises.id") - .where("variant_overrides.id IS NOT NULL").select("DISTINCT enterprises.*") - - hubs_using_overrides.each do |hub| - overridable_producers = OpenFoodNetwork::Permissions.new(hub.owner).variant_override_producers - - variants = Spree::Variant.where(is_master: false, product_id: Spree::Product.not_deleted.where(supplier_id: overridable_producers)) - - variants.each do |variant| - InventoryItem.create(enterprise: hub, variant: variant, visible: true) - end - end - end - - def down - end -end diff --git a/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb b/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb deleted file mode 100644 index b56a4a8a93..0000000000 --- a/db/migrate/20160224034034_grant_explicit_variant_override_permissions.rb +++ /dev/null @@ -1,30 +0,0 @@ -class GrantExplicitVariantOverridePermissions < ActiveRecord::Migration - def up - hubs = Enterprise.is_distributor - - begin - EnterpriseRelationship.skip_callback :save, :after, :apply_variant_override_permissions - - hubs.each do |hub| - next if hub.owner.admin? - explicitly_granting_producer_ids = hub.relationships_as_child - .with_permission(:create_variant_overrides).map(&:parent_id) - - managed_producer_ids = Enterprise.managed_by(hub.owner).is_primary_producer.pluck(:id) - implicitly_granting_producer_ids = managed_producer_ids - explicitly_granting_producer_ids - [hub.id] - - # create explicit VO permissions for producers currently granting implicit permission - Enterprise.where(id: implicitly_granting_producer_ids).each do |producer| - relationship = producer.relationships_as_parent.find_or_initialize_by_child_id(hub.id) - permission = relationship.permissions.find_or_initialize_by_name(:create_variant_overrides) - relationship.save! unless permission.persisted? - end - end - ensure - EnterpriseRelationship.set_callback :save, :after, :apply_variant_override_permissions - end - end - - def down - end -end diff --git a/db/migrate/20160224230143_add_permission_revoked_at_to_variant_overrides.rb b/db/migrate/20160224230143_add_permission_revoked_at_to_variant_overrides.rb deleted file mode 100644 index afa58ebe26..0000000000 --- a/db/migrate/20160224230143_add_permission_revoked_at_to_variant_overrides.rb +++ /dev/null @@ -1,21 +0,0 @@ -class AddPermissionRevokedAtToVariantOverrides < ActiveRecord::Migration - def up - add_column :variant_overrides, :permission_revoked_at, :datetime, default: nil - - variant_override_hubs = Enterprise.where(id: VariantOverride.all.map(&:hub_id).uniq) - - variant_override_hubs.each do |hub| - permitting_producer_ids = hub.relationships_as_child - .with_permission(:create_variant_overrides).map(&:parent_id) - - variant_overrides_with_revoked_permissions = VariantOverride.for_hubs(hub) - .joins(variant: :product).where("spree_products.supplier_id NOT IN (?)", permitting_producer_ids) - - variant_overrides_with_revoked_permissions.update_all(permission_revoked_at: Time.now) - end - end - - def down - remove_column :variant_overrides, :permission_revoked_at - end -end diff --git a/db/migrate/20160302044850_repopulate_inventories.rb b/db/migrate/20160302044850_repopulate_inventories.rb deleted file mode 100644 index e38628439a..0000000000 --- a/db/migrate/20160302044850_repopulate_inventories.rb +++ /dev/null @@ -1,30 +0,0 @@ -class RepopulateInventories < ActiveRecord::Migration - # Previous version of this migration (20160218235221) relied on Permissions#variant_override_producers - # which was then changed, meaning that an incomplete set of variants were added to inventories of most hubs - # Re-running this now will ensure that all permitted variants (including those allowed by 20160224034034) are - # added to the relevant inventories - - def up - # If hubs are actively using overrides, populate their inventories with all variants they have permission to override - # Otherwise leave their inventories empty - - hubs_using_overrides = Enterprise.joins("LEFT OUTER JOIN variant_overrides ON variant_overrides.hub_id = enterprises.id") - .where("variant_overrides.id IS NOT NULL").select("DISTINCT enterprises.*") - - hubs_using_overrides.each do |hub| - overridable_producer_ids = hub.relationships_as_child.with_permission(:create_variant_overrides).map(&:parent_id) | [hub.id] - - variants = Spree::Variant.where(is_master: false, product_id: Spree::Product.not_deleted.where(supplier_id: overridable_producer_ids)) - - variants_to_add = variants.joins("LEFT OUTER JOIN (SELECT * from inventory_items WHERE enterprise_id = #{hub.id}) AS o_inventory_items ON o_inventory_items.variant_id = spree_variants.id") - .where('o_inventory_items.id IS NULL') - - variants_to_add.each do |variant| - inventory_item = InventoryItem.create(enterprise: hub, variant: variant, visible: true) - end - end - end - - def down - end -end diff --git a/db/migrate/20160303004210_create_tag_rules.rb b/db/migrate/20160303004210_create_tag_rules.rb deleted file mode 100644 index 157fee1e69..0000000000 --- a/db/migrate/20160303004210_create_tag_rules.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreateTagRules < ActiveRecord::Migration - def change - create_table :tag_rules do |t| - t.references :enterprise, null: false, index: true - t.string :type, null: false - - t.timestamps - end - end -end diff --git a/db/migrate/20160316051131_add_require_login_to_enterprise.rb b/db/migrate/20160316051131_add_require_login_to_enterprise.rb deleted file mode 100644 index 68de642b62..0000000000 --- a/db/migrate/20160316051131_add_require_login_to_enterprise.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddRequireLoginToEnterprise < ActiveRecord::Migration - def change - add_column :enterprises, :require_login, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20160401043927_change_value_type_of_paypal_passwords.rb b/db/migrate/20160401043927_change_value_type_of_paypal_passwords.rb deleted file mode 100644 index e03ed25f9e..0000000000 --- a/db/migrate/20160401043927_change_value_type_of_paypal_passwords.rb +++ /dev/null @@ -1,15 +0,0 @@ -class ChangeValueTypeOfPaypalPasswords < ActiveRecord::Migration - def up - Spree::Preference - .where("key like ?", "spree/gateway/pay_pal_express/password/%") - .where(value_type: "string") - .update_all(value_type: "password") - end - - def down - Spree::Preference - .where("key like ?", "spree/gateway/pay_pal_express/password/%") - .where(value_type: "password") - .update_all(value_type: "string") - end -end diff --git a/db/migrate/20160520065217_add_is_default_to_tag_rule.rb b/db/migrate/20160520065217_add_is_default_to_tag_rule.rb deleted file mode 100644 index 209520b693..0000000000 --- a/db/migrate/20160520065217_add_is_default_to_tag_rule.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIsDefaultToTagRule < ActiveRecord::Migration - def change - add_column :tag_rules, :is_default, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20160527012603_add_priority_to_tag_rule.rb b/db/migrate/20160527012603_add_priority_to_tag_rule.rb deleted file mode 100644 index 7080d7a9ac..0000000000 --- a/db/migrate/20160527012603_add_priority_to_tag_rule.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPriorityToTagRule < ActiveRecord::Migration - def change - add_column :tag_rules, :priority, :integer, default: 99, null: false - end -end diff --git a/db/migrate/20160630052453_create_schedules.rb b/db/migrate/20160630052453_create_schedules.rb deleted file mode 100644 index f1cf5fa5c5..0000000000 --- a/db/migrate/20160630052453_create_schedules.rb +++ /dev/null @@ -1,8 +0,0 @@ -class CreateSchedules < ActiveRecord::Migration - def change - create_table :schedules do |t| - t.string :name, null: false - t.timestamps - end - end -end diff --git a/db/migrate/20160630055825_create_order_cycle_schedules.rb b/db/migrate/20160630055825_create_order_cycle_schedules.rb deleted file mode 100644 index 99147467c9..0000000000 --- a/db/migrate/20160630055825_create_order_cycle_schedules.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateOrderCycleSchedules < ActiveRecord::Migration - def change - create_table :order_cycle_schedules do |t| - t.references :order_cycle, null: false - t.references :schedule, null: false - end - - add_index :order_cycle_schedules, :order_cycle_id - add_index :order_cycle_schedules, :schedule_id - - add_foreign_key :order_cycle_schedules, :order_cycles, name: 'oc_schedules_order_cycle_id_fk' - add_foreign_key :order_cycle_schedules, :schedules, name: 'oc_schedules_schedule_id_fk' - end -end diff --git a/db/migrate/20160707023818_drop_cms.rb b/db/migrate/20160707023818_drop_cms.rb deleted file mode 100644 index 018b755466..0000000000 --- a/db/migrate/20160707023818_drop_cms.rb +++ /dev/null @@ -1,154 +0,0 @@ -class DropCms < ActiveRecord::Migration - - # Reverse of CreateCms in 20121009232513_create_cms.rb, including foreign keys defined - # in 20140402033428_add_foreign_keys.rb - - def up - drop_table_cascade :cms_sites - drop_table_cascade :cms_layouts - drop_table_cascade :cms_pages - drop_table_cascade :cms_snippets - drop_table_cascade :cms_blocks - drop_table_cascade :cms_files - drop_table_cascade :cms_revisions - drop_table_cascade :cms_categories - drop_table_cascade :cms_categorizations - end - - def down - text_limit = case ActiveRecord::Base.connection.adapter_name - when 'PostgreSQL' - { } - else - { :limit => 16777215 } - end - - # -- Sites -------------------------------------------------------------- - create_table :cms_sites do |t| - t.string :label, :null => false - t.string :identifier, :null => false - t.string :hostname, :null => false - t.string :path - t.string :locale, :null => false, :default => 'en' - t.boolean :is_mirrored, :null => false, :default => false - end - add_index :cms_sites, :hostname - add_index :cms_sites, :is_mirrored - - # -- Layouts ------------------------------------------------------------ - create_table :cms_layouts do |t| - t.integer :site_id, :null => false - t.integer :parent_id - t.string :app_layout - t.string :label, :null => false - t.string :identifier, :null => false - t.text :content, text_limit - t.text :css, text_limit - t.text :js, text_limit - t.integer :position, :null => false, :default => 0 - t.boolean :is_shared, :null => false, :default => false - t.timestamps - end - add_index :cms_layouts, [:parent_id, :position] - add_index :cms_layouts, [:site_id, :identifier], :unique => true - - # -- Pages -------------------------------------------------------------- - create_table :cms_pages do |t| - t.integer :site_id, :null => false - t.integer :layout_id - t.integer :parent_id - t.integer :target_page_id - t.string :label, :null => false - t.string :slug - t.string :full_path, :null => false - t.text :content, text_limit - t.integer :position, :null => false, :default => 0 - t.integer :children_count, :null => false, :default => 0 - t.boolean :is_published, :null => false, :default => true - t.boolean :is_shared, :null => false, :default => false - t.timestamps - end - add_index :cms_pages, [:site_id, :full_path] - add_index :cms_pages, [:parent_id, :position] - - # -- Page Blocks -------------------------------------------------------- - create_table :cms_blocks do |t| - t.integer :page_id, :null => false - t.string :identifier, :null => false - t.text :content - t.timestamps - end - add_index :cms_blocks, [:page_id, :identifier] - - # -- Snippets ----------------------------------------------------------- - create_table :cms_snippets do |t| - t.integer :site_id, :null => false - t.string :label, :null => false - t.string :identifier, :null => false - t.text :content, text_limit - t.integer :position, :null => false, :default => 0 - t.boolean :is_shared, :null => false, :default => false - t.timestamps - end - add_index :cms_snippets, [:site_id, :identifier], :unique => true - add_index :cms_snippets, [:site_id, :position] - - # -- Files -------------------------------------------------------------- - create_table :cms_files do |t| - t.integer :site_id, :null => false - t.integer :block_id - t.string :label, :null => false - t.string :file_file_name, :null => false - t.string :file_content_type, :null => false - t.integer :file_file_size, :null => false - t.string :description, :limit => 2048 - t.integer :position, :null => false, :default => 0 - t.timestamps - end - add_index :cms_files, [:site_id, :label] - add_index :cms_files, [:site_id, :file_file_name] - add_index :cms_files, [:site_id, :position] - add_index :cms_files, [:site_id, :block_id] - - # -- Revisions ----------------------------------------------------------- - create_table :cms_revisions, :force => true do |t| - t.string :record_type, :null => false - t.integer :record_id, :null => false - t.text :data, text_limit - t.datetime :created_at - end - add_index :cms_revisions, [:record_type, :record_id, :created_at] - - # -- Categories --------------------------------------------------------- - create_table :cms_categories, :force => true do |t| - t.integer :site_id, :null => false - t.string :label, :null => false - t.string :categorized_type, :null => false - end - add_index :cms_categories, [:site_id, :categorized_type, :label], :unique => true - - create_table :cms_categorizations, :force => true do |t| - t.integer :category_id, :null => false - t.string :categorized_type, :null => false - t.integer :categorized_id, :null => false - end - add_index :cms_categorizations, [:category_id, :categorized_type, :categorized_id], :unique => true, - :name => 'index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id' - - - # -- Foreign keys, from 20140402033428_add_foreign_keys.rb - add_foreign_key "cms_blocks", "cms_pages", name: "cms_blocks_page_id_fk", column: "page_id" - add_foreign_key "cms_categories", "cms_sites", name: "cms_categories_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "cms_categorizations", "cms_categories", name: "cms_categorizations_category_id_fk", column: "category_id" - add_foreign_key "cms_files", "cms_blocks", name: "cms_files_block_id_fk", column: "block_id" - add_foreign_key "cms_files", "cms_sites", name: "cms_files_site_id_fk", column: "site_id" - add_foreign_key "cms_layouts", "cms_layouts", name: "cms_layouts_parent_id_fk", column: "parent_id" - add_foreign_key "cms_layouts", "cms_sites", name: "cms_layouts_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "cms_pages", "cms_layouts", name: "cms_pages_layout_id_fk", column: "layout_id" - add_foreign_key "cms_pages", "cms_pages", name: "cms_pages_parent_id_fk", column: "parent_id" - add_foreign_key "cms_pages", "cms_sites", name: "cms_pages_site_id_fk", column: "site_id", dependent: :delete - add_foreign_key "cms_pages", "cms_pages", name: "cms_pages_target_page_id_fk", column: "target_page_id" - add_foreign_key "cms_snippets", "cms_sites", name: "cms_snippets_site_id_fk", column: "site_id", dependent: :delete - - end -end diff --git a/db/migrate/20160713003535_add_bill_address_and_ship_address_to_customer.rb b/db/migrate/20160713003535_add_bill_address_and_ship_address_to_customer.rb deleted file mode 100644 index 306276bcc0..0000000000 --- a/db/migrate/20160713003535_add_bill_address_and_ship_address_to_customer.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddBillAddressAndShipAddressToCustomer < ActiveRecord::Migration - def change - add_column :customers, :bill_address_id, :integer - add_column :customers, :ship_address_id, :integer - - add_index :customers, :bill_address_id - add_index :customers, :ship_address_id - - add_foreign_key :customers, :spree_addresses, column: :bill_address_id - add_foreign_key :customers, :spree_addresses, column: :ship_address_id - end -end diff --git a/db/migrate/20160713013358_add_name_to_customer.rb b/db/migrate/20160713013358_add_name_to_customer.rb deleted file mode 100644 index 832816657e..0000000000 --- a/db/migrate/20160713013358_add_name_to_customer.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNameToCustomer < ActiveRecord::Migration - def change - add_column :customers, :name, :string - end -end diff --git a/db/migrate/20160819045727_create_standing_orders.rb b/db/migrate/20160819045727_create_standing_orders.rb deleted file mode 100644 index 661bf7411b..0000000000 --- a/db/migrate/20160819045727_create_standing_orders.rb +++ /dev/null @@ -1,25 +0,0 @@ -class CreateStandingOrders < ActiveRecord::Migration - def change - create_table :standing_orders do |t| - t.references :shop, null: false - t.references :customer, null: false - t.references :schedule, null: false - t.references :payment_method, null: false - t.references :shipping_method, null: false - t.datetime :begins_at, :ends_at - t.timestamps - end - - add_index :standing_orders, :shop_id - add_index :standing_orders, :customer_id - add_index :standing_orders, :schedule_id - add_index :standing_orders, :payment_method_id - add_index :standing_orders, :shipping_method_id - - add_foreign_key :standing_orders, :enterprises, name: 'oc_standing_orders_shop_id_fk', column: :shop_id - add_foreign_key :standing_orders, :customers, name: 'oc_standing_orders_customer_id_fk' - add_foreign_key :standing_orders, :schedules, name: 'oc_standing_orders_schedule_id_fk' - add_foreign_key :standing_orders, :spree_payment_methods, name: 'oc_standing_orders_payment_method_id_fk', column: :payment_method_id - add_foreign_key :standing_orders, :spree_shipping_methods, name: 'oc_standing_orders_shipping_method_id_fk', column: :shipping_method_id - end -end diff --git a/db/migrate/20160819065331_swap_calculator_to_flat_percent_per_item.rb b/db/migrate/20160819065331_swap_calculator_to_flat_percent_per_item.rb deleted file mode 100644 index eb8e206e8f..0000000000 --- a/db/migrate/20160819065331_swap_calculator_to_flat_percent_per_item.rb +++ /dev/null @@ -1,29 +0,0 @@ -class SwapCalculatorToFlatPercentPerItem < ActiveRecord::Migration - class Spree::Calculator < ActiveRecord::Base - end - - def up - Spree::Calculator.where(calculable_type: "EnterpriseFee", type: 'Spree::Calculator::FlatPercentItemTotal').each do |c| - swap_calculator_type c, 'Calculator::FlatPercentPerItem' - end - end - - def down - Spree::Calculator.where(calculable_type: "EnterpriseFee", type: 'Spree::Calculator::FlatPercentPerItem').each do |c| - swap_calculator_type c, 'Calculator::FlatPercentItemTotal' - end - end - - - private - - def swap_calculator_type(calculator, to_class) - value = calculator.preferred_flat_percent - - calculator.type = to_class - calculator.save - - calculator = Spree::Calculator.find calculator.id - calculator.preferred_flat_percent = value - end -end diff --git a/db/migrate/20160824013751_create_standing_line_items.rb b/db/migrate/20160824013751_create_standing_line_items.rb deleted file mode 100644 index 90a0d46af3..0000000000 --- a/db/migrate/20160824013751_create_standing_line_items.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreateStandingLineItems < ActiveRecord::Migration - def change - create_table :standing_line_items do |t| - t.references :standing_order, null: false - t.references :variant, null: false - t.integer :quantity, null: false - t.timestamps - end - - add_index :standing_line_items, :standing_order_id - add_index :standing_line_items, :variant_id - - add_foreign_key :standing_line_items, :standing_orders, name: 'oc_standing_line_items_standing_order_id_fk' - add_foreign_key :standing_line_items, :spree_variants, name: 'oc_standing_line_items_variant_id_fk', column: :variant_id - end -end diff --git a/db/migrate/20160828115018_create_stripe_accounts.rb b/db/migrate/20160828115018_create_stripe_accounts.rb deleted file mode 100644 index 56ab206540..0000000000 --- a/db/migrate/20160828115018_create_stripe_accounts.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateStripeAccounts < ActiveRecord::Migration - def change - create_table :stripe_accounts do |t| - t.string :stripe_user_id - t.string :stripe_publishable_key - t.timestamps - t.belongs_to :enterprise - end - - add_index :stripe_accounts, :enterprise_id, unique: true - end -end diff --git a/db/migrate/20160916024535_add_state_to_spree_adjustments.spree.rb b/db/migrate/20160916024535_add_state_to_spree_adjustments.spree.rb deleted file mode 100644 index a4224678df..0000000000 --- a/db/migrate/20160916024535_add_state_to_spree_adjustments.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20121213162028) -class AddStateToSpreeAdjustments < ActiveRecord::Migration - def change - add_column :spree_adjustments, :state, :string - remove_column :spree_adjustments, :locked - end -end diff --git a/db/migrate/20160921060442_add_allow_guest_orders_to_enterprise.rb b/db/migrate/20160921060442_add_allow_guest_orders_to_enterprise.rb deleted file mode 100644 index 7e92c7e74c..0000000000 --- a/db/migrate/20160921060442_add_allow_guest_orders_to_enterprise.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddAllowGuestOrdersToEnterprise < ActiveRecord::Migration - def change - add_column :enterprises, :allow_guest_orders, :boolean, default: true, null: false - end -end diff --git a/db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb b/db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb deleted file mode 100644 index 887ce44058..0000000000 --- a/db/migrate/20161012022142_add_allow_order_changes_to_enterprise.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddAllowOrderChangesToEnterprise < ActiveRecord::Migration - def change - add_column :enterprises, :allow_order_changes, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20161014000216_add_ship_and_bill_address_to_standing_orders.rb b/db/migrate/20161014000216_add_ship_and_bill_address_to_standing_orders.rb deleted file mode 100644 index 259227be5f..0000000000 --- a/db/migrate/20161014000216_add_ship_and_bill_address_to_standing_orders.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddShipAndBillAddressToStandingOrders < ActiveRecord::Migration - def change - add_column :standing_orders, :bill_address_id, :integer, null: false - add_column :standing_orders, :ship_address_id, :integer, null: false - - add_index :standing_orders, :bill_address_id - add_index :standing_orders, :ship_address_id - - add_foreign_key :standing_orders, :spree_addresses, column: :bill_address_id - add_foreign_key :standing_orders, :spree_addresses, column: :ship_address_id - end -end diff --git a/db/migrate/20161020012017_create_standing_order_orders.rb b/db/migrate/20161020012017_create_standing_order_orders.rb deleted file mode 100644 index cbaa0c14cc..0000000000 --- a/db/migrate/20161020012017_create_standing_order_orders.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreateStandingOrderOrders < ActiveRecord::Migration - def change - create_table :standing_order_orders do |t| - t.references :standing_order, null: false - t.references :order, null: false - t.datetime :cancelled_at - t.timestamps - end - - add_index :standing_order_orders, :standing_order_id - add_index :standing_order_orders, :order_id, unique: true - - add_foreign_key "standing_order_orders", "standing_orders", name: "standing_order_id_fk", column: "standing_order_id" - add_foreign_key "standing_order_orders", "spree_orders", name: "order_id_fk", column: "order_id" - end -end diff --git a/db/migrate/20161110002554_add_standing_orders_placed_at_to_order_cycles.rb b/db/migrate/20161110002554_add_standing_orders_placed_at_to_order_cycles.rb deleted file mode 100644 index 9becae9930..0000000000 --- a/db/migrate/20161110002554_add_standing_orders_placed_at_to_order_cycles.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStandingOrdersPlacedAtToOrderCycles < ActiveRecord::Migration - def change - add_column :order_cycles, :standing_orders_placed_at, :datetime - end -end diff --git a/db/migrate/20161130001339_add_price_estimate_to_standing_line_items.rb b/db/migrate/20161130001339_add_price_estimate_to_standing_line_items.rb deleted file mode 100644 index 967a24b838..0000000000 --- a/db/migrate/20161130001339_add_price_estimate_to_standing_line_items.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPriceEstimateToStandingLineItems < ActiveRecord::Migration - def change - add_column :standing_line_items, :price_estimate, :decimal, :precision => 8, :scale => 2 - end -end diff --git a/db/migrate/20161206232009_add_canceled_at_to_standing_orders.rb b/db/migrate/20161206232009_add_canceled_at_to_standing_orders.rb deleted file mode 100644 index f004e28557..0000000000 --- a/db/migrate/20161206232009_add_canceled_at_to_standing_orders.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddCanceledAtToStandingOrders < ActiveRecord::Migration - def change - add_column :standing_orders, :canceled_at, :datetime - end -end diff --git a/db/migrate/20161207040232_rename_standing_order_orders_cancelled_at.rb b/db/migrate/20161207040232_rename_standing_order_orders_cancelled_at.rb deleted file mode 100644 index 6d2c3d0c3f..0000000000 --- a/db/migrate/20161207040232_rename_standing_order_orders_cancelled_at.rb +++ /dev/null @@ -1,7 +0,0 @@ -class RenameStandingOrderOrdersCancelledAt < ActiveRecord::Migration - def change - # No, I'm not illiterate. I just want to maintain consistency with - # existing Spree column names that are spelt using US English - rename_column :standing_order_orders, :cancelled_at, :canceled_at - end -end diff --git a/db/migrate/20161207042153_add_paused_at_to_standing_orders.rb b/db/migrate/20161207042153_add_paused_at_to_standing_orders.rb deleted file mode 100644 index e6e6e95852..0000000000 --- a/db/migrate/20161207042153_add_paused_at_to_standing_orders.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPausedAtToStandingOrders < ActiveRecord::Migration - def change - add_column :standing_orders, :paused_at, :datetime - end -end diff --git a/db/migrate/20161208233703_add_standing_orders_confirmed_at_to_order_cycles.rb b/db/migrate/20161208233703_add_standing_orders_confirmed_at_to_order_cycles.rb deleted file mode 100644 index 3f4bb3c378..0000000000 --- a/db/migrate/20161208233703_add_standing_orders_confirmed_at_to_order_cycles.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStandingOrdersConfirmedAtToOrderCycles < ActiveRecord::Migration - def change - add_column :order_cycles, :standing_orders_confirmed_at, :datetime - end -end diff --git a/db/migrate/20161210225156_rename_standing_order_orders_to_proxy_orders.rb b/db/migrate/20161210225156_rename_standing_order_orders_to_proxy_orders.rb deleted file mode 100644 index 964037f823..0000000000 --- a/db/migrate/20161210225156_rename_standing_order_orders_to_proxy_orders.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RenameStandingOrderOrdersToProxyOrders < ActiveRecord::Migration - def change - remove_index :standing_order_orders, :order_id - remove_index :standing_order_orders, :standing_order_id - rename_table :standing_order_orders, :proxy_orders - add_index :proxy_orders, :order_id, unique: true - add_index :proxy_orders, :standing_order_id - end -end diff --git a/db/migrate/20161210235939_add_order_cycle_id_to_proxy_orders.rb b/db/migrate/20161210235939_add_order_cycle_id_to_proxy_orders.rb deleted file mode 100644 index fd18937ea0..0000000000 --- a/db/migrate/20161210235939_add_order_cycle_id_to_proxy_orders.rb +++ /dev/null @@ -1,20 +0,0 @@ -class AddOrderCycleIdToProxyOrders < ActiveRecord::Migration - def up - add_column :proxy_orders, :order_cycle_id, :integer - - ProxyOrder.find_each do |proxy_order| - order_cycle_id = proxy_order.order.order_cycle_id - proxy_order.update_attribute(:order_cycle_id, order_cycle_id) - end - - change_column :proxy_orders, :order_cycle_id, :integer, null: false - add_index :proxy_orders, [:order_cycle_id, :standing_order_id], unique: true - add_foreign_key :proxy_orders, :order_cycles - end - - def down - remove_foreign_key :proxy_orders, :order_cycles - remove_index :proxy_orders, :order_cycle_id - remove_column :proxy_orders, :order_cycle_id - end -end diff --git a/db/migrate/20161211210859_remove_proxy_order_order_not_null_constraint.rb b/db/migrate/20161211210859_remove_proxy_order_order_not_null_constraint.rb deleted file mode 100644 index 726dde623a..0000000000 --- a/db/migrate/20161211210859_remove_proxy_order_order_not_null_constraint.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveProxyOrderOrderNotNullConstraint < ActiveRecord::Migration - def up - change_column :proxy_orders, :order_id, :integer, null: true - end - - def down - change_column :proxy_orders, :order_id, :integer, null: false - end -end diff --git a/db/migrate/20161215032136_add_enable_standing_orders_to_enterprises.rb b/db/migrate/20161215032136_add_enable_standing_orders_to_enterprises.rb deleted file mode 100644 index 3bd4ad13cb..0000000000 --- a/db/migrate/20161215032136_add_enable_standing_orders_to_enterprises.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddEnableStandingOrdersToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :enable_standing_orders, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20161215230219_add_invoice_text_and_invoice_logo_to_enterprises.rb b/db/migrate/20161215230219_add_invoice_text_and_invoice_logo_to_enterprises.rb deleted file mode 100644 index d9cfca91ba..0000000000 --- a/db/migrate/20161215230219_add_invoice_text_and_invoice_logo_to_enterprises.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddInvoiceTextAndInvoiceLogoToEnterprises < ActiveRecord::Migration - def change - add_column :enterprises, :invoice_text, :text - add_column :enterprises, :display_invoice_logo, :boolean, default: false - end -end diff --git a/db/migrate/20161222022340_add_placed_at_and_confirmed_at_to_proxy_orders.rb b/db/migrate/20161222022340_add_placed_at_and_confirmed_at_to_proxy_orders.rb deleted file mode 100644 index daf67b1211..0000000000 --- a/db/migrate/20161222022340_add_placed_at_and_confirmed_at_to_proxy_orders.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddPlacedAtAndConfirmedAtToProxyOrders < ActiveRecord::Migration - def change - add_column :proxy_orders, :placed_at, :datetime - add_column :proxy_orders, :confirmed_at, :datetime - end -end diff --git a/db/migrate/20170225203658_add_user_id_to_spree_credit_cards.rb b/db/migrate/20170225203658_add_user_id_to_spree_credit_cards.rb deleted file mode 100644 index 29e50e0c1a..0000000000 --- a/db/migrate/20170225203658_add_user_id_to_spree_credit_cards.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddUserIdToSpreeCreditCards < ActiveRecord::Migration - def change - unless Spree::CreditCard.column_names.include? "user_id" - add_column :spree_credit_cards, :user_id, :integer - add_index :spree_credit_cards, :user_id - end - end -end diff --git a/db/migrate/20170304151129_add_payment_method_to_spree_credit_cards.rb b/db/migrate/20170304151129_add_payment_method_to_spree_credit_cards.rb deleted file mode 100644 index 76c1cab805..0000000000 --- a/db/migrate/20170304151129_add_payment_method_to_spree_credit_cards.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddPaymentMethodToSpreeCreditCards < ActiveRecord::Migration - def change - unless Spree::CreditCard.column_names.include? "payment_method_id" - add_column :spree_credit_cards, :payment_method_id, :integer - add_index :spree_credit_cards, :payment_method_id - end - end -end diff --git a/db/migrate/20170310231746_add_import_date_to_spree_variants.rb b/db/migrate/20170310231746_add_import_date_to_spree_variants.rb deleted file mode 100644 index d5acbf882e..0000000000 --- a/db/migrate/20170310231746_add_import_date_to_spree_variants.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddImportDateToSpreeVariants < ActiveRecord::Migration - def change - add_column :spree_variants, :import_date, :datetime - end -end diff --git a/db/migrate/20170314132401_add_import_date_to_variant_overrides.rb b/db/migrate/20170314132401_add_import_date_to_variant_overrides.rb deleted file mode 100644 index daef32ec61..0000000000 --- a/db/migrate/20170314132401_add_import_date_to_variant_overrides.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddImportDateToVariantOverrides < ActiveRecord::Migration - def change - add_column :variant_overrides, :import_date, :datetime - end -end diff --git a/db/migrate/20170413074528_rename_payment_methods.spree_paypal_express.rb b/db/migrate/20170413074528_rename_payment_methods.spree_paypal_express.rb deleted file mode 100644 index 2c426824d8..0000000000 --- a/db/migrate/20170413074528_rename_payment_methods.spree_paypal_express.rb +++ /dev/null @@ -1,14 +0,0 @@ -# This migration comes from spree_paypal_express (originally 20140117051315) -class RenamePaymentMethods < ActiveRecord::Migration - def up - execute <<-SQL - update spree_payment_methods set type = 'Spree::Gateway::PayPalExpress' WHERE type = 'Spree::BillingIntegration::PaypalExpress' - SQL - end - - def down - execute <<-SQL - update spree_payment_methods set type = 'Spree::BillingIntegration::PaypalExpress' WHERE type = 'Spree::Gateway::PayPalExpress' - SQL - end -end diff --git a/db/migrate/20170413083148_add_tracking_url_to_spree_shipping_methods.spree.rb b/db/migrate/20170413083148_add_tracking_url_to_spree_shipping_methods.spree.rb deleted file mode 100644 index 28a9807184..0000000000 --- a/db/migrate/20170413083148_add_tracking_url_to_spree_shipping_methods.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130301205200) -class AddTrackingUrlToSpreeShippingMethods < ActiveRecord::Migration - def change - add_column :spree_shipping_methods, :tracking_url, :string - end -end diff --git a/db/migrate/20170512115519_add_locale_to_spree_users.rb b/db/migrate/20170512115519_add_locale_to_spree_users.rb deleted file mode 100644 index f694bff1f7..0000000000 --- a/db/migrate/20170512115519_add_locale_to_spree_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddLocaleToSpreeUsers < ActiveRecord::Migration - def change - add_column :spree_users, :locale, :string, limit: 5 - end -end diff --git a/db/migrate/20170710145821_add_confirmable_to_user.rb b/db/migrate/20170710145821_add_confirmable_to_user.rb deleted file mode 100644 index cd458545e0..0000000000 --- a/db/migrate/20170710145821_add_confirmable_to_user.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddConfirmableToUser < ActiveRecord::Migration - def up - add_column :spree_users, :confirmation_token, :string - add_column :spree_users, :confirmed_at, :datetime - add_column :spree_users, :confirmation_sent_at, :datetime - add_column :spree_users, :unconfirmed_email, :string - add_index :spree_users, :confirmation_token, :unique => true - - # Set all current users to confirmed - Spree::User.update_all(confirmed_at: Time.zone.now) - end - - def down - remove_columns :spree_users, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email - end -end diff --git a/db/migrate/20170719125120_remove_confirmable_from_enterprises.rb b/db/migrate/20170719125120_remove_confirmable_from_enterprises.rb deleted file mode 100644 index a4aad51dd4..0000000000 --- a/db/migrate/20170719125120_remove_confirmable_from_enterprises.rb +++ /dev/null @@ -1,16 +0,0 @@ -class RemoveConfirmableFromEnterprises < ActiveRecord::Migration - def up - remove_columns :enterprises, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email - end - - def down - add_column :enterprises, :confirmation_token, :string - add_column :enterprises, :confirmed_at, :datetime - add_column :enterprises, :confirmation_sent_at, :datetime - add_column :enterprises, :unconfirmed_email, :string - add_index :enterprises, :confirmation_token, :unique => true - - # Existing enterprises are assumed to be confirmed - Enterprise.update_all(:confirmed_at => Time.zone.now) - end -end diff --git a/db/migrate/20170727104900_add_receives_notifications_to_enterprise_roles.rb b/db/migrate/20170727104900_add_receives_notifications_to_enterprise_roles.rb deleted file mode 100644 index 128cc2a554..0000000000 --- a/db/migrate/20170727104900_add_receives_notifications_to_enterprise_roles.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddReceivesNotificationsToEnterpriseRoles < ActiveRecord::Migration - def change - add_column :enterprise_roles, :receives_notifications, :boolean, default: false - end -end diff --git a/db/migrate/20170728140134_remove_email_from_enterprises.rb b/db/migrate/20170728140134_remove_email_from_enterprises.rb deleted file mode 100644 index 01e4fe7f87..0000000000 --- a/db/migrate/20170728140134_remove_email_from_enterprises.rb +++ /dev/null @@ -1,48 +0,0 @@ -class RemoveEmailFromEnterprises < ActiveRecord::Migration - class Enterprise < ActiveRecord::Base; end - class Spree::User < ActiveRecord::Base; end - - class EnterpriseRole < ActiveRecord::Base - belongs_to :user, class_name: 'Spree::User' - belongs_to :enterprise, class_name: 'Enterprise' - end - - def up - Enterprise.reset_column_information - Spree::User.reset_column_information - EnterpriseRole.reset_column_information - - Enterprise.select([:id, :email, :owner_id]).each do |enterprise| - update_enterprise_contact enterprise - end - - remove_column :enterprises, :email - rename_column :enterprises, :contact, :contact_name - end - - def down - Enterprise.reset_column_information - Spree::User.reset_column_information - EnterpriseRole.reset_column_information - - add_column :enterprises, :email, :string - rename_column :enterprises, :contact_name, :contact - - Enterprise.select(:id).each do |e| - manager = EnterpriseRole.find_by_enterprise_id_and_receives_notifications(e.id, true) - user = Spree::User.find(manager.user_id) - e.update_attribute :email, user.email - end - end - - def update_enterprise_contact(enterprise) - contact_user = contact_or_owner(enterprise) - - role = EnterpriseRole.find_or_initialize_by_user_id_and_enterprise_id(contact_user.id, enterprise.id) - role.update_attribute :receives_notifications, true - end - - def contact_or_owner(enterprise) - Spree::User.find_by_email(enterprise.email) || Spree::User.find(enterprise.owner_id) - end -end diff --git a/db/migrate/20170913205345_change_default_value_of_spree_users_enterprise_limit.rb b/db/migrate/20170913205345_change_default_value_of_spree_users_enterprise_limit.rb deleted file mode 100644 index 2db2182d9c..0000000000 --- a/db/migrate/20170913205345_change_default_value_of_spree_users_enterprise_limit.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ChangeDefaultValueOfSpreeUsersEnterpriseLimit < ActiveRecord::Migration - def up - change_column :spree_users, :enterprise_limit, :integer, default: 5 - end - - def down - change_column :spree_users, :enterprise_limit, :integer, default: 1 - end -end diff --git a/db/migrate/20170921065259_update_adjustment_states.spree.rb b/db/migrate/20170921065259_update_adjustment_states.spree.rb deleted file mode 100644 index 9040709751..0000000000 --- a/db/migrate/20170921065259_update_adjustment_states.spree.rb +++ /dev/null @@ -1,17 +0,0 @@ -# This migration comes from spree (originally 20130417120035) -class UpdateAdjustmentStates < ActiveRecord::Migration - def up - Spree::Order.complete.find_each do |order| - order.adjustments.update_all(:state => 'closed') - end - - Spree::Shipment.shipped.includes(:adjustment).find_each do |shipment| - shipment.adjustment.update_column(:state, 'finalized') if shipment.adjustment - end - - Spree::Adjustment.where(:state => nil).update_all(:state => 'open') - end - - def down - end -end diff --git a/db/migrate/20171027005930_add_credit_card_to_standing_orders.rb b/db/migrate/20171027005930_add_credit_card_to_standing_orders.rb deleted file mode 100644 index 60e5133a72..0000000000 --- a/db/migrate/20171027005930_add_credit_card_to_standing_orders.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddCreditCardToStandingOrders < ActiveRecord::Migration - def change - add_column :standing_orders, :credit_card_id, :integer - add_index :standing_orders, :credit_card_id - add_foreign_key :standing_orders, :spree_credit_cards, name: :standing_orders_credit_card_id_fk, column: :credit_card_id - end -end diff --git a/db/migrate/20180202024104_rename_standing_orders_to_subscriptions.rb b/db/migrate/20180202024104_rename_standing_orders_to_subscriptions.rb deleted file mode 100644 index 91c90d90b5..0000000000 --- a/db/migrate/20180202024104_rename_standing_orders_to_subscriptions.rb +++ /dev/null @@ -1,99 +0,0 @@ -class RenameStandingOrdersToSubscriptions < ActiveRecord::Migration - def up - remove_foreign_key :proxy_orders, name: :standing_order_id_fk - remove_foreign_key :standing_line_items, name: :oc_standing_line_items_standing_order_id_fk - - remove_foreign_key :standing_orders, name: :oc_standing_orders_customer_id_fk - remove_foreign_key :standing_orders, name: :oc_standing_orders_shop_id_fk - remove_foreign_key :standing_orders, name: :oc_standing_orders_schedule_id_fk - remove_foreign_key :standing_orders, name: :standing_orders_bill_address_id_fk - remove_foreign_key :standing_orders, name: :standing_orders_ship_address_id_fk - remove_foreign_key :standing_orders, name: :standing_orders_credit_card_id_fk - remove_foreign_key :standing_orders, name: :oc_standing_orders_payment_method_id_fk - remove_foreign_key :standing_orders, name: :oc_standing_orders_shipping_method_id_fk - - remove_index :proxy_orders, :column => [:order_cycle_id, :standing_order_id] - remove_index :proxy_orders, :column => [:standing_order_id] - remove_index :standing_line_items, :column => [:standing_order_id] - - rename_table :standing_orders, :subscriptions - - rename_index :subscriptions, :index_standing_orders_on_bill_address_id, :index_subscriptions_on_bill_address_id - rename_index :subscriptions, :index_standing_orders_on_credit_card_id, :index_subscriptions_on_credit_card_id - rename_index :subscriptions, :index_standing_orders_on_customer_id, :index_subscriptions_on_customer_id - rename_index :subscriptions, :index_standing_orders_on_payment_method_id, :index_subscriptions_on_payment_method_id - rename_index :subscriptions, :index_standing_orders_on_schedule_id, :index_subscriptions_on_schedule_id - rename_index :subscriptions, :index_standing_orders_on_ship_address_id, :index_subscriptions_on_ship_address_id - rename_index :subscriptions, :index_standing_orders_on_shipping_method_id, :index_subscriptions_on_shipping_method_id - rename_index :subscriptions, :index_standing_orders_on_shop_id, :index_subscriptions_on_shop_id - - rename_column :enterprises, :enable_standing_orders, :enable_subscriptions - rename_column :proxy_orders, :standing_order_id, :subscription_id - rename_column :standing_line_items, :standing_order_id, :subscription_id - - add_index :proxy_orders, [:order_cycle_id, :subscription_id], unique: true - add_index :proxy_orders, :subscription_id - add_index :standing_line_items, :subscription_id - - add_foreign_key :proxy_orders, :subscriptions, name: :proxy_orders_subscription_id_fk - add_foreign_key :standing_line_items, :subscriptions, name: :standing_line_items_subscription_id_fk - - add_foreign_key :subscriptions, :customers, name: :subscriptions_customer_id_fk - add_foreign_key :subscriptions, :enterprises, name: :subscriptions_shop_id_fk, column: :shop_id - add_foreign_key :subscriptions, :schedules, name: :subscriptions_schedule_id_fk - add_foreign_key :subscriptions, :spree_addresses, name: :subscriptions_bill_address_id_fk, column: :bill_address_id - add_foreign_key :subscriptions, :spree_addresses, name: :subscriptions_ship_address_id_fk, column: :ship_address_id - add_foreign_key :subscriptions, :spree_credit_cards, name: :subscriptions_credit_card_id_fk, column: :credit_card_id - add_foreign_key :subscriptions, :spree_payment_methods, name: :subscriptions_payment_method_id_fk, column: :payment_method_id - add_foreign_key :subscriptions, :spree_shipping_methods, name: :subscriptions_shipping_method_id_fk, column: :shipping_method_id - end - - def down - remove_foreign_key :proxy_orders, name: :proxy_orders_subscription_id_fk - remove_foreign_key :standing_line_items, name: :standing_line_items_subscription_id_fk - - remove_foreign_key :subscriptions, name: :subscriptions_customer_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_shop_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_schedule_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_bill_address_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_ship_address_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_credit_card_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_payment_method_id_fk - remove_foreign_key :subscriptions, name: :subscriptions_shipping_method_id_fk - - remove_index :proxy_orders, :column => [:order_cycle_id, :subscription_id] - remove_index :proxy_orders, :column => [:subscription_id] - remove_index :standing_line_items, :column => [:subscription_id] - - rename_table :subscriptions, :standing_orders - - rename_index :standing_orders, :index_subscriptions_on_bill_address_id, :index_standing_orders_on_bill_address_id - rename_index :standing_orders, :index_subscriptions_on_credit_card_id, :index_standing_orders_on_credit_card_id - rename_index :standing_orders, :index_subscriptions_on_customer_id, :index_standing_orders_on_customer_id - rename_index :standing_orders, :index_subscriptions_on_payment_method_id, :index_standing_orders_on_payment_method_id - rename_index :standing_orders, :index_subscriptions_on_schedule_id, :index_standing_orders_on_schedule_id - rename_index :standing_orders, :index_subscriptions_on_ship_address_id, :index_standing_orders_on_ship_address_id - rename_index :standing_orders, :index_subscriptions_on_shipping_method_id, :index_standing_orders_on_shipping_method_id - rename_index :standing_orders, :index_subscriptions_on_shop_id, :index_standing_orders_on_shop_id - - rename_column :enterprises, :enable_subscriptions, :enable_standing_orders - rename_column :proxy_orders, :subscription_id, :standing_order_id - rename_column :standing_line_items, :subscription_id, :standing_order_id - - add_index :proxy_orders, [:order_cycle_id, :standing_order_id], unique: true - add_index :proxy_orders, :standing_order_id - add_index :standing_line_items, :standing_order_id - - add_foreign_key :proxy_orders, :standing_orders, name: :standing_order_id_fk - add_foreign_key :standing_line_items, :standing_orders, name: :oc_standing_line_items_standing_order_id_fk - - add_foreign_key :standing_orders, :customers, name: :oc_standing_orders_customer_id_fk - add_foreign_key :standing_orders, :enterprises, name: :oc_standing_orders_shop_id_fk, column: :shop_id - add_foreign_key :standing_orders, :schedules, name: :oc_standing_orders_schedule_id_fk - add_foreign_key :standing_orders, :spree_addresses, name: :standing_orders_bill_address_id_fk, column: :bill_address_id - add_foreign_key :standing_orders, :spree_addresses, name: :standing_orders_ship_address_id_fk, column: :ship_address_id - add_foreign_key :standing_orders, :spree_credit_cards, name: :standing_orders_credit_card_id_fk, column: :credit_card_id - add_foreign_key :standing_orders, :spree_payment_methods, name: :oc_standing_orders_payment_method_id_fk, column: :payment_method_id - add_foreign_key :standing_orders, :spree_shipping_methods, name: :oc_standing_orders_shipping_method_id_fk, column: :shipping_method_id - end -end diff --git a/db/migrate/20180204235108_rename_standing_line_items_to_subscription_line_items.rb b/db/migrate/20180204235108_rename_standing_line_items_to_subscription_line_items.rb deleted file mode 100644 index eda85f905b..0000000000 --- a/db/migrate/20180204235108_rename_standing_line_items_to_subscription_line_items.rb +++ /dev/null @@ -1,27 +0,0 @@ -class RenameStandingLineItemsToSubscriptionLineItems < ActiveRecord::Migration - def up - remove_foreign_key :standing_line_items, name: :oc_standing_line_items_variant_id_fk - remove_foreign_key :standing_line_items, name: :standing_line_items_subscription_id_fk - - rename_table :standing_line_items, :subscription_line_items - - rename_index :subscription_line_items, :index_standing_line_items_on_subscription_id, :index_subscription_line_items_on_subscription_id - rename_index :subscription_line_items, :index_standing_line_items_on_variant_id, :index_subscription_line_items_on_variant_id - - add_foreign_key :subscription_line_items, :spree_variants, name: :subscription_line_items_variant_id_fk, column: :variant_id - add_foreign_key :subscription_line_items, :subscriptions, name: :subscription_line_items_subscription_id_fk - end - - def down - remove_foreign_key :subscription_line_items, name: :subscription_line_items_variant_id_fk - remove_foreign_key :subscription_line_items, name: :subscription_line_items_subscription_id_fk - - rename_table :subscription_line_items, :standing_line_items - - rename_index :standing_line_items, :index_subscription_line_items_on_subscription_id, :index_standing_line_items_on_subscription_id - rename_index :standing_line_items, :index_subscription_line_items_on_variant_id, :index_standing_line_items_on_variant_id - - add_foreign_key :standing_line_items, :spree_variants, name: :oc_standing_line_items_variant_id_fk, column: :variant_id - add_foreign_key :standing_line_items, :subscriptions, name: :standing_line_items_subscription_id_fk - end -end diff --git a/db/migrate/20180222231639_add_shipping_fee_estimate_and_payment_fee_estimate_to_subscription.rb b/db/migrate/20180222231639_add_shipping_fee_estimate_and_payment_fee_estimate_to_subscription.rb deleted file mode 100644 index 2c4f29d891..0000000000 --- a/db/migrate/20180222231639_add_shipping_fee_estimate_and_payment_fee_estimate_to_subscription.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddShippingFeeEstimateAndPaymentFeeEstimateToSubscription < ActiveRecord::Migration - def change - add_column :subscriptions, :shipping_fee_estimate, :decimal, :precision => 8, :scale => 2 - add_column :subscriptions, :payment_fee_estimate, :decimal, :precision => 8, :scale => 2 - end -end diff --git a/db/migrate/20180316034336_remove_placed_at_and_confirmed_at_from_order_cycles.rb b/db/migrate/20180316034336_remove_placed_at_and_confirmed_at_from_order_cycles.rb deleted file mode 100644 index b41d698eb3..0000000000 --- a/db/migrate/20180316034336_remove_placed_at_and_confirmed_at_from_order_cycles.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RemovePlacedAtAndConfirmedAtFromOrderCycles < ActiveRecord::Migration - def up - remove_column :order_cycles, :standing_orders_placed_at - remove_column :order_cycles, :standing_orders_confirmed_at - end - - def down - add_column :order_cycles, :standing_orders_placed_at, :datetime - add_column :order_cycles, :standing_orders_confirmed_at, :datetime - end -end diff --git a/db/migrate/20180406045821_add_charges_allowed_to_customers.rb b/db/migrate/20180406045821_add_charges_allowed_to_customers.rb deleted file mode 100644 index 4503dc87b6..0000000000 --- a/db/migrate/20180406045821_add_charges_allowed_to_customers.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddChargesAllowedToCustomers < ActiveRecord::Migration - def change - add_column :customers, :allow_charges, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20180418025217_add_is_default_to_credit_card.rb b/db/migrate/20180418025217_add_is_default_to_credit_card.rb deleted file mode 100644 index c39b3e44dc..0000000000 --- a/db/migrate/20180418025217_add_is_default_to_credit_card.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIsDefaultToCreditCard < ActiveRecord::Migration - def change - add_column :spree_credit_cards, :is_default, :boolean, default: false - end -end diff --git a/db/migrate/20180426145630_create_spree_stock_items.spree.rb b/db/migrate/20180426145630_create_spree_stock_items.spree.rb deleted file mode 100644 index cd6f349740..0000000000 --- a/db/migrate/20180426145630_create_spree_stock_items.spree.rb +++ /dev/null @@ -1,15 +0,0 @@ -# This migration comes from spree (originally 20130211190146) -class CreateSpreeStockItems < ActiveRecord::Migration - def change - create_table :spree_stock_items do |t| - t.belongs_to :stock_location - t.belongs_to :variant - t.integer :count_on_hand, null: false, default: 0 - t.integer :lock_version - - t.timestamps - end - add_index :spree_stock_items, :stock_location_id - add_index :spree_stock_items, [:stock_location_id, :variant_id], :name => 'stock_item_by_loc_and_var_id' - end -end diff --git a/db/migrate/20180426145631_create_spree_stock_locations.spree.rb b/db/migrate/20180426145631_create_spree_stock_locations.spree.rb deleted file mode 100644 index a3e4d1a4dc..0000000000 --- a/db/migrate/20180426145631_create_spree_stock_locations.spree.rb +++ /dev/null @@ -1,12 +0,0 @@ -# This migration comes from spree (originally 20130211191120) -class CreateSpreeStockLocations < ActiveRecord::Migration - def change - create_table :spree_stock_locations do |t| - t.string :name - t.belongs_to :address - - t.timestamps - end - add_index :spree_stock_locations, :address_id - end -end diff --git a/db/migrate/20180426145632_create_default_stock.spree.rb b/db/migrate/20180426145632_create_default_stock.spree.rb deleted file mode 100644 index 7e1d188e4a..0000000000 --- a/db/migrate/20180426145632_create_default_stock.spree.rb +++ /dev/null @@ -1,34 +0,0 @@ -Spree::Stock::Quantifier.class_eval do - def initialize(variant) - @variant = variant - @stock_items = Spree::StockItem.joins(:stock_location).where(:variant_id => @variant) - end -end - -# This migration comes from spree (originally 20130213191427) -class CreateDefaultStock < ActiveRecord::Migration - def up - Spree::StockLocation.skip_callback(:create, :after, :create_stock_items) - Spree::StockItem.skip_callback(:save, :after, :process_backorders) - location = Spree::StockLocation.create(name: 'default') - Spree::Variant.all.each do |variant| - stock_item = location.stock_items.build(variant: variant) - stock_item.send(:count_on_hand=, variant.count_on_hand) - stock_item.save! - end - - remove_column :spree_variants, :count_on_hand - end - - def down - add_column :spree_variants, :count_on_hand, :integer - - Spree::StockItem.all.each do |stock_item| - stock_item.variant.update_column :count_on_hand, stock_item.count_on_hand - end - - Spree::StockLocation.delete_all - Spree::StockItem.delete_all - end -end - diff --git a/db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb b/db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb deleted file mode 100644 index e102d7febb..0000000000 --- a/db/migrate/20180426145633_add_stock_location_id_to_spree_shipments.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130226191231) -class AddStockLocationIdToSpreeShipments < ActiveRecord::Migration - def change - add_column :spree_shipments, :stock_location_id, :integer - end -end diff --git a/db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb b/db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb deleted file mode 100644 index c3879d3604..0000000000 --- a/db/migrate/20180426145634_add_pending_to_inventory_unit.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130227143905) -class AddPendingToInventoryUnit < ActiveRecord::Migration - def change - add_column :spree_inventory_units, :pending, :boolean, :default => true - Spree::InventoryUnit.update_all(:pending => false) - end -end diff --git a/db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb b/db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb deleted file mode 100644 index 0732d4ffd0..0000000000 --- a/db/migrate/20180426145635_remove_on_demand_from_product_and_variant.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130228164411) -class RemoveOnDemandFromProductAndVariant < ActiveRecord::Migration - def change - remove_column :spree_products, :on_demand - # we are removing spree_variants.on_demand in a later migration - end -end diff --git a/db/migrate/20180426145636_create_shipping_method_zone.spree.rb b/db/migrate/20180426145636_create_shipping_method_zone.spree.rb deleted file mode 100644 index 2d99447b13..0000000000 --- a/db/migrate/20180426145636_create_shipping_method_zone.spree.rb +++ /dev/null @@ -1,23 +0,0 @@ -# This migration comes from spree (originally 20130228210442) -class CreateShippingMethodZone < ActiveRecord::Migration - def up - create_table :shipping_methods_zones, :id => false do |t| - t.integer :shipping_method_id - t.integer :zone_id - end - # This association has been corrected in a latter migration - # but when this database migration runs, the table is still incorrectly named - # 'shipping_methods_zones' instead of 'spre_shipping_methods_zones' - Spree::ShippingMethod.has_and_belongs_to_many :zones, :join_table => 'shipping_methods_zones', - :class_name => 'Spree::Zone', - :foreign_key => 'shipping_method_id' - Spree::ShippingMethod.all.each{|sm| sm.zones << Spree::Zone.find(sm.zone_id)} - - remove_column :spree_shipping_methods, :zone_id - end - - def down - drop_table :shipping_methods_zones - add_column :spree_shipping_methods, :zone_id, :integer - end -end diff --git a/db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb b/db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb deleted file mode 100644 index f686ac4aa7..0000000000 --- a/db/migrate/20180426145637_remove_shipping_category_id_from_shipping_method.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130301162745) -class RemoveShippingCategoryIdFromShippingMethod < ActiveRecord::Migration - def change - remove_column :spree_shipping_methods, :shipping_category_id - end -end diff --git a/db/migrate/20180426145638_create_shipping_method_categories.spree.rb b/db/migrate/20180426145638_create_shipping_method_categories.spree.rb deleted file mode 100644 index 2af03a7ec0..0000000000 --- a/db/migrate/20180426145638_create_shipping_method_categories.spree.rb +++ /dev/null @@ -1,14 +0,0 @@ -# This migration comes from spree (originally 20130301162924) -class CreateShippingMethodCategories < ActiveRecord::Migration - def change - create_table :spree_shipping_method_categories do |t| - t.integer :shipping_method_id, :null => false - t.integer :shipping_category_id, :null => false - - t.timestamps - end - - add_index :spree_shipping_method_categories, :shipping_method_id - add_index :spree_shipping_method_categories, :shipping_category_id - end -end diff --git a/db/migrate/20180426145639_create_spree_shipping_rates.spree.rb b/db/migrate/20180426145639_create_spree_shipping_rates.spree.rb deleted file mode 100644 index f2932a57b3..0000000000 --- a/db/migrate/20180426145639_create_spree_shipping_rates.spree.rb +++ /dev/null @@ -1,25 +0,0 @@ -# This migration comes from spree (originally 20130304162240) -class CreateSpreeShippingRates < ActiveRecord::Migration - def up - create_table :spree_shipping_rates do |t| - t.belongs_to :shipment - t.belongs_to :shipping_method - t.boolean :selected, :default => false - t.decimal :cost, :precision => 8, :scale => 2 - t.timestamps - end - add_index(:spree_shipping_rates, [:shipment_id, :shipping_method_id], - :name => 'spree_shipping_rates_join_index', - :unique => true) - - # Spree::Shipment.all.each do |shipment| - # shipping_method = Spree::ShippingMethod.find(shipment.shipment_method_id) - # shipment.add_shipping_method(shipping_method, true) - # end - end - - def down - # add_column :spree_shipments, :shipping_method_id, :integer - drop_table :spree_shipping_rates - end -end diff --git a/db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb b/db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb deleted file mode 100644 index 1562aecdb2..0000000000 --- a/db/migrate/20180426145640_remove_category_match_attributes_from_shipping_method.spree.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree (originally 20130304192936) -class RemoveCategoryMatchAttributesFromShippingMethod < ActiveRecord::Migration - def change - remove_column :spree_shipping_methods, :match_none - remove_column :spree_shipping_methods, :match_one - remove_column :spree_shipping_methods, :match_all - end -end diff --git a/db/migrate/20180426145641_create_stock_movements.spree.rb b/db/migrate/20180426145641_create_stock_movements.spree.rb deleted file mode 100644 index d7c8cb88d3..0000000000 --- a/db/migrate/20180426145641_create_stock_movements.spree.rb +++ /dev/null @@ -1,13 +0,0 @@ -# This migration comes from spree (originally 20130305143310) -class CreateStockMovements < ActiveRecord::Migration - def change - create_table :spree_stock_movements do |t| - t.belongs_to :stock_item - t.integer :quantity - t.string :action - - t.timestamps - end - add_index :spree_stock_movements, :stock_item_id - end -end diff --git a/db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb b/db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb deleted file mode 100644 index 4a16efeb40..0000000000 --- a/db/migrate/20180426145642_add_address_fields_to_stock_location.spree.rb +++ /dev/null @@ -1,23 +0,0 @@ -# This migration comes from spree (originally 20130306181701) -class AddAddressFieldsToStockLocation < ActiveRecord::Migration - def change - remove_column :spree_stock_locations, :address_id - - add_column :spree_stock_locations, :address1, :string - add_column :spree_stock_locations, :address2, :string - add_column :spree_stock_locations, :city, :string - add_column :spree_stock_locations, :state_id, :integer - add_column :spree_stock_locations, :state_name, :string - add_column :spree_stock_locations, :country_id, :integer - add_column :spree_stock_locations, :zipcode, :string - add_column :spree_stock_locations, :phone, :string - - - usa = Spree::Country.where(:iso => 'US').first - # In case USA isn't found. - # See #3115 - country = usa || Spree::Country.first - Spree::Country.reset_column_information - Spree::StockLocation.update_all(:country_id => country) - end -end diff --git a/db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb b/db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb deleted file mode 100644 index 0e69642de2..0000000000 --- a/db/migrate/20180426145643_add_active_field_to_stock_locations.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130306191917) -class AddActiveFieldToStockLocations < ActiveRecord::Migration - def change - add_column :spree_stock_locations, :active, :boolean, :default => true - end -end diff --git a/db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb b/db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb deleted file mode 100644 index 839e3b3d09..0000000000 --- a/db/migrate/20180426145644_add_backorderable_to_stock_item.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130306195650) -class AddBackorderableToStockItem < ActiveRecord::Migration - def change - add_column :spree_stock_items, :backorderable, :boolean, :default => true - end -end diff --git a/db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb b/db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb deleted file mode 100644 index c991b94e4a..0000000000 --- a/db/migrate/20180426145645_add_default_quantity_to_stock_movement.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130307161754) -class AddDefaultQuantityToStockMovement < ActiveRecord::Migration - def change - change_column :spree_stock_movements, :quantity, :integer, :default => 0 - end -end diff --git a/db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb b/db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb deleted file mode 100644 index 7e0f0987b7..0000000000 --- a/db/migrate/20180426145646_add_source_and_destination_to_stock_movements.spree.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This migration comes from spree (originally 20130318151756) -class AddSourceAndDestinationToStockMovements < ActiveRecord::Migration - def change - change_table :spree_stock_movements do |t| - t.references :source, polymorphic: true - t.references :destination, polymorphic: true - end - end -end diff --git a/db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb b/db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb deleted file mode 100644 index 7c1a74679a..0000000000 --- a/db/migrate/20180426145647_add_originator_to_stock_movement.spree.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from spree (originally 20130319183250) -class AddOriginatorToStockMovement < ActiveRecord::Migration - def change - change_table :spree_stock_movements do |t| - t.references :originator, polymorphic: true - end - end -end diff --git a/db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb b/db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb deleted file mode 100644 index 6735614f4e..0000000000 --- a/db/migrate/20180426145648_drop_source_and_destination_from_stock_movement.spree.rb +++ /dev/null @@ -1,16 +0,0 @@ -# This migration comes from spree (originally 20130319190507) -class DropSourceAndDestinationFromStockMovement < ActiveRecord::Migration - def up - change_table :spree_stock_movements do |t| - t.remove_references :source, :polymorphic => true - t.remove_references :destination, :polymorphic => true - end - end - - def down - change_table :spree_stock_movements do |t| - t.references :source, polymorphic: true - t.references :destination, polymorphic: true - end - end -end diff --git a/db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb b/db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb deleted file mode 100644 index 4f759427ee..0000000000 --- a/db/migrate/20180426145649_migrate_inventory_unit_sold_to_on_hand.spree.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This migration comes from spree (originally 20130325163316) -class MigrateInventoryUnitSoldToOnHand < ActiveRecord::Migration - def up - Spree::InventoryUnit.where(:state => 'sold').update_all(:state => 'on_hand') - end - - def down - Spree::InventoryUnit.where(:state => 'on_hand').update_all(:state => 'sold') - end -end diff --git a/db/migrate/20180426145650_add_stock_location_to_rma.spree.rb b/db/migrate/20180426145650_add_stock_location_to_rma.spree.rb deleted file mode 100644 index 54d85f76a4..0000000000 --- a/db/migrate/20180426145650_add_stock_location_to_rma.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130326175857) -class AddStockLocationToRma < ActiveRecord::Migration - def change - add_column :spree_return_authorizations, :stock_location_id, :integer - end -end diff --git a/db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb b/db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb deleted file mode 100644 index f5c1b5a0cf..0000000000 --- a/db/migrate/20180426145651_update_shipment_state_for_canceled_orders.spree.rb +++ /dev/null @@ -1,16 +0,0 @@ -# This migration comes from spree (originally 20130328130308) -class UpdateShipmentStateForCanceledOrders < ActiveRecord::Migration - def up - shipments = Spree::Shipment.joins(:order). - where("spree_orders.state = 'canceled'") - case Spree::Shipment.connection.adapter_name - when "SQLite3" - shipments.update_all("state = 'cancelled'") - when "MySQL" || "PostgreSQL" - shipments.update_all("spree_shipments.state = 'cancelled'") - end - end - - def down - end -end diff --git a/db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb b/db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb deleted file mode 100644 index c522a765cc..0000000000 --- a/db/migrate/20180426145652_remove_stock_item_and_variant_lock.spree.rb +++ /dev/null @@ -1,15 +0,0 @@ -# This migration comes from spree (originally 20130329134939) -class RemoveStockItemAndVariantLock < ActiveRecord::Migration - def up - # we are moving to pessimistic locking on stock_items - remove_column :spree_stock_items, :lock_version - - # variants no longer manage their count_on_hand so we are removing their lock - remove_column :spree_variants, :lock_version - end - - def down - add_column :spree_stock_items, :lock_version, :integer - add_column :spree_variants, :lock_version, :integer - end -end diff --git a/db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb b/db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb deleted file mode 100644 index 67c24f568d..0000000000 --- a/db/migrate/20180426145653_add_shipping_rates_to_shipments.spree.rb +++ /dev/null @@ -1,16 +0,0 @@ -# This migration comes from spree (originally 20130417123427) -class AddShippingRatesToShipments < ActiveRecord::Migration - def up - Spree::Shipment.all.each do |shipment| - shipment.shipping_rates.create!(:shipping_method_id => shipment.shipping_method_id, - :cost => shipment.cost, - :selected => true) - end - - remove_column :spree_shipments, :shipping_method_id - end - - def down - add_column :spree_shipments, :shipping_method_id, :integer - end -end diff --git a/db/migrate/20180426145654_create_spree_stock_transfers.spree.rb b/db/migrate/20180426145654_create_spree_stock_transfers.spree.rb deleted file mode 100644 index 1b73d9b176..0000000000 --- a/db/migrate/20180426145654_create_spree_stock_transfers.spree.rb +++ /dev/null @@ -1,15 +0,0 @@ -# This migration comes from spree (originally 20130418125341) -class CreateSpreeStockTransfers < ActiveRecord::Migration - def change - create_table :spree_stock_transfers do |t| - t.string :type - t.string :reference_number - t.integer :source_location_id - t.integer :destination_location_id - t.timestamps - end - - add_index :spree_stock_transfers, :source_location_id - add_index :spree_stock_transfers, :destination_location_id - end -end diff --git a/db/migrate/20180426145655_drop_products_count_on_hand.spree.rb b/db/migrate/20180426145655_drop_products_count_on_hand.spree.rb deleted file mode 100644 index 29cb947a56..0000000000 --- a/db/migrate/20180426145655_drop_products_count_on_hand.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130423110707) -class DropProductsCountOnHand < ActiveRecord::Migration - def up - remove_column :spree_products, :count_on_hand - end -end diff --git a/db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb b/db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb deleted file mode 100644 index 64b9ccb108..0000000000 --- a/db/migrate/20180426145656_set_default_shipping_rate_cost.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130423223847) -class SetDefaultShippingRateCost < ActiveRecord::Migration - def change - change_column :spree_shipping_rates, :cost, :decimal, default: 0, precision: 8, scale: 2 - end -end diff --git a/db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb b/db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb deleted file mode 100644 index cf06743da0..0000000000 --- a/db/migrate/20180426145657_add_number_to_stock_transfer.spree.rb +++ /dev/null @@ -1,24 +0,0 @@ -# This migration comes from spree (originally 20130509115210) -class AddNumberToStockTransfer < ActiveRecord::Migration - def up - remove_index :spree_stock_transfers, :source_location_id - remove_index :spree_stock_transfers, :destination_location_id - - rename_column :spree_stock_transfers, :reference_number, :reference - add_column :spree_stock_transfers, :number, :string - - Spree::StockTransfer.all.each do |transfer| - transfer.send(:generate_stock_transfer_number) - transfer.save! - end - - add_index :spree_stock_transfers, :number - add_index :spree_stock_transfers, :source_location_id - add_index :spree_stock_transfers, :destination_location_id - end - - def down - rename_column :spree_stock_transfers, :reference, :reference_number - remove_column :spree_stock_transfers, :number, :string - end -end diff --git a/db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb b/db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb deleted file mode 100644 index cd089f846d..0000000000 --- a/db/migrate/20180426145658_add_sku_index_to_spree_variants.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130514151929) -class AddSkuIndexToSpreeVariants < ActiveRecord::Migration - def change - add_index :spree_variants, :sku - end -end diff --git a/db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb b/db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb deleted file mode 100644 index 29939c59e6..0000000000 --- a/db/migrate/20180426145659_add_backorderable_default_to_spree_stock_location.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130515180736) -class AddBackorderableDefaultToSpreeStockLocation < ActiveRecord::Migration - def change - add_column :spree_stock_locations, :backorderable_default, :boolean, default: true - end -end diff --git a/db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb b/db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb deleted file mode 100644 index bfc55eac56..0000000000 --- a/db/migrate/20180426145660_add_propage_all_variants_to_spree_stock_location.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130516151222) -class AddPropageAllVariantsToSpreeStockLocation < ActiveRecord::Migration - def change - add_column :spree_stock_locations, :propagate_all_variants, :boolean, default: true - end -end diff --git a/db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb b/db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb deleted file mode 100644 index 5c7ee6dd95..0000000000 --- a/db/migrate/20180426145661_rename_shipping_methods_zones_to_spree_shipping_methods_zones.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130611054351) -class RenameShippingMethodsZonesToSpreeShippingMethodsZones < ActiveRecord::Migration - def change - rename_table :shipping_methods_zones, :spree_shipping_methods_zones - end -end diff --git a/db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb b/db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb deleted file mode 100644 index c804d9a1f7..0000000000 --- a/db/migrate/20180426145662_add_deleted_at_to_spree_tax_rates.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130708052307) -class AddDeletedAtToSpreeTaxRates < ActiveRecord::Migration - def change - add_column :spree_tax_rates, :deleted_at, :datetime - end -end diff --git a/db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb b/db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb deleted file mode 100644 index 42c60bd3f3..0000000000 --- a/db/migrate/20180426145663_remove_lock_version_from_inventory_units.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130711200933) -class RemoveLockVersionFromInventoryUnits < ActiveRecord::Migration - def change - # we are moving to pessimistic locking on stock_items - remove_column :spree_inventory_units, :lock_version - end -end diff --git a/db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb b/db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb deleted file mode 100644 index d54222f559..0000000000 --- a/db/migrate/20180426145664_add_cost_price_to_line_item.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130718042445) -class AddCostPriceToLineItem < ActiveRecord::Migration - def change - add_column :spree_line_items, :cost_price, :decimal, :precision => 8, :scale => 2 - end -end diff --git a/db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb b/db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb deleted file mode 100644 index a05f4279a4..0000000000 --- a/db/migrate/20180426145665_set_backorderable_to_default_to_false.spree.rb +++ /dev/null @@ -1,7 +0,0 @@ -# This migration comes from spree (originally 20130718233855) -class SetBackorderableToDefaultToFalse < ActiveRecord::Migration - def change - change_column :spree_stock_items, :backorderable, :boolean, :default => false - change_column :spree_stock_locations, :backorderable_default, :boolean, :default => false - end -end diff --git a/db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb b/db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb deleted file mode 100644 index fe59c0fc21..0000000000 --- a/db/migrate/20180426145666_add_created_by_id_to_spree_orders.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130725031716) -class AddCreatedByIdToSpreeOrders < ActiveRecord::Migration - def change - add_column :spree_orders, :created_by_id, :integer - end -end diff --git a/db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb b/db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb deleted file mode 100644 index c4c279ca4c..0000000000 --- a/db/migrate/20180426145667_index_completed_at_on_spree_orders.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130729214043) -class IndexCompletedAtOnSpreeOrders < ActiveRecord::Migration - def change - add_index :spree_orders, :completed_at - end -end diff --git a/db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb b/db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb deleted file mode 100644 index 2b7e1a51bc..0000000000 --- a/db/migrate/20180426145668_add_tax_category_id_to_spree_line_items.spree.rb +++ /dev/null @@ -1,6 +0,0 @@ -# This migration comes from spree (originally 20130802014537) -class AddTaxCategoryIdToSpreeLineItems < ActiveRecord::Migration - def change - add_column :spree_line_items, :tax_category_id, :integer - end -end diff --git a/db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb b/db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb deleted file mode 100644 index 4ce74249b3..0000000000 --- a/db/migrate/20180426145669_migrate_tax_categories_to_line_items.spree.rb +++ /dev/null @@ -1,14 +0,0 @@ -# This migration comes from spree (originally 20130802022321) -class MigrateTaxCategoriesToLineItems < ActiveRecord::Migration - def change - Spree::LineItem.includes(:variant => { :product => :tax_category }).find_in_batches do |line_items| - line_items.each do |line_item| - next if line_item.variant.nil? - next if line_item.variant.product.nil? - next if line_item.product.nil? - next unless line_item.product.tax_category.present? - line_item.update_column(:tax_category_id, line_item.product.tax_category.id) - end - end - end -end diff --git a/db/migrate/20180510083800_remove_credit_card_from_subscriptions.rb b/db/migrate/20180510083800_remove_credit_card_from_subscriptions.rb deleted file mode 100644 index 0821fbef61..0000000000 --- a/db/migrate/20180510083800_remove_credit_card_from_subscriptions.rb +++ /dev/null @@ -1,13 +0,0 @@ -class RemoveCreditCardFromSubscriptions < ActiveRecord::Migration - def up - remove_foreign_key :subscriptions, name: :subscriptions_credit_card_id_fk - remove_index :subscriptions, :credit_card_id - remove_column :subscriptions, :credit_card_id - end - - def down - add_column :subscriptions, :credit_card_id, :integer - add_index :subscriptions, :credit_card_id - add_foreign_key :subscriptions, :spree_credit_cards, name: :subscriptions_credit_card_id_fk, column: :credit_card_id - end -end diff --git a/db/migrate/20180812214434_drop_carts.rb b/db/migrate/20180812214434_drop_carts.rb deleted file mode 100644 index f3dfb36ee7..0000000000 --- a/db/migrate/20180812214434_drop_carts.rb +++ /dev/null @@ -1,7 +0,0 @@ -class DropCarts < ActiveRecord::Migration - def change - remove_foreign_key :spree_orders, column: :cart_id - remove_column :spree_orders, :cart_id - drop_table :carts - end -end diff --git a/db/migrate/20180906094641_add_uniqueness_of_variant_id_to_spree_stock_items.rb b/db/migrate/20180906094641_add_uniqueness_of_variant_id_to_spree_stock_items.rb deleted file mode 100644 index 93b2853208..0000000000 --- a/db/migrate/20180906094641_add_uniqueness_of_variant_id_to_spree_stock_items.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Since OFN has only a single default StockLocation, variants in OFN can only -# have a stock item. By adding this unique index we constraint that at DB level -# ensuring data integrity. -class AddUniquenessOfVariantIdToSpreeStockItems < ActiveRecord::Migration - def change - add_index :spree_stock_items, :variant_id, unique: true - end -end diff --git a/db/migrate/20180910155506_add_uniqueness_of_order_id_to_spree_shipments.rb b/db/migrate/20180910155506_add_uniqueness_of_order_id_to_spree_shipments.rb deleted file mode 100644 index 0ee5849afd..0000000000 --- a/db/migrate/20180910155506_add_uniqueness_of_order_id_to_spree_shipments.rb +++ /dev/null @@ -1,92 +0,0 @@ -# This migration is an OFN specific migration that enforces an order to have a single shipment at all times -class AddUniquenessOfOrderIdToSpreeShipments < ActiveRecord::Migration - def change - Spree::InventoryUnit.connection.schema_cache.clear! - Spree::InventoryUnit.reset_column_information - - destroy_all_but_latest_shipments - - remove_index :spree_shipments, :order_id - add_index :spree_shipments, :order_id, unique: true - end - - private - - # Destroy all but the latest shipment in each order - def destroy_all_but_latest_shipments - latest_shipments = Spree::Shipment. - select("order_id, MAX(updated_at) updated_at"). - group(:order_id). - having("count(*) > 1") - - all_duplicated_shipments = Spree::Shipment. - joins("INNER JOIN (#{latest_shipments.to_sql}) latest_shipments ON spree_shipments.order_id = latest_shipments.order_id") - backup_to_csv(all_duplicated_shipments) - - shipments_to_delete = Spree::Shipment. - joins("INNER JOIN (#{latest_shipments.to_sql}) latest_shipments ON spree_shipments.order_id = latest_shipments.order_id AND spree_shipments.updated_at != latest_shipments.updated_at") - remove_association_to_adjustments(shipments_to_delete) - shipments_to_delete.destroy_all - end - - def remove_association_to_adjustments(shipments) - Spree::Adjustment. - joins("INNER JOIN (#{shipments.to_sql}) shipments_to_delete ON shipments_to_delete.id = spree_adjustments.source_id and spree_adjustments.source_type = 'Spree::Shipment'"). - update_all(source_id: nil, source_type: nil, originator_id: nil, originator_type: nil, mandatory: nil) - end - - def backup_to_csv(shipments) - CSV.open(csv_path, "w") do |csv| - csv << csv_header_row - - shipments.each do |shipment| - csv << shipment_csv_row(shipment) - end - end - end - - def csv_header_row - %w( - id - tracking - number - order_number - shipping_method_name - cost - state - shipped_at - created_at - updated_at - address_json - ) - end - - def shipment_csv_row(shipment) - [ - shipment.id, - shipment.tracking, - shipment.number, - shipment.order.number, - shipment.shipping_method.andand.name, - shipment.cost, - shipment.state, - shipment.shipped_at, - shipment.created_at, - shipment.updated_at, - shipment.address.to_json - ] - end - - def csv_path - ensure_reports_path_exists - reports_path.join("duplicated_shipments_backup.csv") - end - - def reports_path - Rails.root.join("reports") - end - - def ensure_reports_path_exists - Dir.mkdir(reports_path) unless File.exist?(reports_path) - end -end diff --git a/db/migrate/20180919102548_remove_shipping_method_name_from_spree_line_items.rb b/db/migrate/20180919102548_remove_shipping_method_name_from_spree_line_items.rb deleted file mode 100644 index eaae250a18..0000000000 --- a/db/migrate/20180919102548_remove_shipping_method_name_from_spree_line_items.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveShippingMethodNameFromSpreeLineItems < ActiveRecord::Migration - def up - remove_column :spree_line_items, :shipping_method_name - end - - def down - add_column :spree_line_items, :shipping_method_name, :string - end -end diff --git a/db/migrate/20181008201815_update_instagram_data.rb b/db/migrate/20181008201815_update_instagram_data.rb deleted file mode 100644 index d1a45dc155..0000000000 --- a/db/migrate/20181008201815_update_instagram_data.rb +++ /dev/null @@ -1,8 +0,0 @@ -class UpdateInstagramData < ActiveRecord::Migration - def change - Enterprise.where("instagram like ?", "%instagram.com%").find_each do |e| - e.instagram = e.instagram.split('/').last - e.save - end - end -end diff --git a/db/migrate/20181010093850_fix_variants_missing_unit_value.rb b/db/migrate/20181010093850_fix_variants_missing_unit_value.rb deleted file mode 100644 index c4226d0dc2..0000000000 --- a/db/migrate/20181010093850_fix_variants_missing_unit_value.rb +++ /dev/null @@ -1,49 +0,0 @@ -# Fixes variants whose product.variant_unit is 'weight' and miss a unit_value, -# showing 1 unit of the specified weight. That is, if the user chose Kg, it'll -# display 1 as unit. -class FixVariantsMissingUnitValue < ActiveRecord::Migration - HUMAN_UNIT_VALUE = 1 - - def up - logger.info "Fixing variants missing unit_value...\n" - - variants_missing_unit_value.find_each do |variant| - logger.info "Processing variant #{variant.id}..." - - fix_unit_value(variant) - end - - logger.info "Done!" - end - - def down - end - - private - - def variants_missing_unit_value - Spree::Variant - .joins(:product) - .readonly(false) - .where( - spree_products: { variant_unit: 'weight' }, - spree_variants: { unit_value: nil } - ) - end - - def fix_unit_value(variant) - variant.unit_value = HUMAN_UNIT_VALUE * variant.product.variant_unit_scale - - if variant.save - logger.info "Successfully fixed variant #{variant.id}" - else - logger.info "Failed fixing variant #{variant.id}" - end - - logger.info "" - end - - def logger - @logger ||= Logger.new('log/migrate.log') - end -end diff --git a/db/migrate/20181020103501_revoke_variant_overrideswithout_permissions.rb b/db/migrate/20181020103501_revoke_variant_overrideswithout_permissions.rb deleted file mode 100644 index d8140c9bf3..0000000000 --- a/db/migrate/20181020103501_revoke_variant_overrideswithout_permissions.rb +++ /dev/null @@ -1,17 +0,0 @@ -class RevokeVariantOverrideswithoutPermissions < ActiveRecord::Migration - def up - # This process was executed when the permission_revoked_at colum was created (see AddPermissionRevokedAtToVariantOverrides) - # It needs to be repeated due to #2739 - variant_override_hubs = Enterprise.where(id: VariantOverride.select(:hub_id).uniq) - - variant_override_hubs.find_each do |hub| - permitting_producer_ids = hub.relationships_as_child - .with_permission(:create_variant_overrides).pluck(:parent_id) - - variant_overrides_with_revoked_permissions = VariantOverride.for_hubs(hub) - .joins(variant: :product).where("spree_products.supplier_id NOT IN (?)", permitting_producer_ids) - - variant_overrides_with_revoked_permissions.update_all(permission_revoked_at: Time.now) - end - end -end diff --git a/db/migrate/20181031105158_allow_all_suppliers_own_variant_overrides.rb b/db/migrate/20181031105158_allow_all_suppliers_own_variant_overrides.rb deleted file mode 100644 index a04bd5dfff..0000000000 --- a/db/migrate/20181031105158_allow_all_suppliers_own_variant_overrides.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AllowAllSuppliersOwnVariantOverrides < ActiveRecord::Migration - def up - # This migration is fixing a detail of previous migration RevokeVariantOverrideswithoutPermissions - # Here we allow all variant_overrides where hub_id is the products supplier_id - # This is needed when the supplier herself uses the inventory to manage stock and not the catalog - owned_variant_overrides = VariantOverride.unscoped - .joins(variant: :product).where("spree_products.supplier_id = variant_overrides.hub_id") - - owned_variant_overrides.update_all(permission_revoked_at: nil) - end -end - diff --git a/db/migrate/20181106162211_update_weight_calculator_type_class_name.rb b/db/migrate/20181106162211_update_weight_calculator_type_class_name.rb deleted file mode 100644 index f8e15b3414..0000000000 --- a/db/migrate/20181106162211_update_weight_calculator_type_class_name.rb +++ /dev/null @@ -1,9 +0,0 @@ -class UpdateWeightCalculatorTypeClassName < ActiveRecord::Migration - def up - Spree::Calculator.connection.execute("UPDATE spree_calculators SET type = 'Calculator::Weight' WHERE type = 'OpenFoodNetwork::Calculator::Weight'") - end - - def down - Spree::Calculator.connection.execute("UPDATE spree_calculators SET type = 'OpenFoodNetwork::Calculator::Weight' WHERE type = 'Calculator::Weight'") - end -end diff --git a/db/migrate/20181123012635_associate_customers_to_users.rb b/db/migrate/20181123012635_associate_customers_to_users.rb deleted file mode 100644 index 95fab93677..0000000000 --- a/db/migrate/20181123012635_associate_customers_to_users.rb +++ /dev/null @@ -1,42 +0,0 @@ -# When we introduced the Customer model, we didn't associate any existing -# customers with users that have the same email address. -# Later we decided to create that association when users sign up. But we didn't -# update all the existing customers. We do that now for data consistency and to -# solve several bugs. -# -# - https://github.com/openfoodfoundation/openfoodnetwork/pull/2084 -# - https://github.com/openfoodfoundation/openfoodnetwork/issues/2841 -class AssociateCustomersToUsers < ActiveRecord::Migration - class Customer < ActiveRecord::Base - end - - def up - save_customers - execute "UPDATE customers - SET user_id = spree_users.id - FROM spree_users - WHERE customers.email = spree_users.email - AND customers.user_id IS NULL;" - end - - def down - customers = backed_up_customers - Customer.where(id: customers).update_all(user_id: nil) - end - - def save_customers - customers = Customer. - joins("INNER JOIN spree_users ON customers.email = spree_users.email"). - where(user_id: nil).all - - File.write(backup_file, YAML.dump(customers)) - end - - def backed_up_customers - YAML.load(File.read(backup_file)) - end - - def backup_file - File.join("log", "customers_without_user_association.log") - end -end diff --git a/db/migrate/20181128054803_old_migrations_removed.rb b/db/migrate/20181128054803_old_migrations_removed.rb new file mode 100644 index 0000000000..e0ad67a62b --- /dev/null +++ b/db/migrate/20181128054803_old_migrations_removed.rb @@ -0,0 +1,11 @@ +class OldMigrationsRemoved < ActiveRecord::Migration + LAST_DELETED_MIGRATION = 20181128054803 + def up + if ActiveRecord::Migrator.current_version < LAST_DELETED_MIGRATION + message = "You haven't updated your dev environment in a long time! " \ + "Legacy migration files before 2019 have now been removed. " \ + "Run `rails db:schema:load` before running `rails db:migrate`." + raise StandardError, message + end + end +end diff --git a/db/migrate/20181128054803_simplify_variant_override_stock_settings.rb b/db/migrate/20181128054803_simplify_variant_override_stock_settings.rb deleted file mode 100644 index 6627dca015..0000000000 --- a/db/migrate/20181128054803_simplify_variant_override_stock_settings.rb +++ /dev/null @@ -1,165 +0,0 @@ -# This simplifies variant overrides to have only the following combinations: -# -# on_demand | count_on_hand -# -----------+--------------- -# true | nil -# false | set -# nil | nil -# -# Refer to the table {here}[https://github.com/openfoodfoundation/openfoodnetwork/issues/3067] for -# the effect of different variant and variant override stock configurations. -# -# Furthermore, this will allow all existing variant overrides to satisfy the newly added model -# validation rules. -class SimplifyVariantOverrideStockSettings < ActiveRecord::Migration - class VariantOverride < ActiveRecord::Base - belongs_to :variant - belongs_to :hub, class_name: "Enterprise" - - scope :with_count_on_hand, -> { where("count_on_hand IS NOT NULL") } - scope :without_count_on_hand, -> { where(count_on_hand: nil) } - end - - class Variant < ActiveRecord::Base - self.table_name = "spree_variants" - - belongs_to :product - - def name - namer = OpenFoodNetwork::OptionValueNamer.new(self) - namer.name - end - end - - class Product < ActiveRecord::Base - self.table_name = "spree_products" - - belongs_to :supplier, class_name: "Enterprise" - end - - class Enterprise < ActiveRecord::Base; end - - def up - ensure_reports_path_exists - - CSV.open(csv_path, "w") do |csv| - csv << csv_header_row - - update_use_producer_stock_settings_with_count_on_hand(csv) - update_on_demand_with_count_on_hand(csv) - update_limited_stock_without_count_on_hand(csv) - end - - split_csv_by_distributor - end - - def down - CSV.foreach(csv_path, headers: true) do |row| - VariantOverride.where(id: row["variant_override_id"]) - .update_all(on_demand: row["previous_on_demand"], - count_on_hand: row["previous_count_on_hand"]) - end - end - - private - - def reports_path - Rails.root.join("reports", "SimplifyVariantOverrideStockSettings") - end - - def ensure_reports_path_exists - Dir.mkdir(reports_path) unless File.exist?(reports_path) - end - - def csv_path - reports_path.join("changed_variant_overrides.csv") - end - - def distributor_csv_path(name, id) - reports_path.join("changed_variant_overrides-#{name.parameterize('_')}-#{id}.csv") - end - - # When on_demand is nil but count_on_hand is set, force limited stock. - def update_use_producer_stock_settings_with_count_on_hand(csv) - variant_overrides = VariantOverride.where(on_demand: nil).with_count_on_hand - update_variant_overrides_and_log(csv, variant_overrides) do |variant_override| - variant_override.update_attributes!(on_demand: false) - end - end - - # Clear count_on_hand if forcing on demand. - def update_on_demand_with_count_on_hand(csv) - variant_overrides = VariantOverride.where(on_demand: true).with_count_on_hand - update_variant_overrides_and_log(csv, variant_overrides) do |variant_override| - variant_override.update_attributes!(count_on_hand: nil) - end - end - - # When on_demand is false but count on hand is not specified, set this to use producer stock - # settings. - def update_limited_stock_without_count_on_hand(csv) - variant_overrides = VariantOverride.where(on_demand: false).without_count_on_hand - update_variant_overrides_and_log(csv, variant_overrides) do |variant_override| - variant_override.update_attributes!(on_demand: nil) - end - end - - def update_variant_overrides_and_log(csv, variant_overrides) - variant_overrides.find_each do |variant_override| - csv << variant_override_log_row(variant_override) do - yield variant_override - end - end - end - - def csv_header_row - %w( - variant_override_id - distributor_name distributor_id - producer_name producer_id - product_name product_id - variant_description variant_id - previous_on_demand previous_count_on_hand - updated_on_demand updated_count_on_hand - ) - end - - def variant_override_log_row(variant_override) - variant = variant_override.variant - distributor = variant_override.hub - product = variant.andand.product - supplier = product.andand.supplier - - row = [ - variant_override.id, - distributor.andand.name, distributor.andand.id, - supplier.andand.name, supplier.andand.id, - product.andand.name, product.andand.id, - variant.andand.name, variant.andand.id, - variant_override.on_demand, variant_override.count_on_hand - ] - - yield variant_override - - row + [variant_override.on_demand, variant_override.count_on_hand] - end - - def split_csv_by_distributor - table = CSV.read(csv_path) - distributor_ids = table[1..-1].map { |row| row[2] }.uniq # Don't use the header row. - - distributor_ids.each do |distributor_id| - distributor_data_rows = filter_data_rows_for_distributor(table[1..-1], distributor_id) - distributor_name = distributor_data_rows.first[1] - - CSV.open(distributor_csv_path(distributor_name, distributor_id), "w") do |csv| - csv << table[0] # Header row - distributor_data_rows.each { |row| csv << row } - end - end - end - - def filter_data_rows_for_distributor(data_rows, distributor_id) - data_rows.select { |row| row[2] == distributor_id } - end -end From 63ac6c50881ecdd7c49b93613dfa4fb0ae55a7ff Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 17 Apr 2020 12:40:54 +1000 Subject: [PATCH 124/166] Remove superfluous conditional A migration's `up` method is only run when the migration needs to be applied. The only case we could have a higher version number is when a migration with a higher version got merged before the current one. And in that case, we still want this migration to fail, because it hasn't been applied yet. --- db/migrate/20181128054803_old_migrations_removed.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/db/migrate/20181128054803_old_migrations_removed.rb b/db/migrate/20181128054803_old_migrations_removed.rb index e0ad67a62b..3cd68a2610 100644 --- a/db/migrate/20181128054803_old_migrations_removed.rb +++ b/db/migrate/20181128054803_old_migrations_removed.rb @@ -1,11 +1,8 @@ class OldMigrationsRemoved < ActiveRecord::Migration - LAST_DELETED_MIGRATION = 20181128054803 def up - if ActiveRecord::Migrator.current_version < LAST_DELETED_MIGRATION - message = "You haven't updated your dev environment in a long time! " \ - "Legacy migration files before 2019 have now been removed. " \ - "Run `rails db:schema:load` before running `rails db:migrate`." - raise StandardError, message - end + message = "You haven't updated your dev environment in a long time! " \ + "Legacy migration files before 2019 have now been removed. " \ + "Run `rails db:schema:load` before running `rails db:migrate`." + raise StandardError, message end end From 8af40f4675fb67c731fb93c72229e6aa251be742 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 17 Apr 2020 12:47:49 +1000 Subject: [PATCH 125/166] Format and indent migration message It's much clearer to read this way: ``` == OldMigrationsRemoved: migrating =========================================== rake aborted! StandardError: An error has occurred, this and all later migrations canceled: You haven't updated your dev environment in a long time! Legacy migration files before 2019 have now been removed. Run `rails db:schema:load` before running `rails db:migrate`. ``` --- db/migrate/20181128054803_old_migrations_removed.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/db/migrate/20181128054803_old_migrations_removed.rb b/db/migrate/20181128054803_old_migrations_removed.rb index 3cd68a2610..435848834a 100644 --- a/db/migrate/20181128054803_old_migrations_removed.rb +++ b/db/migrate/20181128054803_old_migrations_removed.rb @@ -1,8 +1,11 @@ class OldMigrationsRemoved < ActiveRecord::Migration def up - message = "You haven't updated your dev environment in a long time! " \ - "Legacy migration files before 2019 have now been removed. " \ - "Run `rails db:schema:load` before running `rails db:migrate`." - raise StandardError, message + raise StandardError, <<-MESSAGE + + You haven't updated your dev environment in a long time! + Legacy migration files before 2019 have now been removed. + Run `rails db:schema:load` before running `rails db:migrate`. + + MESSAGE end end From 75207247e69126bb86b2e81a6382cbeaa96945c9 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 17 Apr 2020 12:52:05 +1000 Subject: [PATCH 126/166] Correct database commands --- db/migrate/20181128054803_old_migrations_removed.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db/migrate/20181128054803_old_migrations_removed.rb b/db/migrate/20181128054803_old_migrations_removed.rb index 435848834a..47d233f0aa 100644 --- a/db/migrate/20181128054803_old_migrations_removed.rb +++ b/db/migrate/20181128054803_old_migrations_removed.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + class OldMigrationsRemoved < ActiveRecord::Migration def up raise StandardError, <<-MESSAGE You haven't updated your dev environment in a long time! Legacy migration files before 2019 have now been removed. - Run `rails db:schema:load` before running `rails db:migrate`. + Run `rake db:schema:load` before running `rake db:migrate`. MESSAGE end From 4658a53aeba91b9ba988efb1b5687165c74d22d2 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 17 Apr 2020 15:37:54 +1000 Subject: [PATCH 127/166] Update translations from Transifex --- config/locales/ca.yml | 6 +- config/locales/es_CR.yml | 64 +++++++------- config/locales/fr.yml | 2 +- config/locales/fr_BE.yml | 23 +++++- config/locales/it.yml | 1 + config/locales/pt_BR.yml | 34 ++++---- config/locales/tr.yml | 174 +++++++++++++++++++++------------------ 7 files changed, 168 insertions(+), 136 deletions(-) diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 684076b91b..40c6b80622 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1456,13 +1456,13 @@ ca: email_payment_summary: Resum del pagament email_payment_method: "Pagament a través de:" email_so_placement_intro_html: "Tens una nova comanda amb %{distributor} " - email_so_placement_details_html: "Aquests són els detalls de la comanda de %{distributor} :" + email_so_placement_details_html: "Aquests són els detalls de la comanda de %{distributor} :" email_so_placement_changes: "Malauradament, no tots els productes que has demanat estaven disponibles. Les quantitats originals que has sol·licitat apareixen ratllades a sota." email_so_payment_success_intro_html: "S'ha processat un pagament automàtic per a la vostra comanda des de %{distributor} ." email_so_placement_explainer_html: "Aquesta comanda s'ha creat automàticament per tu." - email_so_edit_true_html: "Potd fer canvis fins que les comandes es tanquin el %{orders_close_at}." + email_so_edit_true_html: "Pots fer canvis fins que les comandes es tanquin el %{orders_close_at}." email_so_edit_false_html: "Pots veure detalls d'aquesta comanda en qualsevol moment." - email_so_contact_distributor_html: "Si tens alguna pregunta pots contactar amb %{distributor} a través d'%{email}." + email_so_contact_distributor_html: "Si tens alguna pregunta pots contactar amb %{distributor} a través d'%{email}." email_so_contact_distributor_to_change_order_html: "Aquesta comanda s'ha creat automàticament per a vostè. Podeu fer canvis fins que les comandes es tanquin a %{orders_close_at} contactant a %{distributor} a través d'%{email}." email_so_confirmation_intro_html: "La teva comanda amb %{distributor} ja està confirmada" email_so_confirmation_explainer_html: "Vas realitzar aquesta comanda automàticament i ara s'ha finalitzat." diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index f3d0609a9a..fc946b9c93 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -30,7 +30,7 @@ es_CR: email: taken: "Ya existe una cuenta con este correo electrónico. Inicie sesión o restablezca tu contraseña." spree/order: - no_card: No hay tarjetas de crédito autorizadas disponibles para realizar el cargo + no_card: No hay tarjetas de crédito autorizadas disponibles para realizar el cobro spree/credit_card: attributes: base: @@ -83,21 +83,21 @@ es_CR: failed_to_send: "Se produjo un error al enviar su correo electrónico de confirmación." resend_confirmation_email: "Reenviar el correo electrónico de confirmación." confirmed: "¡Gracias por confirmar su correo electrónico! Ahora puede iniciar sesión." - not_confirmed: "Su dirección de correo electrónico no pudo ser confirmada. Tal vez ya has completado este paso?" + not_confirmed: "Su dirección de correo electrónico no pudo ser confirmada. -¿Tal vez ya realizó este paso?" user_confirmations: spree_user: - send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + send_instructions: "Recibirá un correo electrónico con instrucciones sobre cómo confirmar su cuenta dentro de unos minutos." confirmation_sent: "Se ha enviado un correo electrónico de confirmación" confirmation_not_sent: "Error al enviar el correo electrónico de confirmación." user_registrations: spree_user: - signed_up_but_unconfirmed: "Se ha enviado un mensaje con un enlace de confirmación a tu dirección de correo electrónico. Abre el enlace para activar tu cuenta." - unknown_error: "Algo salió mal al crear tu cuenta. Comprueba tu dirección de correo electrónico y vuelve a intentarlo." + signed_up_but_unconfirmed: "Se ha enviado un mensaje con un enlace de confirmación a su dirección de correo electrónico. Abra el enlace para activar su cuenta." + unknown_error: "Algo salió mal al crear su cuenta. Compruebe su dirección de correo electrónico y vuelva a intentarlo." failure: invalid: | Correo o contraseña inválidos. - ¿Has sido invitada? Tal vez necesites crear una cuenta o recuperar tu contraseña. - unconfirmed: "Debes confirmar tu cuenta antes de continuar." + ¿Ha sido invitada? Tal vez necesite crear una cuenta nueva o recuperar su contraseña. + unconfirmed: "Debe confirmar su cuenta antes de continuar." already_registered: "Esta dirección de correo electrónico ya está registrada. Inicie sesión para continuar, o vuelva atrás y use otra dirección de correo electrónico." success: logged_in_succesfully: "Sesión iniciada con éxito" @@ -221,7 +221,7 @@ es_CR: distributors: Distribuidores bulk_order_management: Gestión de pedidos en bloque enterprises: Organizaciones - enterprise_groups: Redes + enterprise_groups: Grupos reports: Reportes variant_overrides: Inventario import: Importar @@ -554,7 +554,7 @@ es_CR: title: Inventario description: Utilice esta página para administrar inventarios para sus organizaciones. Todos los detalles del producto establecidos aquí anularán los establecidos en la página de 'Productos' enable_reset?: ¿Activar Reset del Stock? - default_stock: "Stock predeterminado" + default_stock: "Inventario predeterminado" inherit?: ¿Heredado? add: Añadir hide: Ocultar @@ -663,9 +663,9 @@ es_CR: primary_details: name: Nombre name_placeholder: ej. Professor Plum's Biodynamic Truffles - groups: Redes - groups_tip: Seleccione las redes o zonas de los que es miembro. Esto ayudará a los consumidores a encontrar tu organización. - groups_placeholder: Escribe para buscar las redes disponibles... + groups: Grupos + groups_tip: Seleccione cualquier grupo o región de la que sea miembro. Esto ayudará a los clientes a encontrar su organización. + groups_placeholder: Comience a escribir para buscar los grupos disponibles ... primary_producer: Productora Principal? primary_producer_tip: Seleciona "Productora" si eres la principal productora. producer: Productora @@ -739,7 +739,7 @@ es_CR: confirm_modal: title: Conectar con Stripe part1: Stripe es un servicio de pagos que permite a las tiendas aceptar pagos con tarjeta de crédito de las consumidoras. - part2: Para usar esta función, debes conectar tu cuenta Stripe con OFN. Al hacer clic en 'Acepto' a continuación, se redireccionará al sitio web de Stripe donde puedes conectar una cuenta de Stripe existente o crear una nueva si aún no la tienes. + part2: Para usar esta función, debes conectar su cuenta Stripe con OFN. Al hacer clic en 'Acepto' a continuación, se redireccionará al sitio web de Stripe donde puede conectar una cuenta de Stripe existente o crear una nueva si aún no la tiene. part3: Esto permitirá que Open Food Network acepte pagos con tarjeta de crédito de los clientes en su nombre. Tenga en cuenta que deberá mantener su propia cuenta de Stripe, pagar las tarifas de Stripe y gestionar los reembolsos y el servicio al cliente por usted mismo. i_agree: Estoy de acuerdo cancel: Cancelar @@ -796,13 +796,13 @@ es_CR: sell_your_produce: Vende tu propia producción producer_shop_description_text: Venda sus productos directamente a los clientes a través de su propia tienda. producer_shop_description_text2: Una tienda de productora es para vender sus productos solamente, si quiere vender productos de otros productores, seleccione "Grupo de Productoras" - producer_hub: Centro de acopio + producer_hub: Hub de productoras producer_hub_text: Vende tu propia producción y la de otros producer_hub_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos tuyos o de otras organizaciones y véndelo a través de tu tienda en Open Food Network. profile: Solo perfil get_listing: Obtener un listado profile_description_text: La gente podrá encontrarte y ponerse en contacto contigo en Open Food Network. Su organización será visible en el mapa y se podrá buscar en los listados. - hub_shop: Tienda del centro de acopio + hub_shop: Tienda del Hub hub_shop_text: Vender la producción de otros hub_shop_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos de otras organizaciones y véndelo a través de tu tienda en Open Food Network. choose_option: Por favor, elija una de las opciones anteriores. @@ -1205,7 +1205,7 @@ es_CR: menu_2_url: "/map" menu_3_title: "Productoras" menu_3_url: "/producers" - menu_4_title: "Redes" + menu_4_title: "Grupos" menu_4_url: "/groups" menu_5_title: "Acerca de" menu_5_url: "https://laferia.cr/" @@ -1261,7 +1261,7 @@ es_CR: label_map: "Mapa" label_producer: "Productora" label_producers: "Productoras" - label_groups: "Redes" + label_groups: "Grupos" label_about: "Acerca de" label_connect: "Conectar" label_learn: "Aprender" @@ -1322,7 +1322,7 @@ es_CR: cookie_stripe_desc: "Datos recopilados por nuestro procesador de pagos Stripe para detectar fraudes https://stripe.com/cookies-policy/legal. No todas las tiendas usan Stripe como método de pago pero es una buena práctica evitar fraude aplicarlo a todas las páginas. Stripe probablemente crea una imagen de cuáles de nuestras páginas generalmente interactúan con su API y luego marca cualquier cosa inusual. Por lo tanto configurar la cookie Stripe tiene una función más amplia que la simple provisión de un método de pago a un usuario. Eliminarla podría afectar la seguridad del servicio en sí. Puede obtener más información acerca de Stripe y leer su política de privacidad en https://stripe.com/privacy." statistics_cookies: "Cookies de estadísticas" statistics_cookies_desc: "Las siguientes no son estrictamente necesarias, pero ayudan a proporcionarle una mejor experiencia de usuario al permitirnos analizar el comportamiento del usuario, identificar qué funciones usa más o no, comprender los problemas de la experiencia del usuario, etc." - statistics_cookies_analytics_desc_html: "Para recopilar y analizar los datos de uso de la plataforma utilizamos Google Analytics, ya que era el servicio predeterminado conectado con Spree (el software de código abierto de comercio electrónico en el que creamos) pero nuestra visión es cambiar a Matomo (ex Piwik, herramienta analítica de código abierto que cumple con GDPR y protege tu privacidad) tan pronto como podamos." + statistics_cookies_analytics_desc_html: "Para recopilar y analizar los datos de uso de la plataforma utilizamos Google Analytics, ya que era el servicio predeterminado conectado con Spree (el software de código abierto de comercio electrónico que utilizamos) pero nuestra visión es cambiar a Matomo (ex Piwik, herramienta analítica de código abierto que cumple con GDPR y protege su privacidad) tan pronto como podamos." statistics_cookies_matomo_desc_html: "Para recopilar y analizar los datos de uso de la plataforma, utilizamos Matomo (ex Piwik), una herramienta analítica de código abierto que cumple con GDPR y protege tu privacidad" statistics_cookies_matomo_optout: "¿Deseas excluirte de Matomo Analytics? No recopilamos ningún dato personal y Matomo nos ayuda a mejorar nuestro servicio, pero respetamos tu elección :-)" cookie_analytics_utma_desc: "Se usa para distinguir usuarios y sesiones. La cookie se crea cuando la biblioteca javascript se ejecuta y no existe ninguna cookie __utma existente. La cookie se actualiza cada vez que se envían datos a Google Analytics." @@ -1483,7 +1483,7 @@ es_CR: email_signup_welcome: "Bienvenido a %{sitename}!" email_signup_confirmed_email: "Gracias por confirmar su email." email_signup_shop_html: "Ahora puedes iniciar sesión en %{link}." - email_signup_text: "Gracias por unirse a la red. Si es un comprador, ¡esperamos presentarle a muchos agricultores, grupos de consumo y comida deliciosa! Si eres una productora o formas parte de una organización de alimentos, estamos emocionados de que formes parte de la red." + email_signup_text: "Gracias por unirse a la red. Si es un comprador, ¡esperamos presentarle a muchos agricultores, grupos de consumo y comida deliciosa! Si es un productor o forma parte de una organización de alimentos, estamos emocionados de que forme parte de la red." email_signup_help_html: "Agradecemos todas tus preguntas y feedback; puedes usar el botón de Enviar Feedback en el sitio o escribir un email a %{email}" invite_email: greeting: "¡Hola!" @@ -1555,11 +1555,11 @@ es_CR: components_profiles_show: "Mostrar perfiles" components_filters_nofilters: "Sin filtros" components_filters_clearfilters: "Limpiar todos los filtros" - groups_title: Redes - groups_headline: Redes / regiones - groups_text: "Cada productora es única. Cada organización tiene algo diferente que ofrecer. Nuestras redes son colectivos de productoras, grupos y distribuidoras que comparten valores agroecológicos. Esto hace que tu experiencia de compra sea más fácil. Puedes buscar las redes y estar seguro que se ha hecho una selección de proyectos con estos criterios." + groups_title: Grupos + groups_headline: Grupos / regiones + groups_text: "Cada productor es único. Cada organización tiene algo diferente que ofrecer. Nuestros grupos son colectivos de productores, centros de acopio y distribuidores que comparten valores agroecológicos. Esto hace que su experiencia de compra sea más fácil." groups_search: "Buscar nombre o palabra clave" - groups_no_groups: "No se encontraron redes" + groups_no_groups: "No se encontraron grupos" groups_about: "Acerca de nosotras" groups_producers: "Nuestras productoras" groups_hubs: "Nuestros Grupos de Consumo" @@ -1570,7 +1570,7 @@ es_CR: groups_contact_website: Visite nuestro sitio web groups_contact_facebook: Síganos en Facebook groups_signup_title: Registrarse como un grupo - groups_signup_headline: Registro de redes + groups_signup_headline: Registro de grupos groups_signup_intro: "Somos una asombrosa plataforma de mercadeo colaborativo, la forma más sencilla para que sus miembros e interesados encuentren nuevos mercados. No tenemos fines de lucro, somos asequibles y simples." groups_signup_email: Envíenos un correo electrónico groups_signup_motivation1: Nosotros transformamos sistemas de comida de forma justa. @@ -1592,9 +1592,9 @@ es_CR: modal_hubs_abstract: ¡Nuestros Grupos de Consumo son el punto de contacto entre usted y la gente que hace su comida! modal_hubs_content1: Puede buscar un grupo de consumo conveniente por ubicación o nombre. Algunos grupos de consumo tienen múltiples puntos en loa que puede recoger las compras, y algunos también brindan opciones de entrega a domicilio. Cada Grupo de Consumo es un punto de venta con operaciones de negocio y logística independientes, entonces puede esperar diferencias entre Grupos de Consumo. modal_hubs_content2: Sólo puedes comprar en un grupo de consumo a la vez. - modal_groups: "Redes / Regiones" + modal_groups: "Grupos / Regiones" modal_groups_content1: Estas son las organizaciones y relaciones entre grupos de consumo que conforman el Open Food Network. - modal_groups_content2: Algunas redes están organizadas por ubicación, otros por afinidades no geográficas. + modal_groups_content2: Algunos grupos están organizados por ubicación, otros por afinidades no geográficas. modal_how: "Cómo funciona" modal_how_shop: Comprar en Open Food Network modal_how_shop_explained: ¡Buscar un grupo de consumo cerca de ti para empezar a comprar! Puedes expandir cada grupo de consumo para ver qué tipos de productos están disponibles, y hacer clic para empezar a comprar. (Sólo puedes comprar en un grupo de consumo a la vez.) @@ -1638,13 +1638,13 @@ es_CR: sell_motivation: "Muestra tus preciosos alimentos." sell_producers: "Productoras" sell_hubs: "Hubs" - sell_groups: "Redes" + sell_groups: "Grupos" sell_producers_detail: "Crea tu perfil en OFN en cuestión de minutos. En cualquier momento puedes actualizar tu perfil a una tienda en línea y vender tus productos directamente a los consumidores." sell_hubs_detail: "Crea un perfil para tu organización en OFN. En cualquier momento puedes actualizar tu perfil a una tienda de varias productoras." sell_groups_detail: "Crea un directorio personalizado de organizaciones (productoras u otras organizaciones) para tu región o para tu organización." sell_user_guide: "Descubre mucho más en la guía de usuario." sell_listing_price: "Listado en la OFN es gratis. Abrir y administrar una tienda en OFN es gratis hasta $ 500 en ventas mensuales. Si vende más, puede elegir la contribución de su comunidad entre el 1% y el 3% de las ventas. Para obtener más detalles sobre los precios, visite la sección Plataforma de software a través del enlace Acerca de en el menú superior." - sell_embed: "También podemos incrustar una tienda OFN en tu propia web personalizada o crear un sitio web de la red local a medida para tu región." + sell_embed: "También podemos incrustar una tienda OFN en tu propia web personalizada o crear un sitio web de la red local a medida para su región." sell_ask_services: "Pregúntanos sobre los servicios de OFN" shops_title: Tiendas shops_headline: Compras, transformadas. @@ -1921,7 +1921,7 @@ es_CR: admin_enterprise_relationships_permits: "Permite" admin_enterprise_relationships_seach_placeholder: "Buscar" admin_enterprise_relationships_button_create: "Crear" - admin_enterprise_groups: "Redes de organizaciones" + admin_enterprise_groups: "Grupos de organizaciones" admin_enterprise_groups_name: "Nombre" admin_enterprise_groups_owner: "Propietaria" admin_enterprise_groups_on_front_page: "¿En la página principal?" @@ -1976,7 +1976,7 @@ es_CR: delete: Borrar add_producer_property: "Añadir propiedad de productora" in_progress: "En Proceso" - started_at: "Empezo el" + started_at: "Empezó el" queued: "En Cola" scheduled_for: "Planificado para" customers: "Consumidores" @@ -2540,7 +2540,7 @@ es_CR: please_select_a_shop: "Por favor seleccione una tienda" insufficient_stock: "Stock insuficiente disponible, solo quedan %{on_hand}" out_of_stock: - reduced_stock_available: Stock reducido disponible + reduced_stock_available: Inventario reducido disponible out_of_stock_text: > Mientras estabas comprando, los niveles de stock para uno o más de los productos de tu carrito se han reducido. Aquí está lo que ha cambiado: @@ -2956,7 +2956,7 @@ es_CR: enterprises: "Organizaciones" enterprise_relationships: "Permisos" customers: "Consumidoras" - groups: "Redes" + groups: "Grupos" product_properties: index: inherits_properties_checkbox_hint: "¿Heredar propiedades desde %{supplier}? (a menos que sea anulado arriba)" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 422c67981d..1c24fb93c9 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1543,7 +1543,7 @@ fr: products_loading: "Produits en cours de chargement..." products_updating_cart: "Actualisation du panier..." products_cart_empty: "Panier vide" - products_edit_cart: "Valider votre panier" + products_edit_cart: "Poursuivre" products_from: de products_change: "Aucun changement à sauvegarder." products_update_error: "Échec de l'enregistrement dû à:" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index ff58ad6631..b14690a1f0 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -31,6 +31,10 @@ fr_BE: taken: "Un compte existe déjà pour cette adresse électronique. Connectez-vous ou demandez un nouveau mot de passe." spree/order: no_card: Aucune carte de paiement autorisée disponible + spree/credit_card: + attributes: + base: + card_expired: "a expiré" order_cycle: attributes: orders_close_at: @@ -248,6 +252,8 @@ fr_BE: notes: Commentaires error: Erreur processing_payment: "Paiement en cours..." + no_pending_payments: "Aucun paiement en attente" + invalid_payment_state: "État de paiement invalide" filter_results: Filtrer les résultats quantity: Quantité pick_up: Retrait @@ -867,6 +873,7 @@ fr_BE: distributor: "Distributeur·trice" products: "Produits" tags: "Tags" + delivery_details: "Détails de la livraison" fees: "Commission" previous: "Précédent" save: "Sauvergarder" @@ -1129,11 +1136,11 @@ fr_BE: shared: menu: cart: - cart: "Cart" + cart: "Panier" signed_in: profile: "Profil" mobile_menu: - cart: "Carte" + cart: "Panier" joyride: checkout: "Passer la commande" already_ordered_products: "Déjà commandé dans ce cycle de vente" @@ -1291,6 +1298,7 @@ fr_BE: saving_credit_card: Enregistrement de la carte de crédit... card_has_been_removed: "Votre carte a été supprimée (numéro : %{number})" card_could_not_be_removed: Désolée, la carte n'a pas pu être supprimée :-( + invalid_credit_card: "Carte de crédit non valable" ie_warning_headline: "Votre navigateur n'est pas à jour :-(" ie_warning_text: "Pour une expérience optimale sur Open Food Network, nous vous recommandons fortement de mettre à jour votre navigateur:" ie_warning_chrome: Télécharger Chrome @@ -1492,6 +1500,7 @@ fr_BE: shopping_oc_closed_description: "Veuillez attendre l'ouverture du prochain cycle de vente (ou contactez directement le comptoir pour voir si nous pouvons accepter une commande tardive)." shopping_oc_last_closed: "Le dernier cycle de vente s'est terminé il y a %{distance_of_time}" shopping_oc_next_open: "Le prochain cycle de vente ouvrira dans %{distance_of_time}" + shopping_oc_select: "Sélectionnez..." shopping_tabs_home: "Accueil" shopping_tabs_shop: "Comptoir" shopping_tabs_about: "A propos" @@ -1865,6 +1874,7 @@ fr_BE: headline: "C'est terminé!" thanks: "Merci d'avoir complété le profil de %{enterprise}" login: "Vous pouvez modifier ou mettre à jour les détails de votre entreprise à tout moment en vous connectant sur Open Food Network, rubrique Admin." + action: "Aller au tableau de bord des entreprises" back: "Retour" continue: "Suivant" action_or: "OU" @@ -2283,6 +2293,7 @@ fr_BE: enterprise_register_success_notice: "Bravo ! L'entreprise %{enterprise} est maintenant inscrite sur Open Food Network :-)" enterprise_bulk_update_success_notice: "Entreprises mises à jour avec succès" enterprise_bulk_update_error: 'Echec dans la mise à jour' + enterprise_shop_show_error: "Le comptoir que vous recherchez n'existe pas ou est inactif sur OFN. Veuillez vérifier les autres comptoirs." order_cycles_create_notice: 'Votre cycle de vente a été créé.' order_cycles_update_notice: 'Votre cycle de vente a été mis à jour.' order_cycles_bulk_update_notice: 'Des cycles de vente ont été mis à jour.' @@ -2444,6 +2455,12 @@ fr_BE: severity: Rigueur description: Description resolve: Résoudre + exchange_products: + load_more_variants: "Charger plus de variantes" + load_all_variants: "Charger toutes les variantes" + select_all_variants: "Sélectionner toutes %{total_number_of_variants}les variantes" + variants_loaded: " %{num_of_variants_loaded}de %{total_number_of_variants}variantes chargées" + loading_variants: "Chargement des variantes" tag_rules: shipping_method_tagged_top: "Méthodes d'expédition étiquetées" shipping_method_tagged_bottom: "sont:" @@ -2956,6 +2973,8 @@ fr_BE: tax_invoice: "FACTURE" code: "Code" from: "De" + to: "Facture à" + shipping: "Expédition" form: distribution_fields: title: "Distribution" diff --git a/config/locales/it.yml b/config/locales/it.yml index 317c08bdd0..b555d60965 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -3030,6 +3030,7 @@ it: tax_invoice: "FATTURA DELLE TASSE" code: "Codice" from: "Da" + shipping: "Spedizione" form: distribution_fields: title: "Distribuzione" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 588f9cf757..2bb99574e9 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -16,7 +16,7 @@ pt_BR: spree/product: primary_taxon: "Categoria de Produto" supplier: "Fornecedor" - shipping_category_id: "Tipos de Envio" + shipping_category_id: "Tipos de Frete" variant_unit: "Unidade variante" variant_unit_name: "Nome da unidade variante" spree/credit_card: @@ -210,7 +210,7 @@ pt_BR: remove: Remover or: ou collapse_all: Recolher todos - expand_all: Aumentar tudo + expand_all: Expandir tudo loading: Carregando... show_more: Mostrar mais show_all: Mostrar tudo @@ -589,13 +589,13 @@ pt_BR: actions_delete: "Deletar selecionado" loading: "Carregando pedidos" no_results: "Nenhum pedido encontrado. " - group_buy_unit_size: "Tamanho da Unidade para Grupo de Compras" + group_buy_unit_size: "Unidade de Medida para Grupo de Compras" total_qtt_ordered: "Quantidade total do pedido" max_qtt_ordered: "Quantidade máxima do pedido" current_fulfilled_units: "Unidades completadas no momento" max_fulfilled_units: "Máximo de unidades completadas " order_error: "Alguns erros devem ser corrigidos antes de atualizar os pedidos.\nOs campos com bordas vermelhas contém erros." - variants_without_unit_value: "AVISO: Algumas variantes não possuem unidade de valor" + variants_without_unit_value: "AVISO: Algumas variantes não possuem unidade de medida" select_variant: "Selecione uma variante" enterprise: select_outgoing_oc_products_from: 'Selecione a saída do ciclo de pedidos ' @@ -972,7 +972,7 @@ pt_BR: not_visible: "%{enterprise} não está visível e, portanto, não pode ser encontrado no mapa ou em pesquisas" reports: hidden: ESCONDIDO - unitsize: TAMANHO DA UNIDADE + unitsize: Unidade de Medida total: TOTAL total_items: TOTAL DE ITEMS supplier_totals: Total do fornecedor do ciclo de pedidos @@ -1205,7 +1205,7 @@ pt_BR: menu_4_title: "Grupos" menu_4_url: "/groups" menu_5_title: "Sobre" - menu_5_url: "https://about.openfoodnetwork.org.au/" + menu_5_url: "https://about.openfoodbrasil.com.br/" menu_6_title: "Conectar" menu_6_url: "https://openfoodnetwork.org/au/connect/" menu_7_title: "Aprender" @@ -1542,11 +1542,11 @@ pt_BR: products_cart_empty: "Carrinho vazio" products_edit_cart: "Edite seu carrinho" products_from: de - products_change: "Nenhuma modificação a ser salva." + products_change: "Nenhuma alteração a ser salva." products_update_error: "Falha ao salvar, com o seguinte erro:" products_update_error_msg: "Falha ao salvar." products_update_error_data: "Falha no salvamento devido a dados inválidos:" - products_changes_saved: "Modificações salvas." + products_changes_saved: "Alterações salvas." search_no_results_html: "Sinto muito, nenhum resultado encontrado para %{query}. Que tal tentar outra busca?" components_profiles_popover: "Perfis Simples não possuem uma loja virtual na Open Food Brasil, mas podem ter suas próprias lojas físicas ou online em outro endereço" components_profiles_show: "Mostrar perfis" @@ -1899,7 +1899,7 @@ pt_BR: transaction_date: "DataData" payment_state: "Status do Pagamento" shipping_state: "Status da entrega" - value: "Valor" + value: "Quantidade" balance_due: "saldo devedor" credit: "Crédito" Paid: "Pago" @@ -1946,7 +1946,7 @@ pt_BR: supplier: "Fornecedor" product_name: "Nome do Produto" product_description: "Descrição do Produto" - units: "O tamanho da unidade" + units: "Unidade de medida" coordinator: "Coordenador" distributor: "Distribuidor" enterprise_fees: "Taxas da iniciativa" @@ -2154,14 +2154,14 @@ pt_BR: report_header_sells: Vende report_header_visible: Visível report_header_price: Preço - report_header_unit_size: Tamanho da Unidade + report_header_unit_size: Unidade de Medida report_header_distributor: Distribuidor report_header_distributor_address: Endereço do distribuidor report_header_distributor_city: Cidade do distribuidor report_header_distributor_postcode: CEP do distribuidor report_header_delivery_address: Endereço para entrega report_header_delivery_postcode: CEP para entrega - report_header_bulk_unit_size: Tamanho de unidade para atacado + report_header_bulk_unit_size: Unidade de Medida para atacado report_header_weight: Peso report_header_sum_total: Soma total report_header_date_of_order: Data do pedido @@ -2307,7 +2307,7 @@ pt_BR: shipped: Enviado js: saving: 'Salvando...' - changes_saved: 'Mudanças salvas.' + changes_saved: 'Alterações salvas.' save_changes_first: Salve as alterações primeiro. all_changes_saved: Todas as alterações foram salvas unsaved_changes: Você possui alterações não salvas @@ -2573,7 +2573,7 @@ pt_BR: visible: VISÍVEL not_visible: NÃO VISÍVEL services: - unsaved_changes_message: Existem mudanças não salvas, salvar agora ou ignorar? + unsaved_changes_message: Existem alterações não salvas. Salvar agora ou ignorar? save: SALVAR ignore: IGNORAR add_to_order_cycle: "adicionar ao ciclo de pedidos" @@ -2876,7 +2876,7 @@ pt_BR: back_to_taxonomies_list: "Voltar à lista de taxonomias" shipping_methods: "Métodos de envio" shipping_categories: "Categorias de Remessa" - new_shipping_category: "Nova categoria de remessa" + new_shipping_category: "Nova categoria de frete" back_to_shipping_categories: "Voltar para categorias de remessa" analytics_trackers: "Rastreadores de análise" no_trackers_found: "Nenhum rastreador encontrado" @@ -3119,8 +3119,8 @@ pt_BR: new_product: "Novo produto" supplier: "Fornecedor" product_name: "Nome do Produto" - units: "Tamanho da Unidade" - value: "Valor" + units: "Unidade de Medida" + value: "Quantidade" unit_name: "Nome da Unidade" price: "Preço" on_hand: "Disponível" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 6c5579977e..12473fe9d8 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -9,14 +9,14 @@ tr: shipment_state: ' Teslimat Durumu' completed_at: Oluşturulma Tarihi number: Numara - state: Şehir + state: Durum email: Müşteri E-postası spree/payment: amount: Tutar spree/product: primary_taxon: "Ürün Kategorisi" supplier: "Tedarikçi" - shipping_category_id: "Nakliye Kategorisi" + shipping_category_id: "Teslimat Kategorisi" variant_unit: "Varyant Birimi" variant_unit_name: "Varyant Birim Adı" spree/credit_card: @@ -31,20 +31,24 @@ tr: taken: "Bu e-posta adına kayıtlı bir hesap var. Lütfen giriş yapın veya şifrenizi sıfırlayın." spree/order: no_card: Ödeme alınabilecek kayıtlı bir kredi kartı bulunmamaktadır. + spree/credit_card: + attributes: + base: + card_expired: "süresi doldu" order_cycle: attributes: orders_close_at: after_orders_open_at: Açılış tarihinden sonra olmalı variant_override: count_on_hand: - using_producer_stock_settings_but_count_on_hand_set: "Boş bırakılmalı çünkü üreticinin stokları kullanılıyor" + using_producer_stock_settings_but_count_on_hand_set: "Boş bırakılmalı çünkü üretici stok ayarları kullanılıyor" on_demand_but_count_on_hand_set: "talep üzerine is boş bırakılmalıdır" limited_stock_but_no_count_on_hand: "Sınırlı stok durumundan dolayı belirtilmeli" activemodel: attributes: order_management/reports/enterprise_fee_summary/parameters: start_at: "Başlangıç" - end_at: "Son" + end_at: "Bitiş" distributor_ids: "Pazarlar" producer_ids: "Üreticiler" order_cycle_ids: "Sipariş Dönemleri" @@ -67,12 +71,12 @@ tr: schedule: not_coordinated_by_shop: "%{shop} tarafından koordine edilmiyor" payment_method: - not_available_to_shop: "%{shop} tarafından kullanılamıyor" + not_available_to_shop: "%{shop} için müsait değil" invalid_type: "Nakit veya online ödeme yöntemi olmalıdır" - charges_not_allowed: "^ Bu müşteri tarafından kredi kartı ile ödeme yöntemi kabul edilmemektedir." + charges_not_allowed: "^ Bu müşteri tarafından kredi kartı ücretlendirme kabul edilmemektedir." no_default_card: "^ Bu müşteri için kayıtlı kart bulunmuyor" shipping_method: - not_available_to_shop: "%{shop} tarafından kullanılamıyor" + not_available_to_shop: "%{shop} için kullanıma uygun değil" devise: confirmations: send_instructions: "Birkaç dakika içinde, hesabınızı nasıl doğrulayacağınız ile ilgili talimatları içeren bir e-posta alacaksınız." @@ -118,7 +122,7 @@ tr: welcome: subject: "%{enterprise} şimdi %{sitename} 'de" email_welcome: "Hoşgeldiniz" - email_registered: "şimdi şunun bir parçası" + email_registered: "şimdi bir parçası" email_userguide_html: "Tezgah veya Pazar hesapları ayarları ile ilgili ayrıntılı desteğe sahip Kullanıcı Kılavuzu burada: %{link}" userguide: "Açık Gıda Ağı Kullanıcı Kılavuzu" email_admin_html: "%{link}'dan oturum açarak veya ana sayfanın sağ üst kısmındaki ayarlar simgesini tıkladıktan sonra Yönetim' butonu üzerinden hesabınızı yönetebilirsiniz." @@ -137,8 +141,8 @@ tr: shipment_summary: "Teslimat Özeti" subject: "Teslimat Bildirimi" thanks: "İş birliğiniz için teşekkür ederim." - track_information: "Kargo Takip Bilgileri: %{tracking}" - track_link: "Kargo Takip Bağlantısı: %{url}" + track_information: "Takip Bilgileri: %{tracking}" + track_link: "Takip Bağlantısı: %{url}" subscription_mailer: placement_summary_email: subject: Yakın zamanda oluşturulan üye siparişlerinin bir özeti @@ -149,7 +153,7 @@ tr: greeting: "Merhaba %{name}," intro: "Aşağıda, %{shop} için yeni tamamlanmış olan üye siparişlerinin bir özeti bulunmaktadır." summary_overview: - total: Otomatik işlem için toplam %{count} üye işaretlendi. + total: Otomatik işlem için toplam %{count} üyelik işaretlendi. success_zero: Bunlardan hiçbiri başarıyla işlenmedi. success_some: Bunlardan %{count} işlem başarıyla tamamlandı. success_all: Hepsi başarıyla işlendi. @@ -176,10 +180,10 @@ tr: explainer: Bu siparişlerin otomatik olarak işlenmesi bilinmeyen bir nedenden dolayı başarısız oldu. Bu gerçekleşmemesi gereken bir durum, bu hatayı alıyorsanız lütfen bizimle iletişime geçin. home: "AGA" title: Açık Gıda Ağı - welcome_to: '''na Hoşgeldiniz' - site_meta_description: "Açık Gıda Ağı, farklı ülkelerdeki temiz gıda üreticileri ve yazılımcılar tarafından yeni bir gıda sistemi oluşturmak üzere tasarlandı. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır ve tamamen şeffaftır." + welcome_to: 'Hoşgeldiniz' + site_meta_description: "Açık Gıda Ağı, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." search_by_name: İsim veya konuma göre arama yapın... - producers_join: Yerel ve temiz üreticiler şimdi Açık Gıda Ağı'na katılabilirler. + producers_join: Temiz gıda üreticileri! Açık Gıda Ağı sizler için kullanıma açıldı. charges_sales_tax: KDV Uyguluyor mu? print_invoice: "Faturayı yazdır" print_ticket: "Etiketi Yazdır" @@ -188,7 +192,7 @@ tr: resend_confirmation: "Onayı Tekrar Gönderin" view_order: "Siparişi Görüntüle" edit_order: "Siparişi Düzenle" - ship_order: "Siparişi Teslim Et" + ship_order: "Siparişi Gönder" cancel_order: "Siparişi İptal Et" confirm_send_invoice: "Bu siparişin faturası müşteriye gönderilecek. Devam etmek istiyor musunuz?" confirm_resend_order_confirmation: "Sipariş onayı e-postasını tekrar göndermek istediğinizden emin misiniz?" @@ -220,7 +224,7 @@ tr: enterprise_groups: Gruplar reports: Raporlar variant_overrides: Stok - import: İçe Aktar + import: Aktar spree_products: Spree Ürünleri all: Hepsi current: Güncel @@ -237,20 +241,22 @@ tr: items: Kalemler summary: Özet detailed: Detaylı - updated: Güncellenmiş + updated: Güncel 'yes': "Evet" 'no': "Hayır" - y: 'Y' - n: 'N' - powered_by: Tarafından desteklenmektedir + y: 'E' + n: 'H' + powered_by: Destekleyici blocked_cookies_alert: "Tarayıcınız bu ekranı kullanmak için gereken çerezleri engelliyor olabilir. Çerezlere izin vermek ve sayfayı yeniden yüklemek için aşağıya tıklayın." allow_cookies: "Çerezlere izin ver" notes: Notlar error: Hata processing_payment: "Ödeme İşlemi Gerçekleştiriliyor.." + no_pending_payments: "Bekleyen ödeme yok" + invalid_payment_state: "Geçersiz ödeme durumu" filter_results: Sonuçları Filtrele quantity: Miktar - pick_up: Teslimat Noktası + pick_up: Teslim Alma copy: Kopyala change_my_password: "Şifremi Değiştir" update_password: "Şifreyi Güncelle" @@ -258,8 +264,8 @@ tr: reset_password_token: Şifre kodunu sıfırla expired: Süresi doldu, lütfen yeni bir tane isteyin back_to_payments_list: "Ödeme Listesine Geri Dön" - maestro_or_solo_cards: "Maestro / Solo kartları" - backordered: "Bekleyen Sipariş" + maestro_or_solo_cards: "Ödeme kartları" + backordered: "Bakiye Sipariş" on hand: "Mevcut" ship: "Teslimat" actions: @@ -272,13 +278,13 @@ tr: delete: "Sil" admin: begins_at: Başlangıç - begins_on: Başlangıç + begins_on: Başlangıç vakti customer: Müşteri date: Tarih email: E-posta ends_at: Bitiş - ends_on: 'Bitiş ' - name: Ad + ends_on: Bitiş vakti + name: İsim on_hand: Mevcut on_demand: Talep Üzerine on_demand?: Talep Üzerine? @@ -296,7 +302,7 @@ tr: shipping_method: Teslimat Yöntemi shop: Tezgah sku: Stok Kodu - status_state: Şehir + status_state: Durum tags: Etiketler variant: Varyant weight: Ağırlık @@ -342,11 +348,11 @@ tr: enable_receipt_printing?: "Sipariş listesinde termal yazıcılar kullanarak makbuz yazdırma seçeneklerini göster?" stripe_connect_settings: edit: - title: "Şerit Bağlantısı" + title: "Ödeme Bağlantısı" settings: "Ayarlar" - stripe_connect_enabled: Satıcıların Stripe Connect kullanarak ödeme kabul etmesine izin verilsin mi? - no_api_key_msg: Bu işletme için Stripe hesabı yok. - configuration_explanation_html: Stripe Connect entegrasyonunu yapılandırma hakkında ayrıntılı talimatlar için lütfen bu kılavuza bakın . + stripe_connect_enabled: Satıcıların online ödeme kullanarak ödeme kabul etmesine izin verilsin mi? + no_api_key_msg: Bu işletme için online ödeme hesabı yok. + configuration_explanation_html: Online ödeme entegrasyonunu yapılandırma hakkında ayrıntılı talimatlar için lütfen bu kılavuza bakın . status: Durum ok: Tamam instance_secret_key: Örnek Gizli Anahtarı @@ -355,7 +361,7 @@ tr: charges_enabled: Ücretlendirmeler Etkin charges_enabled_warning: "Uyarı: Hesabınız için ücretlendirmeler etkin değil" auth_fail_error: Girdiğiniz API anahtarı geçersiz - empty_api_key_error_html: Stripe API anahtarı sağlanmadı. API anahtarınızı ayarlamak için lütfen bu talimatları izleyin + empty_api_key_error_html: Ödeme API anahtarı sağlanmadı. API anahtarınızı ayarlamak için lütfen bu talimatları izleyin matomo_settings: edit: title: "Matomo Ayarları" @@ -390,12 +396,12 @@ tr: header: Başlık home_page: Ana Sayfa producer_signup_page: Üretici kayıt sayfası - hub_signup_page: Pazar Yeri kayıt sayfası + hub_signup_page: Pazar kayıt sayfası group_signup_page: Grup kayıt sayfası main_links: Ana Menü Bağlantıları footer_and_external_links: Altbilgi ve Dış Bağlantılar your_content: İçeriğiniz - user_guide: Kullanici Rehberi + user_guide: Kullanici Kılavuzu enterprise_fees: index: title: "İşletme Ücretleri" @@ -470,8 +476,8 @@ tr: index: notice: "Dikkat" beta_notice: "Bu özellik hala beta sürümündedir: kullanırken bazı hatalarla karşılaşabilirsiniz. Lütfen teknik destek için iletişime geçmekten çekinmeyin." - select_file: Yüklemek için bir çizelge seçin - spreadsheet: Çizelge + select_file: Yüklemek için bir dosya seçin + spreadsheet: Dosya choose_import_type: İçe aktarım türünü seçin import_into: İçe aktarım türü product_list: Ürün listesi @@ -484,7 +490,7 @@ tr: category_values: Mevcut Kategori Değerleri product_categories: Ürün Kategorileri tax_categories: Vergi Kategorileri - shipping_categories: Nakliye Kategorileri + shipping_categories: Teslimat Kategorileri import: review: İncele import: İçe Aktar @@ -509,7 +515,7 @@ tr: overwrite_empty: Boşsa üzerine yaz default_stock: Stok seviyesini ayarla default_tax_cat: Vergi kategorisini ayarla - default_shipping_cat: Nakliye kategorisi belirle + default_shipping_cat: Teslimat kategorisi belirle default_available_date: Tarih belirle validation_overview: İçe aktarım doğrulaması gözden geçirme entries_found: İçe aktarılan dosyada bulunan girişler @@ -592,7 +598,7 @@ tr: variants_without_unit_value: "UYARI: Bazı varyantların birim değeri yok" select_variant: "Bir varyant seçin" enterprise: - select_outgoing_oc_products_from: sipariş döneminde dıları gidecek ürünleri şurdan seçin + select_outgoing_oc_products_from: Sipariş dönemi giden ürünleri şurdan seçin enterprises: index: title: İşletmeler @@ -635,7 +641,7 @@ tr: promo_image_placeholder: 'Bu görsel ''Hakkımızda'' kısmında görüntülenir' promo_image_note1: 'DİKKAT:' promo_image_note2: Kapak resmi 1200 x 260 formatına göre kırpılacaktır. - promo_image_note3: Kapak resmi, bir işletmenin profil sayfasının üstünde görüntülenir. + promo_image_note3: Kapak resmi, işletmenin profil sayfasının üstünde görüntülenir. inventory_settings: text1: Stok seviyelerini ve fiyatları şuradan yönetebilirsiniz inventory: Stok @@ -644,8 +650,8 @@ tr: ürünün satış listenize eklenmeden önce Stok listenize eklenip eklenmemesi gerektiğini seçebilirsiniz. Eğer ürünlerinizi yönetmek için Stok sistemini kullanmıyorsanız 'tavsiye edilen' seçeneği ile devam etmeniz gerekir. - preferred_product_selection_from_inventory_only_yes: Tezgahınıza yeni ürünler eklenebilir (önerilir) - preferred_product_selection_from_inventory_only_no: Yeni ürünler tezgahınıza eklemeden önce Stok listesine girilmelidir + preferred_product_selection_from_inventory_only_yes: Vitrininize yeni ürünler eklenebilir (önerilir) + preferred_product_selection_from_inventory_only_no: Yeni ürünler vitrininize eklemeden önce Stok listesine girilmelidir payment_methods: name: Ad applies: Uygulanma? @@ -670,13 +676,13 @@ tr: visible_in_search: Haritada görünsün mü? visible_in_search_tip: Sitede arama yapılırken bu işletmenin müşteriler tarafından görünür olup olmayacağını belirler. visible: Görünür - not_visible: Görünmez + not_visible: Gizli permalink: Bağlantı Adı (boşluk yok) permalink_tip: "Bağlantı adı, mağazanızın bağlantı URL'sini oluşturmak için kullanılır: %{link}sectiginiz-ad/tezgah" link_to_front: Tezgah linkiniz link_to_front_tip: Açık Gıda Ağı’ndaki tezgahınıza doğrudan bağlantı linki ofn_uid: AGA KN - ofn_uid_tip: Açık Gıda Topluluğu'na kayıtlı işletmenize özel tanımlanan kimlik numarası + ofn_uid_tip: Açık Gıda Ağı'na kayıtlı işletmenize özel tanımlanan kimlik numarası shipping_methods: name: Ad applies: Uygulanma? @@ -702,16 +708,16 @@ tr: enable_subscriptions_tip: "Üyelik işlevselliği etkinleştirilsin mi?" enable_subscriptions_false: "Kapalı" enable_subscriptions_true: "Etkin" - shopfront_message: "Tezgah Mesajınız" + shopfront_message: "Vitrin Mesajınız" shopfront_message_placeholder: > Müşterilerinize merhaba diyebilir, tezgahınız ve alışveriş şartlarınız - ile ilgili bilgi verebilirsiniz. Yazdıklarınız, müşteriler tezgahınızı + ile ilgili bilgi verebilirsiniz. Yazdıklarınız, müşteriler vitrininizi ziyaret ettiğinde görünür olacak. shopfront_message_link_tooltip: "Bağlantı ekle / düzenle" shopfront_message_link_prompt: "Lütfen eklemek için bir URL girin" - shopfront_closed_message: "Kapalı Tezgah Mesajı" + shopfront_closed_message: "Kapalı Vitrin Mesajı" shopfront_closed_message_placeholder: > - Tezgahınızın neden satışa kapalı olduğunu ve ne zaman açılacağını müşterilerinize + Vitrininizin neden satışa kapalı olduğunu ve ne zaman açılacağını müşterilerinize açıklayan bir mesaj yazın. Bu mesaj, açık sipariş döneminiz olmadığında sizi ziyaret edenler tarafından görülecek. shopfront_category_ordering: "Vitrin Kategori Sıralaması" @@ -723,15 +729,15 @@ tr: facebook_placeholder: "Örn: www.facebook.com/TurkiyeKoop" linkedin_placeholder: "Örn: www.linkedin.com/in/adınızsoyadınız" stripe_connect: - connect_with_stripe: "Stripe ile bağlan" - stripe_connect_intro: "Kredi kartı ile ödeme kabul etmek için, şerit hesabınızı Açık Gıda Ağına bağlamanız gerekir. Başlamak için sağdaki düğmeyi kullanın." - stripe_account_connected: "Stripe hesabı bağlı." + connect_with_stripe: "Iyzico sistemi ile bağlan" + stripe_connect_intro: "Kredi kartı ile ödeme kabul etmek için, Iyzico hesabınızı Açık Gıda Ağına bağlamanız gerekir. Başlamak için sağdaki düğmeyi kullanın." + stripe_account_connected: "Iyzico hesabı bağlı." disconnect: "Çıkış yap" confirm_modal: - title: Stripe ile bağlan - part1: Stripe, AGA'ya kayıtlı satıcıların, müşterilerinden kredi kartı ödemelerini kabul etmelerine imkan veren bir hizmet sağlayıcıdır. - part2: Bu özelliği kullanmak için Stripe hesabınızı AGA'ya bağlamanız gerekir. Aşağıdaki 'Kabul Ediyorum' butonunu tıkladığınızda, mevcut bir Stripe hesabını bağlayabileceğiniz Stripe web sitesine yönlendirilir veya hesabınız yoksa yeni bir tane oluşturabilirsiniz. - part3: AGA'nın müşterilerden sizin adınıza kredi kartı ödemelerini kabul etmesini sağlayacaktır. Kendi Stripe hesabınızı korumanız, Stripe ücretlerini ödemeniz ve ters ibrazları ve müşteri hizmetlerini kendiniz ele almanız gerektiğini lütfen unutmayın. + title: Iyzico ile bağlan + part1: Iyzico, AGA'ya kayıtlı satıcıların, müşterilerinden kredi kartı ödemelerini kabul etmelerine imkan veren bir hizmet sağlayıcıdır. + part2: Bu özelliği kullanmak için Iyzico hesabınızı AGA'ya bağlamanız gerekir. Aşağıdaki 'Kabul Ediyorum' butonunu tıkladığınızda, mevcut bir Iyzico hesabını bağlayabileceğiniz Iyzico web sitesine yönlendirilir veya hesabınız yoksa yeni bir tane oluşturabilirsiniz. + part3: AGA'nın müşterilerden sizin adınıza kredi kartı ödemelerini kabul etmesini sağlayacaktır. Kendi Iyzico hesabınızı korumanız, Iyzico ücretlerini ödemeniz ve ters ibrazları ve müşteri hizmetlerini kendiniz ele almanız gerektiğini lütfen unutmayın. i_agree: Onaylıyorum cancel: İptal Et tag_rules: @@ -782,7 +788,7 @@ tr: producer_profile: Üretici Profili connect_ofn: AGA üzerinden bağlan always_free: HER ZAMAN ÜCRETSİZ - producer_description_text: Ürünlerinizi Açık Gıda Ağı'na yükleyin. Böylece ürünleriniz ortak hesaplar üzerinden satışa sunulabilir. + producer_description_text: Ürünlerinizi Açık Gıda Ağı'na yükleyin. Böylece ürünleriniz pazar hesapları üzerinden satışa sunulabilir. producer_shop: Üretici Tezgahı sell_your_produce: Kendi ürününü sat producer_shop_description_text: Açık Gıda Ağı üzerinden açtığınız bireysel tezgahınız ile ürünlerinizi doğrudan müşterilere ulaştırabilirsiniz. @@ -864,6 +870,7 @@ tr: distributor: "Dağıtımcı" products: "Ürünler" tags: "Etiketler" + delivery_details: "Teslimat Detayları" fees: "Ücretler" previous: "Önceki" save: "Kaydet" @@ -916,8 +923,8 @@ tr: schedules: Takvimler new_schedule: Yeni Takvim name_and_timing_form: - name: ad - orders_open: 'Siparişler şu zamanda açık:' + name: Ad + orders_open: 'Sipariş açılma vakti:' coordinator: Koordinatör orders_close: Siparişler kapalı row: @@ -950,7 +957,7 @@ tr: could_not_resume_the_order: Sipariş sürdürülemedi shared: user_guide_link: - user_guide: Kullanici rehberi + user_guide: Kullanıcı Kılavuzu enterprises_hubs_tabs: has_no_payment_methods: "%{enterprise} için bir ödeme yöntemi yok" has_no_shipping_methods: "%{enterprise} için bir teslimat yöntemi yok" @@ -1030,7 +1037,7 @@ tr: enable_subscriptions_step_1_html: 1. %{enterprises_link} sayfasına gidin, tezgahınızı bulun ve ‘Yönet’i tıklayın enable_subscriptions_step_2: '''Tezgah Tercihleri'' altındaki Üyelikler seçeneğini etkinleştirin' set_up_shipping_and_payment_methods_html: '%{shipping_link} ve %{payment_link} yöntemlerini ayarlayın' - set_up_shipping_and_payment_methods_note_html: Yalnızca Nakit ve Şerit ödeme yöntemlerinin
'ü üyeliklerle kullanılabilir + set_up_shipping_and_payment_methods_note_html: Yalnızca Nakit ve Online ödeme yöntemlerinin
'ü üyeliklerle kullanılabilir ensure_at_least_one_customer_html: En az bir %{customer_link} bulunduğundan emin olun create_at_least_one_schedule: En az bir Takvim oluşturun create_at_least_one_schedule_step_1_html: 1. %{order_cycles_link} sayfasına gidin @@ -1055,7 +1062,7 @@ tr: details: details: Bilgi invalid_error: Hata! Lütfen zorunlu alanların tümünü doldurun ... - allowed_payment_method_types_tip: Şu anda yalnızca Nakit ve Stripe ödeme yöntemleri kullanılabilir + allowed_payment_method_types_tip: Şu anda yalnızca belirli ödeme yöntemleri kullanılabilir credit_card: Kredi kartı charges_not_allowed: Bu müşteri ücret yansıtılmasına izin vermiyor no_default_card: Müşterinin tahsilat yapılabilecek bir kartı yok @@ -1101,11 +1108,11 @@ tr: associated_subscriptions_error: Bağlantılı üyelikler olduğu için bu takvim silinemiyor controllers: enterprises: - stripe_connect_cancelled: "Stripe bağlantısı iptal edildi" - stripe_connect_success: "Stripe hesabı başarıyla bağlandı" - stripe_connect_fail: Maalesef, Stripe hesabınızın bağlantısı başarısız oldu + stripe_connect_cancelled: "Iyzico bağlantısı iptal edildi" + stripe_connect_success: "Iyzico hesabı başarıyla bağlandı" + stripe_connect_fail: Maalesef, Iyzico hesabınızın bağlantısı başarısız oldu stripe_connect_settings: - resource: Stripe Connect yapılandırması + resource: Iyzico yapılandırması api: enterprise_logo: destroy_attachment_does_not_exist: "Logo mevcut değil" @@ -1120,8 +1127,8 @@ tr: failed: "Ödeme başarısız oldu. Siparişinizi işleme koyabilmemiz için lütfen bizimle iletişime geçin." shops: hubs: - show_closed_shops: "Kapalı pazarları göster" - hide_closed_shops: "Kapalı pazarları gizle" + show_closed_shops: "Kapalı dükkanları göster" + hide_closed_shops: "Kapalı dükkanları gizle" show_on_map: "Tümünü haritada göster" shared: menu: @@ -1185,24 +1192,24 @@ tr: invoice_issued_on: "Fatura Düznleme Tarihi" order_number: "Fatura numarası:" date_of_transaction: "İşlem tarihi:" - ticket_column_qty: "miktar" - ticket_column_item: "ürün" + ticket_column_qty: "Miktar" + ticket_column_item: "Ürün" ticket_column_unit_price: "Birim fiyat" ticket_column_total_price: "Toplam tutar" menu_1_title: "Pazarlar" - menu_1_url: "/pazarlar" + menu_1_url: "/shops" menu_2_title: "harita" - menu_2_url: "/harita" + menu_2_url: "/map" menu_3_title: "üreticiler" - menu_3_url: "/ üreticiler" + menu_3_url: "/producers" menu_4_title: "Gruplar" menu_4_url: "/ gruplar" menu_5_title: "hakkında" - menu_5_url: "https://about.openfoodnetwork.org.au/" + menu_5_url: "https://acikgida.com" menu_6_title: "Bağlan" - menu_6_url: "https://openfoodnetwork.org/au/connect/" + menu_6_url: "https://acikgida.com" menu_7_title: "öğren" - menu_7_url: "https://openfoodnetwork.org/au/learn/" + menu_7_url: "https://acikgida.com" logo: "Logo (640x130)" logo_mobile: "Cep telefonu logosu (75x26)" logo_mobile_svg: "Cep Telefonu logo (SVG)" @@ -1277,7 +1284,7 @@ tr: card_securitycode: "Güvenlik Kodu" card_expiry_date: Son kullanma tarihi card_masked_digit: "X" - card_expiry_abbreviation: "Tecrübe" + card_expiry_abbreviation: "Son kullanma tarihi" new_credit_card: "Yeni kredi kartı" my_credit_cards: Kredi kartlarım add_new_credit_card: Yeni kredi kartı ekle @@ -1490,6 +1497,7 @@ tr: shopping_oc_closed_description: "Lütfen bir sonraki dönem açılana kadar bekleyin (veya geç siparişleri kabul edip edemeyeceğimizi görmek için doğrudan bizimle iletişime geçin)" shopping_oc_last_closed: "Son dönem %{distance_of_time} önce kapandı" shopping_oc_next_open: "Bir sonraki dönem %{distance_of_time}'da açılıyor" + shopping_oc_select: "Seçin..." shopping_tabs_home: "Ana sayfa" shopping_tabs_shop: "Alışveriş yap" shopping_tabs_about: "hakkında" @@ -1539,7 +1547,7 @@ tr: products_update_error_msg: "Kaydetme başarısız oldu." products_update_error_data: "Geçersiz veriler nedeniyle kaydetme başarısız oldu:" products_changes_saved: "Değişiklikler kaydedildi." - search_no_results_html: "Üzgünüz, %{query} için sonuç bulunamadı. Başka bir arama yapmak ister misiniz?" + search_no_results_html: "Üzgünüz, %{query} sonuç bulunamadı. Başka bir arama yapmak ister misiniz?" components_profiles_popover: "Açık Gıda Ağında bir vitrini olmayan ancak başka bir sitede kendi satış siteleri olan hesaplar" components_profiles_show: "Profilleri göster" components_filters_nofilters: "Filtresiz" @@ -1635,9 +1643,9 @@ tr: sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. OFN'de bir mağaza açmak ve işletmek aylık 500 dolara kadar ücretsizdir. Daha fazla satıyorsanız, satışların% 1'i ile% 3'ü arasında topluluk katkınızı seçebilirsiniz. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkında bağlantısını kullanarak Yazılım Platformu bölümünü ziyaret edin." sell_embed: "Açık Gıda Ağı üzerinden oluşturduğunuz tezgahınızı kendi web siteniz üzerinden de kullanmanıza yardımcı olabiliriz. Müşterileriniz mevcut internet siteniz üzerinden de aynı şekilde sipariş verebilirler. " sell_ask_services: "Bize AGA hizmetleri hakkında soru sorun." - shops_title: Mağazalar + shops_title: Dükkanlar shops_headline: Alışveriş biçim değiştiriyor - shops_text: Gıdalar döngüler halinde büyür, çiftçiler döngüler halinde hasat eder ve döngüler halinde yiyecek sipariş ederiz. Sipariş döngüsünün kapalı olduğunu fark ederseniz, kısa süre sonra tekrar kontrol edin. + shops_text: Gıda dönemsel yetişir, dönemsel hasat edilir ve dönemsel sipariş edilir. Aradığınız sipariş dönemi kapalı ise kısa süre sonra tekrar kontrol edin. shops_signup_title: Pazar olarak kaydolun shops_signup_headline: Gıda pazarları, sınır yok. shops_signup_motivation: Her türlü gıda işletmesi/topluluğu modelini destekliyoruz. Bağımsız ve şeffaf bir sosyal girişimiz. İşlerinizi kolaylaştırmaya çalışan yol arkadaşlarıyız. @@ -1863,6 +1871,7 @@ tr: headline: "Tamamlandı!" thanks: "%{enterprise} ile ilgili ayrıntıları doldurduğunuz için teşekkür ederiz." login: "Dilediğiniz zaman Açık Gıda Ağı üzerinden giriş yapıp Yönetici paneline giderek işletmenizin ayarlarını güncelleyebilirsiniz." + action: "İşletme Paneline Git" back: "Geri" continue: "Devam et" action_or: "VEYA" @@ -2279,6 +2288,7 @@ tr: enterprise_register_success_notice: "Tebrikler! %{enterprise}için kayıt tamamlandı!" enterprise_bulk_update_success_notice: "İşletmeler başarıyla güncellendi" enterprise_bulk_update_error: 'Güncelleştirme başarısız' + enterprise_shop_show_error: "Aradığınız dükkan AGA üzerinde bulunamıyor veya gizli durumda. Lütfen diğerlerini kontrol edin." order_cycles_create_notice: 'Sipariş döneminiz oluşturuldu.' order_cycles_update_notice: 'Sipariş döneminiz güncellendi.' order_cycles_bulk_update_notice: 'Sipariş dönemleri güncellendi.' @@ -2859,7 +2869,7 @@ tr: shipping_methods: "Teslimat Yöntemleri" shipping_categories: "Nakliye Kategorileri" new_shipping_category: "Yeni Nakliye Kategorisi" - back_to_shipping_categories: "Nakliye Kategorilerine Geri Dön" + back_to_shipping_categories: "Teslimat Kategorilerine Geri Dön" analytics_trackers: "Analitik İzleyiciler" no_trackers_found: "İzleyici Bulunamadı" new_tracker: "Yeni İzleyici" @@ -3017,6 +3027,8 @@ tr: tax_invoice: "VERGİ FATURASI" code: "Kod" from: "İtibaren" + to: "Fatura Adresi" + shipping: "Teslimat" form: distribution_fields: title: "Dağıtım" @@ -3219,7 +3231,7 @@ tr: enter_new_card: Yeni bir kart için bilgileri girin used_saved_card: "Kayıtlı bir kart kullanın:" or_enter_new_card: "Veya yeni bir kart için bilgileri girin:" - remember_this_card: Bu kartı hatırlıyor musunuz? + remember_this_card: Bu kart hatırlansın mı? date_picker: format: '% Y-% A-%d' js_format: 'yy-aa-gg' From b5d159e163dd4a5c02cd9d128ea60fd28724ce2d Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 17 Apr 2020 16:09:22 +1000 Subject: [PATCH 128/166] Add cache to mirror_db script Also added some better error handling around image syncing. --- script/mirror_db.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/script/mirror_db.sh b/script/mirror_db.sh index ede932c821..c69db3490d 100755 --- a/script/mirror_db.sh +++ b/script/mirror_db.sh @@ -10,6 +10,7 @@ HOST="$1" BUCKET="$2" : ${DB_USER='ofn_user'} : ${DB_DATABASE='openfoodnetwork'} +: ${DB_CACHE_FILE="tmp/$HOST.sql"} DB_OPTIONS=( --exclude-table-data=sessions @@ -32,20 +33,30 @@ fi # -- Mirror database echo "Mirroring database..." -dropdb -h localhost -U ofn open_food_network_dev +dropdb -h localhost -U ofn open_food_network_dev --if-exists createdb -h localhost -U ofn open_food_network_dev -ssh -C "$HOST" "pg_dump -h localhost -U $DB_USER $DB_DATABASE ${DB_OPTIONS[@]}" | psql -h localhost -U ofn open_food_network_dev + +if [ -s "$DB_CACHE_FILE" ]; then + echo "Using cached dump '$DB_CACHE_FILE'." + psql -h localhost -U ofn open_food_network_dev < "$DB_CACHE_FILE" +else + echo "Downlowding dump to '$DB_CACHE_FILE'." + ssh -C "$HOST" "pg_dump -h localhost -U $DB_USER $DB_DATABASE ${DB_OPTIONS[@]}"\ + | tee "$DB_CACHE_FILE"\ + | psql -h localhost -U ofn open_food_network_dev +fi # -- Disable S3 echo "Preparing mirrored database..." $RAILS_RUN script/prepare_imported_db.rb # -- Mirror images -if [ -n "$BUCKET" ] && hash aws 2>/dev/null; then +if [ -n "$BUCKET" ]; then + if hash aws 2>/dev/null; then echo "Mirroring images..." aws s3 sync "s3://$BUCKET/public public/" - -else + else echo "Please install the AWS CLI tools so that I can copy the images from $BUCKET for you." echo "eg. sudo easy_install awscli" + fi fi From ffceff3f0ab60c21c29eee76e5e4667f6df8535a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 11:41:02 +0100 Subject: [PATCH 129/166] Update GETTING_STARTED.md Update link to osx catalina setup guide in wiki --- GETTING_STARTED.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index c372d152d7..84b38663aa 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -118,7 +118,7 @@ $ createdb open_food_network_test --owner=ofn If these commands succeed, you should be able to [continue the setup process](#get-it-running). [developer-wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki -[sierra]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup%3A-macOS-%28Sierra%2C-HighSierra-and-Mojave%29 +[sierra]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup%3A-macOS-%28Sierra%2C-HighSierra%2C-Mojave-and-Catalina%29 [el-capitan]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X-(El-Capitan) [ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu [wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki From 427dc549458a7ee9ac30eb8654cb6ee2f0f6b9ea Mon Sep 17 00:00:00 2001 From: blainebillings Date: Thu, 20 Feb 2020 09:28:43 -0500 Subject: [PATCH 130/166] Change Result of PriceSack Calculation from Integers to Floats --- app/models/spree/calculator/price_sack_decorator.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/spree/calculator/price_sack_decorator.rb b/app/models/spree/calculator/price_sack_decorator.rb index 41aeabf330..b474f77861 100644 --- a/app/models/spree/calculator/price_sack_decorator.rb +++ b/app/models/spree/calculator/price_sack_decorator.rb @@ -17,9 +17,9 @@ module Spree order_amount = line_items_for(object).map { |x| x.price * x.quantity }.sum if order_amount < min - cost = preferred_normal_amount.to_i + cost = preferred_normal_amount.to_f elsif order_amount >= min - cost = preferred_discount_amount.to_i + cost = preferred_discount_amount.to_f end cost From 993a684e446e20e5333b71ef38eb929de5a3a19b Mon Sep 17 00:00:00 2001 From: blainebillings Date: Tue, 25 Feb 2020 09:28:54 -0500 Subject: [PATCH 131/166] Add Price Sack Spec for Float Amounts --- spec/models/spree/calculator/price_sack_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/models/spree/calculator/price_sack_spec.rb b/spec/models/spree/calculator/price_sack_spec.rb index 9b0a38d0e8..f77cd01da4 100644 --- a/spec/models/spree/calculator/price_sack_spec.rb +++ b/spec/models/spree/calculator/price_sack_spec.rb @@ -8,6 +8,13 @@ describe Spree::Calculator::PriceSack do calculator.preferred_discount_amount = 1 calculator end + let(:floatCalculator) do + floatCalculator = Spree::Calculator::PriceSack.new + floatCalculator.preferred_minimal_amount = 5 + floatCalculator.preferred_normal_amount = 10.4 + floatCalculator.preferred_discount_amount = 1.2 + floatCalculator + end let(:line_item) { build(:line_item, price: price, quantity: 2) } @@ -16,6 +23,11 @@ describe Spree::Calculator::PriceSack do it "uses the preferred normal amount" do expect(calculator.compute(line_item)).to eq(10) end + context "and preferred normal amount is float" do + it "uses the float preferred normal amount" do + expect(floatCalculator.compute(line_item)).to eq(10.4) + end + end end context 'when the order amount is above preferred minimal' do @@ -23,6 +35,11 @@ describe Spree::Calculator::PriceSack do it "uses the preferred discount amount" do expect(calculator.compute(line_item)).to eq(1) end + context "and preferred discount amount is float" do + it "uses the float preferred discount amount" do + expect(floatCalculator.compute(line_item)).to eq(1.2) + end + end end context "extends LocalizedNumber" do From d23397f250b68dd023deb8ec17e2bba17fc3fdd6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 14:49:09 +0100 Subject: [PATCH 132/166] Move float test to a separate context --- .../spree/calculator/price_sack_spec.rb | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/spec/models/spree/calculator/price_sack_spec.rb b/spec/models/spree/calculator/price_sack_spec.rb index f77cd01da4..751f337cee 100644 --- a/spec/models/spree/calculator/price_sack_spec.rb +++ b/spec/models/spree/calculator/price_sack_spec.rb @@ -8,36 +8,46 @@ describe Spree::Calculator::PriceSack do calculator.preferred_discount_amount = 1 calculator end - let(:floatCalculator) do - floatCalculator = Spree::Calculator::PriceSack.new - floatCalculator.preferred_minimal_amount = 5 - floatCalculator.preferred_normal_amount = 10.4 - floatCalculator.preferred_discount_amount = 1.2 - floatCalculator - end - let(:line_item) { build(:line_item, price: price, quantity: 2) } context 'when the order amount is below preferred minimal' do let(:price) { 2 } + it "uses the preferred normal amount" do expect(calculator.compute(line_item)).to eq(10) end - context "and preferred normal amount is float" do - it "uses the float preferred normal amount" do - expect(floatCalculator.compute(line_item)).to eq(10.4) - end - end end context 'when the order amount is above preferred minimal' do let(:price) { 6 } + it "uses the preferred discount amount" do expect(calculator.compute(line_item)).to eq(1) end - context "and preferred discount amount is float" do + end + + context "preferred discount amount is float" do + let(:float_calculator) do + float_calculator = Spree::Calculator::PriceSack.new + float_calculator.preferred_minimal_amount = 5 + float_calculator.preferred_normal_amount = 10.4 + float_calculator.preferred_discount_amount = 1.2 + float_calculator + end + + context 'when the order amount is below preferred minimal' do + let(:price) { 2 } + + it "uses the float preferred normal amount" do + expect(float_calculator.compute(line_item)).to eq(10.4) + end + end + + context 'when the order amount is above preferred minimal' do + let(:price) { 6 } + it "uses the float preferred discount amount" do - expect(floatCalculator.compute(line_item)).to eq(1.2) + expect(float_calculator.compute(line_item)).to eq(1.2) end end end From 914751842258fe025246cf2ddb056777bf4273b3 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 14:51:06 +0100 Subject: [PATCH 133/166] Remove some unnecessary code --- spec/models/spree/calculator/price_sack_spec.rb | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/spec/models/spree/calculator/price_sack_spec.rb b/spec/models/spree/calculator/price_sack_spec.rb index 751f337cee..921b657f88 100644 --- a/spec/models/spree/calculator/price_sack_spec.rb +++ b/spec/models/spree/calculator/price_sack_spec.rb @@ -27,19 +27,16 @@ describe Spree::Calculator::PriceSack do end context "preferred discount amount is float" do - let(:float_calculator) do - float_calculator = Spree::Calculator::PriceSack.new - float_calculator.preferred_minimal_amount = 5 - float_calculator.preferred_normal_amount = 10.4 - float_calculator.preferred_discount_amount = 1.2 - float_calculator + before do + calculator.preferred_normal_amount = 10.4 + calculator.preferred_discount_amount = 1.2 end context 'when the order amount is below preferred minimal' do let(:price) { 2 } it "uses the float preferred normal amount" do - expect(float_calculator.compute(line_item)).to eq(10.4) + expect(calculator.compute(line_item)).to eq(10.4) end end @@ -47,7 +44,7 @@ describe Spree::Calculator::PriceSack do let(:price) { 6 } it "uses the float preferred discount amount" do - expect(float_calculator.compute(line_item)).to eq(1.2) + expect(calculator.compute(line_item)).to eq(1.2) end end end From d96d6b23378124b0cab264dd145a9ba4fec88b84 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 15:21:03 +0100 Subject: [PATCH 134/166] Split orders_spec in two: tests for orders list page and tests for orders edit page --- spec/features/admin/order_spec.rb | 373 +++++++++++++++++++++++++++++ spec/features/admin/orders_spec.rb | 299 ----------------------- 2 files changed, 373 insertions(+), 299 deletions(-) create mode 100644 spec/features/admin/order_spec.rb diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb new file mode 100644 index 0000000000..a957e47617 --- /dev/null +++ b/spec/features/admin/order_spec.rb @@ -0,0 +1,373 @@ +require "spec_helper" +include ActionView::Helpers::NumberHelper + +feature ' + As an administrator + I want to create and edit orders +', js: true do + include AuthenticationWorkflow + include WebHelper + include CheckoutHelper + + background do + @user = create(:user) + @product = create(:simple_product) + @distributor = create(:distributor_enterprise, owner: @user, charges_sales_tax: true) + @order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first]) + + @order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due') + @customer = create(:customer, enterprise: @distributor, email: @user.email, user: @user, ship_address: create(:address)) + + # ensure order has a payment to capture + @order.finalize! + + create :check_payment, order: @order, amount: @order.total + end + + def new_order_with_distribution(distributor, order_cycle) + visit 'admin/orders/new' + expect(page).to have_selector('#s2id_order_distributor_id') + select2_select distributor.name, from: 'order_distributor_id' + select2_select order_cycle.name, from: 'order_order_cycle_id' + click_button 'Next' + end + + scenario "creating an order with distributor and order cycle" do + distributor_disabled = create(:distributor_enterprise) + create(:simple_order_cycle, name: 'Two') + + quick_login_as_admin + + visit '/admin/orders' + click_link 'New Order' + + # Distributors without an order cycle should be shown as disabled + open_select2('#s2id_order_distributor_id') + expect(page).to have_selector "ul.select2-results li.select2-result.select2-disabled", text: distributor_disabled.name + close_select2('#s2id_order_distributor_id') + + # Order cycle selector should be disabled + expect(page).to have_selector "#s2id_order_order_cycle_id.select2-container-disabled" + + # When we select a distributor, it should limit order cycle selection to those for that distributor + select2_select @distributor.name, from: 'order_distributor_id' + expect(page).to have_select2 'order_order_cycle_id', options: ['One (open)'] + select2_select @order_cycle.name, from: 'order_order_cycle_id' + click_button 'Next' + + # it suppresses validation errors when setting distribution + expect(page).not_to have_selector '#errorExplanation' + expect(page).to have_content 'ADD PRODUCT' + targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + find('button.add_variant').click + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + expect(page).to have_selector 'td', text: @product.name + + click_button 'Update' + + expect(page).to have_selector 'h1', text: 'Customer Details' + o = Spree::Order.last + expect(o.distributor).to eq(@distributor) + expect(o.order_cycle).to eq(@order_cycle) + end + + scenario "can add a product to an existing order" do + quick_login_as_admin + visit '/admin/orders' + + click_icon :edit + + targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + + find('button.add_variant').click + + expect(page).to have_selector 'td', text: @product.name + expect(@order.line_items(true).map(&:product)).to include @product + end + + scenario "displays error when incorrect distribution for products is chosen" do + d = create(:distributor_enterprise) + oc = create(:simple_order_cycle, distributors: [d]) + + # Move the order back to the cart state + @order.state = 'cart' + @order.completed_at = nil + # A nil user keeps the order in the cart state + # Even if the edit page tries to automatically progress the order workflow + @order.user = nil + @order.save + + quick_login_as_admin + visit '/admin/orders' + uncheck 'Only show complete orders' + page.find('a.icon-search').click + + click_icon :edit + expect(page).to have_select2 "order_distributor_id", with_options: [d.name] + select2_select d.name, from: 'order_distributor_id' + select2_select oc.name, from: 'order_order_cycle_id' + + click_button 'Update And Recalculate Fees' + expect(page).to have_content "Distributor or order cycle cannot supply the products in your cart" + end + + scenario "can't add products to an order outside the order's hub and order cycle" do + product = create(:simple_product) + + quick_login_as_admin + visit '/admin/orders' + page.find('td.actions a.icon-edit').click + + expect(page).not_to have_select2 "add_variant_id", with_options: [product.name] + end + + scenario "can't change distributor or order cycle once order has been finalized" do + quick_login_as_admin + visit '/admin/orders' + page.find('td.actions a.icon-edit').click + + expect(page).not_to have_select2 'order_distributor_id' + expect(page).not_to have_select2 'order_order_cycle_id' + + expect(page).to have_selector 'p', text: "Distributor: #{@order.distributor.name}" + expect(page).to have_selector 'p', text: "Order cycle: #{@order.order_cycle.name}" + end + + scenario "filling customer details" do + # Given a customer with an order, which includes their shipping and billing address + + # We change the 1st order's address details + # This way we validate that the original details (stored in customer) are picked up in the 2nd order + @order.ship_address = create(:address, lastname: 'Ship') + @order.bill_address = create(:address, lastname: 'Bill') + @order.save! + + # We set the existing shipping method to delivery, this shipping method will be used in the 2nd order + # Otherwise order_updater.shipping_address_from_distributor will set the 2nd order address to the distributor address + @order.shipping_method.update_attribute :require_ship_address, true + + # When I create a new order + quick_login_as @user + new_order_with_distribution(@distributor, @order_cycle) + targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + find('button.add_variant').click + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + click_button 'Update' + + expect(page).to have_selector 'h1.page-title', text: "Customer Details" + + # And I select that customer's email address and save the order + targetted_select2_search @customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' + click_button 'Update' + expect(page).to have_selector "h1.page-title", text: "Customer Details" + + # Then their addresses should be associated with the order + order = Spree::Order.last + expect(order.ship_address.lastname).to eq @customer.ship_address.lastname + expect(order.bill_address.lastname).to eq @customer.bill_address.lastname + end + + context "as an enterprise manager" do + let(:coordinator1) { create(:distributor_enterprise) } + let(:coordinator2) { create(:distributor_enterprise) } + let!(:order_cycle1) { create(:order_cycle, coordinator: coordinator1) } + let!(:order_cycle2) { create(:simple_order_cycle, coordinator: coordinator2) } + let!(:supplier1) { order_cycle1.suppliers.first } + let!(:supplier2) { order_cycle1.suppliers.last } + let!(:distributor1) { order_cycle1.distributors.first } + let!(:distributor2) { order_cycle1.distributors.reject{ |d| d == distributor1 }.last } # ensure d1 != d2 + let(:product) { order_cycle1.products.first } + + before(:each) do + @enterprise_user = create_enterprise_user + @enterprise_user.enterprise_roles.build(enterprise: supplier1).save + @enterprise_user.enterprise_roles.build(enterprise: coordinator1).save + @enterprise_user.enterprise_roles.build(enterprise: distributor1).save + + quick_login_as @enterprise_user + end + + feature "viewing the edit page" do + let!(:shipping_method_for_distributor1) { create(:shipping_method, name: "Normal", distributors: [distributor1]) } + let!(:different_shipping_method_for_distributor1) { create(:shipping_method, name: "Different", distributors: [distributor1]) } + let!(:shipping_method_for_distributor2) { create(:shipping_method, name: "Other", distributors: [distributor2]) } + + let!(:order) do + create(:order_with_taxes, distributor: distributor1, ship_address: create(:address), + product_price: 110, tax_rate_amount: 0.1, + tax_rate_name: "Tax 1").tap do |record| + Spree::TaxRate.adjust(record) + record.update_shipping_fees! + end + end + + background do + Spree::Config[:enable_receipt_printing?] = true + distributor1.update_attribute(:abn, '12345678') + + visit spree.edit_admin_order_path(order) + end + + scenario "shows a list of line_items" do + within('table.index tbody', match: :first) do + order.line_items.each do |item| + expect(page).to have_selector "td", match: :first, text: item.full_name + expect(page).to have_selector "td.item-price", text: item.single_display_amount + expect(page).to have_selector "input#quantity[value='#{item.quantity}']", visible: false + expect(page).to have_selector "td.item-total", text: item.display_amount + end + end + end + + scenario "shows the order items total" do + within('fieldset#order-total') do + expect(page).to have_selector "span.order-total", text: order.display_item_total + end + end + + scenario "shows the order non-tax adjustments" do + within('table.index tbody') do + order.adjustments.eligible.each do |adjustment| + expect(page).to have_selector "td", match: :first, text: adjustment.label + expect(page).to have_selector "td.total", text: adjustment.display_amount + end + end + end + + scenario "shows the order total" do + expect(page).to have_selector "fieldset#order-total", text: order.display_total + end + + scenario "shows the order tax adjustments" do + within('fieldset', text: I18n.t('spree.admin.orders.form.line_item_adjustments').upcase) do + expect(page).to have_selector "td", match: :first, text: "Tax 1" + expect(page).to have_selector "td.total", text: Spree::Money.new(10) + end + end + + scenario "shows the dropdown menu" do + find("#links-dropdown .ofn-drop-down").click + within "#links-dropdown" do + expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(order) + expect(page).to have_link "Send Invoice", href: spree.invoice_admin_order_path(order) + expect(page).to have_link "Print Invoice", href: spree.print_admin_order_path(order) + expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, e: 'cancel') + end + end + + scenario "cannot split the order in different stock locations" do + # There's only 1 stock location in OFN, so the split functionality that comes with spree should be hidden + expect(page).to_not have_selector '.split-item' + end + + scenario "can edit shipping method" do + expect(page).to_not have_content different_shipping_method_for_distributor1.name + + find('.edit-method').click + expect(page).to have_select2 'selected_shipping_rate_id', with_options: [shipping_method_for_distributor1.name, different_shipping_method_for_distributor1.name], without_options: [shipping_method_for_distributor2.name] + select2_select different_shipping_method_for_distributor1.name, from: 'selected_shipping_rate_id' + find('.save-method').click + + expect(page).to have_content different_shipping_method_for_distributor1.name + end + + scenario "can edit tracking number" do + test_tracking_number = "ABCCBA" + expect(page).to_not have_content test_tracking_number + + find('.edit-tracking').click + fill_in "tracking", with: test_tracking_number + find('.save-tracking').click + + expect(page).to have_content test_tracking_number + end + + scenario "can print an order's ticket" do + find("#links-dropdown .ofn-drop-down").click + + ticket_window = window_opened_by do + within('#links-dropdown') do + click_link('Print Ticket') + end + end + + within_window ticket_window do + accept_alert do + print_data = page.evaluate_script('printData'); + elements_in_print_data = + [ + order.distributor.name, + order.distributor.address.address_part1, + order.distributor.address.address_part2, + order.distributor.contact.email, + order.number, + order.line_items.map { |line_item| + [line_item.quantity.to_s, + line_item.product.name, + line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false), + line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] + }, + checkout_adjustments_for(order, exclude: [:line_item]).reject { |a| a.amount == 0 }.map { |adjustment| + [raw(adjustment.label), + display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] + }, + order.display_total.format(with_currency: false), + display_checkout_taxes_hash(order).map { |tax_rate, tax_value| + [tax_rate, + tax_value.format(with_currency: false)] + }, + display_checkout_total_less_tax(order).format(with_currency: false) + ] + expect(print_data.join).to include(*elements_in_print_data.flatten) + end + end + end + + scenario "editing shipping fees" do + click_link "Adjustments" + page.find('td.actions a.icon-edit').click + + fill_in "Amount", with: "5" + click_button "Continue" + + expect(page.find("td.amount")).to have_content "$5.00" + end + + context "when an included variant has been deleted" do + let!(:deleted_variant) do + order.line_items.first.variant.tap(&:delete) + end + + it "still lists the variant in the order page" do + within ".stock-contents" do + expect(page).to have_content deleted_variant.product_and_full_name + end + end + end + end + + scenario "creating an order with distributor and order cycle" do + new_order_with_distribution(distributor1, order_cycle1) + + expect(page).to have_content 'ADD PRODUCT' + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + + find('button.add_variant').click + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + expect(page).to have_selector 'td', text: product.name + + expect(page).to have_select2 'order_distributor_id', with_options: [distributor1.name] + expect(page).to_not have_select2 'order_distributor_id', with_options: [distributor2.name] + + expect(page).to have_select2 'order_order_cycle_id', with_options: ["#{order_cycle1.name} (open)"] + expect(page).to_not have_select2 'order_order_cycle_id', with_options: ["#{order_cycle2.name} (open)"] + + click_button 'Update' + + expect(page).to have_selector 'h1', text: 'Customer Details' + o = Spree::Order.last + expect(o.distributor).to eq distributor1 + expect(o.order_cycle).to eq order_cycle1 + end + end +end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 09bec96ccf..79e6d444b2 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -24,14 +24,6 @@ feature ' create :check_payment, order: @order, amount: @order.total end - def new_order_with_distribution(distributor, order_cycle) - visit 'admin/orders/new' - expect(page).to have_selector('#s2id_order_distributor_id') - select2_select distributor.name, from: 'order_distributor_id' - select2_select order_cycle.name, from: 'order_order_cycle_id' - click_button 'Next' - end - scenario "order cycles appear in descending order by close date on orders page" do create(:simple_order_cycle, name: 'Two', orders_close_at: 2.weeks.from_now) create(:simple_order_cycle, name: 'Four', orders_close_at: 4.weeks.from_now) @@ -45,59 +37,6 @@ feature ' expect(find('#q_order_cycle_id_in', visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two.*One/m) end - scenario "creating an order with distributor and order cycle" do - distributor_disabled = create(:distributor_enterprise) - create(:simple_order_cycle, name: 'Two') - - quick_login_as_admin - - visit '/admin/orders' - click_link 'New Order' - - # Distributors without an order cycle should be shown as disabled - open_select2('#s2id_order_distributor_id') - expect(page).to have_selector "ul.select2-results li.select2-result.select2-disabled", text: distributor_disabled.name - close_select2('#s2id_order_distributor_id') - - # Order cycle selector should be disabled - expect(page).to have_selector "#s2id_order_order_cycle_id.select2-container-disabled" - - # When we select a distributor, it should limit order cycle selection to those for that distributor - select2_select @distributor.name, from: 'order_distributor_id' - expect(page).to have_select2 'order_order_cycle_id', options: ['One (open)'] - select2_select @order_cycle.name, from: 'order_order_cycle_id' - click_button 'Next' - - # it suppresses validation errors when setting distribution - expect(page).not_to have_selector '#errorExplanation' - expect(page).to have_content 'ADD PRODUCT' - targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' - find('button.add_variant').click - page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS - expect(page).to have_selector 'td', text: @product.name - - click_button 'Update' - - expect(page).to have_selector 'h1', text: 'Customer Details' - o = Spree::Order.last - expect(o.distributor).to eq(@distributor) - expect(o.order_cycle).to eq(@order_cycle) - end - - scenario "can add a product to an existing order" do - quick_login_as_admin - visit '/admin/orders' - - click_icon :edit - - targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' - - find('button.add_variant').click - - expect(page).to have_selector 'td', text: @product.name - expect(@order.line_items(true).map(&:product)).to include @product - end - scenario "displays error when incorrect distribution for products is chosen" do d = create(:distributor_enterprise) oc = create(:simple_order_cycle, distributors: [d]) @@ -146,40 +85,6 @@ feature ' expect(page).to have_selector 'p', text: "Order cycle: #{@order.order_cycle.name}" end - scenario "filling customer details" do - # Given a customer with an order, which includes their shipping and billing address - - # We change the 1st order's address details - # This way we validate that the original details (stored in customer) are picked up in the 2nd order - @order.ship_address = create(:address, lastname: 'Ship') - @order.bill_address = create(:address, lastname: 'Bill') - @order.save! - - # We set the existing shipping method to delivery, this shipping method will be used in the 2nd order - # Otherwise order_updater.shipping_address_from_distributor will set the 2nd order address to the distributor address - @order.shipping_method.update_attribute :require_ship_address, true - - # When I create a new order - quick_login_as @user - new_order_with_distribution(@distributor, @order_cycle) - targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' - find('button.add_variant').click - page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS - click_button 'Update' - - expect(page).to have_selector 'h1.page-title', text: "Customer Details" - - # And I select that customer's email address and save the order - targetted_select2_search @customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' - click_button 'Update' - expect(page).to have_selector "h1.page-title", text: "Customer Details" - - # Then their addresses should be associated with the order - order = Spree::Order.last - expect(order.ship_address.lastname).to eq @customer.ship_address.lastname - expect(order.bill_address.lastname).to eq @customer.bill_address.lastname - end - scenario "capture payment from the orders index page" do quick_login_as_admin @@ -209,208 +114,4 @@ feature ' expect(page).to have_css "i.success" expect(@order.reload.shipments.any?(&:shipped?)).to be true end - - context "as an enterprise manager" do - let(:coordinator1) { create(:distributor_enterprise) } - let(:coordinator2) { create(:distributor_enterprise) } - let!(:order_cycle1) { create(:order_cycle, coordinator: coordinator1) } - let!(:order_cycle2) { create(:simple_order_cycle, coordinator: coordinator2) } - let!(:supplier1) { order_cycle1.suppliers.first } - let!(:supplier2) { order_cycle1.suppliers.last } - let!(:distributor1) { order_cycle1.distributors.first } - let!(:distributor2) { order_cycle1.distributors.reject{ |d| d == distributor1 }.last } # ensure d1 != d2 - let(:product) { order_cycle1.products.first } - - before(:each) do - @enterprise_user = create_enterprise_user - @enterprise_user.enterprise_roles.build(enterprise: supplier1).save - @enterprise_user.enterprise_roles.build(enterprise: coordinator1).save - @enterprise_user.enterprise_roles.build(enterprise: distributor1).save - - quick_login_as @enterprise_user - end - - feature "viewing the edit page" do - let!(:shipping_method_for_distributor1) { create(:shipping_method, name: "Normal", distributors: [distributor1]) } - let!(:different_shipping_method_for_distributor1) { create(:shipping_method, name: "Different", distributors: [distributor1]) } - let!(:shipping_method_for_distributor2) { create(:shipping_method, name: "Other", distributors: [distributor2]) } - - let!(:order) do - create(:order_with_taxes, distributor: distributor1, ship_address: create(:address), - product_price: 110, tax_rate_amount: 0.1, - tax_rate_name: "Tax 1").tap do |record| - Spree::TaxRate.adjust(record) - record.update_shipping_fees! - end - end - - background do - Spree::Config[:enable_receipt_printing?] = true - distributor1.update_attribute(:abn, '12345678') - - visit spree.edit_admin_order_path(order) - end - - scenario "shows a list of line_items" do - within('table.index tbody', match: :first) do - order.line_items.each do |item| - expect(page).to have_selector "td", match: :first, text: item.full_name - expect(page).to have_selector "td.item-price", text: item.single_display_amount - expect(page).to have_selector "input#quantity[value='#{item.quantity}']", visible: false - expect(page).to have_selector "td.item-total", text: item.display_amount - end - end - end - - scenario "shows the order items total" do - within('fieldset#order-total') do - expect(page).to have_selector "span.order-total", text: order.display_item_total - end - end - - scenario "shows the order non-tax adjustments" do - within('table.index tbody') do - order.adjustments.eligible.each do |adjustment| - expect(page).to have_selector "td", match: :first, text: adjustment.label - expect(page).to have_selector "td.total", text: adjustment.display_amount - end - end - end - - scenario "shows the order total" do - expect(page).to have_selector "fieldset#order-total", text: order.display_total - end - - scenario "shows the order tax adjustments" do - within('fieldset', text: I18n.t('spree.admin.orders.form.line_item_adjustments').upcase) do - expect(page).to have_selector "td", match: :first, text: "Tax 1" - expect(page).to have_selector "td.total", text: Spree::Money.new(10) - end - end - - scenario "shows the dropdown menu" do - find("#links-dropdown .ofn-drop-down").click - within "#links-dropdown" do - expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(order) - expect(page).to have_link "Send Invoice", href: spree.invoice_admin_order_path(order) - expect(page).to have_link "Print Invoice", href: spree.print_admin_order_path(order) - expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, e: 'cancel') - end - end - - scenario "cannot split the order in different stock locations" do - # There's only 1 stock location in OFN, so the split functionality that comes with spree should be hidden - expect(page).to_not have_selector '.split-item' - end - - scenario "can edit shipping method" do - expect(page).to_not have_content different_shipping_method_for_distributor1.name - - find('.edit-method').click - expect(page).to have_select2 'selected_shipping_rate_id', with_options: [shipping_method_for_distributor1.name, different_shipping_method_for_distributor1.name], without_options: [shipping_method_for_distributor2.name] - select2_select different_shipping_method_for_distributor1.name, from: 'selected_shipping_rate_id' - find('.save-method').click - - expect(page).to have_content different_shipping_method_for_distributor1.name - end - - scenario "can edit tracking number" do - test_tracking_number = "ABCCBA" - expect(page).to_not have_content test_tracking_number - - find('.edit-tracking').click - fill_in "tracking", with: test_tracking_number - find('.save-tracking').click - - expect(page).to have_content test_tracking_number - end - - scenario "can print an order's ticket" do - find("#links-dropdown .ofn-drop-down").click - - ticket_window = window_opened_by do - within('#links-dropdown') do - click_link('Print Ticket') - end - end - - within_window ticket_window do - accept_alert do - print_data = page.evaluate_script('printData'); - elements_in_print_data = - [ - order.distributor.name, - order.distributor.address.address_part1, - order.distributor.address.address_part2, - order.distributor.contact.email, - order.number, - order.line_items.map { |line_item| - [line_item.quantity.to_s, - line_item.product.name, - line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false), - line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] - }, - checkout_adjustments_for(order, exclude: [:line_item]).reject { |a| a.amount == 0 }.map { |adjustment| - [raw(adjustment.label), - display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] - }, - order.display_total.format(with_currency: false), - display_checkout_taxes_hash(order).map { |tax_rate, tax_value| - [tax_rate, - tax_value.format(with_currency: false)] - }, - display_checkout_total_less_tax(order).format(with_currency: false) - ] - expect(print_data.join).to include(*elements_in_print_data.flatten) - end - end - end - - scenario "editing shipping fees" do - click_link "Adjustments" - page.find('td.actions a.icon-edit').click - - fill_in "Amount", with: "5" - click_button "Continue" - - expect(page.find("td.amount")).to have_content "$5.00" - end - - context "when an included variant has been deleted" do - let!(:deleted_variant) do - order.line_items.first.variant.tap(&:delete) - end - - it "still lists the variant in the order page" do - within ".stock-contents" do - expect(page).to have_content deleted_variant.product_and_full_name - end - end - end - end - - scenario "creating an order with distributor and order cycle" do - new_order_with_distribution(distributor1, order_cycle1) - - expect(page).to have_content 'ADD PRODUCT' - targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' - - find('button.add_variant').click - page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS - expect(page).to have_selector 'td', text: product.name - - expect(page).to have_select2 'order_distributor_id', with_options: [distributor1.name] - expect(page).to_not have_select2 'order_distributor_id', with_options: [distributor2.name] - - expect(page).to have_select2 'order_order_cycle_id', with_options: ["#{order_cycle1.name} (open)"] - expect(page).to_not have_select2 'order_order_cycle_id', with_options: ["#{order_cycle2.name} (open)"] - - click_button 'Update' - - expect(page).to have_selector 'h1', text: 'Customer Details' - o = Spree::Order.last - expect(o.distributor).to eq distributor1 - expect(o.order_cycle).to eq order_cycle1 - end - end end From 04c962432a7664a716907a55a9cd15afd115c6a8 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 17 Apr 2020 12:15:37 +0200 Subject: [PATCH 135/166] Skip deleted default_scope in OC notification This fixes the RuntimeError we get when accessing deleted variants due to the variant being nil. https://github.com/rails/rails/issues/11036 is still an open Rails bug, as some people mention in https://github.com/rails/rails/pull/21550. The issue is that `includes` doesn't respect `unscoped`. I found a potential solution for the entire app in https://github.com/rails/rails/issues/11036#issuecomment-302133116 but our friend @markets has a gem, https://github.com/markets/unscoped_associations, that solves that too. --- app/mailers/producer_mailer.rb | 61 +++++++++++++++++++--------- spec/mailers/producer_mailer_spec.rb | 13 ++++++ 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index 959cdf3537..ee4e25bce5 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -2,28 +2,31 @@ class ProducerMailer < Spree::BaseMailer include I18nHelper def order_cycle_report(producer, order_cycle) - @producer = producer - @coordinator = order_cycle.coordinator - @order_cycle = order_cycle - line_items = line_items_from(@order_cycle, @producer) - @grouped_line_items = line_items.group_by(&:product_and_full_name) - @receival_instructions = @order_cycle.receival_instructions_for @producer - @total = total_from_line_items(line_items) - @tax_total = tax_total_from_line_items(line_items) + unscoping do + @producer = producer + @coordinator = order_cycle.coordinator + @order_cycle = order_cycle - I18n.with_locale valid_locale(@producer.owner) do - order_cycle_subject = I18n.t('producer_mailer.order_cycle.subject', producer: producer.name) - subject = "[#{Spree::Config.site_name}] #{order_cycle_subject}" + line_items = line_items_from(@order_cycle, @producer) + @grouped_line_items = line_items.group_by(&:product_and_full_name) + @receival_instructions = @order_cycle.receival_instructions_for @producer + @total = total_from_line_items(line_items) + @tax_total = tax_total_from_line_items(line_items) - return unless has_orders?(order_cycle, producer) + I18n.with_locale valid_locale(@producer.owner) do + order_cycle_subject = I18n.t('producer_mailer.order_cycle.subject', producer: producer.name) + subject = "[#{Spree::Config.site_name}] #{order_cycle_subject}" - mail( - to: @producer.contact.email, - from: from_address, - subject: subject, - reply_to: @coordinator.contact.email, - cc: @coordinator.contact.email - ) + return unless has_orders?(order_cycle, producer) + + mail( + to: @producer.contact.email, + from: from_address, + subject: subject, + reply_to: @coordinator.contact.email, + cc: @coordinator.contact.email + ) + end end end @@ -35,7 +38,7 @@ class ProducerMailer < Spree::BaseMailer def line_items_from(order_cycle, producer) Spree::LineItem. - includes(variant: { option_values: :option_type }). + includes(variant: [:product, { option_values: :option_type }]). from_order_cycle(order_cycle). sorted_by_name_and_unit_value. merge(Spree::Product.in_supplier(producer)). @@ -49,4 +52,22 @@ class ProducerMailer < Spree::BaseMailer def tax_total_from_line_items(line_items) Spree::Money.new line_items.sum(&:included_tax) end + + # This hack makes ActiveRecord skip the default_scope (deleted_at IS NULL) + # when eager loading associations. Further details: + # https://github.com/rails/rails/issues/11036 + def unscoping + variant_default_scopes = Spree::Variant.default_scopes + product_default_scopes = Spree::Product.default_scopes + + Spree::Variant.default_scopes = [] + Spree::Product.default_scopes = [] + + return_value = yield + + Spree::Variant.default_scopes = variant_default_scopes + Spree::Product.default_scopes = product_default_scopes + + return_value + end end diff --git a/spec/mailers/producer_mailer_spec.rb b/spec/mailers/producer_mailer_spec.rb index c74998c3ab..2449d450c0 100644 --- a/spec/mailers/producer_mailer_spec.rb +++ b/spec/mailers/producer_mailer_spec.rb @@ -101,6 +101,19 @@ describe ProducerMailer, type: :mailer do end.to change(ActionMailer::Base.deliveries, :count).by(0) end + it "shows a deleted variant's full name" do + variant = p1.variants.first + full_name = variant.full_name + variant.delete + + expect(mail.body.encoded).to include(full_name) + end + + it 'shows deleted products' do + p1.delete + expect(mail.body.encoded).to include(p1.name) + end + private def body_lines_including(mail, s) From 6dd4a866e5188367ea4205fbf8553ee7001048c6 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 17 Apr 2020 17:00:11 +0200 Subject: [PATCH 136/166] Address some Rubocop violations --- .rubocop_todo.yml | 2 -- app/mailers/producer_mailer.rb | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6b7b8ddfde..3d3889f7d0 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -173,7 +173,6 @@ Naming/MethodParameterName: Naming/PredicateName: Exclude: - 'spec/**/*' - - 'app/mailers/producer_mailer.rb' - 'app/models/enterprise.rb' - 'app/models/enterprise_relationship.rb' - 'app/models/order_cycle.rb' @@ -630,7 +629,6 @@ Style/FrozenStringLiteralComment: - 'app/jobs/subscription_placement_job.rb' - 'app/jobs/welcome_enterprise_job.rb' - 'app/mailers/enterprise_mailer.rb' - - 'app/mailers/producer_mailer.rb' - 'app/mailers/spree/base_mailer_decorator.rb' - 'app/mailers/spree/order_mailer_decorator.rb' - 'app/mailers/spree/user_mailer.rb' diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index ee4e25bce5..5fc8e6419d 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -17,7 +17,7 @@ class ProducerMailer < Spree::BaseMailer order_cycle_subject = I18n.t('producer_mailer.order_cycle.subject', producer: producer.name) subject = "[#{Spree::Config.site_name}] #{order_cycle_subject}" - return unless has_orders?(order_cycle, producer) + return unless orders?(order_cycle, producer) mail( to: @producer.contact.email, @@ -32,7 +32,7 @@ class ProducerMailer < Spree::BaseMailer private - def has_orders?(order_cycle, producer) + def orders?(order_cycle, producer) line_items_from(order_cycle, producer).any? end From 06ead827d8a41b6f0f0ac0491b405484ddfd09d8 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 17 Apr 2020 17:14:51 +0200 Subject: [PATCH 137/166] Split long method --- .rubocop_manual_todo.yml | 2 -- app/mailers/producer_mailer.rb | 42 ++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index de9861fa40..8587ac7850 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -377,7 +377,6 @@ Metrics/AbcSize: - app/helpers/spree/admin/base_helper.rb - app/helpers/spree/admin/zones_helper.rb - app/helpers/spree/orders_helper.rb - - app/mailers/producer_mailer.rb - app/models/calculator/flat_percent_per_item.rb - app/models/column_preference.rb - app/models/enterprise.rb @@ -574,7 +573,6 @@ Metrics/MethodLength: - app/helpers/spree/admin/navigation_helper.rb - app/helpers/spree/admin/base_helper.rb - app/jobs/subscription_placement_job.rb - - app/mailers/producer_mailer.rb - app/models/column_preference.rb - app/models/enterprise.rb - app/models/enterprise_relationship.rb diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index 5fc8e6419d..e130fefd1f 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -1,22 +1,16 @@ +# frozen_string_literal: true + class ProducerMailer < Spree::BaseMailer include I18nHelper def order_cycle_report(producer, order_cycle) - unscoping do - @producer = producer - @coordinator = order_cycle.coordinator - @order_cycle = order_cycle + @producer = producer + @order_cycle = order_cycle - line_items = line_items_from(@order_cycle, @producer) - @grouped_line_items = line_items.group_by(&:product_and_full_name) - @receival_instructions = @order_cycle.receival_instructions_for @producer - @total = total_from_line_items(line_items) - @tax_total = tax_total_from_line_items(line_items) - - I18n.with_locale valid_locale(@producer.owner) do - order_cycle_subject = I18n.t('producer_mailer.order_cycle.subject', producer: producer.name) - subject = "[#{Spree::Config.site_name}] #{order_cycle_subject}" + with_unscoped_products_and_variants do + load_data + I18n.with_locale(owner_locale) do return unless orders?(order_cycle, producer) mail( @@ -32,6 +26,26 @@ class ProducerMailer < Spree::BaseMailer private + def owner_locale + valid_locale(@producer.owner) + end + + def load_data + @coordinator = @order_cycle.coordinator + + line_items = line_items_from(@order_cycle, @producer) + + @grouped_line_items = line_items.group_by(&:product_and_full_name) + @receival_instructions = @order_cycle.receival_instructions_for(@producer) + @total = total_from_line_items(line_items) + @tax_total = tax_total_from_line_items(line_items) + end + + def subject + order_cycle_subject = I18n.t('producer_mailer.order_cycle.subject', producer: @producer.name) + "[#{Spree::Config.site_name}] #{order_cycle_subject}" + end + def orders?(order_cycle, producer) line_items_from(order_cycle, producer).any? end @@ -56,7 +70,7 @@ class ProducerMailer < Spree::BaseMailer # This hack makes ActiveRecord skip the default_scope (deleted_at IS NULL) # when eager loading associations. Further details: # https://github.com/rails/rails/issues/11036 - def unscoping + def with_unscoped_products_and_variants variant_default_scopes = Spree::Variant.default_scopes product_default_scopes = Spree::Product.default_scopes From 63eb0980eb10706d91dbedaa9af9a09b5586fe10 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 17 Apr 2020 17:19:51 +0200 Subject: [PATCH 138/166] Memoize result of line items query No need to fetch twice what we just loaded from DB. --- app/mailers/producer_mailer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index e130fefd1f..153a99d358 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -51,7 +51,7 @@ class ProducerMailer < Spree::BaseMailer end def line_items_from(order_cycle, producer) - Spree::LineItem. + @line_items ||= Spree::LineItem. includes(variant: [:product, { option_values: :option_type }]). from_order_cycle(order_cycle). sorted_by_name_and_unit_value. From c455dfb609d684925d461b8f556ff777a367e7c4 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 15:58:43 +0100 Subject: [PATCH 139/166] Make some specs faster by going directly to the order edit page and move incomplete order spec to a specific context --- spec/features/admin/order_spec.rb | 22 ++-- spec/features/admin/orders_spec.rb | 160 ++++++++++++----------------- 2 files changed, 72 insertions(+), 110 deletions(-) diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index a957e47617..831e4d8824 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -25,7 +25,7 @@ feature ' end def new_order_with_distribution(distributor, order_cycle) - visit 'admin/orders/new' + visit spree.new_admin_order_path expect(page).to have_selector('#s2id_order_distributor_id') select2_select distributor.name, from: 'order_distributor_id' select2_select order_cycle.name, from: 'order_order_cycle_id' @@ -37,8 +37,7 @@ feature ' create(:simple_order_cycle, name: 'Two') quick_login_as_admin - - visit '/admin/orders' + visit spree.admin_orders_path click_link 'New Order' # Distributors without an order cycle should be shown as disabled @@ -73,9 +72,7 @@ feature ' scenario "can add a product to an existing order" do quick_login_as_admin - visit '/admin/orders' - - click_icon :edit + visit spree.edit_admin_order_path(@order) targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' @@ -98,11 +95,8 @@ feature ' @order.save quick_login_as_admin - visit '/admin/orders' - uncheck 'Only show complete orders' - page.find('a.icon-search').click + visit spree.edit_admin_order_path(@order) - click_icon :edit expect(page).to have_select2 "order_distributor_id", with_options: [d.name] select2_select d.name, from: 'order_distributor_id' select2_select oc.name, from: 'order_order_cycle_id' @@ -115,16 +109,14 @@ feature ' product = create(:simple_product) quick_login_as_admin - visit '/admin/orders' - page.find('td.actions a.icon-edit').click + visit spree.edit_admin_order_path(@order) expect(page).not_to have_select2 "add_variant_id", with_options: [product.name] end scenario "can't change distributor or order cycle once order has been finalized" do quick_login_as_admin - visit '/admin/orders' - page.find('td.actions a.icon-edit').click + visit spree.edit_admin_order_path(@order) expect(page).not_to have_select2 'order_distributor_id' expect(page).not_to have_select2 'order_order_cycle_id' @@ -330,7 +322,7 @@ feature ' fill_in "Amount", with: "5" click_button "Continue" - expect(page.find("td.amount")).to have_content "$5.00" + expect(page.find("td.amount")).to have_content "5.00" end context "when an included variant has been deleted" do diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 79e6d444b2..307fc71b9c 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -9,109 +9,79 @@ feature ' include WebHelper include CheckoutHelper - background do - @user = create(:user) - @product = create(:simple_product) - @distributor = create(:distributor_enterprise, owner: @user, charges_sales_tax: true) - @order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first]) + let(:user) { create(:user) } + let(:product) { create(:simple_product) } + let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) } + let(:order_cycle) { create(:simple_order_cycle, name: 'One', distributors: [distributor], variants: [product.variants.first]) } - @order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due') - @customer = create(:customer, enterprise: @distributor, email: @user.email, user: @user, ship_address: create(:address)) + context "with complete order" do + before do + @order = create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') + @customer = create(:customer, enterprise: distributor, email: user.email, user: user, ship_address: create(:address)) - # ensure order has a payment to capture - @order.finalize! + # ensure order has a payment to capture + @order.finalize! - create :check_payment, order: @order, amount: @order.total + create :check_payment, order: @order, amount: @order.total + end + + scenario "order cycles appear in descending order by close date on orders page" do + create(:simple_order_cycle, name: 'Two', orders_close_at: 2.weeks.from_now) + create(:simple_order_cycle, name: 'Four', orders_close_at: 4.weeks.from_now) + create(:simple_order_cycle, name: 'Three', orders_close_at: 3.weeks.from_now) + + quick_login_as_admin + visit 'admin/orders' + + open_select2('#s2id_q_order_cycle_id_in') + + expect(find('#q_order_cycle_id_in', visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two.*One/m) + end + + scenario "capture payment from the orders index page" do + quick_login_as_admin + + visit spree.admin_orders_path + expect(page).to have_current_path spree.admin_orders_path + + # click the 'capture' link for the order + page.find("[data-powertip=Capture]").click + + expect(page).to have_css "i.success" + expect(page).to have_css "button.icon-road" + + # check the order was captured + expect(@order.reload.payment_state).to eq "paid" + + # we should still be on the same page + expect(page).to have_current_path spree.admin_orders_path + end + + scenario "ship order from the orders index page" do + @order.payments.first.capture! + quick_login_as_admin + visit spree.admin_orders_path + + page.find("[data-powertip=Ship]").click + + expect(page).to have_css "i.success" + expect(@order.reload.shipments.any?(&:shipped?)).to be true + end end - scenario "order cycles appear in descending order by close date on orders page" do - create(:simple_order_cycle, name: 'Two', orders_close_at: 2.weeks.from_now) - create(:simple_order_cycle, name: 'Four', orders_close_at: 4.weeks.from_now) - create(:simple_order_cycle, name: 'Three', orders_close_at: 3.weeks.from_now) + context "with incomplete order" do + scenario "can edit order" do + incomplete_order = create(:order, distributor: distributor, order_cycle: order_cycle) - quick_login_as_admin - visit 'admin/orders' + quick_login_as_admin - open_select2('#s2id_q_order_cycle_id_in') + visit spree.admin_orders_path + uncheck 'Only show complete orders' + page.find('a.icon-search').click - expect(find('#q_order_cycle_id_in', visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two.*One/m) - end + click_icon :edit - scenario "displays error when incorrect distribution for products is chosen" do - d = create(:distributor_enterprise) - oc = create(:simple_order_cycle, distributors: [d]) - - # Move the order back to the cart state - @order.state = 'cart' - @order.completed_at = nil - # A nil user keeps the order in the cart state - # Even if the edit page tries to automatically progress the order workflow - @order.user = nil - @order.save - - quick_login_as_admin - visit '/admin/orders' - uncheck 'Only show complete orders' - page.find('a.icon-search').click - - click_icon :edit - expect(page).to have_select2 "order_distributor_id", with_options: [d.name] - select2_select d.name, from: 'order_distributor_id' - select2_select oc.name, from: 'order_order_cycle_id' - - click_button 'Update And Recalculate Fees' - expect(page).to have_content "Distributor or order cycle cannot supply the products in your cart" - end - - scenario "can't add products to an order outside the order's hub and order cycle" do - product = create(:simple_product) - - quick_login_as_admin - visit '/admin/orders' - page.find('td.actions a.icon-edit').click - - expect(page).not_to have_select2 "add_variant_id", with_options: [product.name] - end - - scenario "can't change distributor or order cycle once order has been finalized" do - quick_login_as_admin - visit '/admin/orders' - page.find('td.actions a.icon-edit').click - - expect(page).not_to have_select2 'order_distributor_id' - expect(page).not_to have_select2 'order_order_cycle_id' - - expect(page).to have_selector 'p', text: "Distributor: #{@order.distributor.name}" - expect(page).to have_selector 'p', text: "Order cycle: #{@order.order_cycle.name}" - end - - scenario "capture payment from the orders index page" do - quick_login_as_admin - - visit spree.admin_orders_path - expect(page).to have_current_path spree.admin_orders_path - - # click the 'capture' link for the order - page.find("[data-powertip=Capture]").click - - expect(page).to have_css "i.success" - expect(page).to have_css "button.icon-road" - - # check the order was captured - expect(@order.reload.payment_state).to eq "paid" - - # we should still be on the same page - expect(page).to have_current_path spree.admin_orders_path - end - - scenario "ship order from the orders index page" do - @order.payments.first.capture! - quick_login_as_admin - visit spree.admin_orders_path - - page.find("[data-powertip=Ship]").click - - expect(page).to have_css "i.success" - expect(@order.reload.shipments.any?(&:shipped?)).to be true + expect(page).to have_current_path spree.edit_admin_order_path(incomplete_order) + end end end From d8e6d98912330ef1ddd062b0cafb52cf733b83d5 Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Fri, 17 Apr 2020 17:34:53 +0200 Subject: [PATCH 140/166] Preload line item's option_values This fixes an N+1 with the query ```sql SELECT "spree_option_values".* FROM "spree_option_values" INNER JOIN "spree_option_types" ON "spree_option_types"."id" = "spree_option_values"."option_type_id" INNER JOIN "spree_option_values_line_items" ON "spree_option_values"."id" = "spree_option_values_line_items"."option_value_id" WHERE "spree_option_values_line_items"."line_item_id" = 1679 ORDER BY spree_option_types.position asc ``` --- app/mailers/producer_mailer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index 153a99d358..48f3c6a34d 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -52,7 +52,7 @@ class ProducerMailer < Spree::BaseMailer def line_items_from(order_cycle, producer) @line_items ||= Spree::LineItem. - includes(variant: [:product, { option_values: :option_type }]). + includes(:option_values, variant: [:product, { option_values: :option_type }]). from_order_cycle(order_cycle). sorted_by_name_and_unit_value. merge(Spree::Product.in_supplier(producer)). From e901615b61e3ada7e5cc0a0504dfe31260b9f31a Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 16:56:56 +0100 Subject: [PATCH 141/166] Make spec simpler --- spec/features/admin/orders_spec.rb | 61 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 307fc71b9c..b50f64a955 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -14,16 +14,8 @@ feature ' let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) } let(:order_cycle) { create(:simple_order_cycle, name: 'One', distributors: [distributor], variants: [product.variants.first]) } - context "with complete order" do - before do - @order = create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') - @customer = create(:customer, enterprise: distributor, email: user.email, user: user, ship_address: create(:address)) - - # ensure order has a payment to capture - @order.finalize! - - create :check_payment, order: @order, amount: @order.total - end + context "with a complete order" do + let(:order) { create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') } scenario "order cycles appear in descending order by close date on orders page" do create(:simple_order_cycle, name: 'Two', orders_close_at: 2.weeks.from_now) @@ -35,37 +27,44 @@ feature ' open_select2('#s2id_q_order_cycle_id_in') - expect(find('#q_order_cycle_id_in', visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two.*One/m) + expect(find('#q_order_cycle_id_in', visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two/m) end - scenario "capture payment from the orders index page" do - quick_login_as_admin + context "with a capturable order" do + before do + order.finalize! # ensure order has a payment to capture + create :check_payment, order: order, amount: order.total + end - visit spree.admin_orders_path - expect(page).to have_current_path spree.admin_orders_path + scenario "capture payment" do + quick_login_as_admin - # click the 'capture' link for the order - page.find("[data-powertip=Capture]").click + visit spree.admin_orders_path + expect(page).to have_current_path spree.admin_orders_path - expect(page).to have_css "i.success" - expect(page).to have_css "button.icon-road" + # click the 'capture' link for the order + page.find("[data-powertip=Capture]").click - # check the order was captured - expect(@order.reload.payment_state).to eq "paid" + expect(page).to have_css "i.success" + expect(page).to have_css "button.icon-road" - # we should still be on the same page - expect(page).to have_current_path spree.admin_orders_path - end + # check the order was captured + expect(order.reload.payment_state).to eq "paid" - scenario "ship order from the orders index page" do - @order.payments.first.capture! - quick_login_as_admin - visit spree.admin_orders_path + # we should still be on the same page + expect(page).to have_current_path spree.admin_orders_path + end - page.find("[data-powertip=Ship]").click + scenario "ship order from the orders index page" do + order.payments.first.capture! + quick_login_as_admin + visit spree.admin_orders_path - expect(page).to have_css "i.success" - expect(@order.reload.shipments.any?(&:shipped?)).to be true + page.find("[data-powertip=Ship]").click + + expect(page).to have_css "i.success" + expect(order.reload.shipments.any?(&:shipped?)).to be true + end end end From c7fb85a71577d80e23806b6cbc79f27dc248da13 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 17:34:36 +0100 Subject: [PATCH 142/166] Replace background with members with before with let statements --- spec/features/admin/order_spec.rb | 76 +++++++++++++++--------------- spec/features/admin/orders_spec.rb | 1 - 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index 831e4d8824..4cc32bcdc0 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -9,19 +9,19 @@ feature ' include WebHelper include CheckoutHelper - background do - @user = create(:user) - @product = create(:simple_product) - @distributor = create(:distributor_enterprise, owner: @user, charges_sales_tax: true) - @order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first]) + let(:user) { create(:user) } + let(:product) { create(:simple_product) } + let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) } + let(:order_cycle) { create(:simple_order_cycle, name: 'One', distributors: [distributor], variants: [product.variants.first]) } - @order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due') - @customer = create(:customer, enterprise: @distributor, email: @user.email, user: @user, ship_address: create(:address)) + let(:order) { create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') } + let(:customer) { create(:customer, enterprise: distributor, email: user.email, user: user, ship_address: create(:address)) } + before do # ensure order has a payment to capture - @order.finalize! + order.finalize! - create :check_payment, order: @order, amount: @order.total + create :check_payment, order: order, amount: order.total end def new_order_with_distribution(distributor, order_cycle) @@ -49,37 +49,37 @@ feature ' expect(page).to have_selector "#s2id_order_order_cycle_id.select2-container-disabled" # When we select a distributor, it should limit order cycle selection to those for that distributor - select2_select @distributor.name, from: 'order_distributor_id' + select2_select distributor.name, from: 'order_distributor_id' expect(page).to have_select2 'order_order_cycle_id', options: ['One (open)'] - select2_select @order_cycle.name, from: 'order_order_cycle_id' + select2_select order_cycle.name, from: 'order_order_cycle_id' click_button 'Next' # it suppresses validation errors when setting distribution expect(page).not_to have_selector '#errorExplanation' expect(page).to have_content 'ADD PRODUCT' - targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' find('button.add_variant').click page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS - expect(page).to have_selector 'td', text: @product.name + expect(page).to have_selector 'td', text: product.name click_button 'Update' expect(page).to have_selector 'h1', text: 'Customer Details' o = Spree::Order.last - expect(o.distributor).to eq(@distributor) - expect(o.order_cycle).to eq(@order_cycle) + expect(o.distributor).to eq(distributor) + expect(o.order_cycle).to eq(order_cycle) end scenario "can add a product to an existing order" do quick_login_as_admin - visit spree.edit_admin_order_path(@order) + visit spree.edit_admin_order_path(order) - targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' find('button.add_variant').click - expect(page).to have_selector 'td', text: @product.name - expect(@order.line_items(true).map(&:product)).to include @product + expect(page).to have_selector 'td', text: product.name + expect(order.line_items(true).map(&:product)).to include product end scenario "displays error when incorrect distribution for products is chosen" do @@ -87,15 +87,15 @@ feature ' oc = create(:simple_order_cycle, distributors: [d]) # Move the order back to the cart state - @order.state = 'cart' - @order.completed_at = nil + order.state = 'cart' + order.completed_at = nil # A nil user keeps the order in the cart state # Even if the edit page tries to automatically progress the order workflow - @order.user = nil - @order.save + order.user = nil + order.save quick_login_as_admin - visit spree.edit_admin_order_path(@order) + visit spree.edit_admin_order_path(order) expect(page).to have_select2 "order_distributor_id", with_options: [d.name] select2_select d.name, from: 'order_distributor_id' @@ -109,20 +109,20 @@ feature ' product = create(:simple_product) quick_login_as_admin - visit spree.edit_admin_order_path(@order) + visit spree.edit_admin_order_path(order) expect(page).not_to have_select2 "add_variant_id", with_options: [product.name] end scenario "can't change distributor or order cycle once order has been finalized" do quick_login_as_admin - visit spree.edit_admin_order_path(@order) + visit spree.edit_admin_order_path(order) expect(page).not_to have_select2 'order_distributor_id' expect(page).not_to have_select2 'order_order_cycle_id' - expect(page).to have_selector 'p', text: "Distributor: #{@order.distributor.name}" - expect(page).to have_selector 'p', text: "Order cycle: #{@order.order_cycle.name}" + expect(page).to have_selector 'p', text: "Distributor: #{order.distributor.name}" + expect(page).to have_selector 'p', text: "Order cycle: #{order.order_cycle.name}" end scenario "filling customer details" do @@ -130,18 +130,18 @@ feature ' # We change the 1st order's address details # This way we validate that the original details (stored in customer) are picked up in the 2nd order - @order.ship_address = create(:address, lastname: 'Ship') - @order.bill_address = create(:address, lastname: 'Bill') - @order.save! + order.ship_address = create(:address, lastname: 'Ship') + order.bill_address = create(:address, lastname: 'Bill') + order.save! # We set the existing shipping method to delivery, this shipping method will be used in the 2nd order # Otherwise order_updater.shipping_address_from_distributor will set the 2nd order address to the distributor address - @order.shipping_method.update_attribute :require_ship_address, true + order.shipping_method.update_attribute :require_ship_address, true # When I create a new order - quick_login_as @user - new_order_with_distribution(@distributor, @order_cycle) - targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + quick_login_as user + new_order_with_distribution(distributor, order_cycle) + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' find('button.add_variant').click page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS click_button 'Update' @@ -149,14 +149,14 @@ feature ' expect(page).to have_selector 'h1.page-title', text: "Customer Details" # And I select that customer's email address and save the order - targetted_select2_search @customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' + targetted_select2_search customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' click_button 'Update' expect(page).to have_selector "h1.page-title", text: "Customer Details" # Then their addresses should be associated with the order order = Spree::Order.last - expect(order.ship_address.lastname).to eq @customer.ship_address.lastname - expect(order.bill_address.lastname).to eq @customer.bill_address.lastname + expect(order.ship_address.lastname).to eq customer.ship_address.lastname + expect(order.bill_address.lastname).to eq customer.bill_address.lastname end context "as an enterprise manager" do diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index b50f64a955..c005287f12 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -7,7 +7,6 @@ feature ' ', js: true do include AuthenticationWorkflow include WebHelper - include CheckoutHelper let(:user) { create(:user) } let(:product) { create(:simple_product) } From 8bd3062b16bc924e417c304c11b49d70a129c0d6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 18:17:54 +0100 Subject: [PATCH 143/166] Fix rubocop issues --- .rubocop_manual_todo.yml | 2 - spec/features/admin/order_spec.rb | 143 +++++++++++++++++++---------- spec/features/admin/orders_spec.rb | 14 ++- 3 files changed, 106 insertions(+), 53 deletions(-) diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index de9861fa40..b6926715ef 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -181,7 +181,6 @@ Layout/LineLength: - spec/features/admin/image_settings_spec.rb - spec/features/admin/multilingual_spec.rb - spec/features/admin/order_cycles_spec.rb - - spec/features/admin/orders_spec.rb - spec/features/admin/overview_spec.rb - spec/features/admin/payment_method_spec.rb - spec/features/admin/product_import_spec.rb @@ -468,7 +467,6 @@ Metrics/BlockLength: - spec/factories/shipping_method_factory.rb - spec/factories/subscription_factory.rb - spec/factories/variant_factory.rb - - spec/features/admin/orders_spec.rb - spec/features/consumer/shopping/embedded_shopfronts_spec.rb - spec/lib/open_food_network/group_buy_report_spec.rb - spec/models/tag_rule/discount_order_spec.rb diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index 4cc32bcdc0..69cbcae456 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require "spec_helper" -include ActionView::Helpers::NumberHelper feature ' As an administrator I want to create and edit orders ', js: true do + include ActionView::Helpers::NumberHelper include AuthenticationWorkflow include WebHelper include CheckoutHelper @@ -12,10 +14,20 @@ feature ' let(:user) { create(:user) } let(:product) { create(:simple_product) } let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) } - let(:order_cycle) { create(:simple_order_cycle, name: 'One', distributors: [distributor], variants: [product.variants.first]) } + let(:order_cycle) do + create(:simple_order_cycle, name: 'One', distributors: [distributor], + variants: [product.variants.first]) + end - let(:order) { create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') } - let(:customer) { create(:customer, enterprise: distributor, email: user.email, user: user, ship_address: create(:address)) } + let(:order) do + create(:order_with_totals_and_distribution, user: user, distributor: distributor, + order_cycle: order_cycle, state: 'complete', + payment_state: 'balance_due') + end + let(:customer) do + create(:customer, enterprise: distributor, email: user.email, + user: user, ship_address: create(:address)) + end before do # ensure order has a payment to capture @@ -42,13 +54,14 @@ feature ' # Distributors without an order cycle should be shown as disabled open_select2('#s2id_order_distributor_id') - expect(page).to have_selector "ul.select2-results li.select2-result.select2-disabled", text: distributor_disabled.name + expect(page).to have_selector "ul.select2-results li.select2-result.select2-disabled", + text: distributor_disabled.name close_select2('#s2id_order_distributor_id') # Order cycle selector should be disabled expect(page).to have_selector "#s2id_order_order_cycle_id.select2-container-disabled" - # When we select a distributor, it should limit order cycle selection to those for that distributor + # The distributor selector should limit the order cycle selection to those for that distributor select2_select distributor.name, from: 'order_distributor_id' expect(page).to have_select2 'order_order_cycle_id', options: ['One (open)'] select2_select order_cycle.name, from: 'order_order_cycle_id' @@ -102,7 +115,8 @@ feature ' select2_select oc.name, from: 'order_order_cycle_id' click_button 'Update And Recalculate Fees' - expect(page).to have_content "Distributor or order cycle cannot supply the products in your cart" + expect(page).to have_content "Distributor or order cycle " \ + "cannot supply the products in your cart" end scenario "can't add products to an order outside the order's hub and order cycle" do @@ -128,14 +142,15 @@ feature ' scenario "filling customer details" do # Given a customer with an order, which includes their shipping and billing address - # We change the 1st order's address details - # This way we validate that the original details (stored in customer) are picked up in the 2nd order + # We change the 1st order's address details, this way + # we validate that the original details (stored in customer) are picked up in the 2nd order order.ship_address = create(:address, lastname: 'Ship') order.bill_address = create(:address, lastname: 'Bill') order.save! - # We set the existing shipping method to delivery, this shipping method will be used in the 2nd order - # Otherwise order_updater.shipping_address_from_distributor will set the 2nd order address to the distributor address + # We set the existing ship method to delivery, this ship method will be used in the 2nd order + # Otherwise order_updater.shipping_address_from_distributor will set + # the 2nd order address to the distributor address order.shipping_method.update_attribute :require_ship_address, true # When I create a new order @@ -149,7 +164,8 @@ feature ' expect(page).to have_selector 'h1.page-title', text: "Customer Details" # And I select that customer's email address and save the order - targetted_select2_search customer.email, from: '#customer_search_override', dropdown_css: '.select2-drop' + targetted_select2_search customer.email, from: '#customer_search_override', + dropdown_css: '.select2-drop' click_button 'Update' expect(page).to have_selector "h1.page-title", text: "Customer Details" @@ -167,7 +183,9 @@ feature ' let!(:supplier1) { order_cycle1.suppliers.first } let!(:supplier2) { order_cycle1.suppliers.last } let!(:distributor1) { order_cycle1.distributors.first } - let!(:distributor2) { order_cycle1.distributors.reject{ |d| d == distributor1 }.last } # ensure d1 != d2 + let!(:distributor2) do + order_cycle1.distributors.reject{ |d| d == distributor1 }.last # ensure d1 != d2 + end let(:product) { order_cycle1.products.first } before(:each) do @@ -180,9 +198,15 @@ feature ' end feature "viewing the edit page" do - let!(:shipping_method_for_distributor1) { create(:shipping_method, name: "Normal", distributors: [distributor1]) } - let!(:different_shipping_method_for_distributor1) { create(:shipping_method, name: "Different", distributors: [distributor1]) } - let!(:shipping_method_for_distributor2) { create(:shipping_method, name: "Other", distributors: [distributor2]) } + let!(:shipping_method_for_distributor1) do + create(:shipping_method, name: "Normal", distributors: [distributor1]) + end + let!(:different_shipping_method_for_distributor1) do + create(:shipping_method, name: "Different", distributors: [distributor1]) + end + let!(:shipping_method_for_distributor2) do + create(:shipping_method, name: "Other", distributors: [distributor2]) + end let!(:order) do create(:order_with_taxes, distributor: distributor1, ship_address: create(:address), @@ -240,15 +264,18 @@ feature ' scenario "shows the dropdown menu" do find("#links-dropdown .ofn-drop-down").click within "#links-dropdown" do - expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(order) + expect(page).to have_link "Resend Confirmation", + href: spree.resend_admin_order_path(order) expect(page).to have_link "Send Invoice", href: spree.invoice_admin_order_path(order) expect(page).to have_link "Print Invoice", href: spree.print_admin_order_path(order) - expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, e: 'cancel') + expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, + e: 'cancel') end end scenario "cannot split the order in different stock locations" do - # There's only 1 stock location in OFN, so the split functionality that comes with spree should be hidden + # There's only 1 stock location in OFN, + # so the split functionality that comes with spree should be hidden expect(page).to_not have_selector '.split-item' end @@ -256,8 +283,13 @@ feature ' expect(page).to_not have_content different_shipping_method_for_distributor1.name find('.edit-method').click - expect(page).to have_select2 'selected_shipping_rate_id', with_options: [shipping_method_for_distributor1.name, different_shipping_method_for_distributor1.name], without_options: [shipping_method_for_distributor2.name] - select2_select different_shipping_method_for_distributor1.name, from: 'selected_shipping_rate_id' + expect(page).to have_select2 'selected_shipping_rate_id', + with_options: [ + shipping_method_for_distributor1.name, + different_shipping_method_for_distributor1.name + ], without_options: [shipping_method_for_distributor2.name] + select2_select different_shipping_method_for_distributor1.name, + from: 'selected_shipping_rate_id' find('.save-method').click expect(page).to have_content different_shipping_method_for_distributor1.name @@ -286,35 +318,48 @@ feature ' within_window ticket_window do accept_alert do print_data = page.evaluate_script('printData'); - elements_in_print_data = - [ - order.distributor.name, - order.distributor.address.address_part1, - order.distributor.address.address_part2, - order.distributor.contact.email, - order.number, - order.line_items.map { |line_item| - [line_item.quantity.to_s, - line_item.product.name, - line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false), - line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] - }, - checkout_adjustments_for(order, exclude: [:line_item]).reject { |a| a.amount == 0 }.map { |adjustment| - [raw(adjustment.label), - display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] - }, - order.display_total.format(with_currency: false), - display_checkout_taxes_hash(order).map { |tax_rate, tax_value| - [tax_rate, - tax_value.format(with_currency: false)] - }, - display_checkout_total_less_tax(order).format(with_currency: false) - ] + elements_in_print_data = [ + order.distributor.name, + order.distributor.address.address_part1, + order.distributor.address.address_part2, + order.distributor.contact.email, order.number, + line_items_in_print_data, + adjustments_in_print_data, + order.display_total.format(with_currency: false), + taxes_in_print_data, + display_checkout_total_less_tax(order).format(with_currency: false) + ] expect(print_data.join).to include(*elements_in_print_data.flatten) end end end + def line_items_in_print_data + order.line_items.map { |line_item| + [line_item.quantity.to_s, + line_item.product.name, + line_item.single_display_amount_with_adjustments.format(symbol: false, + with_currency: false), + line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] + } + end + + def adjustments_in_print_data + checkout_adjustments_for(order, exclude: [:line_item]). + reject { |a| a.amount == 0 }. + map do |adjustment| + [raw(adjustment.label), + display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] + end + end + + def taxes_in_print_data + display_checkout_taxes_hash(order).map { |tax_rate, tax_value| + [tax_rate, + tax_value.format(with_currency: false)] + } + end + scenario "editing shipping fees" do click_link "Adjustments" page.find('td.actions a.icon-edit').click @@ -345,14 +390,16 @@ feature ' targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' find('button.add_variant').click - page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" expect(page).to have_selector 'td', text: product.name expect(page).to have_select2 'order_distributor_id', with_options: [distributor1.name] expect(page).to_not have_select2 'order_distributor_id', with_options: [distributor2.name] - expect(page).to have_select2 'order_order_cycle_id', with_options: ["#{order_cycle1.name} (open)"] - expect(page).to_not have_select2 'order_order_cycle_id', with_options: ["#{order_cycle2.name} (open)"] + expect(page).to have_select2 'order_order_cycle_id', + with_options: ["#{order_cycle1.name} (open)"] + expect(page).to_not have_select2 'order_order_cycle_id', + with_options: ["#{order_cycle2.name} (open)"] click_button 'Update' diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index c005287f12..f17068799e 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -11,10 +11,17 @@ feature ' let(:user) { create(:user) } let(:product) { create(:simple_product) } let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) } - let(:order_cycle) { create(:simple_order_cycle, name: 'One', distributors: [distributor], variants: [product.variants.first]) } + let(:order_cycle) do + create(:simple_order_cycle, name: 'One', distributors: [distributor], + variants: [product.variants.first]) + end context "with a complete order" do - let(:order) { create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') } + let(:order) do + create(:order_with_totals_and_distribution, user: user, distributor: distributor, + order_cycle: order_cycle, + state: 'complete', payment_state: 'balance_due') + end scenario "order cycles appear in descending order by close date on orders page" do create(:simple_order_cycle, name: 'Two', orders_close_at: 2.weeks.from_now) @@ -26,7 +33,8 @@ feature ' open_select2('#s2id_q_order_cycle_id_in') - expect(find('#q_order_cycle_id_in', visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two/m) + expect(find('#q_order_cycle_id_in', + visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two/m) end context "with a capturable order" do From c33352904aa60fd09a223aea36d866f80825eaa8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 18:48:20 +0100 Subject: [PATCH 144/166] Make spec a bit more resilient --- spec/features/admin/order_spec.rb | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index 69cbcae456..4d1b4ed2eb 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -24,10 +24,7 @@ feature ' order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') end - let(:customer) do - create(:customer, enterprise: distributor, email: user.email, - user: user, ship_address: create(:address)) - end + let(:customer) { order.customer } before do # ensure order has a payment to capture @@ -242,11 +239,9 @@ feature ' end scenario "shows the order non-tax adjustments" do - within('table.index tbody') do - order.adjustments.eligible.each do |adjustment| - expect(page).to have_selector "td", match: :first, text: adjustment.label - expect(page).to have_selector "td.total", text: adjustment.display_amount - end + order.adjustments.eligible.each do |adjustment| + expect(page).to have_selector "td", match: :first, text: adjustment.label + expect(page).to have_selector "td.total", text: adjustment.display_amount end end @@ -362,12 +357,13 @@ feature ' scenario "editing shipping fees" do click_link "Adjustments" - page.find('td.actions a.icon-edit').click + shipping_adjustment_tr_selector = "tr#spree_adjustment_#{order.adjustments.shipping.first.id}" + page.find("#{shipping_adjustment_tr_selector} td.actions a.icon-edit").click fill_in "Amount", with: "5" click_button "Continue" - expect(page.find("td.amount")).to have_content "5.00" + expect(page.find("#{shipping_adjustment_tr_selector} td.amount")).to have_content "5.00" end context "when an included variant has been deleted" do From c1b28543c60f78bcebf512cf2f6707df38de7a9e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 19:57:42 +0100 Subject: [PATCH 145/166] Extract print ticket spec to a separate file --- .../features/admin/order_print_ticket_spec.rb | 93 +++++++++++++++++ spec/features/admin/order_spec.rb | 99 +++++-------------- spec/features/admin/orders_spec.rb | 3 +- 3 files changed, 118 insertions(+), 77 deletions(-) create mode 100644 spec/features/admin/order_print_ticket_spec.rb diff --git a/spec/features/admin/order_print_ticket_spec.rb b/spec/features/admin/order_print_ticket_spec.rb new file mode 100644 index 0000000000..add2ef9e7d --- /dev/null +++ b/spec/features/admin/order_print_ticket_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require "spec_helper" + +feature ' + As an administrator + I want to print a ticket for an order +', js: true do + include AuthenticationWorkflow + include CheckoutHelper + include ActionView::Helpers::NumberHelper + + context "as an enterprise manager" do + let!(:shipping_method) { create(:shipping_method, distributors: [distributor]) } + let!(:distributor) { create(:distributor_enterprise) } + + let!(:order) do + create(:order_with_taxes, distributor: distributor, ship_address: create(:address), + product_price: 110, tax_rate_amount: 0.1, + tax_rate_name: "Tax 1").tap do |record| + Spree::TaxRate.adjust(record) + record.update_shipping_fees! + end + end + + before do + @enterprise_user = create_enterprise_user + @enterprise_user.enterprise_roles.build(enterprise: distributor).save + + quick_login_as @enterprise_user + + Spree::Config[:enable_receipt_printing?] = true + end + + feature "viewing the edit page" do + scenario "can print an order's ticket" do + visit spree.edit_admin_order_path(order) + + find("#links-dropdown .ofn-drop-down").click + + ticket_window = window_opened_by do + within('#links-dropdown') do + click_link('Print Ticket') + end + end + + within_window ticket_window do + accept_alert do + print_data = page.evaluate_script('printData'); + elements_in_print_data = [ + order.distributor.name, + order.distributor.address.address_part1, + order.distributor.address.address_part2, + order.distributor.contact.email, order.number, + line_items_in_print_data, + adjustments_in_print_data, + order.display_total.format(with_currency: false), + taxes_in_print_data, + display_checkout_total_less_tax(order).format(with_currency: false) + ] + expect(print_data.join).to include(*elements_in_print_data.flatten) + end + end + end + + def line_items_in_print_data + order.line_items.map { |line_item| + [line_item.quantity.to_s, + line_item.product.name, + line_item.single_display_amount_with_adjustments.format(symbol: false, + with_currency: false), + line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] + } + end + + def adjustments_in_print_data + checkout_adjustments_for(order, exclude: [:line_item]). + reject { |a| a.amount == 0 }. + map do |adjustment| + [raw(adjustment.label), + display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] + end + end + + def taxes_in_print_data + display_checkout_taxes_hash(order).map { |tax_rate, tax_value| + [tax_rate, + tax_value.format(with_currency: false)] + } + end + end + end +end diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index 4d1b4ed2eb..28bf21999f 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -6,10 +6,8 @@ feature ' As an administrator I want to create and edit orders ', js: true do - include ActionView::Helpers::NumberHelper include AuthenticationWorkflow include WebHelper - include CheckoutHelper let(:user) { create(:user) } let(:product) { create(:simple_product) } @@ -198,13 +196,6 @@ feature ' let!(:shipping_method_for_distributor1) do create(:shipping_method, name: "Normal", distributors: [distributor1]) end - let!(:different_shipping_method_for_distributor1) do - create(:shipping_method, name: "Different", distributors: [distributor1]) - end - let!(:shipping_method_for_distributor2) do - create(:shipping_method, name: "Other", distributors: [distributor2]) - end - let!(:order) do create(:order_with_taxes, distributor: distributor1, ship_address: create(:address), product_price: 110, tax_rate_amount: 0.1, @@ -215,7 +206,6 @@ feature ' end background do - Spree::Config[:enable_receipt_printing?] = true distributor1.update_attribute(:abn, '12345678') visit spree.edit_admin_order_path(order) @@ -274,20 +264,31 @@ feature ' expect(page).to_not have_selector '.split-item' end - scenario "can edit shipping method" do - expect(page).to_not have_content different_shipping_method_for_distributor1.name + context "with different shipping methods" do + let!(:different_shipping_method_for_distributor1) do + create(:shipping_method, name: "Different", distributors: [distributor1]) + end + let!(:shipping_method_for_distributor2) do + create(:shipping_method, name: "Other", distributors: [distributor2]) + end - find('.edit-method').click - expect(page).to have_select2 'selected_shipping_rate_id', - with_options: [ - shipping_method_for_distributor1.name, - different_shipping_method_for_distributor1.name - ], without_options: [shipping_method_for_distributor2.name] - select2_select different_shipping_method_for_distributor1.name, - from: 'selected_shipping_rate_id' - find('.save-method').click + scenario "can edit shipping method" do + visit spree.edit_admin_order_path(order) - expect(page).to have_content different_shipping_method_for_distributor1.name + expect(page).to_not have_content different_shipping_method_for_distributor1.name + + find('.edit-method').click + expect(page).to have_select2 'selected_shipping_rate_id', + with_options: [ + shipping_method_for_distributor1.name, + different_shipping_method_for_distributor1.name + ], without_options: [shipping_method_for_distributor2.name] + select2_select different_shipping_method_for_distributor1.name, + from: 'selected_shipping_rate_id' + find('.save-method').click + + expect(page).to have_content different_shipping_method_for_distributor1.name + end end scenario "can edit tracking number" do @@ -301,60 +302,6 @@ feature ' expect(page).to have_content test_tracking_number end - scenario "can print an order's ticket" do - find("#links-dropdown .ofn-drop-down").click - - ticket_window = window_opened_by do - within('#links-dropdown') do - click_link('Print Ticket') - end - end - - within_window ticket_window do - accept_alert do - print_data = page.evaluate_script('printData'); - elements_in_print_data = [ - order.distributor.name, - order.distributor.address.address_part1, - order.distributor.address.address_part2, - order.distributor.contact.email, order.number, - line_items_in_print_data, - adjustments_in_print_data, - order.display_total.format(with_currency: false), - taxes_in_print_data, - display_checkout_total_less_tax(order).format(with_currency: false) - ] - expect(print_data.join).to include(*elements_in_print_data.flatten) - end - end - end - - def line_items_in_print_data - order.line_items.map { |line_item| - [line_item.quantity.to_s, - line_item.product.name, - line_item.single_display_amount_with_adjustments.format(symbol: false, - with_currency: false), - line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)] - } - end - - def adjustments_in_print_data - checkout_adjustments_for(order, exclude: [:line_item]). - reject { |a| a.amount == 0 }. - map do |adjustment| - [raw(adjustment.label), - display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)] - end - end - - def taxes_in_print_data - display_checkout_taxes_hash(order).map { |tax_rate, tax_value| - [tax_rate, - tax_value.format(with_currency: false)] - } - end - scenario "editing shipping fees" do click_link "Adjustments" shipping_adjustment_tr_selector = "tr#spree_adjustment_#{order.adjustments.shipping.first.id}" diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index f17068799e..6713a7521f 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true + require "spec_helper" -include ActionView::Helpers::NumberHelper feature ' As an administrator From 8973a1b76cbb157bbc395b38641a3e5d9179b1c1 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 20:18:13 +0100 Subject: [PATCH 146/166] Merging 6 specs in one takes around 1 minute of execution time --- spec/features/admin/order_spec.rb | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb index 28bf21999f..d9071aff94 100644 --- a/spec/features/admin/order_spec.rb +++ b/spec/features/admin/order_spec.rb @@ -211,7 +211,8 @@ feature ' visit spree.edit_admin_order_path(order) end - scenario "shows a list of line_items" do + scenario "verifying page contents" do + # shows a list of line_items within('table.index tbody', match: :first) do order.line_items.each do |item| expect(page).to have_selector "td", match: :first, text: item.full_name @@ -220,41 +221,35 @@ feature ' expect(page).to have_selector "td.item-total", text: item.display_amount end end - end - scenario "shows the order items total" do + # shows the order items total within('fieldset#order-total') do expect(page).to have_selector "span.order-total", text: order.display_item_total end - end - scenario "shows the order non-tax adjustments" do + # shows the order non-tax adjustments order.adjustments.eligible.each do |adjustment| expect(page).to have_selector "td", match: :first, text: adjustment.label expect(page).to have_selector "td.total", text: adjustment.display_amount end - end - scenario "shows the order total" do + # shows the order total expect(page).to have_selector "fieldset#order-total", text: order.display_total - end - scenario "shows the order tax adjustments" do + # shows the order tax adjustments within('fieldset', text: I18n.t('spree.admin.orders.form.line_item_adjustments').upcase) do expect(page).to have_selector "td", match: :first, text: "Tax 1" expect(page).to have_selector "td.total", text: Spree::Money.new(10) end - end - scenario "shows the dropdown menu" do + # shows the dropdown menu" do find("#links-dropdown .ofn-drop-down").click within "#links-dropdown" do expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(order) expect(page).to have_link "Send Invoice", href: spree.invoice_admin_order_path(order) expect(page).to have_link "Print Invoice", href: spree.print_admin_order_path(order) - expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, - e: 'cancel') + expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, e: 'cancel') end end From 8f8dce4baba19aa370387612f9ab2b6edd76558e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 17 Apr 2020 20:23:29 +0100 Subject: [PATCH 147/166] Do not render inventory items in the shipment that dont have a line item in the order --- app/views/spree/admin/orders/_shipment_manifest.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/spree/admin/orders/_shipment_manifest.html.haml b/app/views/spree/admin/orders/_shipment_manifest.html.haml index 8651ee3188..611cf4a5d7 100644 --- a/app/views/spree/admin/orders/_shipment_manifest.html.haml +++ b/app/views/spree/admin/orders/_shipment_manifest.html.haml @@ -1,5 +1,6 @@ - shipment.manifest.each do |item| - line_item = order.find_line_item_by_variant(item.variant) + - break if line_item.blank? %tr.stock-item{ "data-item-quantity" => "#{item.quantity}" } %td.item-image From 70005a99a3045a9116eee59b50f24f95c5b9d040 Mon Sep 17 00:00:00 2001 From: jeffrey s hill md Date: Fri, 17 Apr 2020 17:02:37 -0500 Subject: [PATCH 148/166] Added missing translations --- .../javascripts/templates/admin/columns_dropdown.html.haml | 2 +- config/locales/en.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/templates/admin/columns_dropdown.html.haml b/app/assets/javascripts/templates/admin/columns_dropdown.html.haml index 37398b200a..cae123bbcf 100644 --- a/app/assets/javascripts/templates/admin/columns_dropdown.html.haml +++ b/app/assets/javascripts/templates/admin/columns_dropdown.html.haml @@ -8,4 +8,4 @@ %hr %div.menu_item.text-center %input.fullwidth.orange{ type: "button", ng: { value: "saved() ? 'Saved': 'Saving'", show: "saved() || saving", disabled: "saved()" } } - %input.fullwidth.red{ type: "button", value: 'Save As Default', ng: { show: "!saved() && !saving", click: "saveColumnPreferences(action)"} } + %input.fullwidth.red{ type: "button", :value => t('admin.column_save_as_default').html_safe, ng: { show: "!saved() && !saving", click: "saveColumnPreferences(action)"} } diff --git a/config/locales/en.yml b/config/locales/en.yml index 21d9ab39cf..c7f1820a65 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -362,6 +362,7 @@ en: choose: "Choose..." please_select: Please select... + column_save_as_default: Save As Default columns: Columns actions: Actions viewing: "Viewing: %{current_view_name}" From a0a361673ae8093a698dc7724b02c6799edad36e Mon Sep 17 00:00:00 2001 From: David Cook Date: Sat, 18 Apr 2020 15:03:35 +1000 Subject: [PATCH 149/166] Fix sorting of orders (wrong copied function call) --- .../admin/orders/controllers/orders_controller.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index d4d86b7ddb..e98fcccb2a 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -67,7 +67,7 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, Reque return unless sort && sort.predicate != "" $scope.sorting = sort.getSortingExpr() - $scope.fetchProducts() + $scope.fetchResults() , true $scope.capturePayment = (order) -> From 910cc99c2f299fa20db8f05ed91de2a55815a796 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 10:23:02 +0100 Subject: [PATCH 150/166] Add spec to cover orders_controller watch sortOptions --- .../controllers/customers_controller_spec.js.coffee | 1 - .../controllers/orders_controller_spec.js.coffee | 11 ++++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee b/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee index a30eb4eeb8..2ffde63a3e 100644 --- a/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/customers/controllers/customers_controller_spec.js.coffee @@ -20,7 +20,6 @@ describe "CustomersCtrl", -> {id: 109, name: "Australia", states: [{id: 55, name: "ACT", abbr: "ACT"}]} ] - inject ($controller, $rootScope, _CustomerResource_, $httpBackend) -> scope = $rootScope http = $httpBackend diff --git a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee index 7886d8ddd6..2e7cfee530 100644 --- a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee @@ -36,9 +36,18 @@ describe "ordersCtrl", -> 'q[s]': 'completed_at desc' })) - describe "using pagination", -> it "changes the page", -> $scope.changePage(2) expect($scope.page).toEqual 2 expect(Orders.index).toHaveBeenCalled() + + describe "sorting products", -> + it "sorts orders", -> + spyOn $scope, "fetchResults" + + $scope.sortOptions.toggle('number') + $scope.$apply() + + expect($scope.sorting).toEqual 'number asc' + expect($scope.fetchResults).toHaveBeenCalled() From 437c7367dbcba5422fdf6c38e6c7c69bdc3d52e8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 14:37:07 +0100 Subject: [PATCH 151/166] Remove dead code --- app/models/spree/property.rb | 6 ------ spec/models/spree/property_spec.rb | 28 ---------------------------- 2 files changed, 34 deletions(-) diff --git a/app/models/spree/property.rb b/app/models/spree/property.rb index 792b39e5b5..92c053f65b 100644 --- a/app/models/spree/property.rb +++ b/app/models/spree/property.rb @@ -10,12 +10,6 @@ module Spree scope :sorted, -> { order(:name) } - scope :applied_by, ->(enterprise) { - select('DISTINCT spree_properties.*'). - joins(:product_properties). - where('spree_product_properties.product_id IN (?)', enterprise.supplied_product_ids) - } - scope :ever_sold_by, ->(shop) { joins(products: { variants: { exchanges: :order_cycle } }). merge(Exchange.outgoing). diff --git a/spec/models/spree/property_spec.rb b/spec/models/spree/property_spec.rb index a155cbfa45..acbd22ca27 100644 --- a/spec/models/spree/property_spec.rb +++ b/spec/models/spree/property_spec.rb @@ -3,34 +3,6 @@ require 'spec_helper' module Spree describe Property do describe "scopes" do - describe ".applied_by" do - let(:producer) { create(:supplier_enterprise) } - let(:producer_other) { create(:supplier_enterprise) } - let(:product) { create(:simple_product, supplier: producer) } - let(:product_other_producer) { create(:simple_product, supplier: producer_other) } - let(:product_other_property) { create(:simple_product, supplier: producer) } - let(:property) { product.properties.last } - let(:property_other) { product_other_producer.properties.last } - - before do - product.set_property 'Organic', 'NASAA 12345' - product_other_property.set_property 'Organic', 'NASAA 12345' - product_other_producer.set_property 'Biodynamic', 'ASDF 1234' - end - - it "returns properties applied to supplied products" do - expect(Spree::Property.applied_by(producer)).to eq [property] - end - - it "doesn't return properties not applied" do - expect(Spree::Property.applied_by(producer)).not_to include property_other - end - - it "doesn't return duplicates" do - expect(Spree::Property.applied_by(producer).to_a.size).to eq 1 - end - end - describe ".currently_sold_by and .ever_sold_by" do let!(:shop) { create(:distributor_enterprise) } let!(:shop_other) { create(:distributor_enterprise) } From 43274ecb4f006f6a63b1419f44bf0e032ce810bf Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 14:47:33 +0100 Subject: [PATCH 152/166] Remove dead code Dead since https://github.com/openfoodfoundation/openfoodnetwork/pull/3305 --- app/models/producer_property.rb | 12 ----- app/models/spree/property.rb | 12 ----- spec/models/producer_property_spec.rb | 74 --------------------------- spec/models/spree/property_spec.rb | 71 ------------------------- 4 files changed, 169 deletions(-) delete mode 100644 spec/models/producer_property_spec.rb delete mode 100644 spec/models/spree/property_spec.rb diff --git a/app/models/producer_property.rb b/app/models/producer_property.rb index a2de688357..67e48d34db 100644 --- a/app/models/producer_property.rb +++ b/app/models/producer_property.rb @@ -4,18 +4,6 @@ class ProducerProperty < ActiveRecord::Base default_scope { order("#{table_name}.position") } - scope :ever_sold_by, ->(shop) { - joins(producer: { supplied_products: { variants: { exchanges: :order_cycle } } }). - merge(Exchange.outgoing). - merge(Exchange.to_enterprise(shop)). - select('DISTINCT producer_properties.*') - } - - scope :currently_sold_by, ->(shop) { - ever_sold_by(shop). - merge(OrderCycle.active) - } - def property_name property.name if property end diff --git a/app/models/spree/property.rb b/app/models/spree/property.rb index 92c053f65b..a598d1594b 100644 --- a/app/models/spree/property.rb +++ b/app/models/spree/property.rb @@ -10,18 +10,6 @@ module Spree scope :sorted, -> { order(:name) } - scope :ever_sold_by, ->(shop) { - joins(products: { variants: { exchanges: :order_cycle } }). - merge(Exchange.outgoing). - merge(Exchange.to_enterprise(shop)). - select('DISTINCT spree_properties.*') - } - - scope :currently_sold_by, ->(shop) { - ever_sold_by(shop). - merge(OrderCycle.active) - } - def property self end diff --git a/spec/models/producer_property_spec.rb b/spec/models/producer_property_spec.rb deleted file mode 100644 index a39d5fd609..0000000000 --- a/spec/models/producer_property_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'spec_helper' - -describe ProducerProperty do - let(:producer) { create(:supplier_enterprise) } - let(:pp) { producer.producer_properties.first } - - before do - producer.set_producer_property 'Organic Certified', 'NASAA 54321' - end - - describe ".currently_sold_by and .ever_sold_by" do - let!(:shop) { create(:distributor_enterprise) } - let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first]) } - let(:product) { create(:simple_product, supplier: producer) } - let(:producer_other) { create(:supplier_enterprise) } - let(:product_other) { create(:simple_product, supplier: producer_other) } - let(:pp_other) { producer_other.producer_properties.first } - - before do - producer_other.set_producer_property 'Spiffy', 'Ya' - end - - describe "with an associated producer property" do - it "returns the producer property" do - expect(ProducerProperty.currently_sold_by(shop)).to eq [pp] - expect(ProducerProperty.ever_sold_by(shop)).to eq [pp] - end - end - - describe "with a producer property for a producer not carried by that shop" do - let!(:exchange) { create(:exchange, order_cycle: oc, incoming: true, sender: producer_other, receiver: oc.coordinator) } - - it "doesn't return the producer property" do - expect(ProducerProperty.currently_sold_by(shop)).not_to include pp_other - expect(ProducerProperty.ever_sold_by(shop)).not_to include pp_other - end - end - - describe "with a producer property for a product in a different shop" do - let(:shop_other) { create(:distributor_enterprise) } - let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first]) } - let!(:exchange) { create(:exchange, order_cycle: oc, incoming: false, sender: oc.coordinator, receiver: shop_other, variants: [product_other.variants.first]) } - - it "doesn't return the producer property" do - expect(ProducerProperty.currently_sold_by(shop)).not_to include pp_other - expect(ProducerProperty.ever_sold_by(shop)).not_to include pp_other - end - end - - describe "with a producer property for a product in a closed order cycle" do - before do - oc.update_attributes! orders_open_at: 2.weeks.ago, orders_close_at: 1.week.ago - end - - it "doesn't return the producer property for .currently_sold_by" do - expect(ProducerProperty.currently_sold_by(shop)).not_to include pp - end - - it "returns the producer property for .ever_sold_by" do - expect(ProducerProperty.ever_sold_by(shop)).to include pp - end - end - - describe "with a duplicate producer property" do - let(:product2) { create(:simple_product, supplier: producer) } - let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first, product2.variants.first]) } - - it "doesn't return duplicates" do - expect(ProducerProperty.currently_sold_by(shop).to_a.size).to eq 1 - expect(ProducerProperty.ever_sold_by(shop).to_a.size).to eq 1 - end - end - end -end diff --git a/spec/models/spree/property_spec.rb b/spec/models/spree/property_spec.rb deleted file mode 100644 index acbd22ca27..0000000000 --- a/spec/models/spree/property_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'spec_helper' - -module Spree - describe Property do - describe "scopes" do - describe ".currently_sold_by and .ever_sold_by" do - let!(:shop) { create(:distributor_enterprise) } - let!(:shop_other) { create(:distributor_enterprise) } - let!(:product) { create(:simple_product) } - let!(:product_other_ex) { create(:simple_product) } - let!(:product_no_oc) { create(:simple_product) } - let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first]) } - let!(:exchange_other_shop) { create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: shop_other, variants: [product_other_ex.variants.first]) } - let(:property) { product.properties.last } - let(:property_other_ex) { product_other_ex.properties.last } - let(:property_no_oc) { product_no_oc.properties.last } - - before do - product.set_property 'Organic', 'NASAA 12345' - product_other_ex.set_property 'Biodynamic', 'ASDF 12345' - product_no_oc.set_property 'Shiny', 'Very' - end - - it "returns the property" do - expect(Property.currently_sold_by(shop)).to eq [property] - expect(Property.ever_sold_by(shop)).to eq [property] - end - - it "doesn't return the property from another exchange" do - expect(Property.currently_sold_by(shop)).not_to include property_other_ex - expect(Property.ever_sold_by(shop)).not_to include property_other_ex - end - - it "doesn't return the property with no order cycle" do - expect(Property.currently_sold_by(shop)).not_to include property_no_oc - expect(Property.ever_sold_by(shop)).not_to include property_no_oc - end - - describe "closed order cyces" do - let!(:product_closed_oc) { create(:simple_product) } - let!(:oc_closed) { create(:closed_order_cycle, distributors: [shop], variants: [product_closed_oc.variants.first]) } - let(:property_closed_oc) { product_closed_oc.properties.last } - - before { product_closed_oc.set_property 'Spiffy', 'Ooh yeah' } - - it "doesn't return the property for .currently_sold_by" do - expect(Property.currently_sold_by(shop)).not_to include property_closed_oc - end - - it "returns the property for .ever_sold_by" do - expect(Property.ever_sold_by(shop)).to include property_closed_oc - end - end - - context "with another product in the order cycle" do - let!(:product2) { create(:simple_product) } - let!(:oc) { create(:simple_order_cycle, distributors: [shop], variants: [product.variants.first, product2.variants.first]) } - - before do - product2.set_property 'Organic', 'NASAA 12345' - end - - it "doesn't return duplicates" do - expect(Property.currently_sold_by(shop).to_a.size).to eq 1 - expect(Property.ever_sold_by(shop).to_a.size).to eq 1 - end - end - end - end - end -end From 2ab07bc6a96ceff9a44d246d7f7ea64c5d392f1e Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 17:33:05 +0100 Subject: [PATCH 153/166] Make search box font size be 16px so that no zoom happens on iphone --- app/assets/stylesheets/darkswarm/_shop-inputs.css.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss b/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss index 55f3309477..3cf5d6e497 100644 --- a/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-inputs.css.scss @@ -9,6 +9,9 @@ input#search { @include medium-input(rgba(0, 0, 0, 0.3), #777, $clr-brick); + + // avoid zoom on iphone, see issue #4535 + font-size: 1rem; } // ordering From 91306d5ce42aecba1ddcd6b61822d90686a38cce Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Tue, 21 Apr 2020 10:13:00 +0200 Subject: [PATCH 154/166] Update all locales with the latest Transifex translations --- config/locales/en_FR.yml | 3 ++ config/locales/fr.yml | 5 +- config/locales/pt_BR.yml | 4 +- config/locales/tr.yml | 104 +++++++++++++++++++-------------------- 4 files changed, 61 insertions(+), 55 deletions(-) diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index f9b0c831ca..c242e06622 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -1919,6 +1919,7 @@ en_FR: admin_enterprise_relationships_permits: "permits" admin_enterprise_relationships_seach_placeholder: "Search" admin_enterprise_relationships_button_create: "Create" + admin_enterprise_relationships_to: "to" admin_enterprise_groups: "Enterprise Groups" admin_enterprise_groups_name: "Name" admin_enterprise_groups_owner: "Owner" @@ -2760,6 +2761,8 @@ en_FR: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 1c24fb93c9..528c35b883 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -596,7 +596,7 @@ fr: max_fulfilled_units: "Nombre max d'unités commandées" order_error: "Des erreurs doivent être résolues avant de pouvoir mettre à jour les commandes.\nLes champs entourés en rouge contiennent des erreurs." variants_without_unit_value: "ATTENTION: certaines variantes n'ont pas de nombre d'unités" - select_variant: "Choisir une variante" + select_variant: "Rechercher un produit et sélectionner une variante" enterprise: select_outgoing_oc_products_from: Sélectionner les produits sortants pour le cycle de vente parmi enterprises: @@ -1921,6 +1921,7 @@ fr: admin_enterprise_relationships_permits: "autorise" admin_enterprise_relationships_seach_placeholder: "Rechercher" admin_enterprise_relationships_button_create: "Créer" + admin_enterprise_relationships_to: "à" admin_enterprise_groups: "Groupes d'entreprises" admin_enterprise_groups_name: "Produit/Variante" admin_enterprise_groups_owner: "Gestionnaire principal" @@ -2790,6 +2791,8 @@ fr: location: "Localisation" count_on_hand: "Quantité en stock" quantity: "Quantité" + on_demand: "A volonté" + on_hand: "En stock" package_from: "conditionnement par" item_description: "Description de la pièce" price: "Prix" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 2bb99574e9..4ea651cb2c 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -2135,7 +2135,7 @@ pt_BR: report_header_quantity: Quantidade report_header_max_quantity: Quantidade máxima report_header_variant: Variante - report_header_variant_value: Valor variante + report_header_variant_value: Valor da variante report_header_variant_unit: Unidade variante report_header_total_available: Total disponível report_header_unallocated: Não atribuído @@ -3201,7 +3201,7 @@ pt_BR: no_results: "Nenhum Resultado" to_add_variants_you_must_first_define: "Para adicionar variantes, primeiro você precisa definir" option_types: "Tipos de Opções" - option_values: "Valores de Opções" + option_values: "Valores das Opções" and: "e" new_variant: "Nova Variante" show_active: "Mostra Ativos" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 12473fe9d8..4176587dcc 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -50,7 +50,7 @@ tr: start_at: "Başlangıç" end_at: "Bitiş" distributor_ids: "Pazarlar" - producer_ids: "Üreticiler" + producer_ids: "ÜRETİCİLER" order_cycle_ids: "Sipariş Dönemleri" enterprise_fee_ids: "Ücret İsimleri" shipping_method_ids: "Teslimat Yöntemleri" @@ -181,7 +181,7 @@ tr: home: "AGA" title: Açık Gıda Ağı welcome_to: 'Hoşgeldiniz' - site_meta_description: "Açık Gıda Ağı, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." + site_meta_description: "Açık Gıda Ağı, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Kar amacı gütmez, toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." search_by_name: İsim veya konuma göre arama yapın... producers_join: Temiz gıda üreticileri! Açık Gıda Ağı sizler için kullanıma açıldı. charges_sales_tax: KDV Uyguluyor mu? @@ -198,7 +198,7 @@ tr: confirm_resend_order_confirmation: "Sipariş onayı e-postasını tekrar göndermek istediğinizden emin misiniz?" must_have_valid_business_number: "Faturaların gönderilebilmesi için %{enterprise_name} adına geçerli bir VKN/TCKN olmalı." invoice: "Fatura" - more: "Daha Fazla?" + more: "Daha Fazla" say_no: "Hayır" say_yes: "Evet" ongoing: Devam eden @@ -1150,7 +1150,7 @@ tr: footer_contact_headline: "İrtibatta olalım" footer_contact_email: "Bize e-posta gönderin" footer_nav_headline: "Gezin" - footer_join_headline: "Bize katıl" + footer_join_headline: "Bize katılın" footer_join_body: "Açık Gıda Ağı üzerinden aracısız, adil ve temiz gıdaya ulaşma yolları keşfedin." footer_join_cta: "Daha fazlasını anlat!" footer_legal_call: "Okuyun" @@ -1164,7 +1164,7 @@ tr: shop: messages: login: "oturum aç" - signup: "kaydol" + signup: "Kaydol" contact: "İletişim" require_customer_login: "Yalnızca onaylı müşteriler buradan alışveriş yapabilir." require_login_html: "Zaten onaylanmış bir müşteriyseniz, devam etmek için %{login} veya %{signup}. Buradan alışveriş yapmaya başlamak ister misiniz? Lütfen katılmak için %{contact} %{enterprise} ile iletişime geçin." @@ -1196,14 +1196,14 @@ tr: ticket_column_item: "Ürün" ticket_column_unit_price: "Birim fiyat" ticket_column_total_price: "Toplam tutar" - menu_1_title: "Pazarlar" + menu_1_title: "Pazar Yeri" menu_1_url: "/shops" - menu_2_title: "harita" + menu_2_title: "HARİTA" menu_2_url: "/map" - menu_3_title: "üreticiler" + menu_3_title: "ÜRETİCİLER" menu_3_url: "/producers" menu_4_title: "Gruplar" - menu_4_url: "/ gruplar" + menu_4_url: "/groups" menu_5_title: "hakkında" menu_5_url: "https://acikgida.com" menu_6_title: "Bağlan" @@ -1241,7 +1241,7 @@ tr: postcode_placeholder: Örn. 16000 suburb: İlçe state: Şehir - country: ülke + country: Ülke unauthorized: Yetkisiz terms_of_service: "Kullanım Şartları" on_demand: Talep üzerine @@ -1254,27 +1254,27 @@ tr: days: günler authorization_failure: "Yetki Hatası" label_shop: "Pazar" - label_shops: "Pazarlar" - label_map: "harita" + label_shops: "Pazar Yeri" + label_map: "HARİTA" label_producer: "Üretici" - label_producers: "üreticiler" + label_producers: "ÜRETİCİLER" label_groups: "Gruplar" label_about: "hakkında" label_connect: "Bağlan" - label_learn: "öğren" + label_learn: "Öğren" label_blog: "Blog" label_support: "Destek" label_shopping: "Alışveriş " label_login: "Oturum aç" label_logout: "Çıkış Yap" - label_signup: "kaydol" - label_administration: "yönetim" - label_admin: "yönetici" - label_account: "hesap" + label_signup: "Kaydol" + label_administration: "Yönetim" + label_admin: "Yönetici" + label_account: "Hesap" label_more: "Daha fazla göster" label_less: "Daha az göster" label_notices: "Uyarılar" - cart_items: "ürünler" + cart_items: "Ürünler" cart_headline: "Alışveriş sepetiniz" total: "Toplam" cart_updating: "Sepet güncelleniyor ..." @@ -1344,12 +1344,12 @@ tr: cookies_policy_link_desc: "Daha fazla bilgi edinmek istiyorsanız," cookies_policy_link: "çerezler politikası" cookies_accept_button: "Çerezleri kabul et" - home_shop: Şimdi Alışveriş Yap + home_shop: ŞİMDİ ALIŞVERİŞ YAPIN brandstory_headline: "Bağımsız, adil ve temiz gıda ..." brandstory_intro: "Bazen sistemi düzeltmenin en iyi yolu yeni bir sistem yaratmaktır…" - brandstory_part1: "Açık Gıda Ağı, farklı ülkelerdeki temiz gıda üreticileri ve yazılımcılar tarafından yeni bir gıda sistemi oluşturmak üzere tasarlandı. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır ve tamamen şeffaftır." + brandstory_part1: "Açık Gıda Ağı, adil ve temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Kar amacı gütmez, toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler." brandstory_part2: "AGA, üreticilere ve alıcılara aracısız ticaret faydaları sağlar ve toplumsal iletişimi ve güveni cesaretlendirerek üretici-türetici ilişkisi oluşturmayı hedefler. Gıda yetiştiriciliği ve satışının kendine özgü ihtiyaçlarını karşılamaya ve sorunlarını çözmeye yönelik olarak tasarlanmıştır. Temiz gıdaya ulaşım sürecini ve yönetimini kolaylaştırır." - brandstory_part3: "Platform üzerinden yalnızca temiz gıda üreticileri satış yapabilir. Eğer siz de temiz gıda üreticisi iseniz, ürünlerinizi AGA üzerinden oluşturduğunuz tezgah ile doğrudan alıcılara ulaştırabilirsiniz. Dilerseniz bölgenizdeki diğer üreticiler ile bir araya gelerek kendi ortak 'Üretici Pazarı' nızı oluşturursunuz. Bu şekilde çeşitliliği ve bereketi artırır, dayanışmanın getirdiği diğer faydalardan da yararlanabilirsiniz." + brandstory_part3: "Platform üzerinden yalnızca temiz gıda üreticileri satış yapabilir. Eğer siz de temiz gıda üreticisi iseniz, ürünlerinizi AGA üzerinden oluşturduğunuz tezgah ile doğrudan alıcılara ulaştırabilirsiniz. Dilerseniz bölgenizdeki diğer üreticiler ile bir araya gelerek kendi ortak 'Üretici Pazarı' veya 'Türetici Pazarı' nızı oluşturursunuz. Bu şekilde çeşitliliği ve bereketi artırır, dayanışmanın getirdiği diğer faydalardan da yararlanabilirsiniz." brandstory_part4: "Her yerde çalışıyor. Her şeyi değiştiriyor." brandstory_part5_strong: "Biz buna Açık Gıda Ağı diyoruz." brandstory_part6: "Hepimiz gıdamızı seviyoruz. Artık gıda sistemimizi de sevmeye başlayabiliriz." @@ -1360,17 +1360,17 @@ tr: system_headline: "Alışveriş - işte böyle çalışıyor." system_step1: "1. Ara" system_step1_text: "Yerel, adil, temiz ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin pazarlarından alışveriş yapın. Uzaklığa göre, ürün kategorisine veya teslimat tercihlerine göre arama yapabilirsiniz. " - system_step2: "2. Pazar" + system_step2: "2. Alışveriş Yap" system_step2_text: "Gıdanızı yerel üretici tezgahlarından, üretici ve türetici pazarlarından temin edin. Yaşanabilir bir dünya için alışkanlıklarınızı şimdi değiştirin. Gıdanızın ve onu size getiren insanların hikayelerini öğrenin!" - system_step3: "Teslimat Noktası / Kargo" - system_step3_text: "Teslimat için bekleyin veya gıdanız ile daha kişisel bir bağ kurmak için üreticinizi veya pazarını ziyaret edin. Doğayla ve gıdayla istediğiniz şekilde ama gerçek bir bağ kurun." + system_step3: "3. Teslimat " + system_step3_text: "Gıdanıza ulaşmak için eve teslim edilmesini ya da kargoyu bekleyin veya gıdanız ile daha kişisel bir bağ kurmak için üreticinizi veya pazarını kendiniz ziyaret edin. Doğayla ve gıdayla istediğiniz şekilde ama gerçek bir bağ kurun. " cta_headline: "Dünyayı daha iyi bir yer yapan alışveriş biçimi." cta_label: "Hazırım" stats_headline: "Yeni bir gıda sistemi yaratıyoruz." - stats_producers: "gıda üreticileri" + stats_producers: "GIDA ÜRETİCİLERİ" stats_shops: "gıda pazarları" stats_shoppers: "gıda alıcıları" - stats_orders: "gıda siparişleri" + stats_orders: "GIDA SİPARİŞLERİ" checkout_title: Ödeme Yap checkout_now: Şimdi ödeme yap checkout_order_ready: Sipariş şu tarihte hazır @@ -1518,11 +1518,11 @@ tr: hubs_profile_only: "Yalnızca profil" hubs_delivery_options: "Teslimat seçenekleri" hubs_pickup: "Teslimat Noktası" - hubs_delivery: "teslimat" + hubs_delivery: "Eve Teslim" hubs_producers: "Üreticilerimiz" - hubs_filter_by: "filtre" - hubs_filter_type: "yazın" - hubs_filter_delivery: "teslimat" + hubs_filter_by: "Filtrele" + hubs_filter_type: "Ürün Çeşidi" + hubs_filter_delivery: "Eve Teslim" hubs_filter_property: "Özellik" hubs_matches: "Bunu mu arıyordunuz?" hubs_intro: Bulunduğunuz bölgeden alışveriş yapın @@ -1607,7 +1607,7 @@ tr: producers_contact_phone: Ara producers_contact_social: Takip et producers_buy_at_html: "%{enterprise} ürünleri için buradan alışveriş yapın:" - producers_filter: Filtre + producers_filter: Filtrele producers_filter_type: tür producers_filter_property: Özellik producers_title: Üreticiler @@ -1640,12 +1640,12 @@ tr: sell_hubs_detail: "AGA üzerinden gıda işletmeniz veya topluluğunuz için bir profil oluşturun. İstediğiniz zaman profilinizi çok üreticili bir pazara yükseltebilirsiniz." sell_groups_detail: "Bölgenizdeki veya ağınızdaki işletmelerin (üreticilerin, pazarların veya diğer grupların) detaylı rehber listesini oluşturun." sell_user_guide: "Kullanım kılavuzumuzda daha fazla bilgi edinin." - sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. OFN'de bir mağaza açmak ve işletmek aylık 500 dolara kadar ücretsizdir. Daha fazla satıyorsanız, satışların% 1'i ile% 3'ü arasında topluluk katkınızı seçebilirsiniz. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkında bağlantısını kullanarak Yazılım Platformu bölümünü ziyaret edin." + sell_listing_price: "AGA üzerinde görünür olmak ücretsizdir. Fiyatlandırma hakkında daha fazla bilgi için, üst menüdeki Hakkında bağlantısını kullanarak Yazılım Platformu bölümünü ziyaret edin." sell_embed: "Açık Gıda Ağı üzerinden oluşturduğunuz tezgahınızı kendi web siteniz üzerinden de kullanmanıza yardımcı olabiliriz. Müşterileriniz mevcut internet siteniz üzerinden de aynı şekilde sipariş verebilirler. " sell_ask_services: "Bize AGA hizmetleri hakkında soru sorun." shops_title: Dükkanlar shops_headline: Alışveriş biçim değiştiriyor - shops_text: Gıda dönemsel yetişir, dönemsel hasat edilir ve dönemsel sipariş edilir. Aradığınız sipariş dönemi kapalı ise kısa süre sonra tekrar kontrol edin. + shops_text: Gıda dönemsel yetiştirilir, dönemsel hasat edilir ve dönemsel sipariş edilir. Aradığınız sipariş dönemi kapalı ise kısa süre sonra tekrar kontrol edin. shops_signup_title: Pazar olarak kaydolun shops_signup_headline: Gıda pazarları, sınır yok. shops_signup_motivation: Her türlü gıda işletmesi/topluluğu modelini destekliyoruz. Bağımsız ve şeffaf bir sosyal girişimiz. İşlerinizi kolaylaştırmaya çalışan yol arkadaşlarıyız. @@ -1744,9 +1744,9 @@ tr: email_required: "Bir e-posta adresi sağlamalısınız" logging_in: "Biraz bekleyin, giriş yapıyoruz" signup_email: "E-posta adresiniz" - choose_password: "bir şifre Şeçin" + choose_password: "Bir şifre seçin" confirm_password: "Şifreyi Onayla" - action_signup: "Şimdi üye Ol" + action_signup: "Şimdi Üye Ol" forgot_password: "Parolanızı mı unuttunuz?" password_reset_sent: "Şifrenizi sıfırlama talimatlarını içeren bir e-posta gönderildi!" reset_password: "Şifreyi yenile" @@ -2065,7 +2065,7 @@ tr: report_customers_cycle: "Sipariş Dönemi" report_customers_type: "Rapor türü" report_customers_csv: "Csv olarak indir" - report_producers: "üreticiler:" + report_producers: "ÜRECİTİLER:" report_type: "Rapor türü:" report_hubs: "Pazarlar:" report_payment: "Ödeme yöntemleri:" @@ -2410,7 +2410,7 @@ tr: Açık Gıda Ağı, mümkün olduğunca çok gıda topluluğu/kooperatifi modelini desteklemeye çalışır. Sizin de gıda topluluğunuzu veya gıda işletmenizi en iyi şekilde yönetmeniz için tüm imkanları ve araçları sağlamaya hazırız. - get_listing: Giriş alın + get_listing: Görünür Olun always_free: HER ZAMAN ÜCRETSİZ sell_produce_others: Başkalarının ürünlerini sat sell_own_produce: Kendi ürününü sat @@ -2419,8 +2419,8 @@ tr: producer: Üretici producer_text1: > Dürüst ve bilinçli üreticiler, insanlara sağlıklı gıdalar sağlar. Siz - de birşeyler yetiştiriyor, büyütüyor, sağıyor, hasat ediyor, pişiriyor - kurutuyor veya hazırlıyorsanız, üreticisiniz demektir. + de birşeyler yetiştiriyor, büyütüyor, sağıyor, hasat ediyor, pişiriyor, + kurutuyor veya hazırlıyorsanız, bir üreticisiniz demektir. producer_text2: > Üreticiler sistem üzerinde farklı şekillerde aktif olarak da hem kendilerine hem de diğer işletmelere daha faydalı olabilirler. Çevrelerindeki üreticilerin @@ -2431,9 +2431,9 @@ tr: Üretici olmayan hesaplar kendi ürünleri olmadığı için Açık Gıda Ağı üzerinden ürün oluşturamazlar. non_producer_text2: > - Bunun yerine çevrelerindeki üreticiler adına sipariş ve teslimatları - yönetebilir, adil ve temiz gıdayı nihai tüketiciler ile buluşturmaya - yardımcı olabilirler. + Bunun yerine çevrelerindeki bulunan veya tedarikçileri olan üreticiler + adına sipariş ve teslimatları yönetebilir, adil ve temiz gıdayı nihai + tüketiciler ile buluşturmaya yardımcı olabilirler. producer_desc: Gıda üreticileri producer_example: 'Örn: ÇİFTÇİLER, FIRINLAR, ÜRETİM KOOPERATİFLERİ vs.' non_producer_desc: Diğer tüm gıda işletmeleri @@ -2479,7 +2479,7 @@ tr: cart: "sepet" complete: "tamamla" confirm: "onayla" - delivery: "teslimat" + delivery: "Eve Teslim" paused: "Durduruldu" payment: "ödeme" pending: "Bekliyor" @@ -2728,7 +2728,7 @@ tr: shipment_inc_vat: "KDV dahil teslimat" shipping_tax_rate: "Kargo Vergi Oranı" category: "Kategori" - delivery: "teslimat" + delivery: "Eve Teslim" temperature_controlled: "Soğuk Sevkiyat" new_product: "Yeni ürün" administration: "yönetim" @@ -2878,7 +2878,7 @@ tr: back_to_trackers_list: "İzleyiciler Listesine Geri Dön" name: "ad" description: "Açıklama" - type: "tür" + type: "Çeşit" default: "varsayılan" calculator: "Hesaplama" zone: "bölge" @@ -2900,7 +2900,7 @@ tr: normal_amount: "Normal Tutar" discount_amount: "İndirim tutarı" no_images_found: "Resim Bulunamadı" - new_image: "Yeni görüntü" + new_image: "Yeni Görüntü" filename: "Dosya adı" alt_text: "alternatif metin" thumbnail: "Küçük görsel" @@ -3107,8 +3107,8 @@ tr: products: image_upload_error: "Ürün resmi tanınamadı. Lütfen PNG veya JPG biçiminde bir resim yükleyin." new: - title: "Yeni ürün" - new_product: "Yeni ürün" + title: "Yeni Ürün" + new_product: "Yeni Ürün" supplier: "Tedarikçi" product_name: "Ürün adı" units: "Ölçü Birimi" @@ -3140,7 +3140,7 @@ tr: import_date: "İçe Aktarım Tarihi" products_variant: variant_has_n_overrides: "Bu varyant %{n} geçersiz kılınma özelliğine sahip" - new_variant: "Yeni varyant" + new_variant: "Yeni Varyant" product_name: Ürün adı primary_taxon_form: product_category: Ürün Kategorisi @@ -3281,7 +3281,7 @@ tr: cart: sepet complete: tamamla confirm: onayla - delivery: teslimat + delivery: Eve Teslim paused: durduruldu payment: ödeme pending: bekliyor @@ -3333,7 +3333,7 @@ tr: until: Şu zamana kadar past_orders: order: Sipariş - shop: Dükkan + shop: Tezgah completed_at: Tamamlanma Tarihi items: Ürünler total: Toplam From 4ef61b642e51c6c062bc8f5f804c3e46bcc689a2 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Wed, 22 Apr 2020 01:33:38 +0200 Subject: [PATCH 158/166] Fix disappearing tags issue --- app/controllers/admin/customers_controller.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/customers_controller.rb b/app/controllers/admin/customers_controller.rb index dac3b209dc..21942786bd 100644 --- a/app/controllers/admin/customers_controller.rb +++ b/app/controllers/admin/customers_controller.rb @@ -102,9 +102,11 @@ module Admin context: 'tags' }) customer_tags.each_with_object({}) do |tag, indexed_hash| - customer_id = tag.taggings.first.taggable_id - indexed_hash[customer_id] ||= [] - indexed_hash[customer_id] << tag.name + tag.taggings.each do |tagging| + customer_id = tagging.taggable_id + indexed_hash[customer_id] ||= [] + indexed_hash[customer_id] << tag.name + end end end end From 240d4a780275c94596ec32181668d1258d3936c9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2020 19:41:50 +0000 Subject: [PATCH 159/166] Bump mini_racer from 0.2.9 to 0.2.10 Bumps [mini_racer](https://github.com/discourse/mini_racer) from 0.2.9 to 0.2.10. - [Release notes](https://github.com/discourse/mini_racer/releases) - [Changelog](https://github.com/rubyjs/mini_racer/blob/master/CHANGELOG) - [Commits](https://github.com/discourse/mini_racer/compare/v0.2.9...v0.2.10) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 350ed39290..dcf202d4f3 100644 --- a/Gemfile +++ b/Gemfile @@ -94,7 +94,7 @@ gem 'test-unit', '~> 3.3' gem 'coffee-rails', '~> 3.2.1' gem 'compass-rails' -gem 'mini_racer', '0.2.9' +gem 'mini_racer', '0.2.10' gem 'uglifier', '>= 1.0.3' diff --git a/Gemfile.lock b/Gemfile.lock index 9b94b0bd72..d56477f603 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -443,8 +443,8 @@ GEM mime-types (1.25.1) mini_mime (1.0.1) mini_portile2 (2.4.0) - mini_racer (0.2.9) - libv8 (>= 6.9.411) + mini_racer (0.2.10) + libv8 (> 7.3) momentjs-rails (2.20.1) railties (>= 3.1) money (5.1.1) @@ -732,7 +732,7 @@ DEPENDENCIES kaminari (~> 0.14.1) knapsack letter_opener (>= 1.4.1) - mini_racer (= 0.2.9) + mini_racer (= 0.2.10) momentjs-rails newrelic_rpm (~> 3.0) oauth2 (~> 1.4.4) From d8f4df4bccb51c55411a69730360ce659de83510 Mon Sep 17 00:00:00 2001 From: Robin Klaus Date: Thu, 23 Apr 2020 09:58:47 +1000 Subject: [PATCH 160/166] Fixed missing translation, added keys to en.yml file --- config/locales/en.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 465a664fce..2a0f2db34e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3387,6 +3387,9 @@ See the %{link} to find out more about %{sitename}'s features and to start using producer_name: "Producer" unit: "Unit" general_settings: + shared: + sortable_header: + name: "Name" edit: legal_settings: "Legal Settings" cookies_consent_banner_toggle: "Display cookies consent banner" From 15319d66e20317aa1c5cacedad9379a394dfc1f3 Mon Sep 17 00:00:00 2001 From: Transifex-Openfoodnetwork Date: Thu, 23 Apr 2020 12:27:58 +1000 Subject: [PATCH 161/166] Updating translations for config/locales/es_CR.yml --- config/locales/es_CR.yml | 537 ++++++++++++++++++++------------------- 1 file changed, 270 insertions(+), 267 deletions(-) diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index fc946b9c93..4e726c2c76 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -43,7 +43,7 @@ es_CR: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de inventario de la productora" on_demand_but_count_on_hand_set: "debe estar en blanco si es bajo demanda" - limited_stock_but_no_count_on_hand: "se debe especificar porque se ha definido un inventario limitado" + limited_stock_but_no_count_on_hand: "debe estar especificado porque se ha definido un inventario limitado" activemodel: attributes: order_management/reports/enterprise_fee_summary/parameters: @@ -114,11 +114,11 @@ es_CR: not_string_error: "debe ser una cadena" invalid_format_error: "debe ser válido" integer_array_validator: - not_array_error: "debe ser una matriz" + not_array_error: "debe ser una lista" invalid_element_error: "debe contener solo enteros válidos" enterprise_mailer: confirmation_instructions: - subject: "Confirma la dirección de correo electrónico de %{enterprise}" + subject: "Por favor, confirma la dirección de correo electrónico de %{enterprise}" welcome: subject: "%{enterprise} está ahora en %{sitename}" email_welcome: "Bienvenido" @@ -127,7 +127,7 @@ es_CR: userguide: "Guía de usuario de La Feria" email_admin_html: "Puede administrar su cuenta iniciando sesión en %{link} o haciendo clic en el engrane arriba a la derecha de la página de inicio, y seleccionando Administración." admin_panel: "Panel de administración" - email_community_html: "También tenemos un foro en líea para la discusión comunal relacionada con el programa OFN y los retos únicos del funcionamiento de una organización de alimentación. Lo invitamos a unirse. Estamos evolucionando de forma constante y su aporte en este formo le dará forma a lo que pase luego. %{link}" + email_community_html: "También tenemos un foro en línea para la discusión comunitaria relacionada con el software OFN y los retos únicos del funcionamiento de una organización de alimentación. Lo invitamos a unirse. Estamos evolucionando constantemente y su aporte en este foro le dará forma a lo que pase luego. %{link}" join_community: "Unirse a la comunidad" invite_manager: subject: "%{enterprise} te ha invitado a ser administrador" @@ -149,7 +149,7 @@ es_CR: greeting: "Hola %{name}," intro: "A continuación se muestra un resumen de los pedidos de suscripción que acaban de realizarse en %{shop}." confirmation_summary_email: - subject: Un resumen de los pedidos de suscripción confirmadas recientemente + subject: Un resumen de los pedidos de suscripción confirmados recientemente greeting: "Hola %{name}," intro: "A continuación se muestra un resumen de los pedidos de suscripción que acaban de finalizar para %{shop}." summary_overview: @@ -181,9 +181,9 @@ es_CR: home: "OFN" title: Open Food Network welcome_to: 'Bienvenido a ' - site_meta_description: "Nosotros empezamos desde abajo. Con granjeros y productoras listas para contar sus historias con orgullo y autenticidad. Con distribuidoras listas para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden..." - search_by_name: Buscar por nombre o municipio... - producers_join: Las productoras australianas ahora son bienvenidas a unirse a Open Food Network. + site_meta_description: "Nosotros empezamos desde abajo. Con granjeros y productores listos para contar sus historias con orgullo y autenticidad. Con distribuidores listos para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden..." + search_by_name: Buscar por nombre o cantón... + producers_join: Los productores costarricenses son bienvenidos a unirse ahora a Open Food Network (LaFeriaCR). charges_sales_tax: ¿Cargos de IVA? print_invoice: "Imprimir factura" print_ticket: "Imprimir Ticket" @@ -219,23 +219,23 @@ es_CR: edit: Editar clone: Duplicar distributors: Distribuidores - bulk_order_management: Gestión de pedidos en bloque + bulk_order_management: Gestión de pedidos en volumen enterprises: Organizaciones enterprise_groups: Grupos reports: Reportes variant_overrides: Inventario import: Importar - spree_products: Productos Spree + spree_products: Productos de temporada all: Todos current: Actual available: Disponible dashboard: Panel de inicio undefined: indefinido - unused: no se usa + unused: no utilizado admin_and_handling: Administración y Manejo profile: Perfil - supplier_only: Sólo Proveedor - has_shopfront: Tiene tienda + supplier_only: Sólo proveedor + has_shopfront: Tiene puesto de tienda weight: Peso volume: Volumen items: Elementos @@ -246,7 +246,7 @@ es_CR: 'no': "No" y: 'S' n: 'N' - powered_by: Powered by + powered_by: Impulsado por blocked_cookies_alert: "Es posible que su navegador esté bloqueando las cookies necesarias para utilizar esta tienda. Haga clic a continuación para permitir las cookies y vuelva a cargar la página." allow_cookies: "Permitir cookies" notes: Notas @@ -283,7 +283,7 @@ es_CR: date: Fecha email: Email ends_at: Termina en - ends_on: Finaliza + ends_on: Finaliza en name: Nombre on_hand: Disponibles on_demand: Bajo demanda @@ -293,7 +293,7 @@ es_CR: payment_method: Método de pago phone: Teléfono price: Precio - producer: Productora + producer: Productor image: Imagen product: Producto quantity: Cantidad @@ -371,51 +371,51 @@ es_CR: config_instructions_html: "Aquí puede configurar la integración de OFN Matomo. La siguiente URL de Matomo debe apuntar a la instancia de Matomo a la que se enviará la información de seguimiento del usuario; si se deja vacío, el seguimiento del usuario Matomo se desactivará. El campo ID del sitio no es obligatorio, pero es útil si está rastreando más de un sitio web en una sola instancia de Matomo; se puede encontrar en la consola de la instancia de Matomo." customers: index: - new_customer: "Nuevo Cliente" + new_customer: "Nuevo cliente" code: Código - duplicate_code: "Este código ya se ha usado." - bill_address: "Dirección de Facturación" - ship_address: "Dirección de Envío" + duplicate_code: "Este código ya ha sido utilizado." + bill_address: "Dirección de facturación" + ship_address: "Dirección de envío" update_address_success: 'Dirección actualizada correctamente.' update_address_error: 'Introduce todos los campos requeridos' edit_bill_address: 'Edita la Dirección de Facturación' edit_ship_address: 'Editar Dirección de Envío' required_fileds: 'Los campos obligatorios se indican con un asterisco' select_country: 'Selecciona país' - select_state: 'Selecciona Provincia' + select_state: 'Selecciona provincia' edit: 'Editar' - update_address: 'Actualizar Dirección' + update_address: 'Actualizar dirección' confirm_delete: '¿Confirmas que quieres borrar?' - search_by_email: "Buscar por email/código" + search_by_email: "Buscar por correo electrónico/código" guest_label: 'Hacer pedido como invitado' destroy: has_associated_orders: 'Error al eliminar: el cliente tiene pedidos asociados a su tienda.' contents: edit: title: Contenido - header: Encabezamiento + header: Encabezado home_page: Página principal producer_signup_page: Página de registro del productor - hub_signup_page: 'Página para registro del centro de acopio ' + hub_signup_page: Página para registro del Hub group_signup_page: Página de registro de grupo main_links: Enlaces al menú principal footer_and_external_links: Pie de página y enlaces externos your_content: Tu contenido - user_guide: Manual de Usuario + user_guide: Manual de usuario enterprise_fees: index: - title: "Comisiones de la Organización" + title: "Comisiones de la organización" enterprise: "Organización" fee_type: "Tipo de Comisión" name: "Nombre" tax_category: "Categoría del impuesto" calculator: "Calculadora" - calculator_values: "Valores de la Calculadora" + calculator_values: "Valores de la calculadora" search: "Buscar" name_placeholder: "por ejemplo, comision de embalaje" enterprise_groups: index: - new_button: Nuevo Grupo de Organizaciones + new_button: Nuevo Grupo de Organización enterprise_roles: form: manages: Gestiona @@ -430,34 +430,34 @@ es_CR: tax_category: Categoría de impuestos inherits_properties?: ¿Hereda propiedades? available_on: Disponible en - av_on: "Av. En" + av_on: "Disp. en" import_date: Importado - upload_an_image: Subir una imagen + upload_an_image: Subir una imágen seo: product_search_keywords: "Palabras clave de búsqueda de productos" - product_search_tip: "Escriba palabras para ayudar a buscar sus productos en las tiendas. Use espacio para separar cada palabra clave." + product_search_tip: "Escriba palabras para ayudar a buscar sus productos en las tiendas. Use un espacio para separar cada palabra clave." SEO_keywords: "Palabras clave de SEO" - seo_tip: "Escriba palabras para ayudar a buscar sus productos en la web. Use espacio para separar cada palabra clave." + seo_tip: "Escriba palabras para ayudar a buscar sus productos en la web. Use un espacio para separar cada palabra clave." search: "Buscar" properties: - property_name: "Nombre de la Propiedad" - inherited_property: "Propiedad Heredada" + property_name: "Nombre de la propiedad" + inherited_property: "Propiedad heredada" variants: infinity: "infinito" to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda." back_to_products_list: "Volver a la lista de productos" editing_product: "Editando producto" tabs: - product_details: "Detalles del Producto" + product_details: "Detalles del producto" group_buy_options: "Opciones de compra grupales" images: "Imágenes" - variants: "variaciones" + variants: "Variedades" product_properties: "Propiedades del producto" product_import: - title: Importación de productos + title: Importe de producto file_not_found: Archivo no encontrado o no se pudo abrir no_data: No se encontraron datos en la hoja de cálculo - confirm_reset: "Esto establecerá el nivel de stock en cero en todos los productos para esta\n organizacion que no están presentes en el archivo cargado" + confirm_reset: "Esto establecerá el nivel de inventario a cero en todos los productos para esta\n organizacion que no están presentes en el archivo cargado" model: no_file: "Error: no se ha subido ningún archivo" could_not_process: "No se pudo procesar el archivo: tipo de archivo inválido" @@ -466,15 +466,15 @@ es_CR: no_product: no coincide con ningún producto en la base de datos not_found: no encontrado en la base de datos not_updatable: No se puede actualizar sobre productos existentes a través de la importación de productos - blank: no puede estar vacío + blank: no puede estar en blanco products_no_permission: no tienes permiso para administrar productos para esta organización - inventory_no_permission: no tienes permiso para crear inventario para esta productora - none_saved: No se guardó ningún producto con éxito + inventory_no_permission: no tienes permiso para crear inventario para este productor + none_saved: no se guardó ningún producto con éxito line_number: "Línea %{number}:" encoding_error: "Verifique la configuración de idioma de su archivo fuente y asegúrese de que esté guardado con la codificación UTF-8" unexpected_error: "La importación de productos encontró un error inesperado al abrir el archivo: %{error_message}" index: - notice: "aviso" + notice: "Aviso" beta_notice: "Esta funcionalidad aún está en versión beta: puede experimentar algunos errores mientras la usa. Por favor no dude en ponerse en contacto con nosotros." select_file: Selecciona una hoja de cálculo para subir spreadsheet: Hoja de cálculo @@ -488,7 +488,7 @@ es_CR: product_list_template: Descargar la plantilla de lista de productos inventory_template: Descargar plantilla de inventario category_values: Valores de categoría disponibles - product_categories: Categorías de Producto + product_categories: Categorías de producto tax_categories: Categorías de impuestos shipping_categories: Categorías de envío import: @@ -503,17 +503,17 @@ es_CR: fix_before_import: Corrija estos errores e intente importar el archivo nuevamente save_valid?: ¿Guardar entradas válidas por ahora y descartar las demás? no_errors: ¡No se detectaron errores! - save_all_imported?: Guardar todos los productos importados? + save_all_imported?: ¿Guardar todos los productos importados? options_and_defaults: Opciones de importación y valores predeterminados no_permission: no tienes permiso para administrar esta organización not_found: no se pudo encontrar la organización en la base de datos no_name: Sin nombre - blank_enterprise: Algunos productos no tienen una organización definida. + blank_enterprise: algunos productos no tienen una organización definida. reset_absent?: Restablecer productos ausentes - reset_absent_tip: Establezca el stock en cero para todos los productos existentes que no estén presentes en el archivo. + reset_absent_tip: Establezca el inventario en cero para todos los productos existentes que no estén presentes en el archivo. overwrite_all: Sobrescribir todo overwrite_empty: Sobrescribir si está vacío - default_stock: Establecer nivel de existencias + default_stock: Establecer nivel de inventario default_tax_cat: Establecer categoría de impuestos default_shipping_cat: Establecer categoría de envío default_available_date: Establecer fecha disponible @@ -524,7 +524,7 @@ es_CR: products_to_update: Los productos se actualizarán inventory_to_create: Se crearán Artículos de inventario inventory_to_update: Los artículos de inventario se actualizarán - products_to_reset: Los productos existentes tendrán su stock restablecido a cero + products_to_reset: Los productos existentes tendrán su inventario restablecido a cero inventory_to_reset: Los artículos de inventario existentes tendrán su stock restablecido a cero line: Línea item_line: Línea del artículo @@ -539,8 +539,8 @@ es_CR: products_updated: Productos actualizados inventory_created: Artículos de inventario creados inventory_updated: Artículos de inventario actualizados - products_reset: Los productos tenían nivel de stock restablecido a cero - inventory_reset: Los artículos de inventario tenían el nivel de stock restablecido a cero + products_reset: Los productos tenían nivel de inventario restablecido a cero + inventory_reset: Los artículos de inventario tenían el nivel de este restablecido a cero all_saved: "Todos los artículos guardados con éxito" some_saved: "Artículos guardados con éxito" save_errors: Guardar errores @@ -1069,7 +1069,7 @@ es_CR: credit_card: Tarjeta de crédito charges_not_allowed: Los cargos no están permitidos para este cliente no_default_card: El cliente no tiene tarjetas disponibles para el cobro - card_ok: El cliente tiene una tarjeta disponible para el cobro + card_ok: El cliente tiene una tarjeta disponible para cobro begins_at_placeholder: "Seleccione una fecha" ends_at_placeholder: "Opcional" loading_flash: @@ -1089,13 +1089,13 @@ es_CR: out_of_stock: "Agotado" orders: number: Número - confirm_edit: ¿Seguro que quieres editar esta orden? Si lo hace, puede ser más difícil sincronizar automáticamente los cambios a la suscripción en el futuro. + confirm_edit: ¿Seguro que quiere editar esta orden? Si lo hace, puede ser más difícil sincronizar automáticamente los cambios a la suscripción en el futuro. confirm_cancel_msg: "¿Seguro que quieres cancelar esta suscripción? Esta acción no se puede deshacer." - cancel_failure_msg: "Lo sentimos, ¡la cancelación falló!" + cancel_failure_msg: "Lo sentimos ¡la cancelación falló!" confirm_pause_msg: "¿Seguro que quieres pausar esta suscripción?" - pause_failure_msg: "Lo sentimos, pausar falló!" + pause_failure_msg: "Lo sentimos ¡pausar falló!" confirm_unpause_msg: "Si tiene un ciclo de pedido abierto en el horario de esta suscripción, se creará un pedido para este cliente. ¿Estás seguro de que deseas anular la pausa de esta suscripción?" - unpause_failure_msg: "Lo sentimos, ¡no se pudo reanudar!" + unpause_failure_msg: "Lo sentimos ¡no se pudo reanudar!" confirm_cancel_open_orders_msg: "Algunos pedidos de esta suscripción están actualmente abiertos. El cliente ya ha sido notificado de que se realizará el pedido. ¿Desea cancelar estos pedidos o conservarlos?" resume_canceled_orders_msg: "Algunos pedidos de esta suscripción se pueden reanudar en este momento. Puede reanudarlos desde el menú desplegable de pedidos." yes_cancel_them: Cancelarlos @@ -1104,7 +1104,7 @@ es_CR: order_update_issues_msg: Algunas órdenes no se pudieron actualizar automáticamente, esto es más probable porque se han editado manualmente. Revise los problemas que se detallan a continuación y realice los ajustes a los pedidos individuales si es necesario. no_results: no_subscriptions: Aún no hay suscripciones ... - why_dont_you_add_one: ¿Por qué no agregas una? :) + why_dont_you_add_one: ¿Por qué no agrega una? :) no_matching_subscriptions: No se encontraron suscripciones coincidentes schedules: destroy: @@ -1113,14 +1113,14 @@ es_CR: enterprises: stripe_connect_cancelled: "Se ha cancelado la conexión a Stripe" stripe_connect_success: "La cuenta Stripe se ha conectado correctamente" - stripe_connect_fail: Lo sentimos, la conexión de tu cuenta Stripe ha fallado + stripe_connect_fail: Lo sentimos, la conexión de su cuenta Stripe ha fallado stripe_connect_settings: resource: Configuración de Stripe Connect api: enterprise_logo: destroy_attachment_does_not_exist: "El logotipo no existe" enterprise_promo_image: - destroy_attachment_does_not_exist: "La imagen promocional no existe" + destroy_attachment_does_not_exist: "La imágen promocional no existe" orders: failed_to_update: "Error al actualizar pedido" checkout: @@ -1145,55 +1145,55 @@ es_CR: checkout: "Validar el carrito ahora" already_ordered_products: "Pedido en este ciclo de pedido" register_call: - selling_on_ofn: "¿Estás interesada en entrar en Open Food Network?" - register: "Regístrate aquí" + selling_on_ofn: "¿Tiene interés sobre entrar en Open Food Network (LaFeriaCR)?" + register: "Regístrarse aquí" footer: footer_secure: "Seguro y de confianza." - footer_secure_text: "Open Food Network usa cifrado SSL (RSA de 2048 bit) en toda su plataforma para mantener privada la información de compras y pagos. Nuestros servidores no almacenan los detalles de tarjetas de créditos y los pagos son procesados por servicios que cumplen con PCI." + footer_secure_text: "Open Food Network (LaFeriaCR) usa cifrado SSL (RSA de 2048 bit) en toda su plataforma para mantener privada la información de compras y pagos. Nuestros servidores no almacenan los detalles de tarjetas de créditos y los pagos son procesados por servicios que cumplen con PCI." footer_contact_headline: "Mantenerse en contacto" footer_contact_email: "Envíenos un correo electrónico" footer_nav_headline: "Navegar" footer_join_headline: "Unirse" - footer_join_body: "Crea un listado, una tienda o un directorio en Open Food Network." - footer_join_cta: "Cuentame más!" + footer_join_body: "Crea un listado, una tienda o un directorio en Open Food Network (LaFeriaCR)." + footer_join_cta: "¡Cuénteme más!" footer_legal_call: "Leer nuestros" - footer_legal_tos: "Terminos y condiciones" + footer_legal_tos: "Términos y condiciones" footer_legal_visit: "Encuéntrenos en" - footer_legal_text_html: "Open Food Network es una plataforma libre y de código abierto. Nuestro contenido tiene una licencia %{content_license} y nuestro código %{code_license}." - footer_data_text_with_privacy_policy_html: "Cuidamos bien tus datos. Consulta nuestra %{privacy_policy} y %{cookies_policy}" - footer_data_text_without_privacy_policy_html: "Cuidamos bien tus datos. Consulta nuestra %{cookies_policy}" + footer_legal_text_html: "Open Food Network (LaFeriaCR) es una plataforma libre y de código abierto. Nuestro contenido tiene una licencia %{content_license} y nuestro código %{code_license}." + footer_data_text_with_privacy_policy_html: "Cuidamos bien sus datos. Consulte nuestra %{privacy_policy} y %{cookies_policy}" + footer_data_text_without_privacy_policy_html: "Cuidamos bien sus datos. Consulte nuestra %{cookies_policy}" footer_data_privacy_policy: "política de privacidad" footer_data_cookies_policy: "política de cookies" shop: messages: - login: "login" - signup: "Regístrate" + login: "Ingresar" + signup: "Registrarse" contact: "contactar" - require_customer_login: "Sólo las consumidoras aprobadas pueden acceder a esta tienda." - require_login_html: "Si ya es un cliente aprobado, %{login} o %{signup} para continuar. ¿Quiere empezar a comprar aquí? Por favor, %{contact} %{enterprise} y pida su adhesión." + require_customer_login: "Sólo los clientes aprobados pueden acceder a esta tienda." + require_login_html: "Si ya es un cliente aprobado, %{login} o %{signup} para continuar. ¿Quiere empezar a comprar aquí? Por favor, %{contact} %{enterprise} y pregunte acerca de participar." require_customer_html: "Si desea comenzar a comprar aquí, por favor %{contact} %{enterprise} para preguntar acerca de incorporación." card_could_not_be_updated: La tarjeta no se pudo actualizar card_could_not_be_saved: la tarjeta no se pudo guardar - spree_gateway_error_flash_for_checkout: "Hubo un problema con tu información de pago: %{error}" + spree_gateway_error_flash_for_checkout: "Hubo un problema con su información de pago: %{error}" invoice_billing_address: "Dirección de facturación:" invoice_column_tax: "Impuesto sobre bienes y servicios" invoice_column_price: "Precio" invoice_column_item: "Artículo" invoice_column_qty: "Cantidad" - invoice_column_unit_price_with_taxes: "Precio unidad (Impuestos incl.)" - invoice_column_unit_price_without_taxes: "Precio unidad (Sin Impuestos)" - invoice_column_price_with_taxes: "Precio total (Impuestos incl.)" - invoice_column_price_without_taxes: "Precio total (Sin Impuestos)" - invoice_column_tax_rate: "% Impuestos" - invoice_tax_total: "IVA Total:" + invoice_column_unit_price_with_taxes: "Precio unidad (impuestos incl.)" + invoice_column_unit_price_without_taxes: "Precio unidad (sin impuestos)" + invoice_column_price_with_taxes: "Precio total (impuestos incl.)" + invoice_column_price_without_taxes: "Precio total (sin impuestos)" + invoice_column_tax_rate: "Tarifa de impuestos" + invoice_tax_total: "Total IVA:" tax_invoice: "FACTURA DE IMPUESTOS" tax_total: "Total impuestos (%{rate}):" - total_excl_tax: "Total (Sin Impuestos):" + total_excl_tax: "Total (sin impuestos):" total_incl_tax: "Total (Impuestos incl.)" abn: "NIF:" acn: "ACN:" invoice_issued_on: "Factura emitida el:" - order_number: "Número de Factura:" + order_number: "Número de factura:" date_of_transaction: "Fecha de la transacción:" ticket_column_qty: "Cantidad" ticket_column_item: "Artículo" @@ -1228,7 +1228,7 @@ es_CR: footer_email: "Correo electrónico" footer_links_md: "Enlaces" footer_about_url: "URL acerca de" - user_guide_link: "Enlace de la Guía de usuario" + user_guide_link: "Enlace de la guía de usuario" name: Nombre first_name: Nombre last_name: Apellido @@ -1236,14 +1236,14 @@ es_CR: phone: Teléfono next: Siguiente address: Dirección - address_placeholder: ej. Carrer Torrent de l'Olla - address2: Dirección (cont.) + address_placeholder: ej. Calle 7 de Plaza Alta + address2: Dirección (continuación) city: Ciudad - city_placeholder: ej. Barcelona + city_placeholder: ej. Alajuela postcode: Código postal postcode_placeholder: ej. 20307 suburb: Barrio - state: Estado + state: Provincia country: País unauthorized: No autorizado terms_of_service: "Términos de servicio" @@ -1252,15 +1252,15 @@ es_CR: not_allowed: No permitido no_shipping: Sin métodos de envío no_payment: Sin métodos de pago - no_shipping_or_payment: Sin envío ni métodos de pago + no_shipping_or_payment: sin envío ni métodos de pago unconfirmed: sin confirmar days: dias authorization_failure: "Fallo de autorización" label_shop: "Tienda" label_shops: "Tiendas" label_map: "Mapa" - label_producer: "Productora" - label_producers: "Productoras" + label_producer: "Productor" + label_producers: "Productores" label_groups: "Grupos" label_about: "Acerca de" label_connect: "Conectar" @@ -1277,7 +1277,7 @@ es_CR: label_more: "Mostrar más" label_less: "Mostrar menos" label_notices: "Noticias" - cart_items: "elementos" + cart_items: "Elementos" cart_headline: "Su carrito de compras" total: "Total" cart_updating: "Actualizando el carrito..." @@ -1360,26 +1360,26 @@ es_CR: learn_cta: "Inspírate" connect_body: "Busca en nuestros directorios de productoras, grupos u otras organizaciones. Haz una lista de tu organización en OFN para que los consumidores puedan encontrarte. Únete a la comunidad para obtener consejos y resolver problemas juntos." connect_cta: "Explorar" - system_headline: "Compras - cómo funcionan." + system_headline: "Compras - aquí está cómo funcionan." system_step1: "1. Buscar" - system_step1_text: "Busca comida local y de temporada en nuestras tiendas diversas e independientes. Busca por municipio y participa en un grupo de consumo." + system_step1_text: "Busque comida local y de temporada en nuestras tiendas diversas e independientes. Busque por cantón y categoría de comida o si prefiere entrega o recoger." system_step2: "2. Comprar" - system_step2_text: "Transforma tu consumo con comida local y asequible de diversas productoras ¡Conoce las historias detrás de tu comida y la gente que la hace!" + system_step2_text: "Transforme su consumo con comida local y asequible de diversos productores ¡Conoce las historias detrás de su comida y la gente que la hace!" system_step3: "3. Recogida" - system_step3_text: "Visita tu Grupo de Consumo para un vínculo más directo con las productoras y tus vecinos, también puedes comprar directamente a algunas productoras o centrales de compras. Compra tu comida de una manera tan diversa como la naturaleza." + system_step3_text: "Visite su productor para crear un vínculo más directo con los productores y sus vecinos, también puedes comprar directamente a algunos productores. Compre su comida de una manera tan diversa como la naturaleza." cta_headline: "Compras que hacen el mundo un mejor lugar." - cta_label: "Estoy lista" - stats_headline: "Entre todas creamos un nuevo sistema de producción, distribución y consumo." - stats_producers: "productoras" + cta_label: "Estoy listo" + stats_headline: "Entre todos creamos un nuevo sistema de producción, distribución y consumo." + stats_producers: "productores" stats_shops: "tiendas" - stats_shoppers: "consumidoras" + stats_shoppers: "consumidores" stats_orders: "pedidos" checkout_title: Validar el carrito checkout_now: Validar el carrito ahora checkout_order_ready: Pedido preparado para checkout_hide: Esconder checkout_expand: Expandir - checkout_headline: "Esta bien, ¿listo para realizar el pedido?" + checkout_headline: "Está bien, ¿listo para realizar el pedido?" checkout_as_guest: "Hacer pedido como invitado" checkout_details: "Sus detalles" checkout_billing: "Información de cobro" @@ -1392,7 +1392,7 @@ es_CR: checkout_instructions: "¿Algún comentario o intrucciones especiales?" checkout_payment: Pago checkout_send: Realizar pedido ahora - checkout_your_order: Tu pedido + checkout_your_order: Su pedido checkout_cart_total: Total del carrito checkout_shipping_price: Envío checkout_total_price: Total @@ -1416,8 +1416,8 @@ es_CR: order_hub_info: Información del centro de acopio order_back_to_store: Volver a la Tienda order_back_to_cart: Volver al Carrito - bom_tip: "Usa esta página para alterar la cantidad del producto en varios pedidos a la vez. Los productos pueden ser eliminados de los pedidos si es necesario. " - unsaved_changes_warning: "Hay cambios no guardados, se perderán si continúas." + bom_tip: "Use esta página para alterar la cantidad del producto en varios pedidos a la vez. Los productos pueden ser eliminados de los pedidos si es necesario. " + unsaved_changes_warning: "Hay cambios no guardados, se perderán si continúa." unsaved_changes_error: "Los campos con bordes rojos contienen errores." products: "Productos" products_in: "en %{oc}" @@ -1426,11 +1426,11 @@ es_CR: email_confirmed: "Gracias por confirmar la dirección de correo electrónico." email_confirmation_activate_account: "Antes de que podamos activar su nueva cuenta, necesitamos confirmar su dirección de correo electrónico." email_confirmation_greeting: "Hola, %{contact}!" - email_confirmation_profile_created: "¡Se creó un un perfil para %{name} con éxito! Para activar su Perfil necesitamos que confirme esta dirección de correos." + email_confirmation_profile_created: "¡Se creó un un perfil para %{name} con éxito! Para activar su Perfil necesitamos que confirme esta dirección de correo." email_confirmation_click_link: "Por favor haga clic en el enlace de abajo para confirmar el correo electrónico y continuar configurando su perfil." email_confirmation_link_label: "Confirmar este correo electrónico »" - email_confirmation_help_html: "Después de confirmar el correo electrónico puedes acceder a tu cuenta de administración para esta organización. Visita %{link} para encontrar más información sobre las características de %{sitename} y empieza a usar tu perfil o tienda online." - email_confirmation_notice_unexpected: "Recibes este mensaje porque te has registrado en %{sitename} o has sido invitado a inscribirte por alguien que probablemente conozcas. Si no entiendes por qué estás recibiendo este correo electrónico, escribe a %{contact}." + email_confirmation_help_html: "Después de confirmar el correo electrónico puede acceder a su cuenta de administración para esta organización. Visite %{link} para encontrar más información sobre las características de %{sitename} y empiece a usar su perfil o tienda en línea." + email_confirmation_notice_unexpected: "Recibe este mensaje porque se ha registrado en %{sitename} o ha sido invitado a inscribirse por alguien que probablemente conozca. Si no entiende por qué está recibiendo este correo electrónico, escriba a %{contact}." email_social: "Conecte con nosotros:" email_contact: "Envíenos un correo electrónico:" email_signoff: "Saludos," @@ -1438,7 +1438,7 @@ es_CR: email_confirm_customer_greeting: "Hola %{name}," email_confirm_customer_intro_html: "¡Gracias por comprar en %{distributor}!" email_confirm_customer_number_html: "Confirmación del pedido #%{number}" - email_confirm_customer_details_html: "Aquí están los detalles de tu pedido de %{distributor}:" + email_confirm_customer_details_html: "Aquí están los detalles de su pedido de %{distributor}:" email_confirm_customer_signoff: "Saludos cordiales," email_confirm_shop_greeting: "Hola %{name}," email_confirm_shop_order_html: "¡Bien! ¡Tiene un nuevo pedido en %{distributor}!" @@ -1461,9 +1461,9 @@ es_CR: email_so_placement_explainer_html: "Esta orden se creó automáticamente para usted." email_so_edit_true_html: "Puede realizar cambios hasta que los pedidos se cierren en %{orders_close_at}." email_so_edit_false_html: "Puede ver detalles de este pedido en cualquier momento." - email_so_contact_distributor_html: "Si tiene alguna pregunta, puede contactar %{distributor} a través de %{email}." - email_so_contact_distributor_to_change_order_html: "Has creado este pedido automáticamente. Puedes realizar cambios hasta que los pedidos se cierren en %{orders_close_at} contactando %{distributor} a través de %{email}." - email_so_confirmation_intro_html: "Tu pedido con %{distributor} ahora está confirmado" + email_so_contact_distributor_html: "Si tiene alguna pregunta, puede contactar a %{distributor} a través de %{email}." + email_so_contact_distributor_to_change_order_html: "Has creado este pedido automáticamente. Puedes realizar cambios hasta que los pedidos se cierren en %{orders_close_at} contactando a %{distributor} a través de %{email}." + email_so_confirmation_intro_html: "Su pedido con %{distributor} ahora está confirmado" email_so_confirmation_explainer_html: "Este pedido fue colocado automáticamente para usted, y ahora ha sido finalizado." email_so_confirmation_details_html: "Aquí encontrará todo lo que necesita saber sobre su pedido en %{distributor} :" email_so_empty_intro_html: "Intentamos realizar un nuevo pedido con %{distributor} , pero tuvimos algunos problemas ..." @@ -1471,7 +1471,7 @@ es_CR: email_so_empty_details_html: "Aquí están los detalles del pedido no realizado para %{distributor} :" email_so_failed_payment_intro_html: "Intentamos procesar un pago, pero tuvimos algunos problemas ..." email_so_failed_payment_explainer_html: "El pago de su suscripción con %{distributor} ha fallado debido a un problema con su tarjeta de crédito. %{distributor} ha recibido notificación de este pago fallido." - email_so_failed_payment_details_html: "Aquí están los detalles del fallo proporcionados por la pasarela de pago:" + email_so_failed_payment_details_html: "Aquí están los detalles del fallo proporcionados por la plataforma de pago:" email_shipping_delivery_details: Detalles de entrega email_shipping_delivery_time: "Entregar en:" email_shipping_delivery_address: "Dirección de entrega:" @@ -1480,11 +1480,11 @@ es_CR: email_shipping_collection_instructions: "Instrucciones de recolección:" email_special_instructions: "Sus notas:" email_signup_greeting: ¡Hola! - email_signup_welcome: "Bienvenido a %{sitename}!" - email_signup_confirmed_email: "Gracias por confirmar su email." + email_signup_welcome: "¡Bienvenido a %{sitename}!" + email_signup_confirmed_email: "Gracias por confirmar su correo electrónico." email_signup_shop_html: "Ahora puedes iniciar sesión en %{link}." email_signup_text: "Gracias por unirse a la red. Si es un comprador, ¡esperamos presentarle a muchos agricultores, grupos de consumo y comida deliciosa! Si es un productor o forma parte de una organización de alimentos, estamos emocionados de que forme parte de la red." - email_signup_help_html: "Agradecemos todas tus preguntas y feedback; puedes usar el botón de Enviar Feedback en el sitio o escribir un email a %{email}" + email_signup_help_html: "Agradecemos todas tus preguntas y retroalimentación; puedes usar el botón de Enviar retroalimenación en el sitio o escribir un correo electrónico a %{email}" invite_email: greeting: "¡Hola!" invited_to_manage: "Ha sido invitado a administrar %{enterprise} en %{instance}." @@ -1494,7 +1494,7 @@ es_CR: producer_mail_greeting: "Estimada" producer_mail_text_before: "Ahora tenemos todas los pedidos de las consumidoras para la siguiente ronda." producer_mail_order_text: "Se muestra un resumen de los pedidos de tus productos:" - producer_mail_delivery_instructions: "Instrucciones de recogida/entrega de stock:" + producer_mail_delivery_instructions: "Instrucciones de recogida/entrega de inventario:" producer_mail_signoff: "Gracias y hasta pronto" shopping_oc_closed: Los pedidos están cerrados shopping_oc_closed_description: "Por favor espere hasta que el próximo ciclo abra (o contactanos de forma directa para ver si podemos aceptar algunos pedidos tardíos)" @@ -1509,11 +1509,11 @@ es_CR: shopping_contact_web: "Contacto" shopping_contact_social: "Seguir" shopping_groups_part_of: "es parte de:" - shopping_producers_of_hub: "productoras de %{hub}:" + shopping_producers_of_hub: "productores de %{hub}:" enterprises_next_closing: "Los pedidos se cerrarán" enterprises_ready_for: "Listo para" enterprises_choose: "Hay más de un ciclo abierto. Escoge en cuál quieres realizar el pedido:" - maps_open: "Abierta" + maps_open: "Abierto" maps_closed: "Cerrado" hubs_buy: "Comprar:" hubs_shopping_here: "Comprando aquí" @@ -1522,7 +1522,7 @@ es_CR: hubs_delivery_options: "Opciones de entrega" hubs_pickup: "Recoger" hubs_delivery: "Entrega" - hubs_producers: "Nuestras productoras" + hubs_producers: "Nuestros productores" hubs_filter_by: "Filtrar por" hubs_filter_type: "Tipo" hubs_filter_delivery: "Entrega" @@ -1539,7 +1539,7 @@ es_CR: products_showing: "Mostrando:" products_or: "Ó" products_with: con - products_search: "Buscar por producto o productora" + products_search: "Buscar por producto o productor" products_loading: "Cargando productos..." products_updating_cart: "Actualizando su carrito..." products_cart_empty: "Carrito vacío" @@ -1921,6 +1921,7 @@ es_CR: admin_enterprise_relationships_permits: "Permite" admin_enterprise_relationships_seach_placeholder: "Buscar" admin_enterprise_relationships_button_create: "Crear" + admin_enterprise_relationships_to: "para" admin_enterprise_groups: "Grupos de organizaciones" admin_enterprise_groups_name: "Nombre" admin_enterprise_groups_owner: "Propietaria" @@ -2318,11 +2319,11 @@ es_CR: oh_no: "¡Vaya! No se ha podido guardar los cambios." unauthorized: "No estás autorizado a acceder a esta página." error: Error - unavailable: No Disponible + unavailable: No disponible profile: Perfil hub: Grupo shop: Tienda - choose: Escoger + choose: Escoge resolve_errors: Resuelve los siguientes errores more_items: "+ %{count} Más" default_card_updated: Tarjeta predeterminada actualizada @@ -2334,7 +2335,7 @@ es_CR: invite: "Invitar" invite_title: "Invitar a un usuario no registrado" tag_rule_help: - title: Reglas de las Etiquetas + title: Reglas de las etiquetas overview: Visión general overview_text: > Las reglas de etiqueta proporcionan una manera de describir qué elementos @@ -2384,7 +2385,7 @@ es_CR: Haga click en una opción para ver información más detallada acerca de cada perfil, y pulse el botón rojo GUARDAR cuando hayas terminado. profile_only: Solo perfil - profile_only_cost: "COSTE: GRATUITO PARA SIEMPRE" + profile_only_cost: "COSTO: GRATUITO PARA SIEMPRE" profile_only_text1: >+ El perfil te hace visible y permite que las personas te puedan contactar. Es una manera de aportar la máxima transparencia y explicar tu historia. @@ -2393,12 +2394,12 @@ es_CR: Si prefieres concentrarte en producir alimentos y deseas dejar el trabajo de venderlo a otras personas, no necesitas una tienda en Open Food Network. profile_only_text3: > - Añade tus productos a Open Food Network, permitiendo a los Grupos de - Consumo vender tus productos. - producer_shop: Tienda Productora + Añade tus productos a Open Food Network (LaFeriaCR), permitiendo a los + Hubs vender tus productos. + producer_shop: Tienda de productor producer_shop_text1: > Vende tus productos directamente a los consumidores con tu tienda en - Open Food Network. + Open Food Network (LaFeriaCR). producer_shop_text2: > Una tienda de productora es para tu producto solamente, si quieres vender productos de otros productores, selecciona 'Grupo de Productores'. @@ -2408,42 +2409,42 @@ es_CR: Agrega productos tuyos o de otras organizaciones y véndelo a través de tu tienda en Open Food Network. producer_hub_text2: > - Los Grupos de Productoras pueden tener diferentes finalidades, ya sea - una cooperativa de alimentos, un grupo de consumo, un supermercado local, - ... + Los Hubs de Productoras pueden tener diferentes finalidades, ya sea + una cooperativa de alimentos, un grupo de consumo o un supermercado + local. producer_hub_text3: > - Open Food Network tiene como objetivo apoyar tantos modelos de organizaciones - como sea posible, queremos aportarte las herramientas que necesites - para poner en marcha tu organización. + Open Food Network (LaFeriaCR) tiene como objetivo apoyar tantos modelos + de organizaciones como sea posible, queremos aportarte las herramientas + que necesites para poner en marcha tu organización. get_listing: Obtener un listado always_free: SIEMPRE GRATIS - sell_produce_others: Vender la producción de otros + sell_produce_others: Vende la producción de otros sell_own_produce: Vende tu propia producción. sell_both: Vende tu propia producción y la de otros enterprise_producer: - producer: Productora + producer: Productor producer_text1: > Los productores pueden crear cosas deliciosas para comer o beber. Usted es un productor si cultiva, mejora, fermenta, ordeña o moldea. producer_text2: > - Las Productoras pueden también realizar otras acciones, como agregar + Los Productores pueden también realizar otras acciones, como agregar productos de otras organizaciones y venderlos a través de su tienda - en Open Food Network. - non_producer: No-productora + en Open Food Network (LaFeriaCR). + non_producer: No-productor non_producer_text1: > - Las no-productoras no producen alimentos por si mismas, lo que significa + Los no-productores no producen alimentos por si mismos, lo que significa que no pueden crear sus propios productos para ofrecerlos a través de - Open Food Network. + Open Food Network (LaFeriaCR). non_producer_text2: > - En cambio, las no-productoras se especializan en vincular a las productoras - con los consumidores finales, ya sea entregando, empaquetando, vendiendo + En cambio, los no-productores se especializan en vincular a los productores + con los consumidores finales, ya sea entregando, empaquetando o vendiendo alimentos. - producer_desc: Productoras - producer_example: ej. AGRICULTORES, PRODUCTORAS + producer_desc: Productores + producer_example: ej. AGRICULTORES, PRODUCTORES non_producer_desc: Todas las demás organizaciones - non_producer_example: ej. Grupos de consumo, Tiendas de proximidad, ... + non_producer_example: ej. Grupos de consumo, tiendas cercanas, ... enterprise_status: - status_title: "%{name} está configurado y listo para funcionar!" + status_title: "¡%{name} está configurado y listo para funcionar!" severity: Gravedad description: Descripción resolve: Resolver @@ -2478,12 +2479,12 @@ es_CR: order_state: address: "dirección" adjustments: "ajustes" - awaiting_return: "Esperando retorno" + awaiting_return: "esperando devolución" canceled: "cancelado" cart: "carrito" complete: "completar" - confirm: "Confirmar" - delivery: "Entrega" + confirm: "confirmar" + delivery: "entrega" paused: "pausado" payment: "pago" pending: "pendiente" @@ -2494,7 +2495,7 @@ es_CR: backorder: "orden pendiente" partial: "parcial" pending: "pendiente" - ready: "Listo" + ready: "listo" shipped: "enviado" canceled: "cancelado" payment_states: @@ -2511,8 +2512,8 @@ es_CR: resend_user_email_confirmation: resend: "Reenviar" sending: "Reenviar..." - done: "Reenvio hecho ✓" - failed: "Reenvio fallido ✗" + done: "Reenvío hecho ✓" + failed: "Reenvío fallido ✗" order_cycles: schedules: adding_a_new_schedule: "Agregar una nueva programación" @@ -2524,7 +2525,7 @@ es_CR: created_schedule: "Programación creada" updated_schedule: "Programación actualizada" deleted_schedule: "Programación eliminada" - name_required_error: "Por favor ingrese un nombre para esta programación" + name_required_error: "Por favor ingrese un nombre para este horario" no_order_cycles_error: "Seleccione al menos un ciclo de pedido (arrastrar y soltar)" available: "Disponible" selected: "Seleccionado" @@ -2533,40 +2534,40 @@ es_CR: add_customer: "Añadir cliente" add_a_new_customer_for: "Añadir un nuevo cliente para %{shop_name}" customer_placeholder: "cliente@ejemplo.org" - valid_email_error: "Introduce un email válido" + valid_email_error: "Introduce un correo electrónico válido" subscriptions: - error_saving: "Error al salvar suscripción " + error_saving: "Error al guardar suscripción " new: please_select_a_shop: "Por favor seleccione una tienda" - insufficient_stock: "Stock insuficiente disponible, solo quedan %{on_hand}" + insufficient_stock: "Inventario insuficiente disponible, solo quedan %{on_hand}" out_of_stock: reduced_stock_available: Inventario reducido disponible out_of_stock_text: > - Mientras estabas comprando, los niveles de stock para uno o más de los productos - de tu carrito se han reducido. Aquí está lo que ha cambiado: - now_out_of_stock: está ahora fuera de stock. - only_n_remainging: "Solo quedan %{num} ." + Mientras usted estaba comprando, los niveles de inventario para uno o más + de los productos de su carrito se han reducido. Aquí está lo que ha cambiado: + now_out_of_stock: está ahora fuera de inventario. + only_n_remainging: "ahora solo hay %{num} restantes." variants: on_demand: 'yes': "Bajo demanda" variant_overrides: on_demand: - use_producer_settings: "Utilizar la configuración de estoc de la productora." + use_producer_settings: "Utilizar la configuración de inventario del productor." 'yes': "Sí" 'no': "No" inventory_products: "Productos del Inventario" hidden_products: "Productos ocultos" new_products: "Nuevos productos" - reset_stock_levels: Restablecer niveles de stock a valores predeterminados - changes_to: Cambios a - one_override: Una se ha sobrescrito + reset_stock_levels: Restablecer niveles de inventario a valores predeterminados + changes_to: Cambia a + one_override: Una sobreescritura overrides: sobrescribe - remain_unsaved: Permanecen sin guardar. - no_changes_to_save: No hay cambios para guardar. ' + remain_unsaved: permanecen sin guardar. + no_changes_to_save: 'No hay cambios para guardar. ' no_authorisation: "No se ha podido obtener autorización para guardar estos cambios, por lo que no se guardarán." some_trouble: "Han habido algunos problemas al guardar: %{errors}" - changing_on_hand_stock: Cambiando los niveles de stock... - stock_reset: Reset Stock a valores por defecto + changing_on_hand_stock: Cambiando los niveles de inventario.. + stock_reset: Restablecer inventario a valores por defecto tag_rules: show_hide_variants: 'Mostrar u ocultar variantes en mi tienda' show_hide_shipping: 'Mostrar u ocultar los métodos de envío al comprar' @@ -2586,15 +2587,15 @@ es_CR: could_not_delete_customer: 'No se pudo eliminar al cliente' product_import: confirmation: | - Esto establecerá el nivel de stock a cero en todos los productos para este - organización no está presente en el archivo subido. + Esto establecerá el nivel de stock a cero en todos los productos para esta + organización que no están presentes en el archivo subido. order_cycles: create_failure: "Error al crear el ciclo de pedido" update_success: 'Se ha actualizado su ciclo de pedido.' update_failure: "Error al actualizar el ciclo de pedido" no_distributors: No hay distribuidores en este ciclo de pedido. Este ciclo de pedido no será visible para las consumidoras hasta que agregues uno. ¿Deseas continuar guardando este ciclo de pedido? ' enterprises: - producer: "Productora" + producer: "Productor" non_producer: "No productor" customers: select_shop: 'Seleccione primero una tienda' @@ -2607,7 +2608,7 @@ es_CR: users: order: "Pedido" registration: - welcome_to_ofn: "Bienvenida a Open Food Network!" + welcome_to_ofn: "¡Bienvenido a Open Food Network (LaFeriaCR)!" signup_or_login: "Empieza registrándose (o iniciando sesión)" have_an_account: "¿Ya tiene una cuenta?" action_login: "Inicie sesión ahora." @@ -2686,7 +2687,7 @@ es_CR: other: "sacos" producers: signup: - start_free_profile: "Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" + start_free_profile: "¡Empieze con un perfil gratuito, y amplíelo cuando esté preparado!" order_management: reports: enterprise_fee_summary: @@ -2751,7 +2752,7 @@ es_CR: start: "Inicio" end: "Final" stop: "Detener" - first: "primero" + first: "Primero" previous: "Anterior" last: "Último" spree: @@ -2766,7 +2767,9 @@ es_CR: location: "Ubicación" count_on_hand: "Cuenta de disponibilidad" quantity: "Cantidad" - package_from: "perfil de" + on_demand: "Bajo demanda" + on_hand: "Disponibles" + package_from: "paquete de" item_description: "Descripción del artículo" price: "Precio" total: "Total" @@ -2783,9 +2786,9 @@ es_CR: billing_address: "Dirección de facturación" shipping_address: "Dirección de envío" first_name: "Nombre" - last_name: "Apellido" + last_name: "Apellidos" street_address: "Dirección" - street_address_2: "Dirección (cont.)" + street_address_2: "Dirección (continuada)" city: "Ciudad" zip: "Código postal" country: "País" @@ -2808,11 +2811,11 @@ es_CR: default_meta_keywords: "Palabras clave Meta predeterminadas" security_settings: "Configuraciones de seguridad" allow_ssl_in_development_and_test: "Permitir el uso de SSL en los modos de desarrollo y prueba" - allow_ssl_in_production: "Permitir que SSL se utilice en modo de producción" + allow_ssl_in_production: "Permitir el uso de SSL modo de producción" allow_ssl_in_staging: "Permitir que SSL se utilice en modo de staging" currency_decimal_mark: "Marca decimal de la moneda" currency_settings: "Ajustes de moneda" - currency_symbol_position: ¿Poner "símbolo de moneda antes o después de la cantidad?" + currency_symbol_position: ¿Poner "símbolo" de moneda antes o después de la cantidad? currency_thousands_separator: "Separador de miles de la moneda" hide_cents: "Ocultar céntimos" display_currency: "Mostrar moneda" @@ -2834,7 +2837,7 @@ es_CR: smtp_authentication_type: "Tipo de autenticación SMTP" smtp_username: "Nombre de usuario SMTP" smtp_password: "Contraseña SMTP" - image_settings: "Ajustes de imagen" + image_settings: "Ajustes de imágen" image_settings_warning: "Deberá regenerar las miniaturas si actualiza los estilos de paperclip. Utilize rake paperclip:refresh:thumbnails CLASS=Spree::Image para hacer esto." attachment_default_style: Estilo de los archivos adjuntos attachment_default_url: "URL predeterminada de los archivos adjuntos" @@ -2846,45 +2849,45 @@ es_CR: tax_categories: "Categorías de impuestos" listing_tax_categories: "Listado de categorías de impuestos" back_to_tax_categories_list: "Volver a la lista de categorías de impuestos" - tax rate: "% Impuestos" - new_tax_rate: "Nuevo impuesto" + tax rate: "Tarifas de impuesto" + new_tax_rate: "Nueva tarifa de impuesto" tax_category: "Categoría de impuestos" rate: "Impuesto" - tax_rate_amount_explanation: "Las tasas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" + tax_rate_amount_explanation: "Las tarifas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" included_in_price: "Incluido en el precio" - show_rate_in_label: "Mostrar impuesto en la etiqueta" - back_to_tax_rates_list: "Volver a la lista de impuestos" + show_rate_in_label: "Mostrar tarifa en la etiqueta" + back_to_tax_rates_list: "Volver a la lista de tarifas de impuestos" tax_settings: "Configuración de Impuestos" zones: "Zonas" new_zone: "Nueva zona" - default_tax: "Impuesto por Defecto" + default_tax: "Impuesto por defecto" default_tax_zone: "Zona de impuestos predeterminada" country_based: "Basado en el país" - state_based: "Basado en el estado" + state_based: "Basado en la provincia" countries: "Países" listing_countries: "Listado de países" - iso_name: "Nombre ISO" - states_required: "Estados requeridos" + iso_name: "Nombre de ISO" + states_required: "Provincias requeridas" editing_country: "Editar país" back_to_countries_list: "Volver a la lista de países" - states: "Estados" + states: "Provincias" abbreviation: "Abreviatura" - new_state: "Nuevo estado" - payment_methods: "Métodos de Pago" + new_state: "Nueva provincia" + payment_methods: "Métodos de pago" new_payment_method: "Nuevo método de pago" provider: "Proveedor" - taxonomies: "Taxonomias" + taxonomies: "Taxonomías" new_taxonomy: "Nueva taxonomía" - back_to_taxonomies_list: "Volver a la Lista de Taxonomías" + back_to_taxonomies_list: "Volver a la lista de taxonomías" shipping_methods: "Métodos de envío" shipping_categories: "Categorías de envío" new_shipping_category: "Nueva categoría de envío" back_to_shipping_categories: "Volver a las categorías de envío" - analytics_trackers: "Analizadores de seguimiento" + analytics_trackers: "Rastreador de analizador" no_trackers_found: "No se encontraron rastreadores" new_tracker: "Nuevo rastreador" add_one: "Agrega uno" - google_analytics_id: "ID d'Analytics" + google_analytics_id: "ID de analizador" back_to_trackers_list: "Volver a la lista de rastreadores" name: "Nombre" description: "Descripción" @@ -2905,35 +2908,35 @@ es_CR: currency: "Moneda" first_item: "Costo del primer artículo" additional_item: "Costo del artículo adicional" - max_items: "Max Artículos" + max_items: "Max. artículos" minimal_amount: "Cantidad mínima" normal_amount: "Cantidad normal" - discount_amount: "Importe de descuento" + discount_amount: "Cantidad de descuento" no_images_found: "No se encontraron imágenes " - new_image: "Nueva Imagen" + new_image: "Nueva imágen" filename: "Nombre de archivo" - alt_text: "Texto Alternativo" + alt_text: "Texto alternativo" thumbnail: "Miniatura" - back_to_images_list: "Volver a lista de imágenes " - email: Email - account_updated: "Cuenta actualizada!" + back_to_images_list: "Volver a la lista de imágenes " + email: Correo electrónico + account_updated: "¡Cuenta actualizada!" email_updated: "La cuenta se actualizará una vez que se confirme el nuevo correo electrónico." my_account: "Mi cuenta" date: "Fecha" time: "Hora" inventory_error_flash_for_insufficient_quantity: "Un artículo de su carrito ya no está disponible." inventory: Inventario - zipcode: Código Postal + zipcode: Código postal weight: Peso (en kg) error_user_destroy_with_orders: "Los usuarios con pedidos completados no pueden ser eliminados" - cannot_create_payment_without_payment_methods: "No se puede crear un pago para una orden sin un medio de pago definido" - please_define_payment_methods: "por favor definir métodos de pago" + cannot_create_payment_without_payment_methods: "No se puede crear un pago para una orden sin un método de pago definido." + please_define_payment_methods: "Por favor definir métodos de pago primero." options: "Opciones" actions: update: "Actualizar" errors: messages: - blank: "no puede estar vacío" + blank: "no puede estar en blanco" layouts: admin: header: @@ -2950,32 +2953,32 @@ es_CR: variant_overrides: "Inventario" reports: "Reportes" configuration: "Configuración" - users: "Usuarias" + users: "Usuarios" roles: "Roles" order_cycles: "Ciclos de Pedido" enterprises: "Organizaciones" enterprise_relationships: "Permisos" - customers: "Consumidoras" + customers: "Cliente" groups: "Grupos" product_properties: index: inherits_properties_checkbox_hint: "¿Heredar propiedades desde %{supplier}? (a menos que sea anulado arriba)" - add_product_properties: "Agregar Propiedades del producto" - select_from_prototype: "seleccionar de prototipo" + add_product_properties: "Agregar propiedades del producto" + select_from_prototype: "Seleccionar de prototipo" properties: index: properties: "Propiedades" new_property: "Nueva propiedad" name: "Nombre" - presentation: "presentación" + presentation: "Presentación" new: new_property: "Nueva propiedad" edit: - editing_property: "Editar Propiedad" - back_to_properties_list: "volver a lista de propiedades" + editing_property: "Editar propiedad" + back_to_properties_list: "Volver a lista de propiedades" form: name: "Nombre" - presentation: "presentación" + presentation: "Presentación" return_authorizations: index: new_return_authorization: "Nueva autorización de devolución" @@ -2988,35 +2991,35 @@ es_CR: continue: "Continuar" new: new_return_authorization: "Nueva autorización de devolución" - back_to_return_authorizations_list: "Back To Return Authorization List" + back_to_return_authorizations_list: "Volver a lista de autorización de devolución" continue: "Continuar" edit: receive: "recibir" are_you_sure: "¿Está seguro?" - return_authorization: "volver a autorización" + return_authorization: "Autorización de devolución" form: product: "Producto" - quantity_shipped: "cantidad enviada" + quantity_shipped: "Cantidad enviada" quantity_returned: "Cantidad devuelta" - return_quantity: "cantidad a devolver" + return_quantity: "Cantidad a devolver" amount: "Cantidad" rma_value: "Valor RMA" - reason: "razón" - stock_location: "localización de inventario" + reason: "Razón" + stock_location: "Ubicación de inventario" states: - authorized: "autorizado" - received: "recibido" - canceled: "cancelado" + authorized: "Autorizado" + received: "Recibido" + canceled: "Cancelado" orders: index: - listing_orders: "Pedidos de listado" + listing_orders: "Listado de pedidos" new_order: "Nuevo pedido" capture: "Captura" ship: "Envío" edit: "Editar" order_not_updated: "El pedido no se pudo actualizar" note: "Nota" - first: "primero" + first: "Primero" last: "Último" previous: "Anterior" next: "Siguiente" @@ -3038,18 +3041,18 @@ es_CR: code: "Código" from: "De" to: "Facturar a" - shipping: "envío" + shipping: "Envío" form: distribution_fields: title: "Distribución" - distributor: "Distribuidora:" + distributor: "Distribuidor:" order_cycle: "Ciclo de pedido:" line_item_adjustments: "Ajustes de artículo" order_adjustments: "Ajustes de pedido" order_total: "Total del pedido" overview: enterprises_header: - ofn_with_tip: Las Organizaciones son Productoras y/o Grupos y son la unidad básica de organización dentro de la Open Food Network. + ofn_with_tip: Las organizaciones son productores y/o grupos y son la unidad básica de organización dentro de Open Food Network. products: active_products: zero: "No tienes ningún producto activo" @@ -3068,7 +3071,7 @@ es_CR: shipping_methods: "Métodos de envío" new_shipping_method: "Nuevo método de envío" name: "Nombre" - products_distributor: "Distribuidora" + products_distributor: "Distribuidor" zone: "Zona" calculator: "Calculadora" display: "Mostrar" @@ -3103,11 +3106,11 @@ es_CR: request_failed_msg: Lo sentimos. Algo salió mal al intentar verificar los detalles de la cuenta con Stripe ... account_missing_msg: No existe una cuenta Stripe para esta organización. connect_one: Connect One - access_revoked_msg: El acceso a esta cuenta de Stripe ha sido anulado, por favor, vuelve a conectar tu cuenta. + access_revoked_msg: El acceso a esta cuenta de Stripe ha sido anulado, por favor, vuelva a conectar su cuenta. status: Estado connected: Conectado - account_id: Account ID - business_name: Nombre de la Organización + account_id: ID de cuenta + business_name: Nombre de la organización charges_enabled: Cargos habilitados payments: source_forms: @@ -3115,12 +3118,12 @@ es_CR: error_saving_payment: Error al guardar el pago submitting_payment: Enviando pago... products: - image_upload_error: "La imagen del producto no fue reconocida. Por favor, cargue una imagen en formato PNG o JPG." + image_upload_error: "La imágen del producto no fue reconocida. Por favor, cargue una imágen en formato PNG o JPG." new: title: "Nuevo producto" new_product: "Nuevo producto" - supplier: "Proveedora" - product_name: "nombre del producto" + supplier: "Proveedor" + product_name: "Nombre del producto" units: "Unidad de medida" value: "Valor" unit_name: "Nombre de la unidad" @@ -3128,16 +3131,16 @@ es_CR: on_hand: "Disponibles" on_demand: "Bajo demanda" product_description: "Descripción del producto" - image: "Imagen" + image: "Imágen" or: "o" - unit_name_placeholder: 'ej. manojos' + unit_name_placeholder: 'ej. racimos' index: header: - title: Editar varios Productos + title: Editar productos por volumen indicators: title: CARGANDO PRODUCTOS - no_products: "Todavía no hay productos. Añade algunos antes" - no_results: "No se han encontrado resultados" + no_products: "Todavía no hay productos ¿Por qué no añades algunos?" + no_results: "Disculpa, no se han encontrado resultados" products_head: name: Nombre unit: Unidad @@ -3146,17 +3149,17 @@ es_CR: tax_category: Categoría de impuestos inherits_properties?: ¿Hereda propiedades? available_on: Disponible en - av_on: "Av. En" + av_on: "Disp. en" import_date: "Fecha de importación" products_variant: variant_has_n_overrides: "Esta variante tiene %{n} override(s)" new_variant: "Nueva variante" - product_name: nombre del producto + product_name: Nombre del producto primary_taxon_form: - product_category: categoría del producto + product_category: Categoría del producto group_buy_form: - group_buy: "¿Agrupado por?" - bulk_unit_size: Tamaño de la unidad a granel + group_buy: "¿Compra grupal?" + bulk_unit_size: Tamaño de la unidad por volumen display_as: display_as: Mostrar como reports: @@ -3177,20 +3180,20 @@ es_CR: select_and_search: "Seleccione los filtros y haga clic en GENERAR REPORTE para acceder a sus datos." users: index: - listing_users: "Listado de Usuarias" - new_user: "Nueva usuaria" - user: "Usuaria" - enterprise_limit: "Límite de la Organización" + listing_users: "Listando usuarios" + new_user: "Nuevo usuario" + user: "Usuario" + enterprise_limit: "Límite de la organización" search: "Buscar" - email: "Email" + email: "Correo electrónico" edit: - editing_user: "Editando usuarias" - back_to_users_list: "Volver a la lista de usuarias" + editing_user: "Editando usuarios" + back_to_users_list: "Volver a la lista de usuarios" general_settings: "Configuración general" form: - email: "Email" + email: "Correo electrónico" roles: "Roles" - enterprise_limit: "Límite de la Organización" + enterprise_limit: "Límite de la organización" confirm_password: "Confirmar contraseña" password: "Contraseña" email_confirmation: @@ -3201,15 +3204,15 @@ es_CR: price: "Precio" options: "Opciones" no_results: "No hay resultados" - to_add_variants_you_must_first_define: "para agregar variantes, se debe primero definir" + to_add_variants_you_must_first_define: "Para agregar variantes, usted debe primero definir" option_types: "Tipos de opciones" - option_values: "valores de opción" + option_values: "Valores de opción" and: "y" new_variant: "Nueva Variante" - show_active: "mostrar activo" + show_active: "Mostrar activo" show_deleted: "Mostrar eliminados" new: - new_variant: "Nueva Variante" + new_variant: "Nueva variante" form: cost_price: "Precio de costo" sku: "SKU" @@ -3217,13 +3220,13 @@ es_CR: display_as: "Mostrar como" display_name: "Nombre para mostrar" autocomplete: - producer_name: "Productora" + producer_name: "Productor" unit: "Unidad" general_settings: edit: legal_settings: "Configuraciones legales" cookies_consent_banner_toggle: "Mostrar el banner de consentimiento de cookies" - privacy_policy_url: "Vínculo con la Política de privacidad" + privacy_policy_url: "Vínculo con la política de privacidad" enterprises_require_tos: "Las organizaciones deben aceptar los Términos del Servicio" cookies_policy_matomo_section: "Mostrar la sección de Matomo en la página de política de cookies" cookies_policy_ga_section: "Mostrar la sección de Google Analytics en la página de la política de cookies" @@ -3254,18 +3257,18 @@ es_CR: line_item: insufficient_stock: "Inventario insuficiente, solo quedan %{on_hand}" out_of_stock: "Agotado" - unavailable_item: "actualmente no disponible" + unavailable_item: "Actualmente no disponible" shipment_states: - backorder: orden pendiente + backorder: pedido pendiente partial: parcial pending: pendiente - ready: Listo + ready: listo shipped: enviado payment_states: - balance_due: saldo debido + balance_due: saldo en deuda completed: completado checkout: validar - credit_owed: crédito debido + credit_owed: crédito adeudado failed: fallido paid: pagado pending: pendiente @@ -3307,8 +3310,8 @@ es_CR: user_mailer: reset_password_instructions: request_sent_text: | - Se ha solicitado el cambio de tu contraseña. - Si tu no lo has solicitado simplemente ignora este email. + La solicitud de restablecer su contraseña se ha realizado. + Si usted no lo ha solicitado, ignora este correo electrónico. link_text: > Si has solicitado esta acción haz click en el siguiente enlace: issue_text: | From 52becf6abcacc65253cc5058c0f01de047cd93c0 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 11:44:46 +0100 Subject: [PATCH 162/166] Extract payment method logic from OrderPaymentFinder into the orders helper --- app/helpers/admin/orders_helper.rb | 4 ++++ app/services/order_payment_finder.rb | 10 +++++++--- app/views/spree/order_mailer/_payment.html.haml | 4 ++-- app/views/spree/shared/_order_details.html.haml | 4 ++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/helpers/admin/orders_helper.rb b/app/helpers/admin/orders_helper.rb index 9e16d27ed5..cbc31d6ba7 100644 --- a/app/helpers/admin/orders_helper.rb +++ b/app/helpers/admin/orders_helper.rb @@ -9,5 +9,9 @@ module Admin adjustment.originator_type == "Spree::ShippingMethod" end end + + def last_payment_method(order) + OrderPaymentFinder.new(order).last_payment&.payment_method + end end end diff --git a/app/services/order_payment_finder.rb b/app/services/order_payment_finder.rb index c28d0e139a..754be34a0f 100644 --- a/app/services/order_payment_finder.rb +++ b/app/services/order_payment_finder.rb @@ -1,7 +1,11 @@ # frozen_string_literal: true -module OrderPaymentFinder - def self.last_payment_method(order) +class OrderPaymentFinder + def initialize(order) + @order = order + end + + def last_payment # `max_by` avoids additional database queries when payments are loaded # already. There is usually only one payment and this shouldn't cause # any overhead compared to `order(:created_at).last`. Using `last` @@ -9,6 +13,6 @@ module OrderPaymentFinder # # We are not using `updated_at` because all payments are touched when the # order is updated and then all payments have the same `updated_at` value. - order.payments.max_by(&:created_at)&.payment_method + @order.payments.max_by(&:created_at) end end diff --git a/app/views/spree/order_mailer/_payment.html.haml b/app/views/spree/order_mailer/_payment.html.haml index 60fc1056f4..85ad234cda 100644 --- a/app/views/spree/order_mailer/_payment.html.haml +++ b/app/views/spree/order_mailer/_payment.html.haml @@ -8,7 +8,7 @@ = t :email_payment_summary %h4 = t :email_payment_method - %strong= OrderPaymentFinder.last_payment_method(@order)&.name + %strong= last_payment_method(@order)&.name %p - %em= OrderPaymentFinder.last_payment_method(@order)&.description + %em= last_payment_method(@order)&.description %p   diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index 22c8ccdf8f..f4861d8148 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -13,9 +13,9 @@ .pad .text-big = t :order_payment - %strong= OrderPaymentFinder.last_payment_method(order)&.name + %strong= last_payment_method(order)&.name %p.text-small.text-skinny.pre-line - %em= OrderPaymentFinder.last_payment_method(order)&.description + %em= last_payment_method(order)&.description .order-summary.text-small %strong From d482cccefec2139295bdbcf9286776566955c955 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 11:56:52 +0100 Subject: [PATCH 163/166] Use OrderPaymentFinder methods instead of payments.last and payments.pending.last --- app/controllers/checkout_controller.rb | 10 ++++--- app/services/order_payment_finder.rb | 26 +++++++++++++------ .../subscriptions/payment_setup.rb | 2 +- .../subscriptions/stripe_payment_setup.rb | 2 +- .../stripe_sca_payment_authorize.rb | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 26c566e9a6..47dbfc53b5 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -153,10 +153,12 @@ class CheckoutController < Spree::StoreController end def valid_payment_intent_provided? - params["payment_intent"]&.starts_with?("pi_") && - @order.state == "payment" && - @order.payments.last.state == "pending" && - @order.payments.last.response_code == params["payment_intent"] + return false unless params["payment_intent"]&.starts_with?("pi_") + + last_payment = OrderPaymentFinder.new(@order).last_payment + @order.state == "payment" && + last_payment&.state == "pending" && + last_payment&.response_code == params["payment_intent"] end def handle_redirect_from_stripe diff --git a/app/services/order_payment_finder.rb b/app/services/order_payment_finder.rb index 754be34a0f..54b19654a3 100644 --- a/app/services/order_payment_finder.rb +++ b/app/services/order_payment_finder.rb @@ -6,13 +6,23 @@ class OrderPaymentFinder end def last_payment - # `max_by` avoids additional database queries when payments are loaded - # already. There is usually only one payment and this shouldn't cause - # any overhead compared to `order(:created_at).last`. Using `last` - # without order is not deterministic. - # - # We are not using `updated_at` because all payments are touched when the - # order is updated and then all payments have the same `updated_at` value. - @order.payments.max_by(&:created_at) + last(@order.payments) + end + + def last_pending_payment + last(@order.pending_payments) + end + + private + + # `max_by` avoids additional database queries when payments are loaded + # already. There is usually only one payment and this shouldn't cause + # any overhead compared to `order(:created_at).last`. Using `last` + # without order is not deterministic. + # + # We are not using `updated_at` because all payments are touched when the + # order is updated and then all payments have the same `updated_at` value. + def last(payments) + payments.max_by(&:created_at) end end diff --git a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb index 1824247e37..6d90236466 100644 --- a/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/payment_setup.rb @@ -18,7 +18,7 @@ module OrderManagement private def create_payment - payment = @order.pending_payments.last + payment = OrderPaymentFinder.new(@order).last_pending_payment return payment if payment.present? @order.payments.create( diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb index 8bc7e4cb9e..37e3a097f3 100644 --- a/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_payment_setup.rb @@ -5,7 +5,7 @@ module OrderManagement class StripePaymentSetup def initialize(order) @order = order - @payment = @order.pending_payments.last + @payment = OrderPaymentFinder.new(@order).last_pending_payment end def call! diff --git a/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb b/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb index da8830ce70..ea4fbe5ce7 100644 --- a/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb +++ b/engines/order_management/app/services/order_management/subscriptions/stripe_sca_payment_authorize.rb @@ -5,7 +5,7 @@ module OrderManagement class StripeScaPaymentAuthorize def initialize(order) @order = order - @payment = @order.pending_payments.last + @payment = OrderPaymentFinder.new(@order).last_pending_payment end def call! From 42be6c905f2483182276eebfb4f146944eda01a3 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 13:02:12 +0100 Subject: [PATCH 164/166] Added spec for OrderPaymentFinder --- spec/services/order_payment_finder_spec.rb | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 spec/services/order_payment_finder_spec.rb diff --git a/spec/services/order_payment_finder_spec.rb b/spec/services/order_payment_finder_spec.rb new file mode 100644 index 0000000000..3d71d9a706 --- /dev/null +++ b/spec/services/order_payment_finder_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe OrderPaymentFinder do + let(:order) { create(:order_with_distributor) } + let(:finder) { OrderPaymentFinder.new(order) } + + context "when order has several non pending payments" do + let!(:failed_payment) { create(:payment, order: order, state: 'failed') } + let!(:complete_payment) { create(:payment, order: order, state: 'completed') } + + it "#last_payment returns the last payment" do + expect(finder.last_payment).to eq complete_payment + end + + it "#last_pending_payment returns nil" do + expect(finder.last_pending_payment).to be nil + end + end + + context "when order has a pending payment and a non pending payment" do + let!(:processing_payment) { create(:payment, order: order, state: 'processing') } + let!(:failed_payment) { create(:payment, order: order, state: 'failed') } + + it "#last_payment returns the last payment" do + expect(finder.last_payment).to eq failed_payment + end + + it "#last_pending_payment returns the pending payment" do + # a payment in the processing state is a pending payment + expect(finder.last_pending_payment).to eq processing_payment + end + + context "and an extra last pending payment" do + let!(:pending_payment) { create(:payment, order: order, state: 'pending') } + + it "#last_payment returns the last payment" do + expect(finder.last_payment).to eq pending_payment + end + + it "#last_pending_payment returns the pending payment" do + expect(finder.last_pending_payment).to eq pending_payment + end + end + end +end From 568e570b4bcb901c36b8f56f4e447d6ca21d6ece Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Sat, 18 Apr 2020 13:09:08 +0100 Subject: [PATCH 165/166] Move method to more generic helper to use it in mailers --- app/helpers/admin/orders_helper.rb | 4 ---- app/helpers/order_helper.rb | 7 +++++++ app/mailers/spree/order_mailer_decorator.rb | 1 + app/mailers/subscription_mailer.rb | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 app/helpers/order_helper.rb diff --git a/app/helpers/admin/orders_helper.rb b/app/helpers/admin/orders_helper.rb index cbc31d6ba7..9e16d27ed5 100644 --- a/app/helpers/admin/orders_helper.rb +++ b/app/helpers/admin/orders_helper.rb @@ -9,9 +9,5 @@ module Admin adjustment.originator_type == "Spree::ShippingMethod" end end - - def last_payment_method(order) - OrderPaymentFinder.new(order).last_payment&.payment_method - end end end diff --git a/app/helpers/order_helper.rb b/app/helpers/order_helper.rb new file mode 100644 index 0000000000..157ee212bb --- /dev/null +++ b/app/helpers/order_helper.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module OrderHelper + def last_payment_method(order) + OrderPaymentFinder.new(order).last_payment&.payment_method + end +end diff --git a/app/mailers/spree/order_mailer_decorator.rb b/app/mailers/spree/order_mailer_decorator.rb index bffc26ee46..fbf17013b8 100644 --- a/app/mailers/spree/order_mailer_decorator.rb +++ b/app/mailers/spree/order_mailer_decorator.rb @@ -2,6 +2,7 @@ Spree::OrderMailer.class_eval do helper HtmlHelper helper CheckoutHelper helper SpreeCurrencyHelper + helper OrderHelper include I18nHelper def cancel_email(order_or_order_id, resend = false) diff --git a/app/mailers/subscription_mailer.rb b/app/mailers/subscription_mailer.rb index e2216c01c9..0267e24ef4 100644 --- a/app/mailers/subscription_mailer.rb +++ b/app/mailers/subscription_mailer.rb @@ -1,6 +1,7 @@ class SubscriptionMailer < Spree::BaseMailer helper CheckoutHelper helper ShopMailHelper + helper OrderHelper include I18nHelper def confirmation_email(order) From bf16a101291cc66ef91529e02515d2e74b229018 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 23 Apr 2020 19:05:22 +0200 Subject: [PATCH 166/166] Update all locales with the latest Transifex translations --- config/locales/ar.yml | 2 + config/locales/ca.yml | 8 +- config/locales/de_DE.yml | 2 + config/locales/en_AU.yml | 2 + config/locales/en_BE.yml | 2 + config/locales/en_CA.yml | 2 + config/locales/en_DE.yml | 2 + config/locales/en_GB.yml | 2 + config/locales/en_NZ.yml | 2 + config/locales/en_PH.yml | 2 + config/locales/en_US.yml | 2 + config/locales/en_ZA.yml | 2 + config/locales/es.yml | 2 + config/locales/es_CR.yml | 190 +++++++++++++++++++------------------- config/locales/fil_PH.yml | 2 + config/locales/fr_BE.yml | 2 + config/locales/fr_CA.yml | 2 + config/locales/it.yml | 2 + config/locales/nb.yml | 2 + config/locales/nl_BE.yml | 2 + config/locales/pt.yml | 2 + config/locales/pt_BR.yml | 2 + config/locales/sv.yml | 2 + config/locales/tr.yml | 2 + 24 files changed, 144 insertions(+), 98 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index d0aa90278c..d364366dff 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -2725,6 +2725,8 @@ ar: location: "الموقع" count_on_hand: "الاعتماد على المتوفر" quantity: "الكمية" + on_demand: "على الطلب" + on_hand: "متوفر" package_from: "التعبئة من" item_description: "وصف السلعة" price: "السعر" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 40c6b80622..2ffb83cecc 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -669,9 +669,9 @@ ca: primary_producer: Productora principal? primary_producer_tip: Selecciona "Productora" si ets productora principal d'aliments. producer: Productora - any: Cap - none: No productora - own: Propi + any: Qualsevol + none: Cap + own: Propis sells: Ven sells_tip: "Cap: l'organització no ven als clients directament.
Propietari: l'organització ven productes propis als clients.
Qualsevol: l'organització pot vendre productes propis o d'altres empreses.
" visible_in_search: Visible a la cerca? @@ -2766,6 +2766,8 @@ ca: location: "Ubicació" count_on_hand: "Compte disponible" quantity: "Quantitat" + on_demand: "Sota demanda" + on_hand: "Disponibles" package_from: "perfil de" item_description: "Descripció de l'article" price: "Preu" diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index 5b6d318b8a..95764417ea 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -2765,6 +2765,8 @@ de_DE: location: "Ort" count_on_hand: "Zählen Sie zur Hand" quantity: "Menge" + on_demand: "Unbegrenzt" + on_hand: "Verfügbar" package_from: "Paket von" item_description: "Artikelbeschreibung" price: "Preis" diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index 2c658de1aa..47288e5a5e 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -2676,6 +2676,8 @@ en_AU: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index 348dbbbc9a..5be45d93e5 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -2632,6 +2632,8 @@ en_BE: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index 6c33563ca2..9e522830cd 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -2754,6 +2754,8 @@ en_CA: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index 2f7d28557a..711d8e4b30 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -2644,6 +2644,8 @@ en_DE: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index 948d6f0220..3f69dae27f 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -2766,6 +2766,8 @@ en_GB: location: "Location" count_on_hand: "Count In Stock" quantity: "Quantity" + on_demand: "Unlimited" + on_hand: "In Stock" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index 65eb93ef25..e54cc75239 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -2760,6 +2760,8 @@ en_NZ: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index 97ae33afaf..3d07dac662 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -2760,6 +2760,8 @@ en_PH: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index 93c675a0d1..507653ccb5 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -2753,6 +2753,8 @@ en_US: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "On Demand" + on_hand: "On Hand" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 74ecc774dc..bcc0f2e080 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -2645,6 +2645,8 @@ en_ZA: location: "Location" count_on_hand: "Count On Hand" quantity: "Quantity" + on_demand: "Unlimited" + on_hand: "In Stock" package_from: "package from" item_description: "Item Description" price: "Price" diff --git a/config/locales/es.yml b/config/locales/es.yml index 28cab71ad3..d287fba960 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2766,6 +2766,8 @@ es: location: "Ubicación" count_on_hand: "Cuenta de disponibilidad" quantity: "Cantidad" + on_demand: "Bajo demanda" + on_hand: "Disponibles" package_from: "perfil de" item_description: "Descripción del artículo" price: "Precio" diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index 4e726c2c76..151ed7be42 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -41,7 +41,7 @@ es_CR: after_orders_open_at: debe ser después de la fecha de apertura variant_override: count_on_hand: - using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de inventario de la productora" + using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque está usando la configuración de inventario del productor" on_demand_but_count_on_hand_set: "debe estar en blanco si es bajo demanda" limited_stock_but_no_count_on_hand: "debe estar especificado porque se ha definido un inventario limitado" activemodel: @@ -105,7 +105,7 @@ es_CR: spree_user: updated_not_active: "Su contraseña ha sido restablecida, pero su correo electrónico aún no ha sido confirmado." updated: "Su contraseña ha sido cambiada con éxito. Ya tienes la sesión iniciada." - send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." + send_instructions: "Recibirá un correo electrónico con instrucciones sobre cómo confirmar su cuenta en unos minutos." models: order_cycle: cloned_order_cycle_name: "COPIA DE %{order_cycle}" @@ -124,8 +124,8 @@ es_CR: email_welcome: "Bienvenido" email_registered: "ahora es parte de" email_userguide_html: "La Guía de Usuario con soporte detallado para configurar su Productora o Grupo de Consumo está aquí: %{link}" - userguide: "Guía de usuario de La Feria" - email_admin_html: "Puede administrar su cuenta iniciando sesión en %{link} o haciendo clic en el engrane arriba a la derecha de la página de inicio, y seleccionando Administración." + userguide: "Guía de usuario de Open Food Network (LaFeriaCR)" + email_admin_html: "Puede administrar su cuenta iniciando sesión en %{link} o haciendo clic en el engranaje arriba a la derecha de la página de inicio, y seleccionando Administración." admin_panel: "Panel de administración" email_community_html: "También tenemos un foro en línea para la discusión comunitaria relacionada con el software OFN y los retos únicos del funcionamiento de una organización de alimentación. Lo invitamos a unirse. Estamos evolucionando constantemente y su aporte en este foro le dará forma a lo que pase luego. %{link}" join_community: "Unirse a la comunidad" @@ -174,7 +174,7 @@ es_CR: explainer: El procesamiento automático de estas órdenes falló debido a un error. El error será mostrado en los casos en que sea posible. failed_payment: title: Error en el pago (%{count} pedidos) - explainer: El procesamiento automático del pago de estos pedidos falló debido a un error. El error ha sido listado donde a sido posible. + explainer: El procesamiento automático del pago de estos pedidos falló debido a un error. El error ha sido listado donde ha sido posible. other: title: Otros fallos (%{count} pedidos) explainer: El procesamiento automático de estas órdenes falló por un motivo desconocido. Esto no debería ocurrir, contáctanos si estás viendo esto. @@ -256,7 +256,7 @@ es_CR: invalid_payment_state: "Estado de pago no válido" filter_results: Filtrar resultados quantity: Cantidad - pick_up: Recogida + pick_up: Recoger copy: Copia change_my_password: "Cambiar mi contraseña" update_password: "Actualizar contraseña" @@ -264,8 +264,8 @@ es_CR: reset_password_token: token de restablecimiento de contraseña expired: ha expirado, por favor solicite una nueva back_to_payments_list: "Volver a la lista de pagos" - maestro_or_solo_cards: "Tarjetas Maestro/Solo" - backordered: "Reabastecido" + maestro_or_solo_cards: "Solo tarjetas MasterCard" + backordered: "Pedido pendiente" on hand: "Disponibles" ship: "Envío" actions: @@ -338,11 +338,11 @@ es_CR: enable_embedded_shopfronts: "Habilitar tiendas integradas" embedded_shopfronts_whitelist: "Lista de dominios externos permitidos" number_localization: - number_localization_settings: "Number Localization Settings" + number_localization_settings: "Configuración de ubicación de número" enable_localized_number: "Usar la logica internacional separador miles/decimales" invoice_settings: edit: - title: "Configuración de Factura" + title: "Configuración de factura" enable_invoices?: "Habilitar facturas?" invoice_style2?: "Utiliza el modelo de factura alternativo que incluye el desglose fiscal total por tipo de interés y tasa de impuestos por artículo (todavía no es adecuado para países que muestran los precios sin impuestos)" enable_receipt_printing?: "¿Mostrar opciones para imprimir recibos usando impresoras térmicas en el desplegable del pedido?" @@ -356,8 +356,8 @@ es_CR: status: Estado ok: Ok instance_secret_key: Clave secreta de instancia - account_id: Account ID - business_name: Nombre de la Organización + account_id: ID de cuenta + business_name: Nombre de la organización charges_enabled: Cargos habilitados charges_enabled_warning: "Advertencia: los cargos no están habilitados para su cuenta" auth_fail_error: La clave API que proporcionó no es válida. @@ -378,8 +378,8 @@ es_CR: ship_address: "Dirección de envío" update_address_success: 'Dirección actualizada correctamente.' update_address_error: 'Introduce todos los campos requeridos' - edit_bill_address: 'Edita la Dirección de Facturación' - edit_ship_address: 'Editar Dirección de Envío' + edit_bill_address: 'Editar la dirección de facturación' + edit_ship_address: 'Editar dirección de envío' required_fileds: 'Los campos obligatorios se indican con un asterisco' select_country: 'Selecciona país' select_state: 'Selecciona provincia' @@ -415,14 +415,14 @@ es_CR: name_placeholder: "por ejemplo, comision de embalaje" enterprise_groups: index: - new_button: Nuevo Grupo de Organización + new_button: Nuevo grupo de organización enterprise_roles: form: - manages: Gestiona + manages: Administra enterprise_role: - manages: Gestionan + manages: Administra products: - unit_name_placeholder: 'ej. manojos' + unit_name_placeholder: 'ej. racimos' index: unit: Unidad display_as: Mostrar como @@ -444,14 +444,14 @@ es_CR: inherited_property: "Propiedad heredada" variants: infinity: "infinito" - to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda." + to_order_tip: "Los artículos hechos según el pedido no tienen un nivel fijado de inventario, como por ejemplo panes hechos según demanda." back_to_products_list: "Volver a la lista de productos" editing_product: "Editando producto" tabs: product_details: "Detalles del producto" group_buy_options: "Opciones de compra grupales" images: "Imágenes" - variants: "Variedades" + variants: "Variante" product_properties: "Propiedades del producto" product_import: title: Importe de producto @@ -774,7 +774,7 @@ es_CR: actions: edit_profile: Configuración properties: Propiedades - payment_methods: Métodos de Pago + payment_methods: Métodos de pago payment_methods_tip: Esta organización no tiene métodos de pago shipping_methods: Métodos de envío shipping_methods_tip: Esta organización tiene métodos de envío @@ -785,42 +785,42 @@ es_CR: role: Rol sells: Vende visible: ¿Visible? - owner: Propietaria - producer: Productora + owner: Propietario + producer: Productor change_type_form: - producer_profile: Perfil Productora + producer_profile: Perfil del productor connect_ofn: Conectar a través de OFN always_free: SIEMPRE GRATIS producer_description_text: Añade tus productos a Open Food Network, permitiendo a los Grupos de Consumo vender tus productos. - producer_shop: Tienda Productora + producer_shop: Tienda de productor sell_your_produce: Vende tu propia producción producer_shop_description_text: Venda sus productos directamente a los clientes a través de su propia tienda. - producer_shop_description_text2: Una tienda de productora es para vender sus productos solamente, si quiere vender productos de otros productores, seleccione "Grupo de Productoras" - producer_hub: Hub de productoras + producer_shop_description_text2: Una tienda de productor es para vender sus productos solamente, si quiere vender productos de otros productores, seleccione "Hub de Productor" + producer_hub: Hub de productor producer_hub_text: Vende tu propia producción y la de otros - producer_hub_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos tuyos o de otras organizaciones y véndelo a través de tu tienda en Open Food Network. + producer_hub_description_text: Su organización es la columna vertebral de un sistema de consumo local. Agregue productos suyos o de otras organizaciones y véndalo a través de su tienda en Open Food Network (LaFeriaCR). profile: Solo perfil get_listing: Obtener un listado - profile_description_text: La gente podrá encontrarte y ponerse en contacto contigo en Open Food Network. Su organización será visible en el mapa y se podrá buscar en los listados. + profile_description_text: La gente podrá encontrarlo y ponerse en contacto con usted en Open Food Network (LaFeriaCR). Su organización será visible en el mapa y se podrá buscar en los listados. hub_shop: Tienda del Hub hub_shop_text: Vender la producción de otros - hub_shop_description_text: Tu organización es la columna vertebral de un sistema de consumo local. Agrega productos de otras organizaciones y véndelo a través de tu tienda en Open Food Network. + hub_shop_description_text: Su organización es la columna vertebral de un sistema de consumo local. Agregue productos de otras organizaciones y véndalo a través de su tienda en Open Food Network (LaFeriaCR). choose_option: Por favor, elija una de las opciones anteriores. change_now: Cambiar enterprise_user_index: loading_enterprises: CARGANDO ORGANIZACIONES no_enterprises_found: No se encuentran organizaciones. - search_placeholder: Buscar por Nombre - manage: Gestionar + search_placeholder: Buscar por nombre + manage: Administrar manage_link: Configuración - producer?: "¿Productora?" + producer?: "¿Productor?" package: "Perfil" status: "Estado" new_form: - owner: Propietaria - owner_tip: La principal usaría responsable para esta organización. - i_am_producer: Soy una Productora - contact_name: Nombre de Contacto + owner: Propietario + owner_tip: El usuario principal responsable para esta organización. + i_am_producer: Soy un productor + contact_name: Nombre de contacto edit: editing: 'Configuración:' back_link: Volver a la lista de organizaciones @@ -828,56 +828,56 @@ es_CR: title: Nueva Organización back_link: Volver a la lista de organizaciones remove_logo: - remove: "Eliminar la imagen" + remove: "Eliminar la imágen" removed_successfully: "Logotipo eliminado con éxito" immediate_removal_warning: "El logotipo se eliminará inmediatamente después de confirmar." remove_promo_image: remove: "Eliminar la imagen" - removed_successfully: "Imagen promocional eliminada con éxito" - immediate_removal_warning: "La imagen promocional se eliminará inmediatamente después de confirmar." + removed_successfully: "Imágen promocional eliminada con éxito" + immediate_removal_warning: "La imágen promocional se eliminará inmediatamente después de confirmar." welcome: - welcome_title: Bienvenida a Open Food Network! - welcome_text: Has creado correctamente un + welcome_title: ¡Bienvenido a Open Food Network (LaFeriaCR)! + welcome_text: Ha creado correctamente un next_step: Siguiente paso - choose_starting_point: 'Selecciona tu perfil:' + choose_starting_point: 'Seleccione su perfil:' profile: 'Perfil' - producer_profile: 'Perfil Productora' + producer_profile: 'Perfil de Productor' invite_manager: user_already_exists: "El usuario ya existe" error: "Algo salió mal" order_cycles: loading_flash: loading_order_cycles: Cargando ciclos de pedido - loading: Cargando... + loading: CARGANDO... new: create: "Crear" cancel: "Cancelar" back_to_list: "Regresar a la lista" edit: - advanced_settings: "Configuración Avanzada" + advanced_settings: "Configuración avanzada" save: "Guardar" - save_and_next: "Salvar y continuar" + save_and_next: "Guardar y continuar" next: "Siguiente" cancel: "Cancelar" back_to_list: "Regresar a la lista" - save_and_back_to_list: "Salvar y volver a lista" - choose_products_from: "Escoger Productos desde:" + save_and_back_to_list: "Guardar y volver a lista" + choose_products_from: "Escoger productos desde:" incoming: save: "Guardar" - save_and_next: "Salvar y continuar" + save_and_next: "Guardar y continuar" next: "Siguiente" cancel: "Cancelar" back_to_list: "Regresar a la lista" outgoing: outgoing: "Saliente" - distributor: "Distribuidora" + distributor: "Distribuidor" products: "Productos" - tags: "Tags" + tags: "Etiquetas" delivery_details: "Detalles de entrega" fees: "Comisiones" previous: "Anterior" save: "Guardar" - save_and_back_to_list: "Salvar y volver a lista" + save_and_back_to_list: "Guardar y volver a lista" cancel: "Cancelar" back_to_list: "Regresar a la lista" wizard_progress: @@ -887,19 +887,19 @@ es_CR: exchange_form: pickup_time_tip: Cuándo estarán listos los pedidos de este ciclo de pedido para los clientes pickup_instructions_placeholder: "Instrucciones de recogida" - pickup_instructions_tip: Estas instrucciones se muestran a las consumidoras después de completar un pedido. + pickup_instructions_tip: Estas instrucciones se muestran a los clientes después de completar un pedido. pickup_time_placeholder: "Listo para ( Fecha / Hora)" receival_instructions_placeholder: "Instrucciones de recepción" add_fee: 'Añadir comisión' remove: 'Eliminar' selected: 'seleccionado' add_exchange_form: - add_supplier: 'Añadir proveedora' - add_distributor: 'Añadir distribuidora' + add_supplier: 'Añadir proveedor' + add_distributor: 'Añadir distribuidor' advanced_settings: - title: Configuración Avanzada + title: Configuración avanzada choose_product_tip: Puede restringir los productos entrantes y salientes a solo el inventario de %{inventory}. - preferred_product_selection_from_coordinator_inventory_only_here: Solo el Inventario de la Coordinadora + preferred_product_selection_from_coordinator_inventory_only_here: Solo el inventario del coordinador preferred_product_selection_from_coordinator_inventory_only_all: Todos los productos disponibles save_reload: Guardar y recargar la página coordinator_fees: @@ -912,14 +912,14 @@ es_CR: form: general_settings: "Configuración general" incoming: Entrante - supplier: Proveedora + supplier: Proveedor receival_details: Detalles de la recepción fees: Comisiones outgoing: Saliente distributor: Distribuidor products: Productos tags: Etiquetas - add_a_tag: Add a tag + add_a_tag: Añade una etiqueta delivery_details: Detalles de Recogida / Entrega index: schedule: Programación @@ -928,11 +928,11 @@ es_CR: name_and_timing_form: name: Nombre orders_open: Pedidos abiertos a - coordinator: Coordinadora - orders_close: Cierre de Pedidos + coordinator: Coordinador + orders_close: Cierre de pedidos row: - suppliers: proveedoras - distributors: distribuidoras + suppliers: proveedores + distributors: distribuidores variants: variedades simple_form: ready_for: Listo para @@ -952,7 +952,7 @@ es_CR: proceed: Proceder producer_properties: index: - title: Propiedades de la Productora + title: Propiedades del productor proxy_orders: cancel: could_not_cancel_the_order: No se pudo cancelar la orden @@ -960,21 +960,21 @@ es_CR: could_not_resume_the_order: No se pudo reanudar el pedido shared: user_guide_link: - user_guide: Manual de Usuario + user_guide: Manual de usuario enterprises_hubs_tabs: - has_no_payment_methods: "%{enterprise} no tiene formas de pago" + has_no_payment_methods: "%{enterprise} no tiene métodos de pago" has_no_shipping_methods: "%{enterprise} no tiene ningún método de envío" has_no_enterprise_fees: "%{enterprise} no tiene comisiones de organización" enterprise_issues: create_new: Crear nuevo - resend_email: Reenviar email - has_no_payment_methods: "%{enterprise} actualmente no tiene formas de pago" + resend_email: Reenviar correo electrónico + has_no_payment_methods: "%{enterprise} actualmente no tiene métodos de pago" has_no_shipping_methods: "%{enterprise} no tiene actualmente métodos de envío" email_confirmation: "La confirmación de correo electrónico está pendiente. Hemos enviado un correo electrónico de confirmación a %{email}." not_visible: "%{enterprise} no es visible y no se puede encontrar en el mapa o en búsquedas" reports: hidden: OCULTO - unitsize: UNIDAD DE MEDIDA + unitsize: TAMAÑO DE LA UNIDAD total: TOTAL total_items: ARTÍCULOS TOTALES supplier_totals: Totales de proveedores del Ciclo de Pedido @@ -989,11 +989,11 @@ es_CR: payment_methods: Reporte de los métodos de pago delivery: Reporte de entrega tax_types: Tipos de impuestos - tax_rates: '% Impuestos' + tax_rates: Tarifas de impuesto pack_by_customer: Paquete por cliente pack_by_supplier: Pack por proveedor orders_and_distributors: - name: Pedidos y Distribuidores + name: Pedidos y distribuidores description: Pedidos con detalles de distribuidor bulk_coop: name: Bulk Co-Op @@ -1004,12 +1004,12 @@ es_CR: orders_and_fulfillment: name: Reportes de Pedidos y Repartos customers: - name: Consumidoras + name: Clientes products_and_inventory: - name: Productos & Inventario + name: Productos e inventario users_and_enterprises: - name: Usuarias y Organizaciones - description: Propiedad y Estado de la Organización + name: Usuarios y organizaciones + description: Posesión y estado de la organización order_cycle_management: name: Gestión del Ciclo de Pedido sales_tax: @@ -1029,21 +1029,21 @@ es_CR: edit: Editar suscripción table: edit_subscription: Editar suscripción - pause_subscription: Pausa Suscripción + pause_subscription: Pausar suscripción unpause_subscription: Reanudar suscripción cancel_subscription: Cancelar suscripción filters: query_placeholder: "Buscar por correo electrónico ..." setup_explanation: just_a_few_more_steps: 'Solo unos pocos pasos más antes de que pueda comenzar:' - enable_subscriptions: "Habilita suscripciones para al menos una de tus tiendas" - enable_subscriptions_step_1_html: 1. Vaya a la página %{enterprises_link}, encuentre su tienda y haga clic en "Administrar" + enable_subscriptions: "Habilita suscripciones para al menos una de sus tiendas" + enable_subscriptions_step_1_html: 1. Ir a la página %{enterprises_link}, encuentre su tienda y haga clic en "Administrar" enable_subscriptions_step_2: 2. En "Preferencias de la tienda", habilite la opción Suscripciones set_up_shipping_and_payment_methods_html: Configurar los métodos %{shipping_link} y %{payment_link} set_up_shipping_and_payment_methods_note_html: Tenga en cuenta que solo se pueden usar
métodos de pago en efectivo y Stripe con las suscripciones ensure_at_least_one_customer_html: Asegúrese de que exista al menos un %{customer_link} create_at_least_one_schedule: Crear al menos una programación - create_at_least_one_schedule_step_1_html: 1. Vaya a la página %{order_cycles_link} + create_at_least_one_schedule_step_1_html: 1. Ir a la página %{order_cycles_link} create_at_least_one_schedule_step_2: 2. Crea un ciclo de pedido si aún no lo has hecho create_at_least_one_schedule_step_3: 3. Haga clic en '+ Nueva programación' y complete el formulario once_you_are_done_you_can_html: Una vez que haya terminado, puede %{reload_this_page_link} @@ -1297,14 +1297,14 @@ es_CR: you_have_no_saved_cards: Aún no has guardado ninguna tarjeta. saving_credit_card: Guardando tarjeta de crédito... card_has_been_removed: "Su tarjeta ha sido eliminada (número: %{number})" - card_could_not_be_removed: Lo sentimos, la tarjeta no se pudo quitar + card_could_not_be_removed: Lo sentimos, la tarjeta no se pudo eliminar invalid_credit_card: "Tarjeta de crédito inválida" ie_warning_headline: "Su navegador está desactualizado :-(" ie_warning_text: "Para una mejor experiencia utilizando La Feria, le recomendamos actualizar su navegador:" ie_warning_chrome: Descargar Chrome ie_warning_firefox: Descargar Firefox ie_warning_ie: Actualizar Internet Explorer - ie_warning_other: "¿No puede actualizar su navegador? Pruebe usar La Feria en su teléfono :-)" + ie_warning_other: "¿No puede actualizar su navegador? Pruebe usar Open Food Network (LaFeriaCR) en su teléfono :-)" legal: cookies_policy: header: "Cómo utilizamos las cookies" @@ -1560,8 +1560,8 @@ es_CR: groups_text: "Cada productor es único. Cada organización tiene algo diferente que ofrecer. Nuestros grupos son colectivos de productores, centros de acopio y distribuidores que comparten valores agroecológicos. Esto hace que su experiencia de compra sea más fácil." groups_search: "Buscar nombre o palabra clave" groups_no_groups: "No se encontraron grupos" - groups_about: "Acerca de nosotras" - groups_producers: "Nuestras productoras" + groups_about: "Acerca de nosotros" + groups_producers: "Nuestros productores" groups_hubs: "Nuestros Grupos de Consumo" groups_contact_web: Contacto groups_contact_social: Seguir @@ -1602,10 +1602,10 @@ es_CR: modal_how_pickup_explained: Algunos grupos de consumo hacen entregas hasta su puerta, mientras otros requieren que recojas las compras. Puedes ver que opciones están disponibles en su página de inicio, y seleccionar cuál te gustaría en las páginas de compras y revisión. Las entregas costarán más, y el precio cambia entre grupos de consumo. Cada grupo es un punto de venta con operaciones y logística independientes, las diferencias son normales y deseables. modal_how_more: Aprender más modal_how_more_explained: "Si quieres saber más acerca de Open Food Network, cómo trabajamos y nos organizamos, visita:" - modal_producers: "Productoras" + modal_producers: "Productores" modal_producers_explained: "Nuestras productoras hacen todos los deliciosos alimentos que puedes comprar en Open Food Network." producers_about: Acerca de nosotros - producers_buy: Comprar + producers_buy: Comprar para producers_contact: Contacto producers_contact_phone: Llamar producers_contact_social: Seguir @@ -1613,14 +1613,14 @@ es_CR: producers_filter: Filtrar por producers_filter_type: Tipo producers_filter_property: Propiedad - producers_title: Productoras + producers_title: Productores producers_headline: Encuentra productoras locales producers_signup_title: Registrarse como productora producers_signup_headline: Productoras de alimentos, empoderadas. producers_signup_motivation: Venda sus alimentos y cuente sus historias en distintos nuevos mercados. Ahorre tiempo y dinero en costos administrativos. Apoyamos la innovación sin el riesgo. Hemos nivelado el campo de juego. producers_signup_send: Únase ahora producers_signup_enterprise: Cuentas de organización - producers_signup_studies: Historias de nuestras productoras. + producers_signup_studies: Historias de nuestros productores. producers_signup_cta_headline: ¡Únase ahora! producers_signup_cta_action: Únase ahora producers_signup_detail: Aquí esta el detalle. @@ -1746,13 +1746,13 @@ es_CR: email_unconfirmed: "Debe confirmar su dirección de correo electrónico antes de poder restablecer su contraseña." email_required: "Debe brindar una dirección de correo electrónico" logging_in: "Espere un momento, le vamos a iniciar una sesión" - signup_email: "Tu correo electrónico" - choose_password: "Escoje una contraseña" + signup_email: "Su correo electrónico" + choose_password: "Elige una contraseña" confirm_password: "Confirmar contraseña" action_signup: "Registrarse ahora" forgot_password: "¿Se le olvidó su contraseña?" password_reset_sent: "¡Le enviamos un correo electrónico con instrucciones para restaurar la contraseña!" - reset_password: "Restaurar contraseña" + reset_password: "Restablecer contraseña" update_and_recalculate_fees: "Actualizar y recalcular comisiones" registration: steps: @@ -2270,7 +2270,7 @@ es_CR: enterprise_owner_error: "^ %{email} no está autorizado a tener más organizaciones (el límite es %{enterprise_limit})." enterprise_role_uniqueness_error: "^Este rol ya está presente." inventory_item_visibility_error: Debe ser verdadero o falso - product_importer_file_error: "Error: no se ha subido ningún archivo" + product_importer_file_error: "error: no se ha subido ningún archivo" product_importer_spreadsheet_error: "No se pudo procesar el archivo: tipo de archivo inválido" product_importer_products_save_error: No se guardó ningún producto con éxito product_import_file_not_found_notice: 'Archivo no encontrado o no se pudo abrir' @@ -2303,7 +2303,7 @@ es_CR: back_to_orders_list: "Volver a la lista de pedidos" no_orders_found: "No se encontraron pedidos" order_information: "información del pedido" - date_completed: "Fecha de finalización" + date_completed: "Fecha completada" amount: "Cantidad" state_names: ready: Listo @@ -2314,7 +2314,7 @@ es_CR: changes_saved: 'Cambios guardados.' save_changes_first: Guarda los cambios primero. all_changes_saved: Todos los cambios guardados - unsaved_changes: Tienes cambios sin guardar + unsaved_changes: Tiene cambios sin guardar all_changes_saved_successfully: Todos los cambios guardados correctamente oh_no: "¡Vaya! No se ha podido guardar los cambios." unauthorized: "No estás autorizado a acceder a esta página." @@ -2336,7 +2336,7 @@ es_CR: invite_title: "Invitar a un usuario no registrado" tag_rule_help: title: Reglas de las etiquetas - overview: Visión general + overview: Vista general overview_text: > Las reglas de etiqueta proporcionan una manera de describir qué elementos son visibles o no para determinados consumidores. Los artículos pueden diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index 1db31edec6..0b3c2d1ce3 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -2772,6 +2772,8 @@ fil_PH: location: "Lokasyon" count_on_hand: "bilangin ang on hand" quantity: "dami" + on_demand: "on demand" + on_hand: "on hand" package_from: "package mula sa" item_description: "Paglalarawan ng item" price: "presyo" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index b14690a1f0..b05a488edf 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -2702,6 +2702,8 @@ fr_BE: location: "Site" count_on_hand: "Compté à la main" quantity: "Nb commandé" + on_demand: "A volonté" + on_hand: "En stock" package_from: "colis provenant de " item_description: "Description de l'article " price: "Prix" diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index 12f9a6a53b..f354f638ce 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -2765,6 +2765,8 @@ fr_CA: location: "Localisation" count_on_hand: "Quantité en stock" quantity: "Quantité" + on_demand: "A volonté" + on_hand: "En stock" package_from: "conditionnement par" item_description: "Description de la pièce" price: "Prix" diff --git a/config/locales/it.yml b/config/locales/it.yml index b555d60965..1e1552af14 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -2759,6 +2759,8 @@ it: location: "Posizione" count_on_hand: "Conta a mente" quantity: "Quantità" + on_demand: "A richiesta" + on_hand: "Disponibile" package_from: "pacchetto da" item_description: "descrizione dell'articolo" price: "Prezzo" diff --git a/config/locales/nb.yml b/config/locales/nb.yml index cf941afc92..9371908c59 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -2754,6 +2754,8 @@ nb: location: "Plassering" count_on_hand: "Antall På Lager" quantity: "Mengde" + on_demand: "Ved forespørsel" + on_hand: "Tilgjengelig" package_from: "pakke fra" item_description: "Beskrivelse Element" price: "Pris" diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index 3ce888b436..ee09e5d0f7 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -2641,6 +2641,8 @@ nl_BE: location: "Locatie" count_on_hand: "Count On Hand" quantity: "Kwantiteit" + on_demand: "Op Aanvraag" + on_hand: "Bij de Hand" package_from: "pakje van " item_description: "Artikelbeschrijving" price: "Prijs" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index d40a0f3ba9..c3a1b473fc 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -2597,6 +2597,8 @@ pt: location: "Localização" count_on_hand: "Disponível" quantity: "Quantidade" + on_demand: "Sob Encomenda" + on_hand: "Disponível" package_from: "Embalagem de" item_description: "Descrição do Item" price: "Preço" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 4ea651cb2c..9966e927c8 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -2764,6 +2764,8 @@ pt_BR: location: "Localização" count_on_hand: "Contagem na mão" quantity: "Quantidade" + on_demand: "Sob Encomenda" + on_hand: "Disponível" package_from: "pacote de" item_description: "Descrição do Item" price: "Preço" diff --git a/config/locales/sv.yml b/config/locales/sv.yml index ca90a48659..53985ac51f 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1898,6 +1898,8 @@ sv: spree: resend: Återsänd quantity: "Antal" + on_demand: "På begäran" + on_hand: "På lager" price: "Pris" total: "Summa" edit: "Redigera" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 4176587dcc..5f3fd36365 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -2756,6 +2756,8 @@ tr: location: "yer" count_on_hand: "Eldeki Miktar" quantity: "miktar" + on_demand: "Talep Üzerine" + on_hand: "Mevcut" package_from: "gelen paket" item_description: "Ürün Açıklaması" price: "Fiyat"