Split before after 1 year groups

12 views
Skip to first unread message

Stephanie_Snowflake

unread,
Aug 16, 2018, 1:55:47 PM8/16/18
to Ruby on Rails: Talk
I'm looking for a way to split a group of data (ex. Sales Orders)

Currently split (In Progress, On Hold, Shipped, Cancelled)

I would like to split Shipped into two

Shipped (before 1 year)
Archive Shipped (after 1 year)


I believe I should add the following line to  sales_orders.html.erb


<%= sidebar_link_to(:status, 'archive_shipped') {"Archive"} %>


and add the following lines in the sales_order.rb



when "recent_shipped"
active.shipped.shipped_date_after(1.year.ago)
when "achive_shipped"
active.shipped.shipped_date_before(1.year.ago)

But I'm not sure where to place this in the file, since I didn't have all the phases (in progress, on hold, shipped, and cancelled) labeled out like :Phase 

I didn't write this application, so I'm trying to make changes that have been requested. 

Please see sales_order.rb below

class SalesOrder < ActiveRecord::Base
  include Filterable
  include Tenancy

  enum status: [ :in_progress, :on_hold, :cancelled, :shipped ]

  has_many :line_items, dependent: :destroy
  has_many :films
  
  accepts_nested_attributes_for :line_items, allow_destroy: true
  
  validates :code, presence: true, 
                   uniqueness: { case_sensitive: false, 
                                 scope: :tenant_code }
  validates :ship_date, presence: true, if: Proc.new { |o| o.shipped? }
  validate :ship_date_after_release?
  validates :release_date, presence: true
  validates :due_date, presence: true

  include PgSearch
  pg_search_scope :search, against: [:code, :customer, :ship_to, :note], 
    :using => { tsearch: { prefix: true } }

  scope :order_by, ->(col, dir) { order("#{col} #{dir}") }
  scope :status, ->(status) { where(status: statuses[status]) }
  scope :due_date_equals, ->(date) { where(due_date: date) }
  scope :type, ->(prefix) { where('code ILIKE ?', prefix) }
  scope :ship_date_before, ->(date) { where("ship_date <= ?", date) } 
  scope :ship_date_after, ->(date) { where("ship_date >= ?", date) } 
  scope :text_search, ->(query) { reorder('').search(query) }
  scope :code_like, ->(code) { where('code ILIKE ?', code.gsub('*', '%')) }
  scope :status_not, ->(status) { where("status <> ?", statuses[status]) }

  def lead_days
    (ship_date - release_date).to_i
  end

  def total_quantity
    line_items.total_quantity
  end

  def assigned_film_count(phase = nil)
    assigned = phase ? films.phase(phase) : films
    assigned.total_order_fill_count
  end

  def assigned_film_percentage
    return 0 if total_quantity == 0
    100*assigned_film_count/total_quantity
  end

  def total_custom_area
    line_items.total_area
  end

  def total_assigned_area
    films.map{ |f| f.area }.sum
  end

  def past_due?
    Date.current > due_date
  end

  def shipped_late?
    ship_date ? ship_date > due_date : false
  end

  def utilization
    100*total_custom_area/total_assigned_area if total_custom_area && total_assigned_area && total_assigned_area > 0
  end

  def self.avg_utilization
    100*total_custom_area/total_assigned_area if total_custom_area && total_assigned_area && total_assigned_area > 0
  end

  def self.total_custom_area
    line_items.total_area
  end

  def self.total_assigned_area
    films.map{ |f| f.area }.sum
  end

  def self.line_items
    LineItem.where(sales_order_id: all.map(&:id))
  end

  def self.films
    Film.where(sales_order_id: all.map(&:id))
  end

  def self.to_csv(options = {})
    CSV.generate(options) do |csv|
      csv << %w(SO# Customer Released Due Ship-to Status Shipped Note)
      all.each do |o|
        csv << [o.code, o.customer, o.release_date, o.due_date, o.ship_to, o.status, o.ship_date, o.note]
      end
    end
  end

  private

  def ship_date_after_release?
    if ship_date.present? && ship_date < release_date
      errors.add(:base, "Must be shipped after release")
    end
  end
end

Hassan Schroeder

unread,
Aug 17, 2018, 4:47:22 PM8/17/18
to rubyonrails-talk
On Thu, Aug 16, 2018 at 10:55 AM, Stephanie_Snowflake
<spicyc...@gmail.com> wrote:
> I'm looking for a way to split a group of data (ex. Sales Orders)
>
> Currently split (In Progress, On Hold, Shipped, Cancelled)
>
> I would like to split Shipped into two
>
> Shipped (before 1 year)
> Archive Shipped (after 1 year)

As far as I can tell, nothing in the model you show has anything to
do with *setting* a status.

You can add ':archive_shipped' to this (and presumably to the DB
schema),

> enum status: [ :in_progress, :on_hold, :cancelled, :shipped ]

but where is the status set to start with?

Also, in passing, "before one year" and "after one year" probably
leaves a day in the middle ("exactly one year") when things will be
at the least indeterminate. FWIW.

--
Hassan Schroeder ------------------------ hassan.s...@gmail.com
twitter: @hassan
Consulting Availability : Silicon Valley or remote

Stephanie_Snowflake

unread,
Oct 12, 2018, 4:34:08 PM10/12/18
to Ruby on Rails: Talk
Have not found in settings for shipping, since it just a status. I would like it to automatic archive if it was shipped after 3 yeaars

Hassan Schroeder

unread,
Oct 12, 2018, 7:10:45 PM10/12/18
to rubyonrails-talk
On Fri, Oct 12, 2018 at 1:34 PM, Stephanie_Snowflake
<spicyc...@gmail.com> wrote:
> Have not found in settings for shipping, since it just a status. I would
> like it to automatic archive if it was shipped after 3 yeaars

Is this a different question? It sounds like you just want a task to run
nightly via cron that sweeps the DB for products with a shipped_date
over 3 years old and "archives" that product.

Depending on your requirements using a rake task or `rails runner`
should handle it.

HTH,
Reply all
Reply to author
Forward
0 new messages