Module: Models::Profitable
- Extended by:
- ActiveSupport::Concern
- Includes:
- Memery
- Defined in:
- app/concerns/models/profitable.rb
Instance Attribute Summary collapse
- #min_profit_markup ⇒ Object readonly
Instance Method Summary collapse
- #default_sales_markup ⇒ Object
- #profit_margins_met? ⇒ Boolean
- #profitable_line_items ⇒ Object
- #profitable_status ⇒ Object
- #profitable_total_discounted ⇒ Object
- #profitable_total_estimated_cost ⇒ Object
- #profitable_total_estimated_line_cost ⇒ Object
-
#profitable_total_profit ⇒ Object
AKA Gross Profit.
-
#profitable_total_profit_margin ⇒ Object
To find the margin, divide gross profit by the revenue.
-
#profitable_total_profit_markup ⇒ Object
To write the markup as a percentage, divide the gross profit by the COGS.
- #track_profit? ⇒ Boolean
- #validate_min_profit_markup? ⇒ Boolean
Instance Attribute Details
#min_profit_markup ⇒ Object (readonly)
10 |
# File 'app/concerns/models/profitable.rb', line 10 validates :min_profit_markup, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, if: :validate_min_profit_markup? |
Instance Method Details
#default_sales_markup ⇒ Object
20 21 22 |
# File 'app/concerns/models/profitable.rb', line 20 def default_sales_markup 30 end |
#profit_margins_met? ⇒ Boolean
102 103 104 105 106 107 108 |
# File 'app/concerns/models/profitable.rb', line 102 def profit_margins_met? return true unless track_profit? return true if min_profit_markup.zero? pm = (profitable_total_profit_markup * 100).to_i pm >= min_profit_markup end |
#profitable_line_items ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/concerns/models/profitable.rb', line 24 def profitable_line_items items = line_items.where("line_items.tax_class = 'g' OR (line_items.tax_class = 'shp' and line_items.price > 0)") .parents_only .includes({ catalog_item: :store_item }, :item, :shipping_cost, :line_discounts) # Exclude shipping line items where charged shipping >= actual shipping cost # Only include shipping in profit calculation when we're losing money on it items.reject do |li| next false unless li.is_shipping? actual_cost = li.shipping_cost&.rate_data&.dig('actual_cost').to_f charged = li.discounted_price.to_f actual_cost > 0 && charged >= actual_cost end end |
#profitable_status ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'app/concerns/models/profitable.rb', line 81 def profitable_status # If there's nothing to calculate 0 /0 then its ok return :ok if profitable_total_profit.zero? && profitable_total_discounted.zero? # Shortcut, if we don't meet the profit margins, its always an alert return :alert unless profit_margins_met? tm = profitable_total_profit_markup if tm >= 0.60 :ok elsif (tm * 100).to_i > default_sales_markup :warning else :alert end end |
#profitable_total_discounted ⇒ Object
40 41 42 |
# File 'app/concerns/models/profitable.rb', line 40 def profitable_total_discounted profitable_line_items.map(&:discounted_total).compact.sum end |
#profitable_total_estimated_cost ⇒ Object
45 46 47 |
# File 'app/concerns/models/profitable.rb', line 45 def profitable_total_estimated_cost profitable_line_items.map(&:estimated_line_cost).compact.sum end |
#profitable_total_estimated_line_cost ⇒ Object
55 56 57 |
# File 'app/concerns/models/profitable.rb', line 55 def profitable_total_estimated_line_cost profitable_line_items.map(&:estimated_line_cost).compact.sum end |
#profitable_total_profit ⇒ Object
AKA Gross Profit
50 51 52 |
# File 'app/concerns/models/profitable.rb', line 50 def profitable_total_profit # AKA Gross Profit profitable_line_items.map(&:current_line_profit).compact.sum end |
#profitable_total_profit_margin ⇒ Object
To find the margin, divide gross profit by the revenue.
61 62 63 64 65 66 67 68 |
# File 'app/concerns/models/profitable.rb', line 61 def profitable_total_profit_margin gross_profit = profitable_total_profit revenue = profitable_total_discounted return 0.0 if revenue.zero? && gross_profit == 0 return -1.0 if revenue == 0 (gross_profit / revenue).round(4) end |
#profitable_total_profit_markup ⇒ Object
To write the markup as a percentage, divide the gross profit by the COGS.
72 73 74 75 76 77 78 |
# File 'app/concerns/models/profitable.rb', line 72 def profitable_total_profit_markup gross_profit = profitable_total_profit cogs = profitable_total_estimated_line_cost return 0.0 if cogs.zero? # Should not happen item never cost nothing but you never know (gross_profit / cogs).round(4) end |
#track_profit? ⇒ Boolean
98 99 100 |
# File 'app/concerns/models/profitable.rb', line 98 def track_profit? has_attribute?(:min_profit_markup) && profitable_line_items.present? && (is_a?(Order) || is_a?(Quote)) end |
#validate_min_profit_markup? ⇒ Boolean
13 14 15 16 17 18 |
# File 'app/concerns/models/profitable.rb', line 13 def validate_min_profit_markup? return false unless has_attribute?(:min_profit_markup) return false if try(:invoiced?) true end |