diff --git a/Gemfile b/Gemfile index f51eb993c4..a49c7ef06a 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,8 @@ gem 'rails', '3.2.21' gem 'rails-i18n', '~> 3.0.0' gem 'i18n', '~> 0.6.11' +gem 'nokogiri' + gem 'pg' gem 'spree', :github => 'openfoodfoundation/spree', :branch => '1-3-stable' gem 'spree_i18n', :github => 'spree/spree_i18n', :branch => '1-3-stable' diff --git a/Gemfile.lock b/Gemfile.lock index 6570f544fe..b5d921244a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -594,6 +594,7 @@ DEPENDENCIES letter_opener momentjs-rails newrelic_rpm + nokogiri oj paper_trail (~> 3.0.8) paperclip diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index ec3954a436..6b59ce6e74 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -61,7 +61,6 @@ module Admin respond_to do |format| if @order_cycle.update_attributes(params[:order_cycle]) OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle, spree_current_user).go! - flash[:notice] = 'Your order cycle has been updated.' format.html { redirect_to admin_order_cycles_path } format.json { render :json => {:success => true} } @@ -87,6 +86,13 @@ module Admin redirect_to main_app.admin_order_cycles_path, :notice => "Your order cycle #{@order_cycle.name} has been cloned." end + # Send notifications to all producers who are part of the order cycle + def notify_producers + Delayed::Job.enqueue OrderCycleNotificationJob.new(params[:id].to_i) + + redirect_to main_app.admin_order_cycles_path, :notice => 'Emails to be sent to producers have been queued for sending.' + end + protected def collection diff --git a/app/jobs/order_cycle_notification_job.rb b/app/jobs/order_cycle_notification_job.rb new file mode 100644 index 0000000000..b18348813e --- /dev/null +++ b/app/jobs/order_cycle_notification_job.rb @@ -0,0 +1,6 @@ +OrderCycleNotificationJob = Struct.new(:order_cycle_id) do + def perform + order_cycle = OrderCycle.find order_cycle_id + order_cycle.suppliers.each { |supplier| ProducerMailer.order_cycle_report(supplier, order_cycle).deliver } + end +end diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb new file mode 100644 index 0000000000..5d8ce57eec --- /dev/null +++ b/app/mailers/producer_mailer.rb @@ -0,0 +1,53 @@ +class ProducerMailer < Spree::BaseMailer + + def order_cycle_report(producer, order_cycle) + @producer = producer + @coordinator = order_cycle.coordinator + @order_cycle = order_cycle + @line_items = aggregated_line_items_from(@order_cycle, @producer) + @receival_time = @order_cycle.receival_time_for @producer + @receival_instructions = @order_cycle.receival_instructions_for @producer + + subject = "[#{Spree::Config.site_name}] Order cycle report for #{producer.name}" + + if has_orders? order_cycle, producer + mail(to: @producer.email, + from: from_address, + subject: subject, + reply_to: @coordinator.email, + cc: @coordinator.email) + end + end + + + private + + def has_orders?(order_cycle, producer) + line_items_from(order_cycle, producer).any? + end + + def aggregated_line_items_from(order_cycle, producer) + aggregate_line_items line_items_from(order_cycle, producer) + end + + def line_items_from(order_cycle, producer) + Spree::LineItem. + joins(:order => :order_cycle, :variant => :product). + where('order_cycles.id = ?', order_cycle). + merge(Spree::Product.in_supplier(producer)). + merge(Spree::Order.complete) + end + + def aggregate_line_items(line_items) + # Arrange the items in a hash to group quantities + line_items.inject({}) do |lis, li| + if lis.key? li.variant + lis[li.variant].quantity += li.quantity + else + lis[li.variant] = li + end + + lis + end + end +end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 1c279ce447..93d09d106c 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -196,6 +196,18 @@ class OrderCycle < ActiveRecord::Base exchanges.outgoing.to_enterprises([distributor]).first end + def exchange_for_supplier(supplier) + exchanges.incoming.from_enterprises([supplier]).first + end + + def receival_time_for(supplier) + exchange_for_supplier(supplier).andand.receival_time + end + + def receival_instructions_for(supplier) + exchange_for_supplier(supplier).andand.receival_instructions + end + def pickup_time_for(distributor) exchange_for_distributor(distributor).andand.pickup_time || distributor.next_collection_at end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 4dbe434a66..fa7db47248 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -132,7 +132,7 @@ class AbilityDecorator can [:admin, :index, :read, :edit, :update], OrderCycle do |order_cycle| OrderCycle.accessible_by(user).include? order_cycle end - can [:bulk_update, :clone, :destroy], OrderCycle do |order_cycle| + can [:bulk_update, :clone, :destroy, :notify_producers], OrderCycle do |order_cycle| user.enterprises.include? order_cycle.coordinator end can [:for_order_cycle], Enterprise diff --git a/app/views/admin/order_cycles/_exchange_form.html.haml b/app/views/admin/order_cycles/_exchange_form.html.haml index 7f0fb983f9..ad9ace7001 100644 --- a/app/views/admin/order_cycles/_exchange_form.html.haml +++ b/app/views/admin/order_cycles/_exchange_form.html.haml @@ -7,6 +7,11 @@ - else {{ (incomingExchangeVariantsFor(exchange.enterprise_id)).length }} selected +- if type == 'supplier' + %td.receival-details + = text_field_tag 'order_cycle_incoming_exchange_{{ $index }}_receival_time', '', 'id' => 'order_cycle_incoming_exchange_{{ $index }}_receival_time', 'placeholder' => 'Receive at (ie. Date / Time)', 'ng-model' => 'exchange.receival_time' + %br/ + = text_field_tag 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', '', 'id' => 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', 'placeholder' => 'Receival instructions', 'ng-model' => 'exchange.receival_instructions' - if type == 'distributor' %td.collection-details = text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'placeholder' => 'Ready for (ie. Date / Time)', 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator' diff --git a/app/views/admin/order_cycles/_form.html.haml b/app/views/admin/order_cycles/_form.html.haml index a5f7ec1518..fe3746bee6 100644 --- a/app/views/admin/order_cycles/_form.html.haml +++ b/app/views/admin/order_cycles/_form.html.haml @@ -9,6 +9,7 @@ %tr %th Supplier %th Products + %th Receival details %th Fees %th.actions %tbody{'ng-repeat' => 'exchange in order_cycle.incoming_exchanges'} diff --git a/app/views/admin/order_cycles/edit.html.haml b/app/views/admin/order_cycles/edit.html.haml index f96d10e01e..b90160e6fe 100644 --- a/app/views/admin/order_cycles/edit.html.haml +++ b/app/views/admin/order_cycles/edit.html.haml @@ -1,7 +1,13 @@ +- if can? :notify_producers, @order_cycle + = content_for :page_actions do + %li + = button_to "Notify producers", main_app.notify_producers_admin_order_cycle_path, :id => 'admin_notify_producers', :confirm => 'Are you sure?' + + %h1 Edit Order Cycle -- ng_controller = order_cycles_simple_form ? 'AdminSimpleEditOrderCycleCtrl' : 'AdminEditOrderCycleCtrl' +- ng_controller = order_cycles_simple_form ? 'AdminSimpleEditOrderCycleCtrl' : 'AdminEditOrderCycleCtrl' = form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.orderCycles', 'ng-controller' => ng_controller, 'ng-submit' => 'submit($event)'} do |f| - if order_cycles_simple_form = render 'simple_form', f: f diff --git a/app/views/producer_mailer/order_cycle_report.text.haml b/app/views/producer_mailer/order_cycle_report.text.haml new file mode 100644 index 0000000000..1bd9099426 --- /dev/null +++ b/app/views/producer_mailer/order_cycle_report.text.haml @@ -0,0 +1,33 @@ +Dear #{@producer.name}, +\ +We now have all the consumer orders for next food drop. Please drop off your delivery at #{@receival_time}. + +- if @receival_instructions + Extra instructions: #{@receival_instructions} + +Please deliver to #{@coordinator.address.address1}, #{@coordinator.address.city}, #{@coordinator.address.zipcode} during the regular delivery time. If this is not convenient then please call #{@coordinator.phone}. + +Note: If you have to arrange a different delivery day and time, it is requested that you do not come on site during drop off/pick up times. + +\ +Orders summary +================ +\ +Here is a summary of the orders for your products: +\ +- @line_items.each_pair do |variant, line_item| + #{variant.sku} - #{raw(variant.product.supplier.name)} - #{raw(variant.product_and_variant_name)} (QTY: #{line_item.quantity}) @ #{line_item.single_money} = #{line_item.display_amount} + +\ +Details +========= +\ +For a detailed orders breakdown, please log into your account. + +Please confirm that you have received this email. + +Please send me an invoice for this amount so we can send you payment. + +If you need to phone on the day please call #{@coordinator.phone}. +\ +Thanks and best wishes - #{@coordinator.name} diff --git a/config/application.rb b/config/application.rb index 5a31bc5774..8a492f5121 100644 --- a/config/application.rb +++ b/config/application.rb @@ -47,7 +47,10 @@ module Openfoodnetwork # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. - config.autoload_paths += %W(#{config.root}/app/presenters) + config.autoload_paths += %W( + #{config.root}/app/presenters + #{config.root}/app/jobs + ) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. diff --git a/config/routes.rb b/config/routes.rb index 40fd6c3d4b..eb8c228b91 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -62,7 +62,11 @@ Openfoodnetwork::Application.routes.draw do namespace :admin do resources :order_cycles do post :bulk_update, on: :collection, as: :bulk_update - get :clone, on: :member + + member do + get :clone + post :notify_producers + end end resources :enterprises do diff --git a/db/migrate/20141229094516_add_receival_time_to_exchange.rb b/db/migrate/20141229094516_add_receival_time_to_exchange.rb new file mode 100644 index 0000000000..06933ed051 --- /dev/null +++ b/db/migrate/20141229094516_add_receival_time_to_exchange.rb @@ -0,0 +1,6 @@ +class AddReceivalTimeToExchange < ActiveRecord::Migration + def change + add_column :exchanges, :receival_time, :string + add_column :exchanges, :receival_instructions, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 8f164fb66c..d5494eb970 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -386,6 +386,8 @@ ActiveRecord::Schema.define(:version => 20151002020537) do t.datetime "created_at", :null => false t.datetime "updated_at", :null => false t.boolean "incoming", :default => false, :null => false + t.string "receival_time" + t.string "receival_instructions" end add_index "exchanges", ["order_cycle_id"], :name => "index_exchanges_on_order_cycle_id" diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index 69ba284cd8..540a18da13 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -1,3 +1,5 @@ +require 'open_food_network/order_cycle_permissions' + module OpenFoodNetwork # There are two translator classes on the boundary between Angular and Rails: On the Angular side, @@ -21,10 +23,14 @@ module OpenFoodNetwork if exchange_exists?(exchange[:enterprise_id], @order_cycle.coordinator_id, true) update_exchange(exchange[:enterprise_id], @order_cycle.coordinator_id, true, - {variant_ids: variant_ids, enterprise_fee_ids: enterprise_fee_ids}) + {variant_ids: variant_ids, enterprise_fee_ids: enterprise_fee_ids, + receival_time: exchange[:receival_time], + receival_instructions: exchange[:receival_instructions]}) else add_exchange(exchange[:enterprise_id], @order_cycle.coordinator_id, true, - {variant_ids: variant_ids, enterprise_fee_ids: enterprise_fee_ids}) + {variant_ids: variant_ids, enterprise_fee_ids: enterprise_fee_ids, + receival_time: exchange[:receival_time], + receival_instructions: exchange[:receival_instructions],}) end end @@ -35,12 +41,16 @@ module OpenFoodNetwork if exchange_exists?(@order_cycle.coordinator_id, exchange[:enterprise_id], false) update_exchange(@order_cycle.coordinator_id, exchange[:enterprise_id], false, - {variant_ids: variant_ids, enterprise_fee_ids: enterprise_fee_ids, - pickup_time: exchange[:pickup_time], pickup_instructions: exchange[:pickup_instructions]}) + {variant_ids: variant_ids, + enterprise_fee_ids: enterprise_fee_ids, + pickup_time: exchange[:pickup_time], + pickup_instructions: exchange[:pickup_instructions]}) else add_exchange(@order_cycle.coordinator_id, exchange[:enterprise_id], false, - {variant_ids: variant_ids, enterprise_fee_ids: enterprise_fee_ids, - pickup_time: exchange[:pickup_time], pickup_instructions: exchange[:pickup_instructions]}) + {variant_ids: variant_ids, + enterprise_fee_ids: enterprise_fee_ids, + pickup_time: exchange[:pickup_time], + pickup_instructions: exchange[:pickup_instructions]}) end end diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 37fdc8893c..3ebbfb2ce3 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' module Admin describe OrderCyclesController do include AuthenticationWorkflow + let!(:distributor_owner) { create_enterprise_user enterprise_limit: 2 } before do @@ -135,6 +136,34 @@ module Admin end end + + describe "notifying producers" do + let(:user) { create_enterprise_user } + let(:admin_user) do + user = create(:user) + user.spree_roles << Spree::Role.find_or_create_by_name!('admin') + user + end + let(:order_cycle) { create(:simple_order_cycle) } + + before do + controller.stub spree_current_user: admin_user + end + + it "enqueues a job" do + expect do + spree_post :notify_producers, {id: order_cycle.id} + end.to enqueue_job OrderCycleNotificationJob + end + + it "redirects back to the order cycles path with a success message" do + spree_post :notify_producers, {id: order_cycle.id} + expect(response).to redirect_to admin_order_cycles_path + flash[:notice].should == 'Emails to be sent to producers have been queued for sending.' + end + end + + describe "destroy" do let!(:distributor) { create(:distributor_enterprise, owner: distributor_owner) } diff --git a/spec/factories.rb b/spec/factories.rb index e0c8831b52..0db34ab78c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -15,9 +15,11 @@ FactoryGirl.define do # Incoming Exchanges ex1 = create(:exchange, :order_cycle => oc, :incoming => true, - :sender => supplier1, :receiver => oc.coordinator) + :sender => supplier1, :receiver => oc.coordinator, + :receival_time => 'time 0', :receival_instructions => 'instructions 0') ex2 = create(:exchange, :order_cycle => oc, :incoming => true, - :sender => supplier2, :receiver => oc.coordinator) + :sender => supplier2, :receiver => oc.coordinator, + :receival_time => 'time 1', :receival_instructions => 'instructions 1') ExchangeFee.create!(exchange: ex1, enterprise_fee: create(:enterprise_fee, enterprise: ex1.sender)) ExchangeFee.create!(exchange: ex2, @@ -71,7 +73,7 @@ FactoryGirl.define do after(:create) do |oc, proxy| proxy.suppliers.each do |supplier| - ex = create(:exchange, :order_cycle => oc, :sender => supplier, :receiver => oc.coordinator, :incoming => true, :pickup_time => 'time', :pickup_instructions => 'instructions') + ex = create(:exchange, :order_cycle => oc, :sender => supplier, :receiver => oc.coordinator, :incoming => true, :receival_time => 'time', :receival_instructions => 'instructions') proxy.variants.each { |v| ex.variants << v } end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 36677a6d4f..575d37d7e7 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -47,7 +47,7 @@ feature %q{ o.order_cycle.should == order_cycle end - scenario "can add a product to an existing order", js: true do + scenario "can add a product to an existing order", js: true, retry: 3 do login_to_admin_section visit '/admin/orders' diff --git a/spec/jobs/order_cycle_notification_job_spec.rb b/spec/jobs/order_cycle_notification_job_spec.rb new file mode 100644 index 0000000000..674bdbdd24 --- /dev/null +++ b/spec/jobs/order_cycle_notification_job_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe OrderCycleNotificationJob do + let(:order_cycle) { create(:order_cycle) } + + it "sends a mail to each supplier" do + mail = double(:mail) + allow(mail).to receive(:deliver) + expect(ProducerMailer).to receive(:order_cycle_report).twice.and_return(mail) + run_job OrderCycleNotificationJob.new(order_cycle.id) + end +end diff --git a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb index 5314c4376c..91882510b4 100644 --- a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb +++ b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb @@ -11,7 +11,7 @@ module OpenFoodNetwork coordinator_id = 123 supplier_id = 456 - incoming_exchange = {:enterprise_id => supplier_id, :incoming => true, :variants => {'1' => true, '2' => false, '3' => true}, :enterprise_fee_ids => [1, 2]} + incoming_exchange = {:enterprise_id => supplier_id, :incoming => true, :variants => {'1' => true, '2' => false, '3' => true}, :enterprise_fee_ids => [1, 2], :receival_time => 'receival time', :receival_instructions => 'receival instructions'} oc = double(:order_cycle, :coordinator_id => coordinator_id, :exchanges => [], :incoming_exchanges => [incoming_exchange], :outgoing_exchanges => []) @@ -19,7 +19,7 @@ module OpenFoodNetwork applicator.should_receive(:incoming_exchange_variant_ids).with(incoming_exchange).and_return([1, 3]) applicator.should_receive(:exchange_exists?).with(supplier_id, coordinator_id, true).and_return(false) - applicator.should_receive(:add_exchange).with(supplier_id, coordinator_id, true, {:variant_ids => [1, 3], :enterprise_fee_ids => [1, 2]}) + applicator.should_receive(:add_exchange).with(supplier_id, coordinator_id, true, {:variant_ids => [1, 3], :enterprise_fee_ids => [1, 2], :receival_time => 'receival time', :receival_instructions => 'receival instructions'}) applicator.should_receive(:destroy_untouched_exchanges) applicator.go! @@ -47,7 +47,7 @@ module OpenFoodNetwork coordinator_id = 123 supplier_id = 456 - incoming_exchange = {:enterprise_id => supplier_id, :incoming => true, :variants => {'1' => true, '2' => false, '3' => true}, :enterprise_fee_ids => [1, 2]} + incoming_exchange = {:enterprise_id => supplier_id, :incoming => true, :variants => {'1' => true, '2' => false, '3' => true}, :enterprise_fee_ids => [1, 2], :receival_time => 'receival time', :receival_instructions => 'receival instructions'} oc = double(:order_cycle, :coordinator_id => coordinator_id, @@ -59,7 +59,7 @@ module OpenFoodNetwork applicator.should_receive(:incoming_exchange_variant_ids).with(incoming_exchange).and_return([1, 3]) applicator.should_receive(:exchange_exists?).with(supplier_id, coordinator_id, true).and_return(true) - applicator.should_receive(:update_exchange).with(supplier_id, coordinator_id, true, {:variant_ids => [1, 3], :enterprise_fee_ids => [1, 2]}) + applicator.should_receive(:update_exchange).with(supplier_id, coordinator_id, true, {:variant_ids => [1, 3], :enterprise_fee_ids => [1, 2], :receival_time => 'receival time', :receival_instructions => 'receival instructions'}) applicator.should_receive(:destroy_untouched_exchanges) applicator.go! diff --git a/spec/mailers/producer_mailer_spec.rb b/spec/mailers/producer_mailer_spec.rb new file mode 100644 index 0000000000..2bc1d77bef --- /dev/null +++ b/spec/mailers/producer_mailer_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper' +require 'yaml' + +describe ProducerMailer do + let(:s1) { create(:supplier_enterprise) } + let(:s2) { create(:supplier_enterprise) } + let(:s3) { create(:supplier_enterprise) } + let(:d1) { create(:distributor_enterprise) } + let(:d2) { create(:distributor_enterprise) } + let(:p1) { create(:product, price: 12.34, supplier: s1) } + let(:p2) { create(:product, price: 23.45, supplier: s2) } + let(:p3) { create(:product, price: 34.56, supplier: s1) } + let(:order_cycle) { create(:simple_order_cycle) } + let!(:incoming_exchange) { order_cycle.exchanges.create! sender: s1, receiver: d1, incoming: true, receival_time: '10am Saturday', receival_instructions: 'Outside shed.' } + + let!(:order) do + order = create(:order, distributor: d1, order_cycle: order_cycle, state: 'complete') + order.line_items << create(:line_item, variant: p1.master) + order.line_items << create(:line_item, variant: p1.master) + order.line_items << create(:line_item, variant: p2.master) + order.finalize! + order.save + order + end + let!(:order_incomplete) do + order = create(:order, distributor: d1, order_cycle: order_cycle, state: 'payment') + order.line_items << create(:line_item, variant: p3.master) + order.save + order + end + let(:mail) { ActionMailer::Base.deliveries.last } + + before do + ActionMailer::Base.deliveries.clear + ProducerMailer.order_cycle_report(s1, order_cycle).deliver + end + + it "should send an email when an order cycle is closed" do + ActionMailer::Base.deliveries.count.should == 1 + end + + it "sets a reply-to of the enterprise email" do + mail.reply_to.should == [s1.email] + end + + it "includes receival time" do + mail.body.should include '10am Saturday' + end + + it "includes receival instructions" do + mail.body.should include 'Outside shed.' + end + + it "cc's the enterprise" do + mail.cc.should == [s1.email] + end + + it "contains an aggregated list of produce" do + body_lines_including(mail, p1.name).each do |line| + line.should include 'QTY: 2' + line.should include '@ $10.00 = $20.00' + end + end + + it "does not include incomplete orders" do + mail.body.should_not include p3.name + end + + it "sends no mail when the producer has no orders" do + expect do + ProducerMailer.order_cycle_report(s3, order_cycle).deliver + end.to change(ActionMailer::Base.deliveries, :count).by(0) + end + + + private + + def body_lines_including(mail, s) + mail.body.to_s.lines.select { |line| line.include? s } + end +end diff --git a/spec/models/exchange_spec.rb b/spec/models/exchange_spec.rb index 0df7aeafab..2ba0e26b24 100644 --- a/spec/models/exchange_spec.rb +++ b/spec/models/exchange_spec.rb @@ -277,6 +277,7 @@ describe Exchange do 'payment_enterprise_id' => exchange.payment_enterprise_id, 'variant_ids' => exchange.variant_ids.sort, 'enterprise_fee_ids' => exchange.enterprise_fee_ids.sort, 'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions, + 'receival_time' => exchange.receival_time, 'receival_instructions' => exchange.receival_instructions, 'created_at' => exchange.created_at, 'updated_at' => exchange.updated_at} end @@ -286,7 +287,8 @@ describe Exchange do 'incoming' => exchange.incoming, 'payment_enterprise_id' => exchange.payment_enterprise_id, 'variant_ids' => exchange.variant_ids.sort, 'enterprise_fee_ids' => exchange.enterprise_fee_ids.sort, - 'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions} + 'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions, + 'receival_time' => exchange.receival_time, 'receival_instructions' => exchange.receival_instructions} end end