mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
(wip) report store statistics in UI
This commit is contained in:
parent
70f7ef8951
commit
d9e8d0e40d
@ -9,7 +9,7 @@ class API::StatisticsController < API::ApiController
|
||||
@statistics = StatisticIndex.all
|
||||
end
|
||||
|
||||
%w[account event machine project subscription training user space].each do |path|
|
||||
%w[account event machine project subscription training user space order].each do |path|
|
||||
class_eval %{
|
||||
def #{path}
|
||||
authorize :statistic, :#{path}?
|
||||
@ -30,11 +30,7 @@ class API::StatisticsController < API::ApiController
|
||||
# return result
|
||||
render json: results
|
||||
end
|
||||
}, __FILE__, __LINE__ - 20
|
||||
end
|
||||
|
||||
%w[account event machine project subscription training user space].each do |path|
|
||||
class_eval %{
|
||||
def export_#{path}
|
||||
authorize :statistic, :export_#{path}?
|
||||
|
||||
@ -56,7 +52,7 @@ class API::StatisticsController < API::ApiController
|
||||
disposition: 'attachment'
|
||||
end
|
||||
end
|
||||
}, __FILE__, __LINE__ - 22
|
||||
}, __FILE__, __LINE__ - 42
|
||||
end
|
||||
|
||||
def export_global
|
||||
|
@ -15,22 +15,23 @@ class Reservation < ApplicationRecord
|
||||
accepts_nested_attributes_for :slots_reservations, allow_destroy: true
|
||||
belongs_to :reservable, polymorphic: true
|
||||
|
||||
has_many :tickets
|
||||
has_many :tickets, dependent: :destroy
|
||||
accepts_nested_attributes_for :tickets, allow_destroy: false
|
||||
|
||||
has_many :invoice_items, as: :object, dependent: :destroy
|
||||
has_one :payment_schedule_object, as: :object, dependent: :destroy
|
||||
|
||||
validates_presence_of :reservable_id, :reservable_type
|
||||
validates :reservable_id, :reservable_type, presence: true
|
||||
validate :machine_not_already_reserved, if: -> { reservable.is_a?(Machine) }
|
||||
validate :training_not_fully_reserved, if: -> { reservable.is_a?(Training) }
|
||||
validate :slots_not_locked
|
||||
|
||||
after_save :update_event_nb_free_places, if: proc { |reservation| reservation.reservable_type == 'Event' }
|
||||
after_commit :notify_member_create_reservation, on: :create
|
||||
after_commit :notify_admin_member_create_reservation, on: :create
|
||||
after_commit :extend_subscription, on: :create
|
||||
after_save :update_event_nb_free_places, if: proc { |reservation| reservation.reservable_type == 'Event' }
|
||||
|
||||
delegate :user, to: :statistic_profile
|
||||
|
||||
# @param canceled if true, count the number of seats for this reservation, including canceled seats
|
||||
def total_booked_seats(canceled: false)
|
||||
@ -50,10 +51,6 @@ class Reservation < ApplicationRecord
|
||||
total
|
||||
end
|
||||
|
||||
def user
|
||||
statistic_profile.user
|
||||
end
|
||||
|
||||
def update_event_nb_free_places
|
||||
return unless reservable_type == 'Event'
|
||||
|
||||
@ -83,11 +80,11 @@ class Reservation < ApplicationRecord
|
||||
daily_slots[1..].each do |slot|
|
||||
found = false
|
||||
result[date].each do |group_start, group_slots|
|
||||
if slot[:start_at] === group_slots.last[:end_at]
|
||||
result[date][group_start].push(slot)
|
||||
found = true
|
||||
break
|
||||
end
|
||||
next unless slot[:start_at] == group_slots.last[:end_at]
|
||||
|
||||
result[date][group_start].push(slot)
|
||||
found = true
|
||||
break
|
||||
end
|
||||
result[date][slot[:start_at]] = [slot] unless found
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Stats
|
||||
class Account
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
end
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This is a statistical data saved in ElasticSearch, about an account creation
|
||||
class Stats::Account
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
end
|
||||
|
@ -1,12 +1,13 @@
|
||||
module Stats
|
||||
class Event
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
include StatReservationConcern
|
||||
# frozen_string_literal: true
|
||||
|
||||
attribute :eventId, Integer
|
||||
attribute :eventDate, String
|
||||
attribute :ageRange, String
|
||||
attribute :eventTheme, String
|
||||
end
|
||||
# This is a statistical data saved in ElasticSearch, about an event reservation
|
||||
class Stats::Event
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
include StatReservationConcern
|
||||
|
||||
attribute :eventId, Integer
|
||||
attribute :eventDate, String
|
||||
attribute :ageRange, String
|
||||
attribute :eventTheme, String
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Stats::StoreOrder
|
||||
# This is a statistical data saved in ElasticSearch, about a store's order
|
||||
class Stats::Order
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
|
@ -1,14 +1,15 @@
|
||||
module Stats
|
||||
class Project
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
# frozen_string_literal: true
|
||||
|
||||
attribute :projectId, Integer
|
||||
attribute :name, String
|
||||
attribute :licence, Hash
|
||||
attribute :themes, Array
|
||||
attribute :components, Array
|
||||
attribute :machines, Array
|
||||
attribute :users, Integer
|
||||
end
|
||||
# This is a statistical data saved in ElasticSearch, about a project publication
|
||||
class Stats::Project
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
|
||||
attribute :projectId, Integer
|
||||
attribute :name, String
|
||||
attribute :licence, Hash
|
||||
attribute :themes, Array
|
||||
attribute :components, Array
|
||||
attribute :machines, Array
|
||||
attribute :users, Integer
|
||||
end
|
||||
|
@ -1,9 +1,10 @@
|
||||
module Stats
|
||||
class Space
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
include StatReservationConcern
|
||||
# frozen_string_literal: true
|
||||
|
||||
attribute :spaceId, Integer
|
||||
end
|
||||
# This is a statistical data saved in ElasticSearch, about a space reservation
|
||||
class Stats::Space
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
include StatReservationConcern
|
||||
|
||||
attribute :spaceId, Integer
|
||||
end
|
||||
|
@ -1,12 +1,13 @@
|
||||
module Stats
|
||||
class Subscription
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
# frozen_string_literal: true
|
||||
|
||||
attribute :ca, Float
|
||||
attribute :planId, Integer
|
||||
attribute :subscriptionId, Integer
|
||||
attribute :invoiceItemId, Integer
|
||||
attribute :groupName, String
|
||||
end
|
||||
# This is a statistical data saved in ElasticSearch, about a subscription to a plan
|
||||
class Stats::Subscription
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
|
||||
attribute :ca, Float
|
||||
attribute :planId, Integer
|
||||
attribute :subscriptionId, Integer
|
||||
attribute :invoiceItemId, Integer
|
||||
attribute :groupName, String
|
||||
end
|
||||
|
@ -1,10 +1,11 @@
|
||||
module Stats
|
||||
class Training
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
include StatReservationConcern
|
||||
# frozen_string_literal: true
|
||||
|
||||
attribute :trainingId, Integer
|
||||
attribute :trainingDate, String
|
||||
end
|
||||
# This is a statistical data saved in ElasticSearch, about a training reservation
|
||||
class Stats::Training
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
include StatReservationConcern
|
||||
|
||||
attribute :trainingId, Integer
|
||||
attribute :trainingDate, String
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Stats
|
||||
class User
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
end
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This is a statistical data saved in ElasticSearch, about revenue generated per user
|
||||
class Stats::User
|
||||
include Elasticsearch::Persistence::Model
|
||||
include StatConcern
|
||||
end
|
||||
|
@ -8,11 +8,11 @@ class Subscription < ApplicationRecord
|
||||
belongs_to :statistic_profile
|
||||
|
||||
has_one :payment_schedule_object, as: :object, dependent: :destroy
|
||||
has_one :payment_gateway_object, as: :item
|
||||
has_one :payment_gateway_object, as: :item, dependent: :destroy
|
||||
has_many :invoice_items, as: :object, dependent: :destroy
|
||||
has_many :offer_days, dependent: :destroy
|
||||
|
||||
validates_presence_of :plan_id
|
||||
validates :plan_id, presence: true
|
||||
validates_with SubscriptionGroupValidator
|
||||
|
||||
# creation
|
||||
@ -21,18 +21,21 @@ class Subscription < ApplicationRecord
|
||||
after_save :notify_admin_subscribed_plan
|
||||
after_save :notify_partner_subscribed_plan, if: :of_partner_plan?
|
||||
|
||||
delegate :user, to: :statistic_profile
|
||||
|
||||
def generate_and_save_invoice(operator_profile_id)
|
||||
generate_invoice(operator_profile_id).save
|
||||
end
|
||||
|
||||
def expire(time)
|
||||
if !expired?
|
||||
update_columns(expiration_date: time, canceled_at: time)
|
||||
if expired?
|
||||
false
|
||||
else
|
||||
# TODO, check if the rubocop:disable directove can be deleted
|
||||
update_columns(expiration_date: time, canceled_at: time) # rubocop:disable Rails/SkipsModelValidations
|
||||
notify_admin_subscription_canceled
|
||||
notify_member_subscription_canceled
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@ -47,10 +50,6 @@ class Subscription < ApplicationRecord
|
||||
expiration_date
|
||||
end
|
||||
|
||||
def user
|
||||
statistic_profile.user
|
||||
end
|
||||
|
||||
def original_payment_schedule
|
||||
payment_schedule_object&.payment_schedule
|
||||
end
|
||||
|
@ -1,6 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Check the access policies for API::StatisticsController
|
||||
class StatisticPolicy < ApplicationPolicy
|
||||
%w(index account event machine project subscription training user space scroll export_subscription export_machine
|
||||
export_training export_event export_account export_project export_space export_global).each do |action|
|
||||
%w[index account event machine project subscription training user space order scroll export_subscription export_machine
|
||||
export_training export_event export_account export_project export_space export_order export_global].each do |action|
|
||||
define_method "#{action}?" do
|
||||
user.admin?
|
||||
end
|
||||
|
@ -42,6 +42,10 @@ class Orders::OrderService
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
# update in elasticsearch (statistics)
|
||||
stat_order = Stats::Order.search(query: { term: { orderId: order.id } })
|
||||
stat_order.map { |s| s.update(state: state) }
|
||||
end
|
||||
|
||||
def in_stock?(order, stock_type = 'external')
|
||||
|
@ -9,15 +9,15 @@ class Statistics::Builders::StoreOrdersBuilderService
|
||||
def build(options = default_options)
|
||||
# project list
|
||||
Statistics::FetcherService.store_orders_list(options).each do |o|
|
||||
Stats::StoreOrder.create({ date: format_date(o[:date]),
|
||||
type: 'order',
|
||||
subType: 'store',
|
||||
ca: o[:ca],
|
||||
products: o[:order_products],
|
||||
categories: o[:order_categories],
|
||||
orderId: o[:order_id],
|
||||
orderState: o[:order_state],
|
||||
stat: 1 }.merge(user_info_stat(o)))
|
||||
Stats::Order.create({ date: format_date(o[:date]),
|
||||
type: 'order',
|
||||
subType: 'store',
|
||||
ca: o[:ca],
|
||||
products: o[:order_products],
|
||||
categories: o[:order_categories],
|
||||
orderId: o[:order_id],
|
||||
state: o[:order_state],
|
||||
stat: 1 }.merge(user_info_stat(o)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -7,7 +7,7 @@ class Statistics::CleanerService
|
||||
class << self
|
||||
def clean_stat(options = default_options)
|
||||
client = Elasticsearch::Model.client
|
||||
%w[Account Event Machine Project Subscription Training User Space].each do |o|
|
||||
%w[Account Event Machine Project Subscription Training User Space Order].each do |o|
|
||||
model = "Stats::#{o}".constantize
|
||||
client.delete_by_query(
|
||||
index: model.index_name,
|
||||
|
@ -186,9 +186,9 @@ class Statistics::FetcherService
|
||||
def store_orders_list(options = default_options)
|
||||
result = []
|
||||
Order.includes(order_items: [:orderable])
|
||||
.joins(:order_items)
|
||||
.joins(:order_items, :order_activities)
|
||||
.where("order_items.orderable_type = 'Product'")
|
||||
.where('orders.created_at >= :start_date AND orders.created_at <= :end_date', options)
|
||||
.where('order_activities.created_at >= :start_date AND order_activities.created_at <= :end_date', options)
|
||||
.each do |o|
|
||||
result.push({ date: o.created_at.to_date, ca: calcul_ca(o.invoice) }
|
||||
.merge(user_info(o.statistic_profile))
|
||||
|
@ -430,6 +430,7 @@ en:
|
||||
subscriptions: "Subscriptions"
|
||||
machines_hours: "Machines slots"
|
||||
spaces: "Spaces"
|
||||
orders: "Orders"
|
||||
trainings: "Trainings"
|
||||
events: "Events"
|
||||
registrations: "Registrations"
|
||||
@ -453,6 +454,7 @@ en:
|
||||
account_creation: "Account creation"
|
||||
project_publication: "Project publication"
|
||||
duration: "Duration"
|
||||
store: "Boutique"
|
||||
#statistics exports to the Excel file format
|
||||
export:
|
||||
entries: "Entries"
|
||||
|
@ -282,7 +282,7 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
%w[account event machine project subscription training user space].each do |path|
|
||||
%w[account event machine project subscription training user space order].each do |path|
|
||||
post "/stats/#{path}/_search", to: "api/statistics##{path}"
|
||||
post "/stats/#{path}/export", to: "api/statistics#export_#{path}"
|
||||
end
|
||||
|
@ -1027,6 +1027,14 @@ unless StatisticIndex.find_by(es_type_key: 'space')
|
||||
])
|
||||
end
|
||||
|
||||
unless StatisticIndex.find_by(es_type_key: 'order')
|
||||
index = StatisticIndex.create!(es_type_key: 'order', label: I18n.t('statistics.orders'))
|
||||
StatisticType.create!([
|
||||
{ statistic_index_id: index.id, key: 'store', label: I18n.t('statistics.store'),
|
||||
graph: true, simple: true }
|
||||
])
|
||||
end
|
||||
|
||||
ProfileCustomField.find_or_create_by(label: 'N° SIRET')
|
||||
ProfileCustomField.find_or_create_by(label: 'Code NAF')
|
||||
ProfileCustomField.find_or_create_by(label: 'N° TVA intracommunautaire')
|
||||
|
@ -12,11 +12,11 @@ class StoreStatisticServiceTest < ActionDispatch::IntegrationTest
|
||||
::Statistics::BuilderService.generate_statistic({ start_date: DateTime.current.beginning_of_day,
|
||||
end_date: DateTime.current.end_of_day })
|
||||
|
||||
Stats::StoreOrder.refresh_index!
|
||||
Stats::Order.refresh_index!
|
||||
|
||||
# we should find order id 15 (created today)
|
||||
stat_order = Stats::StoreOrder.search(query: { bool: { must: [{ term: { date: DateTime.current.to_date.iso8601 } },
|
||||
{ term: { type: 'order' } }] } }).first
|
||||
stat_order = Stats::Order.search(query: { bool: { must: [{ term: { date: DateTime.current.to_date.iso8601 } },
|
||||
{ term: { type: 'order' } }] } }).first
|
||||
assert_not_nil stat_order
|
||||
assert_equal @order.id, stat_order['orderId']
|
||||
check_statistics_on_user(stat_order)
|
||||
|
Loading…
x
Reference in New Issue
Block a user