Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//= require chartkick
//= require moment
//= require fullcalendar
//= require quagga
//= require_tree .


Expand Down Expand Up @@ -68,3 +69,58 @@ $(document).on("click", '#awesomebutton', function(e){
$(line_item).parent().find('.nested-fields:last-child input.__barcode_item_lookup').focus();
*/
});

function order_by_occurrence(arr) {
var counts = {};
arr.forEach(function(value){
if(!counts[value]) {
counts[value] = 0;
}
counts[value]++;
});

return Object.keys(counts).sort(function(curKey,nextKey) {
return counts[curKey] < counts[nextKey];
});
}

function load_quagga(){
if ($('#barcode-scanner').length > 0 && navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === 'function') {

var last_result = [];
if (Quagga.initialized == undefined) {
Quagga.onDetected(function(result) {
var last_code = result.codeResult.code;
last_result.push(last_code);
if (last_result.length > 20) {
code = order_by_occurrence(last_result)[0];
last_result = [];
Quagga.stop();
$.ajax({
type: "POST",
url: '/products/get_barcode',
data: { upc: code }
});
}
});
}

Quagga.init({
inputStream : {
name : "Live",
type : "LiveStream",
numOfWorkers: navigator.hardwareConcurrency,
target: document.querySelector('#barcode-scanner')
},
decoder: {
readers : ['ean_reader','ean_8_reader','code_39_reader','code_39_vin_reader','codabar_reader','upc_reader','upc_e_reader']
}
},function(err) {
if (err) { console.log(err); return }
Quagga.initialized = true;
Quagga.start();
});

}
};
$(document).on('turbolinks:load', load_quagga);
58 changes: 58 additions & 0 deletions app/assets/javascripts/barcode_scan.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
$(document).ready(function () {
$(document).on('click', '.barcode_scanner',function(e) {
var target = $(e.target)
load_quagga(target);

});
function order_by_occurrence(arr) {
var counts = {};
arr.forEach(function(value){
if(!counts[value]) {
counts[value] = 0;
}
counts[value]++;
});

return Object.keys(counts).sort(function(curKey,nextKey) {
return counts[curKey] < counts[nextKey];
});
}
function startScan(result) {
var last_code = result.codeResult.code;
last_result.push(last_code);
if (last_result.length > 19) {
upc_code = order_by_occurrence(last_result)[0];

// last_result = [];
Quagga.stop();
Quagga.offDetected(startScan);
$("#the-one-true-barcode-scanner").empty()
last_target.prev().val(upc_code)
}

}
function load_quagga(target){
if (navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === 'function') {
window.last_result = [];
window.last_target = target
Quagga.onDetected(startScan);

Quagga.init({
inputStream : {
name : "Live",
type : "LiveStream",
numOfWorkers: navigator.hardwareConcurrency,
target: "#the-one-true-barcode-scanner"
},
decoder: {
readers : ['ean_reader','ean_8_reader','code_39_reader','code_39_vin_reader','codabar_reader','upc_reader','upc_e_reader']
}
},function(err) {
if (err) { console.log(err); return }
Quagga.initialized = true;
Quagga.start();
});

}
};
});
21 changes: 21 additions & 0 deletions app/assets/javascripts/distribution_items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
$(document).ready(function () {
$(document).on('click', '.add-item-to-distribution',function(e) {
var target = $(e.target)
var item_quantity = target.parent().parent().children('.item-distribution-quantity').find('.quantity').val()
target.parent().parent().children('.item-distribution-quantity').find('.quantity').val('')
var item_upc = target.parent().parent().children('.item-distribution-upc').find('.upc').val()
target.parent().parent().children('.item-distribution-upc').find('.upc').val('')
var items_total = target.parent().parent().parent().find('.distribution-total-items').data('total')
var fulfilled = target.parent().parent().parent().find('.distribution-remaining-items').data('remaining')
var add_items = target.parent().parent().parent().find('.distributed-item-list')
var new_remainder = parseInt(fulfilled) + parseInt(item_quantity)
add_items.append(`<div><span>barcode: ${item_upc} </span><span> quantity: ${item_quantity} </span></div>`)
target.parent().parent().parent().find('.distribution-remaining-items').data('remaining', new_remainder)
target.parent().parent().parent().find('.distribution-remaining-items').empty()
target.parent().parent().parent().find('.distribution-remaining-items').append(`Fulfilled: ${new_remainder}`)

if (new_remainder >= items_total) {
target.parent().parent().parent().find('.line-item-name').append("<div>COMPLETE</div>")
}
})
})
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*= require bootstrap.min
*= require fullcalendar
*= require actiontext
*= require distribution
*/

//Use @import in order to process SCSS variables
Expand Down
26 changes: 26 additions & 0 deletions app/assets/stylesheets/distribution.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.barcode_scanner {
padding: 5px;
border: solid 1px gray;
border-radius: 5px;
cursor: pointer;
}

.add-items-container {
font-weight: bold;
}
@media only screen and (max-width: 1000px) {
.barcode_scanner {
width: 50%;
padding: 5px;
background-color: lightgreen;
padding: 5px 10px;
border: solid 1px gray;
border-radius: 5px;
cursor: pointer;
}
.list-line-items {
padding-bottom: 20px;
margin-bottom: 20px;
border-bottom: solid 5px grey;
}
}
8 changes: 8 additions & 0 deletions app/controllers/distributions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ def insufficient_amount!
end
end

def fulfill
@distribution = Distribution.includes(:line_items).includes(:storage_location).find(params[:id])
@distribution.line_items.build
@items = current_organization.items.alphabetized
@storage_locations = current_organization.storage_locations
@barcode_items = BarcodeItem.where(barcodeable_id: @items.map(&:id))
end

private

# If a request id is provided, update the request with the newly created distribution's id
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/ui_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ def print_button_to(link, options = {})
_link_to link, { icon: "print", type: "default", text: "Print", size: "xs" }.merge(options)
end

def fulfill_button_to(link, options = {})
_link_to link, { icon: "barcode", type: "default", text: "Fulfill", size: "xs" }.merge(options)
end

# Generic Submit button for a form
def submit_button(options = {}, data = {})
disable_text = options[:disable_text] || "Saving"
Expand Down
2 changes: 1 addition & 1 deletion app/views/barcode_items/_barcode_item_lookup.html.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<% # Increment a counter on how many we've seen so that we can create a unique ID -- really only necessary for test hooks # %>
<input type="text" id=<%= "_barcode-lookup-#{index}" %> class="__barcode_item_lookup form-control" value="" placeholder="Barcode Entry" data-organization-id="<%= params[:organization_id] %>" />
<input class="barcode-lookup" type="text" id=<%= "_barcode-lookup-#{index}" %> class="__barcode_item_lookup form-control" value="" placeholder="Barcode Entry" data-organization-id="<%= params[:organization_id] %>" />
1 change: 1 addition & 0 deletions app/views/distributions/_distribution_row.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<td><%= distribution_row.line_items.total %></td>
<td><%= item_value(distribution_row.value_per_itemizable) %></td>
<td class="text-right">
<%= fulfill_button_to fulfill_distribution_path(distribution_row) %>
<%= view_button_to distribution_path(distribution_row) %>
<%= edit_button_to edit_distribution_path(distribution_row) %>
<%= print_button_to print_distribution_path(distribution_row, format: :pdf) %>
Expand Down
1 change: 1 addition & 0 deletions app/views/distributions/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
</div>
</div>
<% end %>
<div id="the-one-true-barcode-scanner"></div>
</div>
</div>
<!-- /.box -->
Expand Down
35 changes: 35 additions & 0 deletions app/views/distributions/fulfill.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<section class="content">
<% @distribution.line_items.each do |line_item| %>
<div class="row box">
<% bc_item_quantity = @barcode_items.where(barcodeable_id: line_item.item_id).first ? @barcode_items.where(barcodeable_id: line_item.item_id).first.quantity : 0 %>
<% multiplier = bc_item_quantity > 0 ? (line_item.quantity / bc_item_quantity).floor : 0 %>
<% line_item_quantity = line_item.quantity ? line_item.quantity : 0 %>

<div class='col-md-12 box-header line-item-name with-border bg-gray'> <%= line_item.item ? line_item.item.name : '' %></div>

<div class='col-md-6 col-12 distribution-total-items' data-total="<%= line_item_quantity %>">Total Requested: <%= line_item_quantity%> </div>

<div class='col-md-6 col-12 distribution-remaining-items' data-remaining="0"> Fulfilled: 0 </div>
<hr />
<!-- <%# <div class='col-md-6 col-12'> Each container has:<%= bc_item_quantity %></div> %>
<%# <div class='col-md-6 col-12'>Complete Containers: <%= multiplier %></div>%>
<%# <div class='col-md-6 col-12'>Individual Items: <%= line_item_quantity - (multiplier * bc_item_q uantity ) %></div> %>-->
<div class="add-items-container">
<div class="item-distribution-upc col-md-6 col-12">
barcode: <input class="upc" type="text" value="<%= line_item.id %>"></input>
<div id="barcode-id" class="btn fa fa-barcode barcode_scanner"></div>
</div>
<div class="item-distribution-quantity col-md-4 col-12">
quantity: <input class="quantity" type="text" value="<%= bc_item_quantity %>"></input>
</div>
<div class="col-md-2 col-12">
<button class="add-item-to-distribution">ADD</button>
</div>
</div>
<div class="col-12 col-md-12 distributed-item-list">
</div>
</div>

<% end %>
</section>
<div id="the-one-true-barcode-scanner"></div>
21 changes: 16 additions & 5 deletions app/views/line_items/_line_item_fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
<div class="nested-fields">
<%= render partial: "barcode_items/barcode_item_lookup", locals: {index: f.options[:child_index]} %>
<label>OR</label>
<%= f.input_field :item_id, collection: @items, prompt: "Choose an item", class: 'form-control' %>
<section class="row">
<div class="nested-fields list-line-items">
<span class='col-md-3 col-sm-12'>
<%= render partial: "barcode_items/barcode_item_lookup", locals: {index: f.options[:child_index]} %>
<div id="barcode-id" class="fa fa-barcode barcode_scanner"> </div>
</span>
<span class="col-md-4 col-sm-12">
<label>OR</label>
<%= f.input_field :item_id, collection: @items, prompt: "Choose an item", class: 'form-control' %>
</span>
<div class='col-md-3 col-12'>
<%= f.input_field :quantity, placeholder: "Quantity", class: 'form-control' %>
<%= delete_line_item_button f %>
</div>
<div class='col-md-2 col-12'>
<%= delete_line_item_button f %>
</div>
</div>
</section>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
resources :distributions, except: %i(destroy) do
get :print, on: :member
post :reclaim, on: :member
get :fulfill, on: :member
collection do
get :pick_ups
end
Expand Down
Loading