mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-05-19 14:26:14 -04:00
Merge branch 'dev' into awesomecode-style/andor-8234
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --no-offense-counts`
|
||||
# on 2017-12-06 11:20:15 +1300 using RuboCop version 0.49.1.
|
||||
# on 2018-02-05 14:37:22 +1300 using RuboCop version 0.49.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
@@ -39,7 +39,6 @@ Rails/SkipsModelValidations:
|
||||
# SupportedStyles: strict, flexible
|
||||
Rails/TimeZone:
|
||||
Exclude:
|
||||
- 'spec/controllers/accounts_controller_spec.rb'
|
||||
- 'spec/factories/member.rb'
|
||||
- 'spec/factories/post.rb'
|
||||
- 'spec/models/post_spec.rb'
|
||||
@@ -60,7 +59,6 @@ Style/AsciiComments:
|
||||
# SupportedStyles: nested, compact
|
||||
Style/ClassAndModuleChildren:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/orders_controller.rb'
|
||||
- 'lib/actions/oauth_signup_action.rb'
|
||||
- 'lib/haml/filters/escaped_markdown.rb'
|
||||
|
||||
@@ -68,24 +66,11 @@ Style/IdenticalConditionalBranches:
|
||||
Exclude:
|
||||
- 'app/controllers/follows_controller.rb'
|
||||
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: line_count_dependent, lambda, literal
|
||||
Style/Lambda:
|
||||
Exclude:
|
||||
- 'spec/controllers/member_controller_spec.rb'
|
||||
- 'spec/models/photo_spec.rb'
|
||||
|
||||
# Cop supports --auto-correct.
|
||||
Style/MultilineIfModifier:
|
||||
Exclude:
|
||||
- 'spec/rails_helper.rb'
|
||||
|
||||
# Cop supports --auto-correct.
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- 'app/models/planting.rb'
|
||||
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: predicate, comparison
|
||||
@@ -96,11 +81,6 @@ Style/NumericPredicate:
|
||||
- 'app/helpers/plantings_helper.rb'
|
||||
- 'lib/tasks/growstuff.rake'
|
||||
|
||||
# Cop supports --auto-correct.
|
||||
Style/ParallelAssignment:
|
||||
Exclude:
|
||||
- 'app/mailers/notifier.rb'
|
||||
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
||||
# SupportedStyles: slashes, percent_r, mixed
|
||||
|
||||
14
Gemfile
14
Gemfile
@@ -48,7 +48,6 @@ gem 'bootstrap-kaminari-views' # bootstrap views for kaminari
|
||||
gem 'kaminari' # pagination
|
||||
|
||||
gem 'active_utils'
|
||||
gem 'activemerchant'
|
||||
gem 'sidekiq'
|
||||
|
||||
# Markdown formatting for updates etc
|
||||
@@ -78,7 +77,7 @@ gem 'omniauth-facebook'
|
||||
gem 'omniauth-flickr', '>= 0.0.15'
|
||||
gem 'omniauth-twitter'
|
||||
|
||||
gem 'chartkick'
|
||||
gem "chartkick"
|
||||
|
||||
# client for Elasticsearch. Elasticsearch is a flexible
|
||||
# and powerful, distributed, real-time search and analytics engine.
|
||||
@@ -87,15 +86,15 @@ gem 'chartkick'
|
||||
# Project does not use semver, so we want to be in sync with the version of
|
||||
# elasticsearch we use
|
||||
# See https://github.com/elastic/elasticsearch-ruby#compatibility
|
||||
gem 'elasticsearch-api', '~> 2.0.0'
|
||||
gem 'elasticsearch-model'
|
||||
gem 'elasticsearch-rails'
|
||||
gem 'hashie', '>= 3.5.3'
|
||||
gem "elasticsearch-api", "~> 2.0.0"
|
||||
gem "elasticsearch-model"
|
||||
gem "elasticsearch-rails"
|
||||
gem "hashie", ">= 3.5.3"
|
||||
|
||||
gem 'rake', '>= 10.0.0'
|
||||
|
||||
# locale based flash notices for controllers
|
||||
gem 'responders'
|
||||
gem "responders"
|
||||
|
||||
# allows soft delete. Used for members.
|
||||
gem 'acts_as_paranoid', '~> 0.5.0'
|
||||
@@ -125,7 +124,6 @@ group :development do
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'active_merchant-paypal-bogus-gateway'
|
||||
gem 'bullet' # performance tuning by finding unnecesary queries
|
||||
gem 'byebug' # debugging
|
||||
gem 'capybara' # integration tests
|
||||
|
||||
10
Gemfile.lock
10
Gemfile.lock
@@ -26,19 +26,12 @@ GEM
|
||||
addressable
|
||||
active_median (0.1.4)
|
||||
activerecord
|
||||
active_merchant-paypal-bogus-gateway (0.1.0)
|
||||
activemerchant
|
||||
active_utils (3.3.9)
|
||||
activesupport (>= 3.2, < 5.2.0)
|
||||
i18n
|
||||
activejob (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
globalid (>= 0.3.0)
|
||||
activemerchant (1.77.0)
|
||||
activesupport (>= 3.2.14, < 6.x)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
activemodel (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
builder (~> 3.1)
|
||||
@@ -549,9 +542,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
active_median
|
||||
active_merchant-paypal-bogus-gateway
|
||||
active_utils
|
||||
activemerchant
|
||||
acts_as_paranoid (~> 0.5.0)
|
||||
better_errors (~> 2.2.0)
|
||||
binding_of_caller
|
||||
@@ -636,7 +627,6 @@ DEPENDENCIES
|
||||
will_paginate
|
||||
xmlrpc
|
||||
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.4.1p111
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ guard :rspec,
|
||||
failed_mode: :keep do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/libs/#{m[1]}_spec.rb" }
|
||||
watch('spec/spec_helper.rb') { 'spec' }
|
||||
watch('spec/spec_helper.rb') { "spec" }
|
||||
|
||||
# Rails example
|
||||
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
||||
watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
|
||||
watch('config/routes.rb') { 'spec/routing' }
|
||||
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
||||
watch('config/routes.rb') { "spec/routing" }
|
||||
end
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
class AccountTypesController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
|
||||
# GET /account_types
|
||||
def index
|
||||
@account_types = AccountType.all.order(:name)
|
||||
respond_with(@account_types)
|
||||
end
|
||||
|
||||
# GET /account_types/1
|
||||
def show
|
||||
respond_with(@account_types)
|
||||
end
|
||||
|
||||
# GET /account_types/new
|
||||
def new
|
||||
@account_type = AccountType.new
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# GET /account_types/1/edit
|
||||
def edit
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# POST /account_types
|
||||
def create
|
||||
@account_type = AccountType.new(account_type_params)
|
||||
flash[:notice] = I18n.t('account_types.created') if @account_type.save
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# PUT /account_types/1
|
||||
def update
|
||||
flash[:notice] = I18n.t('account_types.updated') if @account_type.update(account_type_params)
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
# DELETE /account_types/1
|
||||
def destroy
|
||||
@account_type.destroy
|
||||
flash[:notice] = I18n.t('account_types.deleted')
|
||||
respond_with(@account_type)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account_type_params
|
||||
params.require(:account_type).permit(:is_paid, :is_permanent_paid, :name)
|
||||
end
|
||||
end
|
||||
@@ -1,31 +0,0 @@
|
||||
class AccountsController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
|
||||
# GET /accounts
|
||||
def index
|
||||
@accounts = Account.all.order(created_at: :desc)
|
||||
respond_with(@accounts)
|
||||
end
|
||||
|
||||
# GET /accounts/1
|
||||
def show
|
||||
respond_with(@account)
|
||||
end
|
||||
|
||||
# GET /accounts/1/edit
|
||||
def edit; end
|
||||
|
||||
# PUT /accounts/1
|
||||
def update
|
||||
flash[:notice] = I18n.t('account.update') if @account.update(params[:account])
|
||||
respond_with(@account)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:account_type_id, :member_id, :paid_until)
|
||||
end
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
module Admin
|
||||
class OrdersController < ApplicationController
|
||||
def index
|
||||
authorize! :manage, :all
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
authorize! :manage, :all
|
||||
@orders = Order.search(by: params[:search_by], for: params[:search_text])
|
||||
|
||||
if @orders.empty?
|
||||
flash[:alert] = "Couldn't find order with #{params[:search_by]} = #{params[:search_text]}"
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.haml
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -30,7 +30,7 @@ class AlternateNamesController < ApplicationController
|
||||
if @alternate_name.save
|
||||
redirect_to @alternate_name.crop, notice: 'Alternate name was successfully created.'
|
||||
else
|
||||
render action: 'new'
|
||||
render action: "new"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ class AlternateNamesController < ApplicationController
|
||||
if @alternate_name.update(alternate_name_params)
|
||||
redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.'
|
||||
else
|
||||
render action: 'edit'
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ class ApplicationController < ActionController::Base
|
||||
before_action :set_locale
|
||||
|
||||
def store_location
|
||||
unless request.path.in?(['/members/sign_in',
|
||||
'/members/sign_up',
|
||||
'/members/password/new',
|
||||
'/members/password/edit',
|
||||
'/members/confirmation',
|
||||
'/members/sign_out']) || request.xhr?
|
||||
unless request.path.in?(["/members/sign_in",
|
||||
"/members/sign_up",
|
||||
"/members/password/new",
|
||||
"/members/password/edit",
|
||||
"/members/confirmation",
|
||||
"/members/sign_out"]) || request.xhr?
|
||||
store_location_for(:member, request.fullpath)
|
||||
end
|
||||
end
|
||||
@@ -77,6 +77,6 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
|
||||
def expire_homepage
|
||||
expire_fragment('homepage_stats')
|
||||
expire_fragment("homepage_stats")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,9 +22,9 @@ class AuthenticationsController < ApplicationController
|
||||
name: name
|
||||
)
|
||||
|
||||
flash[:notice] = 'Authentication successful.'
|
||||
flash[:notice] = "Authentication successful."
|
||||
else
|
||||
flash[:notice] = 'Authentication failed.'
|
||||
flash[:notice] = "Authentication failed."
|
||||
end
|
||||
redirect_to request.env['omniauth.origin'] || edit_member_registration_path
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ module Charts
|
||||
@crop = Crop.find(params[:crop_id])
|
||||
render json: Harvest.joins(:plant_part)
|
||||
.where(crop: @crop)
|
||||
.group('plant_parts.name').count(:id)
|
||||
.group("plant_parts.name").count(:id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -23,9 +23,9 @@ class CropsController < ApplicationController
|
||||
def wrangle
|
||||
@approval_status = params[:approval_status]
|
||||
@crops = case @approval_status
|
||||
when 'pending'
|
||||
when "pending"
|
||||
Crop.pending_approval
|
||||
when 'rejected'
|
||||
when "rejected"
|
||||
Crop.rejected
|
||||
else
|
||||
Crop.recent
|
||||
@@ -78,7 +78,7 @@ class CropsController < ApplicationController
|
||||
@crop.creator = current_member
|
||||
else
|
||||
@crop.requester = current_member
|
||||
@crop.approval_status = 'pending'
|
||||
@crop.approval_status = "pending"
|
||||
end
|
||||
|
||||
notify_wranglers if Crop.transaction { @crop.save && save_crop_names }
|
||||
@@ -89,13 +89,13 @@ class CropsController < ApplicationController
|
||||
def update
|
||||
previous_status = @crop.approval_status
|
||||
|
||||
@crop.creator = current_member if previous_status == 'pending'
|
||||
@crop.creator = current_member if previous_status == "pending"
|
||||
|
||||
if @crop.update(crop_params)
|
||||
recreate_names('alt_name', 'alternate')
|
||||
recreate_names('sci_name', 'scientific')
|
||||
|
||||
notifier.deliver_now! if previous_status == 'pending'
|
||||
notifier.deliver_now! if previous_status == "pending"
|
||||
end
|
||||
|
||||
respond_with @crop
|
||||
@@ -110,9 +110,9 @@ class CropsController < ApplicationController
|
||||
|
||||
def notifier
|
||||
case @crop.approval_status
|
||||
when 'approved'
|
||||
when "approved"
|
||||
Notifier.crop_request_approved(@crop.requester, @crop)
|
||||
when 'rejected'
|
||||
when "rejected"
|
||||
Notifier.crop_request_rejected(@crop.requester, @crop)
|
||||
end
|
||||
end
|
||||
@@ -185,7 +185,7 @@ class CropsController < ApplicationController
|
||||
def crops
|
||||
q = Crop.approved.includes(:scientific_names, plantings: :photos)
|
||||
q = q.popular unless @sort == 'alpha'
|
||||
q.order('LOWER(crops.name)').includes(:photos).paginate(page: params[:page])
|
||||
q.order("LOWER(crops.name)").includes(:photos).paginate(page: params[:page])
|
||||
end
|
||||
|
||||
def requested_crops
|
||||
|
||||
@@ -11,7 +11,7 @@ class FollowsController < ApplicationController
|
||||
flash[:notice] = "Followed #{@follow.followed.login_name}"
|
||||
redirect_to :back
|
||||
else
|
||||
flash[:error] = 'Already following or error while following.'
|
||||
flash[:error] = "Already following or error while following."
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ class LikesController < ApplicationController
|
||||
{
|
||||
id: like.likeable.id,
|
||||
liked_by_member: liked_by_member,
|
||||
description: ActionController::Base.helpers.pluralize(like.likeable.likes.count, 'like'),
|
||||
description: ActionController::Base.helpers.pluralize(like.likeable.likes.count, "like"),
|
||||
url: like_path(like, format: :json)
|
||||
}
|
||||
end
|
||||
|
||||
@@ -49,8 +49,8 @@ class MembersController < ApplicationController
|
||||
end
|
||||
|
||||
EMAIL_TYPE_STRING = {
|
||||
send_notification_email: 'direct message notifications',
|
||||
send_planting_reminder: 'planting reminders'
|
||||
send_notification_email: "direct message notifications",
|
||||
send_planting_reminder: "planting reminders"
|
||||
}.freeze
|
||||
|
||||
def unsubscribe
|
||||
|
||||
@@ -21,7 +21,7 @@ class NotificationsController < ApplicationController
|
||||
def new
|
||||
@notification = Notification.new
|
||||
@recipient = Member.find_by(id: params[:recipient_id])
|
||||
@subject = params[:subject] || ''
|
||||
@subject = params[:subject] || ""
|
||||
end
|
||||
|
||||
# GET /notifications/1/reply
|
||||
@@ -53,7 +53,7 @@ class NotificationsController < ApplicationController
|
||||
if @notification.save
|
||||
redirect_to notifications_path, notice: 'Message was successfully sent.'
|
||||
else
|
||||
render action: 'new'
|
||||
render action: "new"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
end
|
||||
|
||||
def failure
|
||||
flash[:alert] = 'Authentication failed.'
|
||||
redirect_to request.env['omniauth.origin'] || '/'
|
||||
flash[:alert] = "Authentication failed."
|
||||
redirect_to request.env['omniauth.origin'] || "/"
|
||||
end
|
||||
|
||||
private
|
||||
@@ -30,9 +30,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
@authentication = action.establish_authentication(auth, member)
|
||||
|
||||
if action.member_created?
|
||||
raise 'Invalid provider' unless %w(facebook twitter flickr).index(auth['provider'].to_s)
|
||||
raise "Invalid provider" unless %w(facebook twitter flickr).index(auth['provider'].to_s)
|
||||
|
||||
session["devise.#{auth['provider']}_data"] = request.env['omniauth.auth']
|
||||
session["devise.#{auth['provider']}_data"] = request.env["omniauth.auth"]
|
||||
sign_in member
|
||||
redirect_to finish_signup_url(member)
|
||||
else
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
class OrderItemsController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
responders :flash
|
||||
|
||||
# POST /order_items
|
||||
def create
|
||||
if params[:order_item][:price]
|
||||
params[:order_item][:price] = params[:order_item][:price].to_f * 100 # convert to cents
|
||||
end
|
||||
|
||||
@order_item = OrderItem.new(order_item_params)
|
||||
@order_item.order = current_member.current_order || Order.create(member_id: current_member.id)
|
||||
|
||||
if @order_item.save
|
||||
redirect_to @order_item.order, notice: 'Added item to your order.'
|
||||
else
|
||||
redirect_to shop_path, alert: errors
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def errors
|
||||
if @order_item.errors.empty?
|
||||
'There was a problem with your order.'
|
||||
else
|
||||
@order_item.errors.full_messages.to_sentence
|
||||
end
|
||||
end
|
||||
|
||||
def order_item_params
|
||||
params.require(:order_item).permit(:order_id, :price, :product_id, :quantity)
|
||||
end
|
||||
end
|
||||
@@ -1,90 +0,0 @@
|
||||
class OrdersController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
|
||||
# GET /orders
|
||||
def index
|
||||
@orders = Order.by_member(current_member)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# GET /orders/1
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# GET /orders/new
|
||||
def new
|
||||
@order = Order.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# checkout with PayPal
|
||||
def checkout
|
||||
respond_to do |format|
|
||||
if @order.update_attributes(referral_code: params[:referral_code])
|
||||
response = EXPRESS_GATEWAY.setup_purchase(
|
||||
@order.total,
|
||||
items: @order.activemerchant_items,
|
||||
currency: Growstuff::Application.config.currency,
|
||||
no_shipping: true,
|
||||
ip: request.remote_ip,
|
||||
return_url: complete_order_url,
|
||||
cancel_return_url: shop_url
|
||||
)
|
||||
format.html { redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token) }
|
||||
else
|
||||
format.html { render action: 'show' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def complete
|
||||
if params[:token] && params['PayerID']
|
||||
purchase = EXPRESS_GATEWAY.purchase(
|
||||
@order.total,
|
||||
currency: Growstuff::Application.config.currency,
|
||||
ip: request.remote_ip,
|
||||
payer_id: params['PayerID'],
|
||||
token: params[:token]
|
||||
)
|
||||
if purchase.success?
|
||||
@order.completed_at = Time.zone.now
|
||||
@order.record_paypal_details(params[:token])
|
||||
else
|
||||
flash[:alert] = 'Could not complete your order. Please notify support.'
|
||||
end
|
||||
else
|
||||
flash[:alert] = "PayPal didn't return a token or payer_id for your order. Please notify support."
|
||||
end
|
||||
|
||||
@order.update_account # apply paid account benefits, etc.
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
def cancel
|
||||
respond_to do |format|
|
||||
format.html { redirect_to shop_url, notice: 'Order was cancelled.' }
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /orders/1
|
||||
def destroy
|
||||
@order.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to shop_url, notice: 'Order was deleted.' }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
class PagesController < ApplicationController
|
||||
def letsencrypt
|
||||
# use your code here, not mine
|
||||
render text: 'y9KNck8wqkoQLnlr2RgA2TVwWtyYb4PeY_hzGNx0Tfs.dlIPqFhMDCLyQEccczY3roHZ1UWu6UqVeyb9mkRxheU'
|
||||
render text: "y9KNck8wqkoQLnlr2RgA2TVwWtyYb4PeY_hzGNx0Tfs.dlIPqFhMDCLyQEccczY3roHZ1UWu6UqVeyb9mkRxheU"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ class PhotoAssociationsController < ApplicationController
|
||||
respond_to :json, :html
|
||||
|
||||
def destroy
|
||||
raise 'Photos not supported' unless Photo::PHOTO_CAPABLE.include? item_class
|
||||
raise "Photos not supported" unless Photo::PHOTO_CAPABLE.include? item_class
|
||||
@photo = Photo.find_by!(id: params[:photo_id], owner: current_member)
|
||||
@item = Photographing.item(item_id, item_class)
|
||||
@item.photos.delete(@photo)
|
||||
|
||||
@@ -75,10 +75,10 @@ class PhotosController < ApplicationController
|
||||
|
||||
# Item with photos attached
|
||||
def item_to_link_to
|
||||
raise 'No item id provided' if item_id.nil?
|
||||
raise 'No item type provided' if item_type.nil?
|
||||
raise "No item id provided" if item_id.nil?
|
||||
raise "No item type provided" if item_type.nil?
|
||||
item_class = item_type.capitalize
|
||||
raise 'Photos not supported' unless Photo::PHOTO_CAPABLE.include? item_class
|
||||
raise "Photos not supported" unless Photo::PHOTO_CAPABLE.include? item_class
|
||||
item_class.constantize.find_by!(id: params[:id], owner_id: current_member.id)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
class ProductsController < ApplicationController
|
||||
before_action :authenticate_member!
|
||||
load_and_authorize_resource
|
||||
respond_to :html
|
||||
responders :flash
|
||||
|
||||
def index
|
||||
@products = Product.all.order(:name)
|
||||
respond_with @products
|
||||
end
|
||||
|
||||
def show
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
def new
|
||||
@product = Product.new
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
def edit
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
def create
|
||||
@product = Product.create(product_params)
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
def update
|
||||
@product.update(product_params)
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
def destroy
|
||||
@product.destroy
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product_params
|
||||
params.require(:product).permit(:description, :min_price, :recommended_price, :name,
|
||||
:account_type_id, :paid_months)
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,7 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
@twitter_auth = current_member.auth('twitter')
|
||||
@flickr_auth = current_member.auth('flickr')
|
||||
@facebook_auth = current_member.auth('facebook')
|
||||
render 'edit'
|
||||
render "edit"
|
||||
end
|
||||
|
||||
# we need this subclassed method so that Devise doesn't force people to
|
||||
@@ -32,7 +32,7 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
sign_in @member, bypass: true
|
||||
redirect_to edit_member_registration_path
|
||||
else
|
||||
render 'edit'
|
||||
render "edit"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
if @member.destroy_with_password(params.require(:member)[:current_password])
|
||||
redirect_to root_path
|
||||
else
|
||||
render 'edit'
|
||||
render "edit"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ class SessionsController < Devise::SessionsController
|
||||
def create
|
||||
super do |_resource|
|
||||
if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
|
||||
flash[:alert] = 'There are crops waiting to be wrangled.'
|
||||
flash[:alert] = "There are crops waiting to be wrangled."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
class ShopController < ApplicationController
|
||||
respond_to :html
|
||||
def index
|
||||
@products = Product.all
|
||||
@order_item = OrderItem.new
|
||||
|
||||
# this is (hopefully) part of a short-term hack to prevent people from
|
||||
# ordering multiple subscriptions, which would be very confusing to deal
|
||||
# with. We check whether they have an order already in progress, and if
|
||||
# so, point that out to them and encourage them to checkout, rather than
|
||||
# letting them add more stuff to their order.
|
||||
|
||||
@order = nil
|
||||
@most_recent_item = nil
|
||||
return unless current_member
|
||||
@order = current_member.current_order
|
||||
@most_recent_item = @order.order_items.first if @order
|
||||
end
|
||||
end
|
||||
@@ -18,7 +18,7 @@ module ApplicationHelper
|
||||
currency = Growstuff::Application.config.currency
|
||||
link = "http://www.wolframalpha.com/input/?i=#{pid}+#{currency}"
|
||||
|
||||
link_to '(convert)', link, target: '_blank', rel: 'noopener noreferrer'
|
||||
link_to "(convert)", link, target: "_blank", rel: "noopener noreferrer"
|
||||
end
|
||||
|
||||
def build_alert_classes(alert_type = :info)
|
||||
@@ -37,7 +37,7 @@ module ApplicationHelper
|
||||
end
|
||||
|
||||
# Produces a cache key for uniquely identifying cached fragments.
|
||||
def cache_key_for(klass, identifier = 'all')
|
||||
def cache_key_for(klass, identifier = "all")
|
||||
count = klass.count
|
||||
max_updated_at = klass.maximum(:updated_at).try(:utc).try(:to_s, :number)
|
||||
"#{klass.name.downcase.pluralize}/#{identifier}-#{count}-#{max_updated_at}"
|
||||
@@ -102,7 +102,7 @@ module ApplicationHelper
|
||||
elsif planting
|
||||
t(".title.planting_#{type}", planting: planting.to_s)
|
||||
else
|
||||
t('.title.default')
|
||||
t(".title.default")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ module CropsHelper
|
||||
if total_quantity != 0
|
||||
"You have #{total_quantity} #{Seed.model_name.human(count: total_quantity)} of this crop."
|
||||
else
|
||||
'You have an unknown quantity of seeds of this crop.'
|
||||
"You have an unknown quantity of seeds of this crop."
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module GardensHelper
|
||||
def display_garden_description(garden)
|
||||
if garden.description.nil?
|
||||
'no description provided.'
|
||||
"no description provided."
|
||||
else
|
||||
truncate(garden.description, length: 130, separator: ' ', omission: '... ') do
|
||||
link_to 'Read more', garden_path(garden)
|
||||
link_to "Read more", garden_path(garden)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -19,12 +19,12 @@ module GardensHelper
|
||||
|
||||
def display_garden_plantings(plantings)
|
||||
if plantings.blank?
|
||||
'None'
|
||||
"None"
|
||||
else
|
||||
output = '<ul class="plantings">'
|
||||
plantings.each do |planting|
|
||||
output += '<li>'
|
||||
output += planting.quantity.nil? ? '0 ' : "#{planting.quantity} "
|
||||
output += "<li>"
|
||||
output += planting.quantity.nil? ? "0 " : "#{planting.quantity} "
|
||||
output += link_to planting.crop.name, planting.crop
|
||||
output += ", planted on #{planting.planted_at}</li>"
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ module HarvestsHelper
|
||||
end
|
||||
|
||||
def display_harvest_description(harvest)
|
||||
return 'No description provided.' if harvest.description.nil?
|
||||
return "No description provided." if harvest.description.nil?
|
||||
harvest.description
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,18 +3,18 @@ module PlantingsHelper
|
||||
if planting.finished_at.present?
|
||||
planting.finished_at
|
||||
elsif planting.finished
|
||||
'Yes (no date specified)'
|
||||
"Yes (no date specified)"
|
||||
else
|
||||
'(no date specified)'
|
||||
"(no date specified)"
|
||||
end
|
||||
end
|
||||
|
||||
def display_planted_from(planting)
|
||||
planting.planted_from.present? ? planting.planted_from : 'not specified'
|
||||
planting.planted_from.present? ? planting.planted_from : "not specified"
|
||||
end
|
||||
|
||||
def display_planting_quantity(planting)
|
||||
planting.quantity.present? ? planting.quantity : 'not specified'
|
||||
planting.quantity.present? ? planting.quantity : "not specified"
|
||||
end
|
||||
|
||||
def display_planting(planting)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
module SeedsHelper
|
||||
def display_seed_description(seed)
|
||||
if seed.description.nil?
|
||||
'no description provided.'
|
||||
"no description provided."
|
||||
else
|
||||
truncate(seed.description, length: 130, separator: ' ', omission: '... ') { link_to 'Read more', seed_path(seed) }
|
||||
truncate(seed.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", seed_path(seed) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
class Notifier < ActionMailer::Base
|
||||
include NotificationsHelper
|
||||
default from: 'Growstuff <noreply@growstuff.org>'
|
||||
default from: "Growstuff <noreply@growstuff.org>"
|
||||
|
||||
def verifier
|
||||
unless ENV['RAILS_SECRET_TOKEN']
|
||||
raise 'RAILS_SECRET_TOKEN environment variable'\
|
||||
'not set - have you created config/application.yml?'
|
||||
raise "RAILS_SECRET_TOKEN environment variable"\
|
||||
"not set - have you created config/application.yml?"
|
||||
end
|
||||
|
||||
ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
|
||||
@@ -33,7 +33,7 @@ class Notifier < ActionMailer::Base
|
||||
message = { member_id: @member.id, type: :send_planting_reminder }
|
||||
@signed_message = verifier.generate(message)
|
||||
|
||||
mail(to: @member.email, subject: 'What have you planted lately?') if @member.send_planting_reminder
|
||||
mail(to: @member.email, subject: "What have you planted lately?") if @member.send_planting_reminder
|
||||
end
|
||||
|
||||
def new_crop_request(member, request)
|
||||
|
||||
@@ -24,19 +24,14 @@ class Ability
|
||||
# except these, which don't make sense if you're not logged in
|
||||
cannot :read, Notification
|
||||
cannot :read, Authentication
|
||||
cannot :read, Order
|
||||
cannot :read, OrderItem
|
||||
|
||||
# and nobody should be able to view this except admins
|
||||
cannot :read, Role
|
||||
cannot :read, Product
|
||||
cannot :read, Account
|
||||
cannot :read, AccountType
|
||||
|
||||
# nobody should be able to view unapproved crops unless they
|
||||
# are wranglers or admins
|
||||
cannot :read, Crop
|
||||
can :read, Crop, approval_status: 'approved'
|
||||
can :read, Crop, approval_status: "approved"
|
||||
# scientific names should only be viewable if associated crop is approved
|
||||
cannot :read, ScientificName
|
||||
can :read, ScientificName do |sn|
|
||||
@@ -120,20 +115,6 @@ class Ability
|
||||
can :update, Seed, owner_id: member.id
|
||||
can :destroy, Seed, owner_id: member.id
|
||||
|
||||
# orders/shop/etc
|
||||
can :create, Order
|
||||
can :read, Order, member_id: member.id
|
||||
can :complete, Order, member_id: member.id, completed_at: nil
|
||||
can :checkout, Order, member_id: member.id, completed_at: nil
|
||||
can :cancel, Order, member_id: member.id, completed_at: nil
|
||||
can :destroy, Order, member_id: member.id, completed_at: nil
|
||||
|
||||
can :create, OrderItem
|
||||
# for now, let's not let people mess with individual order items
|
||||
cannot :read, OrderItem, order: { member_id: member.id }
|
||||
cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil }
|
||||
cannot :destroy, OrderItem, order: { member_id: member.id, completed_at: nil }
|
||||
|
||||
# following/unfollowing permissions
|
||||
can :create, Follow
|
||||
cannot :create, Follow, followed_id: member.id # can't follow yourself
|
||||
@@ -148,12 +129,6 @@ class Ability
|
||||
can :read, :all
|
||||
can :manage, :all
|
||||
|
||||
# can't change order history, because it's *history*
|
||||
cannot :create, Order
|
||||
cannot :complete, Order
|
||||
cannot :destroy, Order
|
||||
cannot :manage, OrderItem
|
||||
|
||||
# can't delete plant parts if they have harvests associated with them
|
||||
cannot :destroy, PlantPart
|
||||
can :destroy, PlantPart do |pp|
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
class Account < ActiveRecord::Base
|
||||
belongs_to :member
|
||||
belongs_to :account_type
|
||||
|
||||
validates :member_id, uniqueness: {
|
||||
message: 'already has account details associated with it'
|
||||
}
|
||||
|
||||
before_create do |account|
|
||||
unless account.account_type
|
||||
account.account_type = AccountType.find_or_create_by(name:
|
||||
Growstuff::Application.config.default_account_type)
|
||||
end
|
||||
end
|
||||
|
||||
def paid_until_string
|
||||
if account_type.is_permanent_paid
|
||||
'forever'
|
||||
elsif account_type.is_paid
|
||||
paid_until.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
class AccountType < ActiveRecord::Base
|
||||
#
|
||||
# Relationships
|
||||
has_many :products
|
||||
|
||||
#
|
||||
# Validations
|
||||
validates :name, presence: true, uniqueness: true
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class AlternateName < ActiveRecord::Base
|
||||
after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == 'true' }
|
||||
after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" }
|
||||
belongs_to :crop
|
||||
belongs_to :creator, class_name: 'Member'
|
||||
validates :name, presence: true
|
||||
|
||||
@@ -2,7 +2,7 @@ class Comment < ActiveRecord::Base
|
||||
belongs_to :author, class_name: 'Member'
|
||||
belongs_to :post
|
||||
|
||||
scope :post_order, -> { reorder('created_at ASC') } # for display on post page
|
||||
scope :post_order, -> { reorder("created_at ASC") } # for display on post page
|
||||
|
||||
after_create do
|
||||
recipient = post.author.id
|
||||
|
||||
@@ -15,7 +15,7 @@ class Crop < ActiveRecord::Base
|
||||
has_many :photos, through: :plantings
|
||||
has_many :seeds
|
||||
has_many :harvests
|
||||
has_many :plant_parts, -> { uniq.reorder('plant_parts.name') }, through: :harvests
|
||||
has_many :plant_parts, -> { uniq.reorder("plant_parts.name") }, through: :harvests
|
||||
belongs_to :creator, class_name: 'Member'
|
||||
belongs_to :requester, class_name: 'Member'
|
||||
belongs_to :parent, class_name: 'Crop'
|
||||
@@ -26,12 +26,12 @@ class Crop < ActiveRecord::Base
|
||||
## Scopes
|
||||
scope :recent, -> { approved.order(created_at: :desc) }
|
||||
scope :toplevel, -> { approved.where(parent_id: nil) }
|
||||
scope :popular, -> { approved.reorder('plantings_count desc, lower(name) asc') }
|
||||
scope :popular, -> { approved.reorder("plantings_count desc, lower(name) asc") }
|
||||
# ok on sqlite and psql, but not on mysql
|
||||
scope :randomized, -> { approved.reorder('random()') }
|
||||
scope :pending_approval, -> { where(approval_status: 'pending') }
|
||||
scope :approved, -> { where(approval_status: 'approved') }
|
||||
scope :rejected, -> { where(approval_status: 'rejected') }
|
||||
scope :pending_approval, -> { where(approval_status: "pending") }
|
||||
scope :approved, -> { where(approval_status: "approved") }
|
||||
scope :rejected, -> { where(approval_status: "rejected") }
|
||||
scope :interesting, -> { approved.has_photos.randomized }
|
||||
scope :has_photos, -> { includes(:photos).where.not(photos: { id: nil }) }
|
||||
|
||||
@@ -53,17 +53,17 @@ class Crop < ActiveRecord::Base
|
||||
|
||||
####################################
|
||||
# Elastic search configuration
|
||||
if ENV['GROWSTUFF_ELASTICSEARCH'] == 'true'
|
||||
if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
|
||||
include Elasticsearch::Model
|
||||
include Elasticsearch::Model::Callbacks
|
||||
# In order to avoid clashing between different environments,
|
||||
# use Rails.env as a part of index name (eg. development_growstuff)
|
||||
index_name [Rails.env, 'growstuff'].join('_')
|
||||
index_name [Rails.env, "growstuff"].join('_')
|
||||
settings index: { number_of_shards: 1 },
|
||||
analysis: {
|
||||
tokenizer: {
|
||||
gs_edgeNGram_tokenizer: {
|
||||
type: 'edgeNGram', # edgeNGram: NGram match from the start of a token
|
||||
type: "edgeNGram", # edgeNGram: NGram match from the start of a token
|
||||
min_gram: 3,
|
||||
max_gram: 10,
|
||||
# token_chars: Elasticsearch will split on characters
|
||||
@@ -73,8 +73,8 @@ class Crop < ActiveRecord::Base
|
||||
},
|
||||
analyzer: {
|
||||
gs_edgeNGram_analyzer: {
|
||||
tokenizer: 'gs_edgeNGram_tokenizer',
|
||||
filter: ['lowercase']
|
||||
tokenizer: "gs_edgeNGram_tokenizer",
|
||||
filter: ["lowercase"]
|
||||
}
|
||||
}
|
||||
} do
|
||||
@@ -104,7 +104,7 @@ class Crop < ActiveRecord::Base
|
||||
# update the Elasticsearch index (only if we're using it in this
|
||||
# environment)
|
||||
def update_index(_name_obj)
|
||||
__elasticsearch__.index_document if ENV['GROWSTUFF_ELASTICSEARCH'] == 'true'
|
||||
__elasticsearch__.index_document if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
|
||||
end
|
||||
# End Elasticsearch section
|
||||
|
||||
@@ -148,10 +148,10 @@ class Crop < ActiveRecord::Base
|
||||
# value: count of how many times it's been used by harvests
|
||||
def popular_plant_parts
|
||||
PlantPart.joins(:harvests)
|
||||
.where('crop_id = ?', id)
|
||||
.order('count_harvests_id DESC')
|
||||
.group('plant_parts.id', 'plant_parts.name')
|
||||
.count('harvests.id')
|
||||
.where("crop_id = ?", id)
|
||||
.order("count_harvests_id DESC")
|
||||
.group("plant_parts.id", "plant_parts.name")
|
||||
.count("harvests.id")
|
||||
end
|
||||
|
||||
def annual?
|
||||
@@ -167,15 +167,15 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def pending?
|
||||
approval_status == 'pending'
|
||||
approval_status == "pending"
|
||||
end
|
||||
|
||||
def approved?
|
||||
approval_status == 'approved'
|
||||
approval_status == "approved"
|
||||
end
|
||||
|
||||
def rejected?
|
||||
approval_status == 'rejected'
|
||||
approval_status == "rejected"
|
||||
end
|
||||
|
||||
def approval_statuses
|
||||
@@ -183,11 +183,11 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def reasons_for_rejection
|
||||
['already in database', 'not edible', 'not enough information', 'other']
|
||||
["already in database", "not edible", "not enough information", "other"]
|
||||
end
|
||||
|
||||
def rejection_explanation
|
||||
return rejection_notes if reason_for_rejection == 'other'
|
||||
return rejection_notes if reason_for_rejection == "other"
|
||||
reason_for_rejection
|
||||
end
|
||||
|
||||
@@ -212,7 +212,7 @@ class Crop < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.case_insensitive_name(name)
|
||||
where(['lower(crops.name) = :value', { value: name.downcase }])
|
||||
where(["lower(crops.name) = :value", { value: name.downcase }])
|
||||
end
|
||||
|
||||
private
|
||||
@@ -235,11 +235,11 @@ class Crop < ActiveRecord::Base
|
||||
def must_be_rejected_if_rejected_reasons_present
|
||||
return if rejected?
|
||||
return unless reason_for_rejection.present? || rejection_notes.present?
|
||||
errors.add(:approval_status, 'must be rejected if a reason for rejection is present')
|
||||
errors.add(:approval_status, "must be rejected if a reason for rejection is present")
|
||||
end
|
||||
|
||||
def must_have_meaningful_reason_for_rejection
|
||||
return unless reason_for_rejection == 'other' && rejection_notes.blank?
|
||||
errors.add(:rejection_notes, 'must be added if the reason for rejection is "other"')
|
||||
return unless reason_for_rejection == "other" && rejection_notes.blank?
|
||||
errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,6 +65,6 @@ class CsvImporter
|
||||
@cropbot ||= Member.find_by!(login_name: 'cropbot')
|
||||
@cropbot
|
||||
rescue StandardError
|
||||
raise 'cropbot account not found: run rake db:seed'
|
||||
raise "cropbot account not found: run rake db:seed"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Follow < ActiveRecord::Base
|
||||
belongs_to :follower, class_name: 'Member'
|
||||
belongs_to :followed, class_name: 'Member'
|
||||
belongs_to :follower, class_name: "Member"
|
||||
belongs_to :followed, class_name: "Member"
|
||||
validates :follower_id, uniqueness: { scope: :followed_id }
|
||||
|
||||
after_create do
|
||||
|
||||
@@ -4,7 +4,7 @@ class Forum < ActiveRecord::Base
|
||||
friendly_id :name, use: %i(slugged finders)
|
||||
|
||||
has_many :posts
|
||||
belongs_to :owner, class_name: 'Member'
|
||||
belongs_to :owner, class_name: "Member"
|
||||
|
||||
def to_s
|
||||
name
|
||||
|
||||
@@ -35,13 +35,13 @@ class Garden < ActiveRecord::Base
|
||||
allow_nil: true
|
||||
|
||||
AREA_UNITS_VALUES = {
|
||||
'square metres' => 'square metre',
|
||||
'square feet' => 'square foot',
|
||||
'hectares' => 'hectare',
|
||||
'acres' => 'acre'
|
||||
"square metres" => "square metre",
|
||||
"square feet" => "square foot",
|
||||
"hectares" => "hectare",
|
||||
"acres" => "acre"
|
||||
}.freeze
|
||||
validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values,
|
||||
message: '%<value>s is not a valid area unit' },
|
||||
message: "%<value>s is not a valid area unit" },
|
||||
allow_nil: true,
|
||||
allow_blank: true
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@ class Harvest < ActiveRecord::Base
|
||||
|
||||
# Constants
|
||||
UNITS_VALUES = {
|
||||
'individual' => 'individual',
|
||||
'bunches' => 'bunch',
|
||||
'sprigs' => 'sprig',
|
||||
'handfuls' => 'handful',
|
||||
'litres' => 'litre',
|
||||
'pints' => 'pint',
|
||||
'quarts' => 'quart',
|
||||
'buckets' => 'bucket',
|
||||
'baskets' => 'basket',
|
||||
'bushels' => 'bushel'
|
||||
"individual" => "individual",
|
||||
"bunches" => "bunch",
|
||||
"sprigs" => "sprig",
|
||||
"handfuls" => "handful",
|
||||
"litres" => "litre",
|
||||
"pints" => "pint",
|
||||
"quarts" => "quart",
|
||||
"buckets" => "bucket",
|
||||
"baskets" => "basket",
|
||||
"bushels" => "bushel"
|
||||
}.freeze
|
||||
|
||||
WEIGHT_UNITS_VALUES = {
|
||||
'kg' => 'kg',
|
||||
'lb' => 'lb',
|
||||
'oz' => 'oz'
|
||||
"kg" => "kg",
|
||||
"lb" => "lb",
|
||||
"oz" => "oz"
|
||||
}.freeze
|
||||
|
||||
##
|
||||
@@ -44,18 +44,18 @@ class Harvest < ActiveRecord::Base
|
||||
##
|
||||
## Validations
|
||||
validates :crop, approved: true
|
||||
validates :crop, presence: { message: 'must be present and exist in our database' }
|
||||
validates :plant_part, presence: { message: 'must be present and exist in our database' }
|
||||
validates :crop, presence: { message: "must be present and exist in our database" }
|
||||
validates :plant_part, presence: { message: "must be present and exist in our database" }
|
||||
validates :harvested_at, presence: true
|
||||
validates :quantity, allow_nil: true, numericality: {
|
||||
only_integer: false, greater_than_or_equal_to: 0
|
||||
}
|
||||
validates :unit, allow_nil: true, allow_blank: true, inclusion: {
|
||||
in: UNITS_VALUES.values, message: '%<value>s is not a valid unit'
|
||||
in: UNITS_VALUES.values, message: "%<value>s is not a valid unit"
|
||||
}
|
||||
validates :weight_quantity, allow_nil: true, numericality: { only_integer: false }
|
||||
validates :weight_unit, allow_nil: true, allow_blank: true, inclusion: {
|
||||
in: WEIGHT_UNITS_VALUES.values, message: '%<value>s is not a valid unit'
|
||||
in: WEIGHT_UNITS_VALUES.values, message: "%<value>s is not a valid unit"
|
||||
}
|
||||
validate :crop_must_match_planting
|
||||
validate :owner_must_match_planting
|
||||
@@ -71,7 +71,7 @@ class Harvest < ActiveRecord::Base
|
||||
def set_si_weight
|
||||
return if weight_unit.nil?
|
||||
weight_string = "#{weight_quantity} #{weight_unit}"
|
||||
self.si_weight = Unit.new(weight_string).convert_to('kg').to_s('%0.3f').delete(' kg').to_f
|
||||
self.si_weight = Unit.new(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f
|
||||
end
|
||||
|
||||
def cleanup_quantities
|
||||
@@ -94,11 +94,11 @@ class Harvest < ActiveRecord::Base
|
||||
|
||||
def quantity_to_human
|
||||
return number_to_human(quantity.to_s, strip_insignificant_zeros: true) if quantity
|
||||
''
|
||||
""
|
||||
end
|
||||
|
||||
def unit_to_human
|
||||
return '' unless quantity
|
||||
return "" unless quantity
|
||||
if unit == 'individual'
|
||||
'individual'
|
||||
elsif quantity == 1
|
||||
@@ -109,7 +109,7 @@ class Harvest < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def weight_to_human
|
||||
return '' unless weight_quantity
|
||||
return "" unless weight_quantity
|
||||
"weighing #{number_to_human(weight_quantity, strip_insignificant_zeros: true)} #{weight_unit}"
|
||||
end
|
||||
|
||||
@@ -131,17 +131,17 @@ class Harvest < ActiveRecord::Base
|
||||
|
||||
def crop_must_match_planting
|
||||
return if planting.blank? # only check if we are linked to a planting
|
||||
errors.add(:planting, 'must be the same crop') unless crop == planting.crop
|
||||
errors.add(:planting, "must be the same crop") unless crop == planting.crop
|
||||
end
|
||||
|
||||
def owner_must_match_planting
|
||||
return if planting.blank? # only check if we are linked to a planting
|
||||
errors.add(:owner, 'of harvest must be the same as planting') unless owner == planting.owner
|
||||
errors.add(:owner, "of harvest must be the same as planting") unless owner == planting.owner
|
||||
end
|
||||
|
||||
def harvest_must_be_after_planting
|
||||
# only check if we are linked to a planting
|
||||
return unless harvested_at.present? && planting.present? && planting.planted_at.present?
|
||||
errors.add(:planting, 'cannot be harvested before planting') unless harvested_at > planting.planted_at
|
||||
errors.add(:planting, "cannot be harvested before planting") unless harvested_at > planting.planted_at
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ class Member < ActiveRecord::Base
|
||||
friendly_id :login_name, use: %i(slugged finders)
|
||||
|
||||
#
|
||||
# Relationshops
|
||||
# Relationships
|
||||
has_many :posts, foreign_key: 'author_id'
|
||||
has_many :comments, foreign_key: 'author_id'
|
||||
has_many :forums, foreign_key: 'owner_id'
|
||||
@@ -19,14 +19,11 @@ class Member < ActiveRecord::Base
|
||||
has_many :notifications, foreign_key: 'recipient_id'
|
||||
has_many :sent_notifications, foreign_key: 'sender_id'
|
||||
has_many :authentications
|
||||
has_many :orders
|
||||
has_one :account
|
||||
has_one :account_type, through: :account
|
||||
has_many :photos
|
||||
has_many :requested_crops, class_name: Crop, foreign_key: 'requester_id'
|
||||
has_many :likes, dependent: :destroy
|
||||
has_many :follows, class_name: 'Follow', foreign_key: 'follower_id', dependent: :destroy
|
||||
has_many :inverse_follows, class_name: 'Follow', foreign_key: 'followed_id', dependent: :destroy
|
||||
has_many :follows, class_name: "Follow", foreign_key: "follower_id", dependent: :destroy
|
||||
has_many :inverse_follows, class_name: "Follow", foreign_key: "followed_id", dependent: :destroy
|
||||
has_many :followed, through: :follows
|
||||
has_many :followers, through: :inverse_follows, source: :follower
|
||||
|
||||
@@ -38,7 +35,7 @@ class Member < ActiveRecord::Base
|
||||
scope :recently_joined, -> { reorder(confirmed_at: :desc) }
|
||||
scope :wants_newsletter, -> { where(newsletter: true) }
|
||||
scope :interesting, -> { confirmed.located.recently_signed_in.has_plantings }
|
||||
scope :has_plantings, -> { joins(:plantings).group('members.id') }
|
||||
scope :has_plantings, -> { joins(:plantings).group("members.id") }
|
||||
|
||||
# Include default devise modules. Others available are:
|
||||
# :token_authenticatable, :confirmable,
|
||||
@@ -60,13 +57,13 @@ class Member < ActiveRecord::Base
|
||||
validates :tos_agreement, acceptance: { allow_nil: true, accept: true }
|
||||
validates :login_name,
|
||||
length: {
|
||||
minimum: 2, maximum: 25, message: 'should be between 2 and 25 characters long'
|
||||
minimum: 2, maximum: 25, message: "should be between 2 and 25 characters long"
|
||||
},
|
||||
exclusion: {
|
||||
in: %w(growstuff admin moderator staff nearby), message: 'name is reserved'
|
||||
in: %w(growstuff admin moderator staff nearby), message: "name is reserved"
|
||||
},
|
||||
format: {
|
||||
with: /\A\w+\z/, message: 'may only include letters, numbers, or underscores'
|
||||
with: /\A\w+\z/, message: "may only include letters, numbers, or underscores"
|
||||
},
|
||||
uniqueness: {
|
||||
case_sensitive: false
|
||||
@@ -79,11 +76,9 @@ class Member < ActiveRecord::Base
|
||||
after_save :update_newsletter_subscription
|
||||
|
||||
# Give each new member a default garden
|
||||
# and an account record (for paid accounts etc)
|
||||
# we use find_or_create to avoid accidentally creating a second one,
|
||||
# which can happen sometimes especially with FactoryBot associations
|
||||
after_create { |member| Garden.create(name: 'Garden', owner_id: member.id) }
|
||||
after_create { |member| Account.find_or_create_by(member_id: member.id) }
|
||||
after_create { |member| Garden.create(name: "Garden", owner_id: member.id) }
|
||||
|
||||
# allow login via either login_name or email address
|
||||
def self.find_first_by_auth_conditions(warden_conditions)
|
||||
@@ -98,35 +93,7 @@ class Member < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def role?(role_sym)
|
||||
roles.any? { |r| r.name.gsub(/\s+/, '_').underscore.to_sym == role_sym }
|
||||
end
|
||||
|
||||
def current_order
|
||||
orders.find_by(completed_at: nil)
|
||||
end
|
||||
|
||||
# when purchasing a product that gives you a paid account, this method
|
||||
# does all the messing around to actually make sure the account is
|
||||
# updated correctly -- account type, paid until, etc. Usually this is
|
||||
# called by order.update_account, which loops through all order items
|
||||
# and does this for each one.
|
||||
def update_account_after_purchase(product)
|
||||
account.account_type = product.account_type if product.account_type
|
||||
if product.paid_months
|
||||
start_date = account.paid_until || Time.zone.now
|
||||
account.paid_until = start_date + product.paid_months.months
|
||||
end
|
||||
account.save
|
||||
end
|
||||
|
||||
def paid?
|
||||
if account.account_type.is_permanent_paid
|
||||
true
|
||||
elsif account.account_type.is_paid && account.paid_until >= Time.zone.now
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
roles.any? { |r| r.name.gsub(/\s+/, "_").underscore.to_sym == role_sym }
|
||||
end
|
||||
|
||||
def auth(provider)
|
||||
@@ -179,11 +146,11 @@ class Member < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.login_name_or_email(login)
|
||||
where(['lower(login_name) = :value OR lower(email) = :value', { value: login.downcase }])
|
||||
where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }])
|
||||
end
|
||||
|
||||
def self.case_insensitive_login_name(login)
|
||||
where(['lower(login_name) = :value', { value: login.downcase }])
|
||||
where(["lower(login_name) = :value", { value: login.downcase }])
|
||||
end
|
||||
|
||||
def self.nearest_to(place)
|
||||
|
||||
@@ -16,7 +16,7 @@ class Notification < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def replace_blank_subject
|
||||
self.subject = '(no subject)' if subject.nil? || subject =~ /^\s*$/
|
||||
self.subject = "(no subject)" if subject.nil? || subject =~ /^\s*$/
|
||||
end
|
||||
|
||||
def send_email
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
class Order < ActiveRecord::Base
|
||||
#
|
||||
# Relationships
|
||||
belongs_to :member, with_deleted: true
|
||||
has_many :order_items, dependent: :destroy
|
||||
|
||||
#
|
||||
# Validations
|
||||
validates :referral_code, format: {
|
||||
with: /\A[a-zA-Z0-9 ]*\z/,
|
||||
message: 'may only include letters and numbers'
|
||||
}
|
||||
|
||||
#
|
||||
# Teiggers
|
||||
before_save :standardize_referral_code
|
||||
|
||||
#
|
||||
# Scopes
|
||||
scope :by_member, ->(member) { where(member: member) }
|
||||
|
||||
# total price of an order
|
||||
def total
|
||||
sum = 0
|
||||
order_items.each do |i|
|
||||
subtotal = i.price * i.quantity
|
||||
sum += subtotal
|
||||
end
|
||||
sum
|
||||
end
|
||||
|
||||
# return items in the format ActiveMerchant/PayPal want them
|
||||
def activemerchant_items
|
||||
items = []
|
||||
order_items.each do |i|
|
||||
items.push(name: i.product.name,
|
||||
quantity: i.quantity,
|
||||
amount: i.price)
|
||||
end
|
||||
items
|
||||
end
|
||||
|
||||
# record the paypal details for reference
|
||||
def record_paypal_details(token)
|
||||
self.paypal_express_token = token
|
||||
details = EXPRESS_GATEWAY.details_for(token)
|
||||
self.paypal_express_payer_id = details.payer_id
|
||||
save
|
||||
end
|
||||
|
||||
# when an order is completed, we update the member's account to mark
|
||||
# them as paid, or whatever, based on what products they ordered
|
||||
def update_account
|
||||
order_items.each do |i|
|
||||
member.update_account_after_purchase(i.product)
|
||||
end
|
||||
end
|
||||
|
||||
# removes whitespace and forces to uppercase (we're somewhat liberal
|
||||
# in what we accept, but we clean it up anyway.)
|
||||
def standardize_referral_code
|
||||
self.referral_code = referral_code.upcase.gsub(/\s/, '') if referral_code
|
||||
end
|
||||
|
||||
# search orders (used by admin/orders)
|
||||
# usage: Order.search({ :by => 'member', :for => 'Skud' })
|
||||
# can search by: member, order_id, paypal_token, paypal_payer_id,
|
||||
def self.search(args = {})
|
||||
if args[:for]
|
||||
case args[:by]
|
||||
when 'member'
|
||||
member = Member.with_deleted.find_by(login_name: args[:for])
|
||||
return member.orders if member
|
||||
when 'order_id'
|
||||
order = Order.find_by(id: args[:for])
|
||||
return [order] if order
|
||||
when 'paypal_token'
|
||||
order = Order.find_by(paypal_express_token: args[:for])
|
||||
return [order] if order
|
||||
when 'paypal_payer_id'
|
||||
order = Order.find_by(paypal_express_payer_id: args[:for])
|
||||
return [order] if order
|
||||
when 'referral_code'
|
||||
# coerce to uppercase
|
||||
return Order.where(referral_code: args[:for].upcase)
|
||||
end
|
||||
end
|
||||
[]
|
||||
end
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
class OrderItem < ActiveRecord::Base
|
||||
belongs_to :order
|
||||
belongs_to :product
|
||||
|
||||
validate :price_must_be_greater_than_minimum
|
||||
validates :order_id, uniqueness: { message: 'may only have one item.' }
|
||||
|
||||
def price_must_be_greater_than_minimum
|
||||
@product = Product.find(product_id)
|
||||
errors.add(:price, "must be greater than the product's minimum value") if price < @product.min_price
|
||||
end
|
||||
end
|
||||
@@ -30,7 +30,7 @@ class Planting < ActiveRecord::Base
|
||||
scope :one_per_owner, lambda {
|
||||
joins("JOIN members m ON (m.id=plantings.owner_id)
|
||||
LEFT OUTER JOIN plantings p2
|
||||
ON (m.id=p2.owner_id AND plantings.id < p2.id)").where('p2 IS NULL')
|
||||
ON (m.id=p2.owner_id AND plantings.id < p2.id)").where("p2 IS NULL")
|
||||
}
|
||||
|
||||
##
|
||||
@@ -41,17 +41,17 @@ class Planting < ActiveRecord::Base
|
||||
##
|
||||
## Validations
|
||||
validates :garden, presence: true
|
||||
validates :crop, presence: true, approved: { message: 'must be present and exist in our database' }
|
||||
validates :crop, presence: true, approved: { message: "must be present and exist in our database" }
|
||||
validate :finished_must_be_after_planted
|
||||
validate :owner_must_match_garden_owner
|
||||
validates :quantity, allow_nil: true, numericality: {
|
||||
only_integer: true, greater_than_or_equal_to: 0
|
||||
}
|
||||
validates :sunniness, allow_nil: true, allow_blank: true, inclusion: {
|
||||
in: SUNNINESS_VALUES, message: '%<value>s is not a valid sunniness value'
|
||||
in: SUNNINESS_VALUES, message: "%<value>s is not a valid sunniness value"
|
||||
}
|
||||
validates :planted_from, allow_nil: true, allow_blank: true, inclusion: {
|
||||
in: PLANTED_FROM_VALUES, message: '%<value>s is not a valid planting method'
|
||||
in: PLANTED_FROM_VALUES, message: "%<value>s is not a valid planting method"
|
||||
}
|
||||
|
||||
def planting_slug
|
||||
@@ -64,7 +64,7 @@ class Planting < ActiveRecord::Base
|
||||
|
||||
# location = garden owner + garden name, i.e. "Skud's backyard"
|
||||
def location
|
||||
I18n.t('gardens.location', garden: garden.name, owner: garden.owner.login_name)
|
||||
I18n.t("gardens.location", garden: garden.name, owner: garden.owner.login_name)
|
||||
end
|
||||
|
||||
# stringify as "beet in Skud's backyard" or similar
|
||||
@@ -134,10 +134,10 @@ class Planting < ActiveRecord::Base
|
||||
# check that any finished_at date occurs after planted_at
|
||||
def finished_must_be_after_planted
|
||||
return unless planted_at && finished_at # only check if we have both
|
||||
errors.add(:finished_at, 'must be after the planting date') unless planted_at < finished_at
|
||||
errors.add(:finished_at, "must be after the planting date") unless planted_at < finished_at
|
||||
end
|
||||
|
||||
def owner_must_match_garden_owner
|
||||
errors.add(:owner, 'must be the same as garden') unless owner == garden.owner
|
||||
errors.add(:owner, "must be the same as garden") unless owner == garden.owner
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
class Product < ActiveRecord::Base
|
||||
#
|
||||
# Relationships
|
||||
belongs_to :account_type
|
||||
has_and_belongs_to_many :orders # rubocop:disable Rails/HasAndBelongsToMany
|
||||
|
||||
#
|
||||
# Validations
|
||||
validates :paid_months, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
validates :min_price, presence: true
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class ScientificName < ActiveRecord::Base
|
||||
after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == 'true' }
|
||||
after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" }
|
||||
belongs_to :crop
|
||||
belongs_to :creator, class_name: 'Member'
|
||||
validates :name, presence: true
|
||||
|
||||
@@ -16,7 +16,7 @@ class Seed < ActiveRecord::Base
|
||||
#
|
||||
# Validations
|
||||
validates :crop, approved: true
|
||||
validates :crop, presence: { message: 'must be present and exist in our database' }
|
||||
validates :crop, presence: { message: "must be present and exist in our database" }
|
||||
validates :quantity, allow_nil: true,
|
||||
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
validates :days_until_maturity_min, allow_nil: true,
|
||||
@@ -24,17 +24,17 @@ class Seed < ActiveRecord::Base
|
||||
validates :days_until_maturity_max, allow_nil: true,
|
||||
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
validates :tradable_to, allow_nil: false, allow_blank: false,
|
||||
inclusion: { in: TRADABLE_TO_VALUES, message: 'You may only trade seed nowhere, '\
|
||||
'locally, nationally, or internationally' }
|
||||
inclusion: { in: TRADABLE_TO_VALUES, message: "You may only trade seed nowhere, "\
|
||||
"locally, nationally, or internationally" }
|
||||
validates :organic, allow_nil: false, allow_blank: false,
|
||||
inclusion: { in: ORGANIC_VALUES, message: 'You must say whether the seeds '\
|
||||
inclusion: { in: ORGANIC_VALUES, message: "You must say whether the seeds "\
|
||||
"are organic or not, or that you don't know" }
|
||||
validates :gmo, allow_nil: false, allow_blank: false,
|
||||
inclusion: { in: GMO_VALUES, message: 'You must say whether the seeds are '\
|
||||
inclusion: { in: GMO_VALUES, message: "You must say whether the seeds are "\
|
||||
"genetically modified or not, or that you don't know" }
|
||||
validates :heirloom, allow_nil: false, allow_blank: false,
|
||||
inclusion: { in: HEIRLOOM_VALUES, message: 'You must say whether the seeds'\
|
||||
'are heirloom, hybrid, or unknown' }
|
||||
inclusion: { in: HEIRLOOM_VALUES, message: "You must say whether the seeds"\
|
||||
"are heirloom, hybrid, or unknown" }
|
||||
|
||||
#
|
||||
# Delegations
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
class CropSearchService
|
||||
# Crop.search(string)
|
||||
def self.search(query)
|
||||
if ENV['GROWSTUFF_ELASTICSEARCH'] == 'true'
|
||||
search_str = query.nil? ? '' : query.downcase
|
||||
if ENV['GROWSTUFF_ELASTICSEARCH'] == "true"
|
||||
search_str = query.nil? ? "" : query.downcase
|
||||
response = Crop.__elasticsearch__.search( # Finds documents which match any field, but uses the _score from
|
||||
# the best field insead of adding up _score from each field.
|
||||
query: {
|
||||
multi_match: {
|
||||
query: search_str.to_s,
|
||||
analyzer: 'standard',
|
||||
fields: ['name',
|
||||
'scientific_names.scientific_name',
|
||||
'alternate_names.name']
|
||||
analyzer: "standard",
|
||||
fields: ["name",
|
||||
"scientific_names.scientific_name",
|
||||
"alternate_names.name"]
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
term: { approval_status: 'approved' }
|
||||
term: { approval_status: "approved" }
|
||||
},
|
||||
size: 50
|
||||
)
|
||||
@@ -26,7 +26,7 @@ class CropSearchService
|
||||
# collection, so it matches what we get from elasticsearch and we can
|
||||
# manipulate it in the same ways (eg. deleting elements without deleting
|
||||
# the whole record from the db)
|
||||
matches = Crop.approved.where('name ILIKE ?', "%#{query}%").to_a
|
||||
matches = Crop.approved.where("name ILIKE ?", "%#{query}%").to_a
|
||||
|
||||
# we want to make sure that exact matches come first, even if not
|
||||
# using elasticsearch (eg. in development)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
= form_for @account_type do |f|
|
||||
- if @account_type.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@account_type.errors.size, "error")
|
||||
prohibited this account_type from being saved:
|
||||
%ul
|
||||
- @account_type.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.field
|
||||
= f.label :name
|
||||
= f.text_field :name
|
||||
.field
|
||||
= f.label :is_paid
|
||||
= f.check_box :is_paid
|
||||
.field
|
||||
= f.label :is_permanent_paid
|
||||
= f.check_box :is_permanent_paid
|
||||
.actions
|
||||
= f.submit 'Save'
|
||||
@@ -1,7 +0,0 @@
|
||||
- content_for :title, "Editing account type"
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Show', @account_type
|
||||
\|
|
||||
= link_to 'Back', account_types_path
|
||||
@@ -1,23 +0,0 @@
|
||||
- content_for :title, "Listing account types"
|
||||
|
||||
%table
|
||||
%tr
|
||||
%th Name
|
||||
%th Is paid
|
||||
%th Is permanent paid
|
||||
%th
|
||||
%th
|
||||
%th
|
||||
|
||||
- @account_types.each do |account_type|
|
||||
%tr
|
||||
%td= account_type.name
|
||||
%td= account_type.is_paid
|
||||
%td= account_type.is_permanent_paid
|
||||
%td= link_to 'Show', account_type
|
||||
%td= link_to 'Edit', edit_account_type_path(account_type)
|
||||
%td= link_to 'Destroy', account_type, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
|
||||
%br
|
||||
|
||||
= link_to 'New Account type', new_account_type_path
|
||||
@@ -1,5 +0,0 @@
|
||||
- content_for :title, "New account type"
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Back', account_types_path
|
||||
@@ -1,17 +0,0 @@
|
||||
%p#notice= notice
|
||||
|
||||
%p
|
||||
%b Name:
|
||||
= @account_type.name
|
||||
%p
|
||||
%b Is paid:
|
||||
= @account_type.is_paid
|
||||
%p
|
||||
%b Is permanent paid:
|
||||
= @account_type.is_permanent_paid
|
||||
|
||||
= link_to 'Edit', edit_account_type_path(@account_type)
|
||||
\|
|
||||
= link_to 'Delete', @account_type, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
\|
|
||||
= link_to 'Back', account_types_path
|
||||
@@ -1,21 +0,0 @@
|
||||
= form_for @account do |f|
|
||||
- if @account.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@account.errors.size, "error")
|
||||
prohibited this account from being saved:
|
||||
%ul
|
||||
- @account.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.field
|
||||
= f.label :member_id
|
||||
= f.number_field :member_id
|
||||
.field
|
||||
= f.label :account_type
|
||||
= f.text_field :account_type
|
||||
.field
|
||||
= f.label :paid_until
|
||||
= f.datetime_select :paid_until
|
||||
.actions
|
||||
= f.submit 'Save'
|
||||
@@ -1,7 +0,0 @@
|
||||
- content_for :title, "Editing account"
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Show', @account
|
||||
\|
|
||||
= link_to 'Back', accounts_path
|
||||
@@ -1,23 +0,0 @@
|
||||
- content_for :title, "Listing accounts"
|
||||
|
||||
%table
|
||||
%tr
|
||||
%th Member
|
||||
%th Account type
|
||||
%th Paid until
|
||||
%th
|
||||
%th
|
||||
%th
|
||||
|
||||
- @accounts.each do |account|
|
||||
%tr
|
||||
%td= account.member_id
|
||||
%td= account.account_type
|
||||
%td= account.paid_until
|
||||
%td= link_to 'Show', account
|
||||
%td= link_to 'Edit', edit_account_path(account)
|
||||
%td= link_to 'Destroy', account, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
|
||||
%br
|
||||
|
||||
= link_to 'New Account detail', new_account_path
|
||||
@@ -1,5 +0,0 @@
|
||||
- content_for :title, "New account"
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Back', accounts_path
|
||||
@@ -1,15 +0,0 @@
|
||||
%p#notice= notice
|
||||
|
||||
%p
|
||||
%b Member:
|
||||
= @account.member_id
|
||||
%p
|
||||
%b Account type:
|
||||
= @account.account_type.name
|
||||
%p
|
||||
%b Paid until:
|
||||
= @account.paid_until
|
||||
|
||||
= link_to 'Edit', edit_account_path(@account)
|
||||
\|
|
||||
= link_to 'Back', accounts_path
|
||||
@@ -6,8 +6,6 @@
|
||||
.col-md-4
|
||||
%h2 Site admin
|
||||
%ul#site_admin
|
||||
%li= link_to "Account types", account_types_path
|
||||
%li= link_to "Products", products_path
|
||||
%li= link_to "Roles", roles_path
|
||||
%li= link_to "Forums", forums_path
|
||||
%li= link_to "CMS", comfy_admin_cms_path
|
||||
@@ -22,8 +20,3 @@
|
||||
%ul
|
||||
%li= link_to "Newsletter subscribers", admin_newsletter_path
|
||||
%li= link_to "Members", admin_members_path
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
%h2 Orders
|
||||
= render "admin/orders/searchform"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
= form_tag(url_for(controller: 'admin/orders', action: 'search'), method: :get, class: 'form-inline') do
|
||||
= label_tag :distance, "Search orders:", class: 'control-label'
|
||||
= text_field_tag :search_text
|
||||
= select_tag :search_by,
|
||||
options_for_select('Member': 'member', 'Referral code': 'referral_code',
|
||||
'Order ID': 'order_id', 'Paypal Token': 'paypal_token',
|
||||
'Paypal Payer ID': 'paypal_payer_id')
|
||||
= submit_tag "Search", class: 'btn btn-primary'
|
||||
@@ -1,3 +0,0 @@
|
||||
- content_for :title, 'Admin Orders'
|
||||
|
||||
= render "admin/orders/searchform"
|
||||
@@ -1,41 +0,0 @@
|
||||
- content_for :title, 'Search Orders'
|
||||
|
||||
= render "admin/orders/searchform"
|
||||
|
||||
- unless @orders.empty?
|
||||
%h2
|
||||
Found
|
||||
= pluralize(@orders.size, "result")
|
||||
|
||||
%table.table.table-striped
|
||||
%tr
|
||||
%th Member
|
||||
%th Order number
|
||||
%th Date completed
|
||||
%th Referral code
|
||||
%th Items
|
||||
%th
|
||||
|
||||
- @orders.each do |order|
|
||||
%tr
|
||||
%td
|
||||
= link_to order.member.login_name, order.member
|
||||
= "(deleted)" if order.member.deleted_at
|
||||
%td= order.id
|
||||
%td
|
||||
- if order.completed_at
|
||||
= order.completed_at.to_s
|
||||
- else
|
||||
In progress
|
||||
%td
|
||||
= order.referral_code
|
||||
%td
|
||||
- unless order.order_items.empty?
|
||||
- order.order_items.each do |o|
|
||||
= o.quantity
|
||||
x
|
||||
= o.product.name
|
||||
@
|
||||
= price_with_currency(o.price)
|
||||
%br/
|
||||
%td= link_to 'Details', order, class: 'btn btn-default btn-xs'
|
||||
@@ -47,7 +47,6 @@
|
||||
%li= link_to t('.browse_members'), members_path
|
||||
%li= link_to t('.posts'), posts_path
|
||||
%li= link_to t('.forums'), forums_path
|
||||
%li= link_to t('.support_growstuff'), shop_path
|
||||
|
||||
- if member_signed_in?
|
||||
%li.dropdown<
|
||||
@@ -64,7 +63,6 @@
|
||||
%li= link_to t('.harvest'), harvests_by_owner_path(owner: current_member.slug)
|
||||
%li= link_to t('.seeds'), seeds_by_owner_path(owner: current_member.slug)
|
||||
%li= link_to t('.posts'), posts_by_author_path(author: current_member.slug)
|
||||
%li= link_to t('.account'), orders_path
|
||||
%li
|
||||
- if current_member.notifications.unread_count.positive?
|
||||
= link_to(t('.inbox_unread', unread_count: current_member.notifications.unread_count),
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
%h3 Account details
|
||||
|
||||
%p
|
||||
%strong Member since:
|
||||
= member.created_at.to_s(:date)
|
||||
|
||||
%p
|
||||
%strong Account type:
|
||||
= member.account_type
|
||||
account
|
||||
|
||||
%p
|
||||
%strong Last Login:
|
||||
= member.last_sign_in_at
|
||||
|
||||
%p
|
||||
%strong Member Roles:
|
||||
%br
|
||||
- if member.role? :admin
|
||||
Administrator
|
||||
- if member.role? :crop_wrangler
|
||||
Crop Wrangler
|
||||
- else
|
||||
Member
|
||||
9
app/views/members/_roles.html.haml
Normal file
9
app/views/members/_roles.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
%p
|
||||
%strong Member Roles:
|
||||
%br
|
||||
- if member.role? :admin
|
||||
Administrator
|
||||
- if member.role? :crop_wrangler
|
||||
Crop Wrangler
|
||||
- unless (member.role?(:admin) || member.role?(:crop_wrangler))
|
||||
Member
|
||||
@@ -1,3 +1,10 @@
|
||||
%p
|
||||
%strong Member since:
|
||||
= member.created_at.to_s(:date)
|
||||
%p
|
||||
%strong Last Login:
|
||||
= member.last_sign_in_at
|
||||
|
||||
%h3 Activity
|
||||
|
||||
%ul.list-inline
|
||||
@@ -33,4 +40,3 @@
|
||||
= link_to pluralize(member.followers.size, "follower"), member_followers_path(member)
|
||||
- else
|
||||
0 followers
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
- content_for :buttonbar do
|
||||
- if can? :update, @member
|
||||
= link_to 'Edit profile', edit_member_registration_path, class: 'btn btn-default'
|
||||
- if @member == current_member && !@member.paid?
|
||||
= link_to "Upgrade account", shop_path, class: 'btn btn-default'
|
||||
- if can?(:create, Notification) && current_member != @member
|
||||
= link_to 'Send message', new_notification_path(recipient_id: @member.id), class: 'btn btn-default'
|
||||
|
||||
@@ -33,7 +31,7 @@
|
||||
= render partial: "gardens", locals: { member: @member, gardens: @gardens }
|
||||
.col-md-3
|
||||
= render partial: "avatar", locals: { member: @member }
|
||||
= render partial: "account", locals: { member: @member }
|
||||
= render partial: "roles", locals: { member: @member }
|
||||
= render partial: "stats", locals: { member: @member }
|
||||
= render partial: "contact", locals: { member: @member,
|
||||
twitter_auth: @twitter_auth,
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
- content_for :title, "Completed order"
|
||||
|
||||
%p Thank you for your order.
|
||||
|
||||
%p
|
||||
%strong Completed at:
|
||||
= @order.completed_at
|
||||
|
||||
%p
|
||||
%strong Order number:
|
||||
= @order.id
|
||||
|
||||
= render "shared/account_status"
|
||||
|
||||
%h2 Order items
|
||||
|
||||
%table.table.table-striped
|
||||
%tr
|
||||
%th Product
|
||||
%th Price
|
||||
%th Quantity
|
||||
%th Subtotal
|
||||
- total = 0
|
||||
- @order.order_items.each do |i|
|
||||
%tr
|
||||
%td= i.product.name
|
||||
%td
|
||||
= price_with_currency(i.price)
|
||||
%td= i.quantity
|
||||
%td
|
||||
- subtotal = i.price * i.quantity
|
||||
- total += subtotal
|
||||
= price_with_currency(subtotal)
|
||||
|
||||
%tr
|
||||
%td
|
||||
%td
|
||||
%td
|
||||
%strong Total:
|
||||
%td
|
||||
%strong
|
||||
= price_with_currency(total)
|
||||
|
||||
%p
|
||||
= link_to "View other orders/order history", orders_path
|
||||
@@ -1,44 +0,0 @@
|
||||
- content_for :title, "Your Account"
|
||||
|
||||
= render "shared/account_status"
|
||||
|
||||
|
||||
%h2 Orders
|
||||
|
||||
|
||||
- if current_member.orders.present?
|
||||
|
||||
%p
|
||||
Your order history shows what you have bought via our
|
||||
= succeed "." do
|
||||
= link_to "shop", shop_path
|
||||
|
||||
%table.table.table-striped
|
||||
%tr
|
||||
%th Order number
|
||||
%th Date completed
|
||||
%th Items
|
||||
%th
|
||||
- @orders.each do |order|
|
||||
%tr
|
||||
%td= order.id
|
||||
%td
|
||||
- if order.completed_at
|
||||
= order.completed_at.to_s
|
||||
- else
|
||||
In progress
|
||||
%td
|
||||
- unless order.order_items.empty?
|
||||
- order.order_items.each do |o|
|
||||
= o.quantity
|
||||
x
|
||||
= o.product.name
|
||||
@
|
||||
= price_with_currency(o.price)
|
||||
%br/
|
||||
%td= link_to 'Details', order, class: 'btn btn-default btn-xs'
|
||||
- else
|
||||
%p
|
||||
You have not made any orders. You can place an order via our
|
||||
= succeed "." do
|
||||
= link_to "shop", shop_path
|
||||
@@ -1,84 +0,0 @@
|
||||
- content_for :title, @order.completed_at ? "Order details (##{@order.id})" : "Current order"
|
||||
|
||||
%p
|
||||
%strong Order number:
|
||||
= @order.id
|
||||
|
||||
%p
|
||||
%strong Ordered by:
|
||||
= link_to @order.member, @order.member
|
||||
|
||||
%p
|
||||
%strong Date begun:
|
||||
= @order.created_at.to_s
|
||||
|
||||
- if @order.completed_at
|
||||
%p
|
||||
%strong Date completed:
|
||||
= @order.completed_at.to_s
|
||||
|
||||
- if @order.referral_code
|
||||
%p
|
||||
%strong Referral code:
|
||||
= @order.referral_code
|
||||
|
||||
- if current_member.role? :admin
|
||||
%p
|
||||
%strong Paypal Express token:
|
||||
= @order.paypal_express_token
|
||||
%p
|
||||
%strong Paypal Express payer ID:
|
||||
= @order.paypal_express_payer_id
|
||||
|
||||
%h2 Order items
|
||||
|
||||
%table.table.table-striped
|
||||
%tr
|
||||
%th Product
|
||||
%th Price
|
||||
%th Quantity
|
||||
%th Subtotal
|
||||
- @order.order_items.each do |i|
|
||||
%tr
|
||||
%td= i.product.name
|
||||
%td
|
||||
= price_with_currency(i.price)
|
||||
%td= i.quantity
|
||||
%td
|
||||
- subtotal = i.price * i.quantity
|
||||
= price_with_currency(subtotal)
|
||||
|
||||
%tr
|
||||
%td
|
||||
%td
|
||||
%td
|
||||
%strong Total:
|
||||
%td
|
||||
%strong
|
||||
= price_with_currency(@order.total)
|
||||
= forex_link(@order.total)
|
||||
|
||||
- if @order.errors.any?
|
||||
.alert
|
||||
#error_explanation
|
||||
%h3
|
||||
= pluralize(@order.errors.size, "error")
|
||||
stopped you from checking out:
|
||||
%ul
|
||||
- @order.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
- if can?(:complete, @order) || can?(:destroy, @order)
|
||||
= form_tag(checkout_order_path(@order), method: :get, class: 'form-inline') do
|
||||
%p
|
||||
- if can? :complete, @order
|
||||
= label_tag :referral_code, "Do you have a referral code?"
|
||||
= text_field_tag :referral_code, @order.referral_code, class: 'input-medium'
|
||||
= submit_tag "Checkout with PayPal", class: 'btn btn-primary'
|
||||
- if can? :destroy, @order
|
||||
= link_to 'Delete this order', @order, method: :delete,
|
||||
data: { confirm: 'Are you sure?' },
|
||||
class: 'btn btn-default'
|
||||
= link_to "View other orders/order history", orders_path, class: 'btn btn-default'
|
||||
|
||||
%p
|
||||
@@ -1,32 +0,0 @@
|
||||
= form_for @product do |f|
|
||||
- if @product.errors.any?
|
||||
#error_explanation
|
||||
%h2
|
||||
= pluralize(@product.errors.size, "error")
|
||||
prohibited this product from being saved:
|
||||
%ul
|
||||
- @product.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.field
|
||||
= f.label :name
|
||||
= f.text_field :name, class: 'form-control'
|
||||
.field
|
||||
= f.label :description
|
||||
= f.text_area :description, class: 'form-control'
|
||||
.field
|
||||
= f.label :min_price, "Minimum price (in cents)"
|
||||
= f.text_field :min_price
|
||||
.field
|
||||
= f.label :recommended_price, "Recommended price (in cents)"
|
||||
= f.text_field :recommended_price
|
||||
.field
|
||||
= f.label :account_type
|
||||
= collection_select(:product, :account_type_id, AccountType.all, :id,
|
||||
:name, selected: @product.account_type_id)
|
||||
.field
|
||||
= f.label :paid_months
|
||||
= f.text_field :paid_months
|
||||
.form-group
|
||||
.actions
|
||||
= f.submit 'Save'
|
||||
@@ -1,7 +0,0 @@
|
||||
- content_for :title, "Editing product"
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Show', @product
|
||||
\|
|
||||
= link_to 'Back', products_path
|
||||
@@ -1,29 +0,0 @@
|
||||
- content_for :title, "Listing products"
|
||||
|
||||
%table
|
||||
%tr
|
||||
%th Name
|
||||
%th Description
|
||||
%th Min price
|
||||
%th Recommended price
|
||||
%th Account type
|
||||
%th Paid months
|
||||
%th
|
||||
%th
|
||||
%th
|
||||
|
||||
- @products.each do |product|
|
||||
%tr
|
||||
%td= product.name
|
||||
%td= product.description
|
||||
%td= product.min_price
|
||||
%td= product.recommended_price
|
||||
%td= product.account_type ? product.account_type.name : ""
|
||||
%td= product.paid_months
|
||||
%td= link_to 'Show', product
|
||||
%td= link_to 'Edit', edit_product_path(product)
|
||||
%td= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
|
||||
%br
|
||||
|
||||
= link_to 'New Product', new_product_path
|
||||
@@ -1,5 +0,0 @@
|
||||
- content_for :title, "New product"
|
||||
|
||||
= render 'form'
|
||||
|
||||
= link_to 'Back', products_path
|
||||
@@ -1,25 +0,0 @@
|
||||
%p#notice= notice
|
||||
|
||||
%p
|
||||
%b Name:
|
||||
= @product.name
|
||||
%p
|
||||
%b Description:
|
||||
:growstuff_markdown
|
||||
#{strip_tags(@product.description)}
|
||||
%p
|
||||
%b Min price:
|
||||
= @product.min_price
|
||||
%p
|
||||
%b Recommended price:
|
||||
= @product.recommended_price
|
||||
%p
|
||||
%b Account type:
|
||||
= @product.account_type.name
|
||||
%p
|
||||
%b Paid months:
|
||||
= @product.paid_months
|
||||
|
||||
= link_to 'Edit', edit_product_path(@product)
|
||||
\|
|
||||
= link_to 'Back', products_path
|
||||
@@ -1,13 +0,0 @@
|
||||
%h2 Your current account status
|
||||
|
||||
%p
|
||||
%strong Account type:
|
||||
= current_member.account_type.name
|
||||
|
||||
- if current_member.account.paid_until_string
|
||||
%p
|
||||
%strong Paid until:
|
||||
= current_member.account.paid_until_string
|
||||
|
||||
- unless current_member.paid?
|
||||
= link_to "Upgrade and support #{ENV['GROWSTUFF_SITE_NAME']}", shop_path, class: 'btn btn-primary'
|
||||
@@ -1,83 +0,0 @@
|
||||
- content_for :title, t('.title')
|
||||
|
||||
%p
|
||||
Growstuff relies on your support to build and run this open source
|
||||
platform for food growers. We do not have outside investment, and do
|
||||
not accept ads. Instead, we offer paid memberships, which give you
|
||||
access to premium features, and ensure that we focus our efforts on
|
||||
keeping you, our members, happy.
|
||||
|
||||
%p
|
||||
We are currently developing a number of advanced features for paid
|
||||
members. We will announce our progress on these in our
|
||||
= link_to "Feedback and Support forum", "http://www.growstuff.org/forums/growstuff-feedback-support"
|
||||
as well as via other channels.
|
||||
|
||||
%p
|
||||
All our accounts are priced on a sliding scale. You can choose how
|
||||
much you want to pay. Remember, your subscription supports an open
|
||||
source, open data platform supporting home food growers and promoting
|
||||
sustainable food systems!
|
||||
|
||||
- if current_member && current_member.paid?
|
||||
%h2 Thank you for supporting Growstuff
|
||||
|
||||
%p You currently have a paid membership, and can't buy another one at this time.
|
||||
|
||||
= render "shared/account_status"
|
||||
|
||||
- elsif @order && !@order.order_items.empty?
|
||||
%h2 Your current order
|
||||
|
||||
%p
|
||||
You currently have the following item in your cart:
|
||||
%strong
|
||||
= @most_recent_item.product
|
||||
@
|
||||
= price_with_currency(@most_recent_item.price)
|
||||
|
||||
%p
|
||||
= link_to "View order and checkout", order_path(@order)
|
||||
or
|
||||
= succeed "." do
|
||||
= link_to 'delete this order', @order, method: :delete,
|
||||
data: { confirm: 'Are you sure?' }
|
||||
|
||||
- else
|
||||
- @products.each do |p|
|
||||
%h2= p.name
|
||||
|
||||
%div
|
||||
:growstuff_markdown
|
||||
#{ strip_tags p.description }
|
||||
|
||||
%p
|
||||
Pay what you want, starting at
|
||||
= succeed "." do
|
||||
= price_with_currency(p.min_price)
|
||||
= forex_link(p.min_price)
|
||||
- if p.recommended_price
|
||||
Recommended price:
|
||||
= succeed "." do
|
||||
= price_with_currency(p.recommended_price)
|
||||
= forex_link(p.recommended_price)
|
||||
|
||||
%div
|
||||
- if can? :create, Order
|
||||
|
||||
= form_for @order_item do |f|
|
||||
.field
|
||||
= f.text_field :price, value: price_in_dollars(p.recommended_price || p.min_price)
|
||||
.field
|
||||
= f.hidden_field :product_id, value: p.id
|
||||
.field
|
||||
= f.hidden_field :quantity, value: 1
|
||||
.actions
|
||||
= f.submit 'Buy', class: 'btn btn-primary'
|
||||
|
||||
- else
|
||||
Please
|
||||
= link_to "sign in", new_member_session_path
|
||||
or
|
||||
= link_to "sign up", new_member_registration_path
|
||||
to purchase.
|
||||
10
config.rb
10
config.rb
@@ -1,11 +1,11 @@
|
||||
# Require any additional compass plugins here.
|
||||
# rubocop:disable Lint/UselessAssignment
|
||||
# Set this to the root of your project when deployed:
|
||||
http_path = '/'
|
||||
css_dir = 'app/assets/stylesheets'
|
||||
sass_dir = 'app/assets/stylesheets'
|
||||
javascripts_dir = 'app/assets/javascripts'
|
||||
images_dir = 'app/assets/images'
|
||||
http_path = "/"
|
||||
css_dir = "app/assets/stylesheets"
|
||||
sass_dir = "app/assets/stylesheets"
|
||||
javascripts_dir = "app/assets/javascripts"
|
||||
images_dir = "app/assets/images"
|
||||
|
||||
# You can select your preferred output style here (can be overridden via the command line):
|
||||
# output_style = :expanded or :nested or :compact or :compressed
|
||||
|
||||
@@ -42,10 +42,7 @@ module Growstuff
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Configure the default encoding used in templates for Ruby 1.9.
|
||||
config.encoding = 'utf-8'
|
||||
|
||||
# Configure a default account type
|
||||
config.default_account_type = 'Free'
|
||||
config.encoding = "utf-8"
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
config.filter_parameters += [:password]
|
||||
@@ -84,9 +81,9 @@ module Growstuff
|
||||
|
||||
# Growstuff-specific configuration variables
|
||||
config.currency = 'AUD'
|
||||
config.bot_email = 'noreply@growstuff.org'
|
||||
config.bot_email = "noreply@growstuff.org"
|
||||
config.user_agent = 'Growstuff'
|
||||
config.user_agent_email = 'info@growstuff.org'
|
||||
config.user_agent_email = "info@growstuff.org"
|
||||
|
||||
Gibbon::API.api_key = ENV['GROWSTUFF_MAILCHIMP_APIKEY'] || 'notarealkey'
|
||||
# API key can't be blank or tests fail
|
||||
|
||||
@@ -57,11 +57,6 @@ GROWSTUFF_TWITTER_SECRET: ""
|
||||
GROWSTUFF_FLICKR_KEY: ""
|
||||
GROWSTUFF_FLICKR_SECRET: ""
|
||||
|
||||
# Paypal is used for payments, obviously.
|
||||
GROWSTUFF_PAYPAL_USERNAME: "dummy"
|
||||
GROWSTUFF_PAYPAL_PASSWORD: "dummy"
|
||||
GROWSTUFF_PAYPAL_SIGNATURE: "dummy"
|
||||
|
||||
# https://developers.facebook.com/
|
||||
GROWSTUFF_FACEBOOK_KEY: ""
|
||||
GROWSTUFF_FACEBOOK_SECRET: ""
|
||||
|
||||
@@ -63,17 +63,6 @@ Growstuff::Application.configure do
|
||||
config.mapbox_map_id = 'growstuff.i3n2il6a'
|
||||
config.mapbox_access_token = 'pk.eyJ1IjoiZ3Jvd3N0dWZmIiwiYSI6IkdxMkx4alUifQ.n0igaBsw97s14zMa0lwKCA'
|
||||
|
||||
config.after_initialize do
|
||||
ActiveMerchant::Billing::Base.mode = :test
|
||||
paypal_options = {
|
||||
login: ENV['GROWSTUFF_PAYPAL_USERNAME'] || 'dummy',
|
||||
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'] || 'dummy',
|
||||
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE'] || 'dummy'
|
||||
}
|
||||
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
|
||||
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
||||
end
|
||||
|
||||
config.action_controller.action_on_unpermitted_parameters = :raise
|
||||
|
||||
config.active_job.queue_adapter = :sidekiq
|
||||
|
||||
@@ -91,16 +91,5 @@ Growstuff::Application.configure do
|
||||
config.mapbox_map_id = 'growstuff.i3n2c4ie'
|
||||
config.mapbox_access_token = 'pk.eyJ1IjoiZ3Jvd3N0dWZmIiwiYSI6IkdxMkx4alUifQ.n0igaBsw97s14zMa0lwKCA'
|
||||
|
||||
config.after_initialize do
|
||||
ActiveMerchant::Billing::Base.mode = :production
|
||||
paypal_options = {
|
||||
login: ENV['GROWSTUFF_PAYPAL_USERNAME'],
|
||||
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'],
|
||||
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE']
|
||||
}
|
||||
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
|
||||
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
||||
end
|
||||
|
||||
config.active_job.queue_adapter = :sidekiq
|
||||
end
|
||||
|
||||
@@ -89,16 +89,5 @@ Growstuff::Application.configure do
|
||||
config.mapbox_map_id = 'growstuff.i3n2hao7'
|
||||
config.mapbox_access_token = 'pk.eyJ1IjoiZ3Jvd3N0dWZmIiwiYSI6IkdxMkx4alUifQ.n0igaBsw97s14zMa0lwKCA'
|
||||
|
||||
config.after_initialize do
|
||||
ActiveMerchant::Billing::Base.mode = :test
|
||||
paypal_options = {
|
||||
login: ENV['GROWSTUFF_PAYPAL_USERNAME'],
|
||||
password: ENV['GROWSTUFF_PAYPAL_PASSWORD'],
|
||||
signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE']
|
||||
}
|
||||
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
|
||||
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
||||
end
|
||||
|
||||
config.active_job.queue_adapter = :sidekiq
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ Growstuff::Application.configure do
|
||||
|
||||
# Configure static asset server for tests with Cache-Control for performance
|
||||
config.serve_static_files = true
|
||||
config.static_cache_control = 'public, max-age=3600'
|
||||
config.static_cache_control = "public, max-age=3600"
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
@@ -51,19 +51,12 @@ Growstuff::Application.configure do
|
||||
config.analytics_code = ''
|
||||
config.currency = 'AUD'
|
||||
end
|
||||
|
||||
config.after_initialize do
|
||||
require 'active_merchant/ext/paypal_bogus_gateway'
|
||||
ActiveMerchant::Billing::Base.mode = :test
|
||||
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalBogusGateway.new
|
||||
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalBogusGateway.new
|
||||
end
|
||||
end
|
||||
|
||||
Geocoder.configure(lookup: :test)
|
||||
|
||||
Geocoder::Lookup::Test.add_stub(
|
||||
'Amundsen-Scott Base, Antarctica', [
|
||||
"Amundsen-Scott Base, Antarctica", [
|
||||
{
|
||||
'latitude' => -90.0,
|
||||
'longitude' => 0.0
|
||||
@@ -72,7 +65,7 @@ Geocoder::Lookup::Test.add_stub(
|
||||
)
|
||||
|
||||
Geocoder::Lookup::Test.add_stub(
|
||||
'Philippines', [
|
||||
"Philippines", [
|
||||
{
|
||||
'latitude' => 12.7503486,
|
||||
'longitude' => 122.7312101,
|
||||
@@ -86,7 +79,7 @@ Geocoder::Lookup::Test.add_stub(
|
||||
)
|
||||
|
||||
Geocoder::Lookup::Test.add_stub(
|
||||
'Greenwich, UK', [
|
||||
"Greenwich, UK", [
|
||||
{
|
||||
'latitude' => 51.483061,
|
||||
'longitude' => -0.004151
|
||||
@@ -95,7 +88,7 @@ Geocoder::Lookup::Test.add_stub(
|
||||
)
|
||||
|
||||
Geocoder::Lookup::Test.add_stub(
|
||||
'Edinburgh', [
|
||||
"Edinburgh", [
|
||||
{
|
||||
'latitude' => 55.953252,
|
||||
'longitude' => -3.188267
|
||||
@@ -104,7 +97,7 @@ Geocoder::Lookup::Test.add_stub(
|
||||
)
|
||||
|
||||
# Unknown location
|
||||
Geocoder::Lookup::Test.add_stub('Tatooine', [])
|
||||
Geocoder::Lookup::Test.add_stub("Tatooine", [])
|
||||
|
||||
Capybara.configure do |config|
|
||||
config.always_include_port = true
|
||||
@@ -115,12 +108,12 @@ OmniAuth.config.test_mode = true
|
||||
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new(provider: 'facebook',
|
||||
uid: '123545',
|
||||
info: {
|
||||
name: 'John Testerson',
|
||||
name: "John Testerson",
|
||||
nickname: 'JohnnyT',
|
||||
email: 'example.oauth.facebook@example.com',
|
||||
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
|
||||
},
|
||||
credentials: {
|
||||
token: 'token',
|
||||
secret: 'donttell'
|
||||
token: "token",
|
||||
secret: "donttell"
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ Devise.setup do |config|
|
||||
# ==> Mailer Configuration
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
|
||||
config.mailer_sender = 'Growstuff <noreply@growstuff.org>'
|
||||
config.mailer_sender = "Growstuff <noreply@growstuff.org>"
|
||||
|
||||
config.secret_key = ENV['RAILS_SECRET_TOKEN']
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ Geocoder.configure(
|
||||
units: :km,
|
||||
timeout: 10,
|
||||
http_headers: {
|
||||
'User-Agent' =>
|
||||
"User-Agent" =>
|
||||
"#{Growstuff::Application.config.user_agent} #{Growstuff::Application.config.user_agent_email}",
|
||||
'From' => Growstuff::Application.config.user_agent_email
|
||||
"From" => Growstuff::Application.config.user_agent_email
|
||||
}
|
||||
)
|
||||
# This configuration takes precedence over environment/test.rb
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Time::DATE_FORMATS[:default] = '%B %d, %Y at %H:%M'
|
||||
Date::DATE_FORMATS[:default] = '%B %d, %Y'
|
||||
Date::DATE_FORMATS[:default] = "%B %d, %Y"
|
||||
|
||||
Time::DATE_FORMATS[:date] = '%B %d, %Y'
|
||||
Date::DATE_FORMATS[:date] = '%B %d, %Y'
|
||||
Time::DATE_FORMATS[:date] = "%B %d, %Y"
|
||||
Date::DATE_FORMATS[:date] = "%B %d, %Y"
|
||||
|
||||
Date::DATE_FORMATS[:ymd] = '%Y-%m-%d'
|
||||
Date::DATE_FORMATS[:ymd] = "%Y-%m-%d"
|
||||
|
||||
Time::DATE_FORMATS[:datetime] = '%B %d, %Y at %H:%M'
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
---
|
||||
en:
|
||||
account:
|
||||
update: Account detail was successfully updated.
|
||||
account_types:
|
||||
created: Account type was successfully created.
|
||||
deleted: Account type was successfully deleted.
|
||||
updated: Account type was successfully updated.
|
||||
activerecord:
|
||||
models:
|
||||
comment:
|
||||
@@ -99,7 +93,6 @@ en:
|
||||
open:
|
||||
ad_free_linktext: ad-free
|
||||
api_docs_linktext: API documentation
|
||||
buy_account_linktext: buying a paid account
|
||||
creative_commons_linktext: Creative Commons license
|
||||
get_involved_body_html: >
|
||||
We believe in collaboration, and work closely with our members and the wider food-growing community.
|
||||
@@ -213,9 +206,6 @@ en:
|
||||
default: Everyone's seeds
|
||||
owner_seeds: "%{owner} seeds"
|
||||
string: "%{crop} seeds belonging to %{owner}"
|
||||
shop:
|
||||
index:
|
||||
title: Shop
|
||||
unauthorized:
|
||||
create:
|
||||
all: Please sign in or sign up to create a %{subject}.
|
||||
|
||||
@@ -4,10 +4,10 @@ Growstuff::Application.routes.draw do
|
||||
resources :plant_parts
|
||||
|
||||
devise_for :members, controllers: {
|
||||
registrations: 'registrations',
|
||||
passwords: 'passwords',
|
||||
sessions: 'sessions',
|
||||
omniauth_callbacks: 'omniauth_callbacks'
|
||||
registrations: "registrations",
|
||||
passwords: "passwords",
|
||||
sessions: "sessions",
|
||||
omniauth_callbacks: "omniauth_callbacks"
|
||||
}
|
||||
devise_scope :member do
|
||||
get '/members/unsubscribe/:message' => 'members#unsubscribe', as: 'unsubscribe_member'
|
||||
@@ -72,34 +72,19 @@ Growstuff::Application.routes.draw do
|
||||
get '/places/search' => 'places#search', as: 'search_places'
|
||||
get '/places/:place' => 'places#show', as: 'place'
|
||||
|
||||
# everything for paid accounts etc
|
||||
resources :account_types
|
||||
resources :accounts
|
||||
resources :orders
|
||||
get 'orders/:id/checkout' => 'orders#checkout', as: 'checkout_order'
|
||||
get 'orders/:id/complete' => 'orders#complete', as: 'complete_order'
|
||||
get 'orders/:id/cancel' => 'orders#cancel', as: 'cancel_order'
|
||||
|
||||
resources :order_items
|
||||
resources :products
|
||||
|
||||
resources :likes, only: %i(create destroy)
|
||||
|
||||
get 'home/index'
|
||||
get "home/index"
|
||||
root to: 'home#index'
|
||||
|
||||
get 'auth/:provider/callback' => 'authentications#create'
|
||||
get 'members/auth/:provider/callback' => 'authentications#create'
|
||||
|
||||
get '/shop' => 'shop#index'
|
||||
get '/shop/:action' => 'shop#:action'
|
||||
|
||||
comfy_route :cms_admin, path: '/admin/cms'
|
||||
namespace :admin do
|
||||
resources :members
|
||||
end
|
||||
get '/admin/orders' => 'admin/orders#index'
|
||||
get '/admin/orders/:action' => 'admin/orders#:action'
|
||||
|
||||
get '/admin' => 'admin#index'
|
||||
get '/admin/newsletter' => 'admin#newsletter', as: :admin_newsletter
|
||||
get '/admin/:action' => 'admin#:action'
|
||||
|
||||
@@ -4,7 +4,7 @@ if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
|
||||
RVM.use_from_path! File.dirname(File.dirname(__FILE__))
|
||||
rescue LoadError
|
||||
# RVM is unavailable at this point.
|
||||
raise 'RVM ruby lib is currently unavailable.'
|
||||
raise "RVM ruby lib is currently unavailable."
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ class DeviseCreateUsers < ActiveRecord::Migration
|
||||
def change
|
||||
create_table(:users) do |t|
|
||||
## Database authenticatable
|
||||
t.string :email, null: false, default: ''
|
||||
t.string :encrypted_password, null: false, default: ''
|
||||
t.string :email, null: false, default: ""
|
||||
t.string :encrypted_password, null: false, default: ""
|
||||
|
||||
## Recoverable
|
||||
t.string :reset_password_token
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class AddApprovalStatusToCrops < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :crops, :approval_status, :string, default: 'approved'
|
||||
add_column :crops, :approval_status, :string, default: "approved"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class SetPredictionData < ActiveRecord::Migration
|
||||
def up
|
||||
say 'Updating all plantings time to first harvest'
|
||||
say "Updating all plantings time to first harvest"
|
||||
Planting.all.each(&:update_harvest_days)
|
||||
say 'Updating crop median time to first harvest, and lifespan'
|
||||
say "Updating crop median time to first harvest, and lifespan"
|
||||
Crop.all.each do |crop|
|
||||
crop.update_lifespan_medians
|
||||
crop.update_harvest_medians
|
||||
|
||||
@@ -18,19 +18,19 @@ class CreatePhotographings < ActiveRecord::Migration
|
||||
end
|
||||
|
||||
def migrate_data
|
||||
say 'migrating garden photos'
|
||||
say "migrating garden photos"
|
||||
GardensPhoto.all.each do |g|
|
||||
Photographing.create! photo_id: g.photo_id, photographable_id: g.garden_id, photographable_type: 'Garden'
|
||||
end
|
||||
say 'migrating planting photos'
|
||||
say "migrating planting photos"
|
||||
PhotosPlanting.all.each do |p|
|
||||
Photographing.create! photo_id: p.photo_id, photographable_id: p.planting_id, photographable_type: 'Planting'
|
||||
end
|
||||
say 'migrating harvest photos'
|
||||
say "migrating harvest photos"
|
||||
HarvestsPhoto.all.each do |h|
|
||||
Photographing.create! photo_id: h.photo_id, photographable_id: h.harvest_id, photographable_type: 'Harvest'
|
||||
end
|
||||
say 'migrating seed photos'
|
||||
say "migrating seed photos"
|
||||
PhotosSeed.all.each do |s|
|
||||
Photographing.create! photo_id: s.photo_id, photographable_id: s.seed_id, photographable_type: 'Seed'
|
||||
end
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
class AddDatetakenToPhotos < ActiveRecord::Migration
|
||||
def up
|
||||
def change
|
||||
add_column :photos, :date_taken, :datetime
|
||||
update_flickr_metadata
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :photos, :date_taken
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_flickr_metadata
|
||||
# Fetch from flickr, the photos updated the longest ago will be fetched first
|
||||
Photo.all.order(:updated_at).each do |photo|
|
||||
say "Fetch flickr data for #{photo}"
|
||||
photo.set_flickr_metadata!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user