Merge pull request #758 from GabrielSandoval/gab/days_before_maturity

Gab/days before maturity (#678)  Thank you! That haml looks much better.
This commit is contained in:
Mackenzie
2015-07-06 22:31:45 -04:00
15 changed files with 311 additions and 189 deletions

View File

@@ -71,6 +71,7 @@ class PlantingsController < ApplicationController
respond_to do |format|
if @planting.save
@planting.update_attribute(:days_before_maturity, update_days_before_maturity(@planting, planting_params[:crop_id]))
format.html { redirect_to @planting, notice: 'Planting was successfully created.' }
format.json { render json: @planting, status: :created, location: @planting }
expire_fragment("homepage_stats")
@@ -89,6 +90,7 @@ class PlantingsController < ApplicationController
respond_to do |format|
if @planting.update(planting_params)
@planting.update_attribute(:days_before_maturity, update_days_before_maturity(@planting, planting_params[:crop_id]))
format.html { redirect_to @planting, notice: 'Planting was successfully updated.' }
format.json { head :no_content }
else
@@ -119,4 +121,12 @@ class PlantingsController < ApplicationController
:quantity, :sunniness, :planted_from, :owner_id, :finished,
:finished_at)
end
def update_days_before_maturity(planting, crop_id)
if planting.finished_at.nil?
planting.calculate_days_before_maturity(planting, crop_id)
else
(planting.finished_at - planting.planted_at).to_i
end
end
end

View File

@@ -0,0 +1,36 @@
module PlantingsHelper
def display_days_before_maturity(planting)
if planting.finished?
0
elsif !planting.finished_at.nil?
((p = planting.finished_at - DateTime.now).to_i) <= 0 ? 0 : p.to_i
elsif planting.days_before_maturity.nil?
"unknown"
else
((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i <= 0) ? 0 : p.to_i
end
end
def display_finished(planting)
if !planting.finished_at.nil?
planting.finished_at
elsif planting.finished
"Yes (no date specified)"
else
"(no date specified)"
end
end
def display_sunniness(planting)
!planting.sunniness.blank? ? planting.sunniness : "not specified"
end
def display_planted_from(planting)
!planting.planted_from.blank? ? planting.planted_from : "not specified"
end
def display_planting_quantity(planting)
!planting.quantity.blank? ? planting.quantity : "not specified"
end
end

View File

@@ -94,6 +94,21 @@ class Planting < ActiveRecord::Base
return photos.present?
end
def calculate_days_before_maturity(planting, crop)
p_crop = Planting.where(:crop_id => crop).where.not(:id => planting)
differences = p_crop.collect do |p|
if p.finished and !p.finished_at.nil?
(p.finished_at - p.planted_at).to_i
end
end
if differences.compact.empty?
nil
else
differences.compact.sum/differences.compact.length
end
end
# return a list of interesting plantings, for the homepage etc.
# we can't do this via a scope (as far as we know) so sadly we have to
# do it this way.

View File

@@ -43,22 +43,37 @@
%p{:style => 'text-align: center; padding-top: 50px'}
= link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary'
%h3
What's planted here?
%h3 What's planted here?
- if @garden.plantings.current.size > 0
- @garden.plantings.current.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p }
.container
.row
.col-md-1
%b #
.col-md-3
%b Photo
.col-md-6
%b Planting Details
.col-md-2
- @garden.plantings.current.each.with_index do |planting_current, index_current|
= render partial: "plantings/thumbnail", locals: {:planting => planting_current, :index => index_current}
- else
%p
Nothing is currently planted here.
%h3 Previously planted in this garden
- if @garden.plantings.finished.size > 0
%h3 Previously planted in this garden
- @garden.plantings.finished.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p }
.container
.row
.col-md-1
%b #
.col-md-3
%b Photo
.col-md-6
%b Planting Details
.col-md-2
- @garden.plantings.finished.each.with_index do |planting_finished, index_finished|
= render partial: "plantings/thumbnail", locals: {:planting => planting_finished, :index => index_finished}
.col-md-3
%h4 About this garden
%p

View File

@@ -34,8 +34,18 @@
= link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary'
%h3 What's planted here?
- g.featured_plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true }
- if g.featured_plantings.size > 0
.container
.row
.col-md-1
%b #
.col-md-3
%b Photo
.col-md-6
%b Planting Details
.col-md-2
- g.featured_plantings.each.with_index do |planting, index|
= render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index}
%p
= link_to "More about this garden...", url_for(g)

View File

@@ -0,0 +1,14 @@
- if DateTime.now.to_date < planting.planted_at
= "Progress: 0% - not planted yet"
= render partial: "plantings/progress_bar", locals: {status: "warning", progress: "100%"}
- elsif planting.finished?
= "Progress: 100%"
= render partial: "plantings/progress_bar", locals: {status: "success", progress: "100%"}
- elsif planting.days_before_maturity.nil?
= "Progress: 0% - Days before maturity unknown"
= render partial: "plantings/progress_bar", locals: {status: "danger", progress: "100%"}
- else
- if (percent = (((DateTime.now - planting.planted_at)/planting.days_before_maturity*100).to_i)) >= 100
- percent = 100
= "Progress: #{percent}%"
= render partial: "plantings/progress_bar", locals: {status: "success", progress: "#{percent}%"}

View File

@@ -0,0 +1,2 @@
.progress
%div{:class => "progress-bar progress-bar-#{status}", :role => "progressbar", :style => "width: #{progress}"}

View File

@@ -1,47 +1,44 @@
.well
.row
.col-md-3
= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img'), planting
.row
.col-md-1
= "##{index+1}"
.col-md-3
= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting
.col-md-6
%dl.dl-horizontal
%dt Owner:
%dd= link_to planting.owner.login_name, planting.owner
%dt Garden:
%dd= link_to planting.garden.name, planting.garden
%dt Planted on:
%dd= planting.planted_at
%dt Quantity:
%dd= "#{display_planting_quantity(planting)}"
%dt Finished on:
%dd= "#{display_finished(planting)}"
%dt Sun/shade?:
%dd= "#{display_sunniness(planting)}"
%dt Planted from:
%dd= "#{display_planted_from(planting)}"
.col-md-2
%ul{:style => "list-style-type:none"}
%li= link_to 'Details', planting, :class => 'btn btn-default btn-xs'
- if can? :edit, planting
%li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
%li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
%li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
.row
.col-md-1
.col-md-3
%ul{:style => "list-style-type:none"}
%li
%b Crop name:
= link_to planting.crop.name, planting.crop
%li
%b Days until maturity:
= "#{display_days_before_maturity(planting)}"
.col-md-9
%h4
- if defined?(title) && title == 'owner'
= link_to planting.owner, planting.owner
- else
= link_to planting.crop.name, planting
%p
Planted
- if planting.planted_at
= planting.planted_at
in
= link_to planting.location, planting.garden
%p
- if planting.quantity
Quantity:
= planting.quantity
- else
&nbsp;
- if planting.description && ! defined?(hide_description)
%div
:growstuff_markdown
#{ planting.description }
- if planting.finished
%p
Finished:
- if planting.finished_at
= planting.finished_at
- else
Yes (no date specified)
- if can? :edit, planting or can? :destroy, planting
%p
- if can? :edit, planting
=link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
=link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
.col-md-8
%ul{:style => "list-style-type:none"}
%li= render partial: 'plantings/planting_progress', locals: {:planting => planting}

View File

@@ -19,43 +19,16 @@
= will_paginate @plantings
- if @plantings.size > 0
%table.table.table-striped
%tr
- unless @owner
%th Owner
%th Crop
%th Garden
%th Quantity
%th Planted on
%th Finished
%th Sun/shade?
%th Planted from
%th
- @plantings.each do |planting|
%tr
- unless @owner
%td= link_to planting.owner.login_name, planting.owner
%td= link_to planting.crop.name, planting.crop
%td= link_to planting.garden.name, planting.garden
%td= planting.quantity
%td= planting.planted_at
%td
- if planting.finished and planting.finished_at
= planting.finished_at
- elsif planting.finished
Yes (no date specified)
%td= planting.sunniness
%td= planting.planted_from
%td
= link_to 'Details', planting, :class => 'btn btn-default btn-xs'
- if can? :edit, planting
=link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
=link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
.row
.col-md-1
%b #
.col-md-3
%b Photo
.col-md-6
%b Planting Details
.col-md-2
- @plantings.each.with_index do |planting, index|
= render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index}
%div.pagination
= page_entries_info @plantings, :model => "plantings"

View File

@@ -8,7 +8,7 @@
&mdash;
= link_to "view all #{@planting.owner}'s plantings", plantings_by_owner_path(:owner => @planting.owner.slug)
%p
%b Planted:
%b Planted on:
= @planting.planted_at ? @planting.planted_at : "not specified"
%p
@@ -18,28 +18,32 @@
- if ! @planting.owner.location.blank?
= "(#{@planting.owner.location})"
%p
%b Quantity:
= @planting.quantity.blank? ? "not specified" : @planting.quantity
- if ! @planting.planted_from.blank?
%b
= "Quantity: "
= "#{display_planting_quantity(@planting)}"
- if !@planting.planted_from.blank?
%p
%b Planted from:
= @planting.planted_from
- if ! @planting.sunniness.blank?
%b
= "Planted from: "
= "#{display_planted_from(@planting)}"
- if !@planting.sunniness.blank?
%p
%b Sun or shade?
= @planting.sunniness
- if @planting.finished
%p
%b Finished:
- if @planting.finished_at
= @planting.finished_at
- else
Yes (no date specified)
%b
= "Sun or shade?: "
= "#{display_sunniness(@planting)}"
%p
%b
= "Days until maturity: "
= "#{display_days_before_maturity(@planting)}"
%p
%b
= "Finished: "
= "#{display_finished(@planting)}"
%p
%b= render 'planting_progress', planting: @planting
- if can? :edit, @planting or can? :destroy, @planting
%p

View File

@@ -0,0 +1,5 @@
class AddDaysBeforeMaturityToPlantings < ActiveRecord::Migration
def change
add_column :plantings, :days_before_maturity, :integer
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150209105410) do
ActiveRecord::Schema.define(version: 20150625224805) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -380,8 +380,8 @@ ActiveRecord::Schema.define(version: 20150209105410) do
end
create_table "plantings", force: true do |t|
t.integer "garden_id", null: false
t.integer "crop_id", null: false
t.integer "garden_id", null: false
t.integer "crop_id", null: false
t.date "planted_at"
t.integer "quantity"
t.text "description"
@@ -391,8 +391,9 @@ ActiveRecord::Schema.define(version: 20150209105410) do
t.string "sunniness"
t.string "planted_from"
t.integer "owner_id"
t.boolean "finished", default: false
t.boolean "finished", default: false
t.date "finished_at"
t.integer "days_before_maturity"
end
add_index "plantings", ["slug"], name: "index_plantings_on_slug", unique: true, using: :btree

View File

@@ -69,7 +69,6 @@ feature "Planting a crop", :js => true do
describe "Making a planting inactive from garden show" do
let(:path) { garden_path(garden) }
let(:link_text) { "Mark as finished" }
it_behaves_like "append date"
end

View File

@@ -27,6 +27,104 @@ feature "Planting a crop", :js => true do
end
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Progress: 0% - Days before maturity unknown"
end
describe "Progress bar status on planting creation" do
before(:each) do
DateTime.stub(:now){DateTime.new(2015, 10, 20, 10, 34)}
login_as(member)
visit new_planting_path
sync_elasticsearch([maize])
end
it "should show that it is not planted yet" do
fill_autocomplete "crop", :with => "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
fill_in "When", :with => "2015-12-15"
fill_in "How many?", :with => 42
select "cutting", :from => "Planted from:"
select "semi-shade", :from => "Sun or shade?"
fill_in "Tell us more about it", :with => "It's rad."
click_button "Save"
end
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Progress: 0% - not planted yet"
end
it "should show that days before maturity is unknown" do
fill_autocomplete "crop", :with => "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
fill_in "When", :with => "2015-9-15"
fill_in "How many?", :with => 42
select "cutting", :from => "Planted from:"
select "semi-shade", :from => "Sun or shade?"
fill_in "Tell us more about it", :with => "It's rad."
click_button "Save"
end
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Progress: 0% - Days before maturity unknown"
expect(page).to have_content "Days until maturity: unknown"
end
it "should show that planting is in progress" do
fill_autocomplete "crop", :with => "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
fill_in "When", :with => "2015-10-15"
fill_in "How many?", :with => 42
select "cutting", :from => "Planted from:"
select "semi-shade", :from => "Sun or shade?"
fill_in "Tell us more about it", :with => "It's rad."
fill_in "Finished date", :with => "2015-10-30"
click_button "Save"
end
expect(page).to have_content "Planting was successfully created"
expect(page).to_not have_content "Progress: 0% - not planted yet"
expect(page).to_not have_content "Progress: 0% - Days before maturity unknown"
end
it "should show that planting is 100% complete (no date specified)" do
fill_autocomplete "crop", :with => "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
fill_in "When", :with => "2015-10-15"
fill_in "How many?", :with => 42
select "cutting", :from => "Planted from:"
select "semi-shade", :from => "Sun or shade?"
fill_in "Tell us more about it", :with => "It's rad."
check "Mark as finished"
click_button "Save"
end
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Progress: 100%"
expect(page).to have_content "Yes (no date specified)"
expect(page).to have_content "Days until maturity: 0"
end
it "should show that planting is 100% complete (date specified)" do
fill_autocomplete "crop", :with => "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
fill_in "When", :with => "2015-10-15"
fill_in "How many?", :with => 42
select "cutting", :from => "Planted from:"
select "semi-shade", :from => "Sun or shade?"
fill_in "Tell us more about it", :with => "It's rad."
fill_in "Finished date", :with => "2015-10-19"
click_button "Save"
end
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Progress: 100%"
expect(page).to have_content "Days until maturity: 0"
end
end
scenario "Planting from crop page" do
@@ -49,6 +147,17 @@ feature "Planting a crop", :js => true do
expect(page).to have_content "Planting was successfully updated"
end
scenario "Editing a planting to fill in the finished date" do
visit planting_path(planting)
expect(page).to have_content "Progress: 0% - Days before maturity unknown"
click_link "Edit"
check "finished"
fill_in "Finished date", :with => "2015-06-25"
click_button "Save"
expect(page).to have_content "Planting was successfully updated"
expect(page).to_not have_content "Progress: 0% - Days before maturity unknown"
end
scenario "Marking a planting as finished" do
fill_autocomplete "crop", :with => "mai"
select_from_autocomplete "maize"
@@ -94,6 +203,7 @@ feature "Planting a crop", :js => true do
end
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Finished: Yes (no date specified)"
expect(page).to have_content "Progress: 100%"
end
describe "Marking a planting as finished from the show page" do

View File

@@ -1,69 +0,0 @@
## DEPRECATION NOTICE: Do not add new tests to this file!
##
## View and controller tests are deprecated in the Growstuff project.
## We no longer write new view and controller tests, but instead write
## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara).
## These test the full stack, behaving as a browser, and require less complicated setup
## to run. Please feel free to delete old view/controller tests as they are reimplemented
## in feature tests.
##
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe "plantings/_thumbnail" do
before(:each) do
controller.stub(:current_user) { nil }
@member = FactoryGirl.create(:member)
@garden = FactoryGirl.create(:garden, :owner => @member)
@crop = FactoryGirl.create(:tomato)
@planting = FactoryGirl.create(:planting,
:garden => @garden,
:crop => @crop
)
end
context "simple view" do
before(:each) do
render :partial => "thumbnail", :locals => {
:planting => @planting,
}
end
it "renders the quantity planted" do
rendered.should have_content "33"
end
it "renders the date planted" do
rendered.should have_content @planting.planted_at.to_s(:default)
end
it "shows the name of the crop" do
rendered.should have_content @crop.name
end
it "shows the description by default" do
rendered.should have_content "This is a"
end
end
context "with complicated args" do
before(:each) do
render :partial => "thumbnail", :locals => {
:planting => @planting,
:hide_description => true
}
end
it "hides the description if asked" do
rendered.should_not have_content "This is a"
end
end
end