Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IN PROGRESS Barcode ajax #119

Merged
merged 14 commits into from
Aug 11, 2017
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/assets/javascripts/adjustments.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ item_option = (item) ->
#{ item.item_name } -- #{ item.quantity }
</option>"

$(document).on 'turbolinks:load', () ->
$ ->
control_id = '#adjustment_storage_location_id'

$(document).on "change", control_id, (evt) ->
Expand All @@ -29,4 +29,3 @@ $(document).on 'turbolinks:load', () ->
options = $.map data, item_option
console.log("inserted item", insertedItem)
$("select", insertedItem).html(options)

6 changes: 3 additions & 3 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//= require jquery
//= require jquery_ujs
//= require foundation
//= require turbolinks
// require turbolinks // Removed!
//= require cocoon
//
//= require Chart.bundle
Expand All @@ -24,10 +24,10 @@
//= require components
//= require_tree .

$(document).on('turbolinks:load', function() {
$(document).ready(function() {
$(document).foundation();
});

window.setTimeout(function() {
$(".close-button").click();
}, 3000);
}, 3000);
3 changes: 0 additions & 3 deletions app/assets/javascripts/barcode_items.coffee

This file was deleted.

63 changes: 63 additions & 0 deletions app/assets/javascripts/barcode_items.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
$(document).ready(function() {
/* Barcode readers will often "helpfully" send a CRLF at the end of the
scanned string. We're going to capture this and use it to invoke the
lookup method instead, since we don't want to submit the form just yet. */
$('[data-capture-barcode="true"]').on('keypress', '.__barcode_item_lookup', capture_entry);

/**
capture_entry
@brief prevents the form from submitting and instead sends an XHR to lookup the barcode
@param event : the keypress event object
*/
function capture_entry(event) {
if (event.which == '10' || event.which == '13') {
barcode_item_lookup(event.target.value, $(event.target).data("organization-id"),event.target);
event.preventDefault();
}
}

/**
barcode_item_lookup
@brief Invokes an ajax lookup of a provided barcode value
@param value : the barcode
@param organization_id : passed in as a param. This constrains the lookup
@param src : the DOM source, so we can callback to it.
*/
function barcode_item_lookup(value, organization_id,src) {
// Hardcoding magic URLs isn't ideal but it works for now
$.getJSON("/" + organization_id + "/barcode_items/find.json?barcode_item[value]=" + value, function(data) {
// Preserve this for reference of where we came from.
data['src'] = src;
// Pass it all along to the .done() method
return data;
})
.done(fill_fields_with_barcode_results)
.fail(prompt_for_new_barcode_item)
.always(function(data){
// ...
});
}

/**
fill_fields_with_barcode_results
@brief Sets the fields for the line item with the results. Event handler for above.
@param data : JSON object result from the above method. Expecting a JSON-serialized BarcodeItem
*/
function fill_fields_with_barcode_results(data) {
line_item = $(data['src']).closest('.nested-fields');
$(line_item).find('input[type=number]').val(data['quantity']);
$(line_item).find('select option[value="' + data['item_id'] + '"]').attr("selected", true);

// This will facilitate serial barcode inputs.
// First trigger the "add new line item"
$('#__add_line_item').trigger('click');
// Now focus on the barcode field
$(line_item).parent().find('.nested-fields:last-child input.__barcode_item_lookup').focus();
}

function prompt_for_new_barcode_item(data) {
console.log("prompts!");
$(data['src']).val('');
// TODO: Prompt the user with a dialog to create a new barcode entry, then add that to the form
}
});
2 changes: 1 addition & 1 deletion app/assets/javascripts/dashboard.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

$(document).on 'turbolinks:load', () ->
$ ->
$("select#dashboard_filter_interval").on "change", (e) ->
this.form.submit()
2 changes: 1 addition & 1 deletion app/assets/javascripts/distributions.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $ ->
options += "<option value=\"" + data[index].item_id + "\">" + data[index].item_name + " (#{data[index].quantity})" + "</option>\n"
$("select", insertedItem).find('option').remove().end().append(options)

$(document).on "turbolinks:load", ->
$ ->
control = $("select#distribution_storage_location_id")
if (control.length is 0)
return
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/donations.coffee.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@



$(document).on 'turbolinks:load', () ->
$ ->
control_id = "#donation_source"
ddp_text = "<%= Donation::SOURCES[:diaper_drive] %>"
dpl_text = "<%= Donation::SOURCES[:dropoff] %>"
Expand Down
7 changes: 7 additions & 0 deletions app/controllers/barcode_items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ def show
@barcode_item = current_organization.barcode_items.includes(:item).find(params[:id])
end

def find
@barcode_item = current_organization.barcode_items.includes(:item).find_by!(value: barcode_item_params[:value])
respond_to do |format|
format.json { render json: @barcode_item.to_json }
end
end

def update
@barcode_item = current_organization.barcode_items.find(params[:id])
@barcode_item.update_attributes(barcode_item_params)
Expand Down
14 changes: 12 additions & 2 deletions app/controllers/donations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def scale
@storage_locations = current_organization.storage_locations
@dropoff_locations = current_organization.dropoff_locations
@diaper_drive_participants = current_organization.diaper_drive_participants
@items = current_organization.items.alphabetized
@items = current_organization.items.alphabetized
end

def create
Expand All @@ -50,6 +50,7 @@ def create
@diaper_drive_participants = current_organization.diaper_drive_participants
@items = current_organization.items.alphabetized
flash[:notice] = "There was an error starting this donation, try again?"
Rails.logger.info "ERROR: #{@donation.errors}"
render action: :new
end
end
Expand Down Expand Up @@ -90,7 +91,9 @@ def destroy
private
def donation_params
params = strip_unnecessary_params
params.require(:donation).permit(:source, :storage_location_id, :issued_at, :dropoff_location_id, :diaper_drive_participant_id, line_items_attributes: [:item_id, :quantity, :_destroy]).merge(organization: current_organization)
params = compact_line_items
params.require(:donation).permit(:source, :comment, :storage_location_id, :issued_at, :dropoff_location_id, :diaper_drive_participant_id, line_items_attributes: [:item_id, :quantity, :_destroy]).merge(organization: current_organization)

end

def donation_item_params
Expand All @@ -103,4 +106,11 @@ def strip_unnecessary_params
params[:donation].delete(:diaper_drive_participant_id) unless params[:donation][:source] == Donation::SOURCES[:diaper_drive]
params
end

# If line_items have submitted with empty rows, clear those out first.
def compact_line_items
return params unless params[:donation].has_key?(:line_item_attributes)
params[:donation][:line_items_attributes].delete_if { |row, data| data["quantity"].blank? && data["item_id"].blank? }
params
end
end
4 changes: 3 additions & 1 deletion app/models/adjustment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class Adjustment < ApplicationRecord

has_many :line_items, as: :itemizable, inverse_of: :itemizable
has_many :items, through: :line_items
accepts_nested_attributes_for :line_items, allow_destroy: true
accepts_nested_attributes_for :line_items,
allow_destroy: true,
:reject_if => proc { |li| li[:item_id].blank? && li[:quantity].blank? }

validates :storage_location, :organization, presence: true
validates_associated :line_items
Expand Down
3 changes: 2 additions & 1 deletion app/models/distribution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class Distribution < ApplicationRecord
has_many :line_items, as: :itemizable, inverse_of: :itemizable
has_many :items, through: :line_items
accepts_nested_attributes_for :line_items,
allow_destroy: true
allow_destroy: true,
:reject_if => proc { |li| li[:item_id].blank? && li[:quantity].blank? }

validates :storage_location, :partner, :organization, presence: true
validates_associated :line_items
Expand Down
32 changes: 30 additions & 2 deletions app/models/donation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,33 @@ class Donation < ApplicationRecord
belongs_to :dropoff_location, optional: true # Validation is conditionally handled below.
belongs_to :diaper_drive_participant, optional: true # Validation is conditionally handled below.
belongs_to :storage_location
has_many :line_items, as: :itemizable, inverse_of: :itemizable
has_many :line_items, as: :itemizable, inverse_of: :itemizable do
def combine!
# Bail if there's nothing
return if self.size == 0
# First we'll collect all the line_items that are used
combined = {}
parent_id = first.itemizable_id
each do |i|
next unless i.valid?
combined[i.item_id] ||= 0
combined[i.item_id] += i.quantity
end
# Delete all the existing ones in this association -- this
# method aliases to `delete_all`
clear
# And now recreate a new array of line_items using the corrected totals
combined.each do |item_id,qty|
build(quantity: qty, item_id: item_id, itemizable_id: parent_id)
end
end
end
has_many :items, through: :line_items
accepts_nested_attributes_for :line_items,
allow_destroy: true
allow_destroy: true,
:reject_if => proc { |li| li[:item_id].blank? && li[:quantity].blank? }

before_create :combine_duplicates
validates :dropoff_location, presence: { message: "must be specified since you chose '#{SOURCES[:dropoff]}'" }, if: :from_dropoff_location?
validates :diaper_drive_participant, presence: { message: "must be specified since you chose '#{SOURCES[:diaper_drive]}'" }, if: :from_diaper_drive?
validates :source, presence: true, inclusion: { in: SOURCES.values, message: "Must be a valid source." }
Expand Down Expand Up @@ -94,4 +116,10 @@ def update_quantity(q, i)
line_item.quantity += q
line_item.save
end

private
def combine_duplicates
Rails.logger.info "Combining!"
self.line_items.combine!
end
end
3 changes: 2 additions & 1 deletion app/models/transfer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class Transfer < ApplicationRecord
has_many :line_items, as: :itemizable, inverse_of: :itemizable
has_many :items, through: :line_items
accepts_nested_attributes_for :line_items,
allow_destroy: true
allow_destroy: true,
:reject_if => proc { |li| li[:item_id].blank? && li[:quantity].blank? }

validates :from, :to, :organization, presence: true
validates_associated :line_items
Expand Down
5 changes: 5 additions & 0 deletions app/views/barcode_items/_barcode_item_lookup.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<% # Increment a counter on how many we've seen so that we can create a unique ID -- really only necessary for test hooks # %>
<% barcode_lookup_id = "_barcode-lookup-" + (@barcode_item_lookup_count = (@barcode_item_lookup_count || -1) + 1).to_s %>
<label for="<%= barcode_lookup_id %>">Barcode Entry:
<input type="text" id="<%= barcode_lookup_id %>" class="__barcode_item_lookup" value="" data-organization-id="<%= params[:organization_id] %>" />
</label>
7 changes: 7 additions & 0 deletions app/views/distributions/_line_item_fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<div class="nested-fields">
<div class="row">
<div class="input text optional barcode-item-lookup">
<div class="medium-offset-3 medium-6">
<%= render partial: "barcode_items/barcode_item_lookup" %>
</div>
</div>
</div>
<div class="row">
<div class="small-6 medium-3 medium-offset-3 columns">
<%= f.input_field :item_id, collection: @items, prompt: "Choose an item" %>
Expand Down
4 changes: 2 additions & 2 deletions app/views/distributions/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<%= f.input :comment, label: "Comment" %>

<%= f.simple_fields_for :line_items do |item| %>
<div id="distribution_line_items">
<div id="distribution_line_items" data-capture-barcode="true">
<%= render 'line_item_fields', f: item %>
</div>
<div class="row links">
Expand All @@ -35,7 +35,7 @@
data: {
association_insertion_node: "#distribution_line_items",
association_insertion_method: "append"
}
}, id: "__add_line_item"
%>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/views/donations/_donation_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@

<%= f.input :issued_at,
label: "Issued on",
as: :date,
as: :date,
html5: true %>


<%= f.simple_fields_for :line_items do |item| %>
<div id="donation_line_items">
<div id="donation_line_items" data-capture-barcode="true">
<%= render 'line_item_fields', f: item %>
</div>
<div class="row links">
Expand All @@ -39,7 +39,7 @@
data: {
association_insertion_node: "#donation_line_items",
association_insertion_method: "append"
}
}, id: "__add_line_item"
%>
</div>
</div>
Expand Down
7 changes: 7 additions & 0 deletions app/views/donations/_line_item_fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<div class="nested-fields">
<div class="row">
<div class="input text optional barcode-item-lookup">
<div class="medium-offset-3 medium-6">
<%= render partial: "barcode_items/barcode_item_lookup" %>
</div>
</div>
</div>
<div class="row">
<div class="small-6 medium-offset-3 medium-4 columns">
<%= f.input_field :item_id, collection: @items, prompt: "Choose an item" %>
Expand Down
7 changes: 7 additions & 0 deletions app/views/transfers/_line_item_fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<div class="nested-fields">
<div class="row">
<div class="input text optional barcode-item-lookup">
<div class="medium-offset-3 medium-6">
<%= render partial: "barcode_items/barcode_item_lookup" %>
</div>
</div>
</div>
<div class="row">
<div class="small-6 medium-3 medium-offset-3 columns">
<%= f.input_field :item_id, collection: @items, prompt: "Choose an item" %>
Expand Down
4 changes: 2 additions & 2 deletions app/views/transfers/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<%= f.input :comment %>

<%= f.simple_fields_for :line_items do |item| %>
<div id="transfer_line_items">
<div id="transfer_line_items" data-capture-barcode="true">
<%= render 'line_item_fields', f: item %>
</div>
<div class="row links">
Expand All @@ -41,7 +41,7 @@
data: {
association_insertion_node: "#transfer_line_items",
association_insertion_method: "append"
}
}, id: "__add_line_item"
%>
</div>
</div>
Expand Down
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
post :reclaim, on: :member
end

resources :barcode_items
resources :barcode_items do
get :find, on: :collection
end
resources :dropoff_locations
resources :diaper_drive_participants, except: [:destroy]
resources :items
Expand Down