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

786 add ppv to total inventory report #814

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
25 changes: 18 additions & 7 deletions app/assets/javascripts/data-tables-init.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ $(document).on "page:change", ->

fnFooterCallback = (row, data, start, end, display) ->
numColumnIndex = table.find("th.num-value").index()
monetaryColumnIndex = table.find("th.monetary-value").index()
monetaryColumnIndex1 = table.find("th.monetary-value-1").index()
monetaryColumnIndex2 = table.find("th.monetary-value-2").index()

# Utility function to convert "1234567.00" to "1,234,567.00"
numberWithCommas = (x) ->
Expand All @@ -16,17 +17,27 @@ $(document).on "page:change", ->
intVal = (i) ->
if typeof i == 'string' then i.replace(/[\$,]/g, '') * 1 else if typeof i == 'number' then i else 0

# Calculate the totals for the current page
# Calculate the number totals for the current page
numTotal = @api().column(numColumnIndex, page: 'current').data().reduce(((a, b) ->
intVal(a) + intVal(b)
), 0)
pageTotal = @api().column(monetaryColumnIndex, page: 'current').data().reduce(((a, b) ->
intVal(a) + intVal(b)
), 0).toFixed(2)
$(@api().column(numColumnIndex).footer()).html numTotal


# Calculate the number totals for the current page
if monetaryColumnIndex1 > -1
pageTotal = @api().column(monetaryColumnIndex1, page: 'current').data().reduce(((a, b) ->
intVal(a) + intVal(b)
), 0).toFixed(2)
$(@api().column(monetaryColumnIndex1).footer()).html '$'+ numberWithCommas(pageTotal)

if monetaryColumnIndex2 > -1
pageTotal = @api().column(monetaryColumnIndex2, page: 'current').data().reduce(((a, b) ->
intVal(a) + intVal(b)
), 0).toFixed(2)
$(@api().column(monetaryColumnIndex2).footer()).html '$'+ numberWithCommas(pageTotal)

# Render the totals on the footer
$(@api().column(numColumnIndex).footer()).html numTotal
$(@api().column(monetaryColumnIndex).footer()).html '$'+ numberWithCommas(pageTotal)

fnRowCallback = (row, data, index) ->
$row = $(row)
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def net_suite_export
end

def total_inventory_value
params[:date] ||= Time.zone.now.strftime("%m/%d/%Y")
params[:start_date] ||= 1.year.ago.strftime("%m/%d/%Y")
params[:end_date] ||= Date.today.strftime("%m/%d/%Y")
@report = Reports::TotalInventoryValue.new(params, session)
end

Expand Down
31 changes: 29 additions & 2 deletions app/models/category.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ def to_json
}
end

def value(at: nil)
def value(at: nil, unscoped: false)
if at.blank?
items.sum("current_quantity * value")
else
items.includes(:versions).inject(0) do |sum, item|
items_for_totaling =
if unscoped
items.unscope(where: :deleted_at).where.not("deleted_at > :date", date: at)
else
items
end

items_for_totaling.includes(:versions).inject(0.0) do |sum, item|
total = item.total_value(at: at)
if total.present?
sum + total
Expand All @@ -27,6 +34,21 @@ def value(at: nil)
end
end

def total_count(at: nil)
if at.blank?
items.sum(:current_quantity)
else
items.includes(:versions).inject(0) do |sum, item|
total = item.total_count(at: at)
if total.present?
sum + total
else
sum
end
end
end
end

def self.to_json
order(:description).with_programs_and_inject_requested_quantities.map(&:to_json).to_json
end
Expand All @@ -43,4 +65,9 @@ def increment_next_sku
save!
end
end

# Unscope to reveal all records AND scope to those deleted after start_date OR active
def items_including_deleted_after(start_date)
items.unscope(where: :deleted_at).where("deleted_at > ? OR deleted_at IS NULL", start_date)
end
end
19 changes: 18 additions & 1 deletion app/models/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def self.default_scope
has_many :order_details
has_many :orders, through: :order_details
has_many :requested_orders, -> { for_requested_statuses }, through: :order_details, source: :order
has_many :purchase_details
has_many :purchases, through: :purchase_details
has_many :bin_items
has_many :bins, -> { includes(:bin_location).order(:label) }, through: :bin_items
validates :description, presence: true
Expand Down Expand Up @@ -79,6 +81,10 @@ def self.not_deleted
where(deleted_at: nil)
end

def description
super + (deleted? ? " (deleted)" : "")
end

def soft_delete
self.deleted_at = Time.zone.now
save
Expand All @@ -93,9 +99,20 @@ def deleted?
deleted_at != nil
end

def total_count(at: nil)
return current_quantity if at.nil? || at >= updated_at
past_total_count(at)
end

def past_total_count(time)
past_version = version_at(time)
return 0 if past_version.blank? || past_version.current_quantity.nil?
past_version.current_quantity
end

def past_total_value(time)
past_version = version_at(time)
return nil if past_version.blank? || past_version.value.nil?
return 0 if past_version.blank? || past_version.value.nil?
past_version.current_quantity * past_version.value
end

Expand Down
52 changes: 36 additions & 16 deletions app/models/reports/total_inventory_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,69 @@ def self.new(params, _session)
end

module Common
def date
return if @params[:date].blank?
Time.strptime(@params[:date], "%m/%d/%Y").end_of_day
def start_date
return if @params[:start_date].blank?
Date.strptime(@params[:start_date], "%m/%d/%Y")
end

def end_date
return if @params[:end_date].blank?
Date.strptime(@params[:end_date], "%m/%d/%Y")
end

def get_purchases(item)
Purchase.includes(:purchase_details)
.where(purchase_details: { item_id: item.id })
.where(purchase_date: start_date..end_date)
end
end

class SingleCategory
include Common
attr_reader :category
attr_accessor :category, :total_value, :total_ppv

def initialize(params)
@category = Category.find(params[:category_id])
@params = params
@total_value = 0.0
@total_ppv = 0.0
end

def each
category.items.order(:description).each do |item|
yield item.description, item.total_value(at: date)
end
end
category.items_including_deleted_after(start_date).order(:description).each do |item|
@total_value += (item_total_value = item.total_value(at: end_date.end_of_day))
@total_ppv += (total_item_ppv = get_purchases(item).map(&:total_ppv).sum)

def total_value
category.value
yield category.description, item.description,
item.total_count(at: end_date.end_of_day),
item_total_value, total_item_ppv
end
end
end

class AllCategories
include Common
attr_reader :categories
attr_accessor :categories, :total_value, :total_ppv

def initialize(params)
@categories = Category.all
@params = params
@total_value = 0.0
@total_ppv = 0.0
end

def each
categories.each do |category|
yield category.description, category.value(at: date)
end
end
total_category_ppv = category.items_including_deleted_after(start_date)
.map { |item| get_purchases(item).map(&:total_ppv).sum }.sum

def total_value
categories.to_a.sum(&:value)
@total_value += (category_total_value = category.value(at: end_date.end_of_day, unscoped: true))
@total_ppv += total_category_ppv

yield category.description, nil,
category.total_count(at: end_date.end_of_day),
category_total_value, total_category_ppv
end
end
end
end
Expand Down
19 changes: 11 additions & 8 deletions app/views/reports/_total_inventory_value_filters.html.erb
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<div class="row">
<div class="col-xs-12">
<form class="form-inline pull-right">
<%= form_tag total_inventory_value_reports_path, method: "get" do %>
<%= label_tag :date, "Date", class: "control-label" %>
<%= text_field_tag :date, params[:date], data: { provide: "datepicker" } %>
<%= hidden_field_tag :category_id, request.params[:category_id] %>
<%= submit_tag "Filter", class: "btn btn-default" %>
<% end %>
</form>
<%= form_tag total_inventory_value_reports_path, method: "get", class: "form-inline pull-right" do %>
<div class="form-group form-group-sm">
<%= label_tag :start_date, "Start Date", class: "control-label" %>
<%= text_field_tag :start_date, params[:start_date], class: "form-control", data: { provide: "datepicker" } %>
<%= label_tag :end_date, "End Date", class: "control-label" %>
<%= text_field_tag :end_date, params[:end_date], class: "form-control", data: { provide: "datepicker" } %>
</div>

<%= hidden_field_tag :category_id, request.params[:category_id] %>
<%= submit_tag "Filter", class: "btn btn-default" %>
<% end %>
</div>
</div>

Expand Down
19 changes: 14 additions & 5 deletions app/views/reports/_total_inventory_value_table.html.erb
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
<table class="table table-striped table-responsive data-table">
<thead>
<tr>
<th class="sort-asc">Description</th>
<th class="text-center monetary-value">Value</th>
<th class="sort-asc">Category</th>
<th>Item</th>
<th class="text-center num-value">Count</th>
<th class="text-center monetary-value-1">Value</th>
<th class="text-center monetary-value-2">PPV</th>
</tr>
</thead>

<tbody>
<% report.each do |description, value| %>
<% report.each do |category_name, item_name, count, value, ppv| %>
<tr>
<td><%= description %></td>
<td><%= category_name %></td>
<td><%= item_name %></td>
<td class="text-center"><%= count %></td>
<td class="text-center"><%= number_to_currency value, precision: 2 %></td>
<td class="text-center"><%= number_to_currency ppv, precision: 2 %></td>
</tr>
<% end %>
</tbody>

<tfoot>
<tr>
<th></th>
<th class="text-center"><%= number_to_currency report.total_value, precision: 2 %></th>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question for @LisaJBlanchard : Do you want the total at the bottom of these reports to show the total for all pages of the report, or just the current page being viewed? If it should be the total for just this page of data, should there be another place that includes the full total?

<th></th>
<th class="text-center"></th>
<th class="text-center"></th>
<th class="text-center"></th>
</tr>
</tfoot>
</table>