Class: Workarea::Metrics::User
- Inherits:
-
Object
- Object
- Workarea::Metrics::User
- Includes:
- Mongoid::Document
- Defined in:
- app/models/workarea/metrics/user.rb
Class Method Summary collapse
- .best ⇒ Object
- .save_order(email:, revenue:, discounts: 0, at: Time.current) ⇒ Object
- .update_aggregations! ⇒ Object
- .update_calculated_fields! ⇒ Object
- .update_percentiles! ⇒ Object
- .update_percentiles_expression(field) ⇒ Object
Instance Method Summary collapse
-
#average_order_value ⇒ Object
Use calculated value for real-time display, the aggregated value used in insights we be recalculated weekly.
Class Method Details
.best ⇒ Object
57 58 59 60 61 62 63 |
# File 'app/models/workarea/metrics/user.rb', line 57 def best scoped .with_purchases .by_frequency_percentile(81..100) .by_revenue_percentile(81..100) .order_by(revenue: :desc, orders: :desc, last_order_at: :desc, id: :asc) end |
.save_order(email:, revenue:, discounts: 0, at: Time.current) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'app/models/workarea/metrics/user.rb', line 38 def save_order(email:, revenue:, discounts: 0, at: Time.current) revenue_in_default_currency = revenue.to_m.exchange_to(Money.default_currency).to_f discounts_in_default_currency = discounts.to_m.exchange_to(Money.default_currency).to_f collection.update_one( { _id: email }, { '$set' => { last_order_at: at.utc }, '$setOnInsert' => { first_order_at: at.utc }, '$inc' => { orders: 1, revenue: revenue_in_default_currency, discounts: discounts_in_default_currency } }, upsert: true ) end |
.update_aggregations! ⇒ Object
65 66 67 68 |
# File 'app/models/workarea/metrics/user.rb', line 65 def update_aggregations! update_calculated_fields! update_percentiles! end |
.update_calculated_fields! ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/models/workarea/metrics/user.rb', line 70 def update_calculated_fields! collection.aggregate([ { '$addFields' => { 'frequency' => { '$divide' => [ '$orders', { '$subtract' => [Time.current.utc, '$first_order_at'] } ] }, 'average_order_value' => { '$divide' => ['$revenue', '$orders'] } } }, { '$out' => collection.name } ]).first end |
.update_percentiles! ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'app/models/workarea/metrics/user.rb', line 89 def update_percentiles! collection.aggregate([ { '$addFields' => { 'orders_percentile' => update_percentiles_expression(:orders), 'frequency_percentile' => update_percentiles_expression(:frequency), 'revenue_percentile' => update_percentiles_expression(:revenue), 'average_order_value_percentile' => update_percentiles_expression(:average_order_value) } }, { '$out' => collection.name } ]).first end |
.update_percentiles_expression(field) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'app/models/workarea/metrics/user.rb', line 103 def update_percentiles_expression(field) percentiles = CalculatePercentiles.new(collection, field) { '$switch' => { 'branches' => 99.downto(1).map do |percentile| { 'case' => { '$gte' => ["$#{field}", percentiles[percentile.to_s]] }, 'then' => percentile + 1 } end, 'default' => 1 } } end |
Instance Method Details
#average_order_value ⇒ Object
Use calculated value for real-time display, the aggregated value used in insights we be recalculated weekly.
122 123 124 125 |
# File 'app/models/workarea/metrics/user.rb', line 122 def average_order_value return nil if orders.zero? revenue / orders.to_f end |