Skip to content

Commit

Permalink
user-interface for payorder confirmation
Browse files Browse the repository at this point in the history
Conflicts:
	lib/foodsoft_payorder/lib/foodsoft_payorder/update_group_order_articles.rb
  • Loading branch information
wvengen committed Sep 22, 2014
1 parent 3448a8c commit cfbda1b
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 28 deletions.
3 changes: 1 addition & 2 deletions app/controllers/group_orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class GroupOrdersController < ApplicationController
# Security
before_filter :ensure_ordergroup_member
before_filter :parse_order_specifier, :only => [:show, :edit, :price_details]
before_filter :get_order_articles, :only => [:show, :edit]
before_filter :get_order_articles, :only => [:show, :edit, :price_details]
before_filter :enough_apples?, only: [:edit, :update]

def index
Expand Down Expand Up @@ -82,7 +82,6 @@ def update

def price_details
# only makes sense for current ...
@order_articles = []
compute_order_article_details
end

Expand Down
15 changes: 15 additions & 0 deletions lib/foodsoft_payorder/app/controllers/payorders_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class PayordersController < GroupOrdersController

def confirm
# always confirm currently open orders
GroupOrderArticleQuantity.confirm_open!(@current_user.ordergroup)
# redirect to current orders or specified page
return_to = params[:return_to]
if return_to.present? and (return_to.starts_with?(root_path) or return_to.starts_with?(root_url))
redirect_to return_to
else
redirect_to group_order_path(:current)
end
end

end
36 changes: 29 additions & 7 deletions lib/foodsoft_payorder/app/helpers/payorder_helper.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
module PayorderHelper
def order_payment_status_button(options={})
return unless @group_orders_sum > 0
unconfirmed = GroupOrderArticleQuantity.where(group_order_article_id: @goa_by_oa.values.map(&:id)).where(confirmed: [false,nil])
if unconfirmed.empty?
link = my_ordergroup_path
cls = "payment-status-btn #{options[:class]}"
link_to glyph('ok')+' '+I18n.t('helpers.payorder.paid'), link, {style: 'color: green'}.merge(options).merge({class: cls})
else
if order_needs? :payment
# TODO use method to get link, and also support external urls
payment_fee = FoodsoftConfig[:payorder_payment_fee]
amount = -@ordergroup.get_available_funds + payment_fee.to_f
return_to = group_order_path(@order_date || :current)
link = FoodsoftPayorder.payment_link self, amount: amount, fixed: true,
pay_link = FoodsoftPayorder.payment_link self, amount: amount, fixed: true,
title: I18n.t('helpers.payorder.payment_prompt'), return_to: return_to
link = confirm_group_orders_path(return_to: pay_link)
cls = "payment-status-btn btn btn-primary #{options[:class]}"
link_to glyph('chevron-right')+' '+I18n.t('helpers.payorder.payment'), link, options.merge({class: cls})
elsif order_needs? :confirmation
link = confirm_group_orders_path
cls = "payment-status-btn btn btn-primary #{options[:class]}"
# @todo use button_to with Rails 4+ instead of this workaround
form_tag link do
button_tag glyph('chevron-right')+' '+I18n.t('helpers.payorder.confirm'), options.merge({class: cls})
end
else
link = my_ordergroup_path
cls = "payment-status-btn #{options[:class]}"
link_to glyph('ok')+' '+I18n.t('helpers.payorder.paid'), link, {style: 'color: green'}.merge(options).merge({class: cls})
end
end

# @param types [Symbol, Array<Symbol>] Which actions to check: +payment+ or +confirmation+; or +nil+ for any.
# @return [Boolean] Whether the member order needs user action to go through
def order_needs?(what=nil)
@group_orders_sum > 0 or return false
what = [what] unless what.nil? or what.is_a? Array
if what.nil? or what.include? :payment
return true if @ordergroup.get_available_funds < 0
end
if what.nil? or what.include? :confirmation
goaqs = GroupOrderArticleQuantity.where(group_order_article_id: @goa_by_oa.values.map(&:id))
return true if goaqs.where(confirmed: false).any?
end
return false
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/ insert_bottom '.pull-right'
- if FoodsoftConfig[:payorder_payment]
- if @articles_grouped_by_category.count > 0 and @ordergroup.get_available_funds < 0
= order_payment_status_button
= order_payment_status_button if order_needs?
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
/ insert_after 'erb[silent]:contains("<price_details_bottom_mark>")'
- payment_fee = FoodsoftConfig[:payorder_payment_fee]
- if FoodsoftPayorder.enabled? and @order_date == 'current'
- if (payable = -@ordergroup.get_available_funds) > 0
- payable += payment_fee.to_f
- if (sum = @ordergroup.account_balance - @ordergroup.value_of_finished_orders) != 0
%tr.price_details
%td{colspan: cols}
%tr.price_details
%td{colspan: cols-colsright-1}= link_to I18n.t("group_orders.group_order_totals.previous_#{sum>0 ? 'surplus' : 'deficit'}"), my_ordergroup_path
%td.price= number_to_currency(sum.abs)
%td{colspan: colsright, style: 'text-align: left'}= '-' if sum > 0
- if order_needs? :payment
- payable = -@ordergroup.get_available_funds + payment_fee.to_f
%tr.price_details
%td{colspan: cols}
%tr.price_details
%td{colspan: cols-colsright-1}= link_to I18n.t("group_orders.group_order_totals.previous_#{@group_orders_sum>0 ? 'surplus' : 'deficit'}"), my_ordergroup_path
%td.price= number_to_currency(@group_orders_sum.abs)
%td{colspan: colsright, style: 'text-align: left'}= '-' if @group_orders_sum > 0
- if payment_fee
%tr.price_details
%td{colspan: cols-colsright-1}= t '.payment_fee'
%td.price= number_to_currency payment_fee
%td{colspan: colsright}
- if payable != sum
- if payable != @group_orders_sum
%tr.price_details
%th{colspan: cols-colsright-1}= t '.payable'
%th.price= number_to_currency payable
%th{colspan: colsright}
- if order_needs?
%tr.price_details
%td{colspan: cols, style: 'text-align: right'}= order_payment_status_button
1 change: 1 addition & 0 deletions lib/foodsoft_payorder/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ en:
previous_deficit: Previous deficit
helpers:
payorder:
confirm: Confirm
paid: paid
payment: Payment
payment_prompt: Pay for your orders
1 change: 1 addition & 0 deletions lib/foodsoft_payorder/config/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ nl:
previous_deficit: Openstaand bedrag
helpers:
payorder:
confirm: Bevestigen
paid: betaald
payment: Betalen
payment_prompt: Bestelling betalen
3 changes: 3 additions & 0 deletions lib/foodsoft_payorder/config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
Rails.application.routes.draw do
scope '/:foodcoop' do
post '/group_orders/current/confirm', controller: 'payorders', action: 'confirm', as: 'confirm_group_orders'
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,22 @@ def self.paid
.merge(::FinancialTransaction.unscoped.paid) # unscoped required for multishared
end

def confirm!
update_attributes! confirmed: true
group_order_article.order_article.update_results! # @todo only after /all/ goaqs are updated
end

# confirm an ordergroup's open orders
# this can be a lot faster than `#confirm!`-ing every record
def self.confirm_open!(ordergroup)
ordergroup.group_order_article_quantities.joins(group_order_article: {group_order: :order})
.where(orders: {state: 'open'})
.update_all(confirmed: true)
ordergroup.group_order_articles.joins(order_article: :order)
.where(orders: {state: 'open'})
.map{|goa| goa.order_article.update_results!}
end

private

# When a new GroupOrderArticleQuantity is created, check available funds and set it
Expand Down
39 changes: 32 additions & 7 deletions spec/integration/product_distribution_example_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
let(:article) { create :article, supplier: supplier, unit_quantity: 5 }
let(:order) { create(:order, supplier: supplier, article_ids: [article.id]) }
let(:oa) { order.order_articles.first }
let(:goa_a) { oa.group_order_articles.joins(:group_order).where(:group_orders => {:ordergroup_id => user_a.ordergroup.id}).first }
let(:goa_b) { oa.group_order_articles.joins(:group_order).where(:group_orders => {:ordergroup_id => user_b.ordergroup.id}).first }

describe :type => :feature do
describe :type => :feature, :js => true do
before do
# make sure users have enough money to order
[user_a, user_b].each do |user|
Expand All @@ -35,24 +37,47 @@ def dotest
# die zuteilung
order.finish!(admin)
oa.reload
end

def dotest_check_received
# Endstand: insg. Bestellt wurden 6(1)
expect([oa.quantity, oa.tolerance]).to eq [6, 1]
# Gruppe a bekommt 3 einheiten.
goa_a = oa.group_order_articles.joins(:group_order).where(:group_orders => {:ordergroup_id => user_a.ordergroup.id}).first
expect(goa_a.result).to eq(3)
# gruppe b bekommt 2 einheiten.
goa_b = oa.group_order_articles.joins(:group_order).where(:group_orders => {:ordergroup_id => user_b.ordergroup.id}).first
expect(goa_b.result).to eq(2)
end

it 'agrees to documented example', :js => true do
def dotest_check_nothing_received
expect([oa.quantity, oa.tolerance]).to eq [0, 0]
expect([goa_a.result, goa_b.result]).to eq [0, 0]
end

it 'agrees to documented example' do
dotest
dotest_check_received
end

if defined? FoodsoftPayorder
it 'agrees to document example when payorder is enabled', :js => true do
FoodsoftConfig.config[:use_payorder] = true
dotest
describe 'with payorder' do
it 'will not order if not confirmed' do
FoodsoftConfig.config[:use_payorder] = true
dotest
dotest_check_nothing_received
end

it 'agrees to documented example' do
FoodsoftConfig.config[:use_payorder] = true
dotest do
# confirm order each time
visit group_order_path(:current)
within '.page-header' do
click_link_or_button I18n.t('helpers.payorder.confirm')
expect(page).to have_link I18n.t('helpers.payorder.paid')
end
end
dotest_check_received
end
end
end
end
Expand Down

0 comments on commit cfbda1b

Please sign in to comment.