Skip to content

Instantly share code, notes, and snippets.

@adrianotadao
Last active August 25, 2017 14:15
Show Gist options
  • Save adrianotadao/7b2274f624c76152c04d1d782749f5c0 to your computer and use it in GitHub Desktop.
Save adrianotadao/7b2274f624c76152c04d1d782749f5c0 to your computer and use it in GitHub Desktop.
Cursos
# ------------------------------------
# ------------------------------------
# Cursos Obrigatórios
# ------------------------------------
# ------------------------------------
# [x] - Cursos obrigatorios antes de liberar outros (predescessor) - permite acesso, caso contrário mostra um cadeado e não deixa o cara continuar.
class Category
attr_accessor :predecessor_id
belongs_to :predecessor, foreign_key: :predecessor_id, class_name: 'Category'
def can_move_on?(user)
return true if predecessor_id.blank?
predecessor.completed_by_user?(user)
end
end
# ------------------------------------
# [x] - Se a nota for um critério, ela trava a evolução para o próximo curso
class Category
attr_accessor :acceptance_criteria
def can_move_on?(user)
return true if acceptance_criteria.blank?
grade_by_enrollment(user) >= acceptance_criteria
end
end
# ------------------------------------
# ------------------------------------
# Aprovaçã e Retenção
# ------------------------------------
# ------------------------------------
# [x] - Matricula passa a ter um APROVADO = { sim ou nao ou pendente correção }
# [x] - CONCLUIDO (o usuario fez tudo que tinha pra ele fazer ) - SIM | NAO
class Enrollment
enum approved: [:yes, :no, :pending]
enum completed: [:yes, :no]
end
# ------------------------------------
# [x] - OPCAO 1 [100% conclusao OU nota + 100%] // OPCAO 2 [Nota x independente da conclusão ] - precisamos rever a formula de calculo de notas usadas em todas as matriculas ==> NOTA PARCIAL
# [x] - Se eu configurar um curso com regra de aprovação, eu também posso habilitar a regra de retentativa e definir o limite de retentativas para aquele curso
# [x] - Precisamos saber quem foi o usuário que reprovou/aprovou
# [?] - Em caso de re-try e o foi alterada a nota de corte do curso, quando ele tentar de novo, qual vai ser a nota de corte? A antiga ou a nova?
# [?] - Em caso de re-try se tiveram alterações nas questões, ele vai ter que responder as mesmas que ele já respondeu uma vez ou serão as novas?
# [?] - SEMPRE será apenas 1 pessoa que vai aprovar ou reprovar?
class Category
attr_accessor :retries
def can_retry?(user)
return false if user.enrollments.count > retries
user.enrollments.refused.count < retries &&
user.enrollments.approved.count.zero?
end
end
class User
has_many :enrollments
end
class Enrollment
attr_accessor :approved_by, :reproved_by
belongs_to :approved_by, class_name: 'User'
belongs_to :reproved_by, class_name: 'User'
has_many :enrollment_events
enum approved: [:yes, :no, :pending]
enum completed: [:yes, :no]
scope :refused, -> { where(approved: :true) }
scope :approved, -> { where(approved: :no) }
end
class EnrollmentEvents
enum events: [:reproved, :approved]
belongs_to :enrollment
belongs_to :user
end
class Worksheet
enum status: [:current, :refused]
end
# ------------------------------------
# [x] - Sempre que um curso for concluido, a gente grava em algum lugar o `evento de conclusão` - id do curso, id do usuario, date_time, nota, approved bit.
# [?] - Aqui, podemos considerar algo tipo approved_at na própria matrícula?
# [x] - Em caso de alteração da nota de corte, esse valor nunca pode mudar para quem já está matriculado.
class Enrollment
attr_accessor :minimal_grade
end
# [x] - Não podemos perder as respostas que ele deu anteriormente
# [?] - Podemos criar 1 worksheet novo para cada tentativa?
# ------------------------------------
# ------------------------------------
# Certificados
# ------------------------------------
# ------------------------------------
# [x] - Certificado só é exibido na aprovação
# [x] - PDF padrão do Skore, com variaveis para NOME USUARIO, NOME DO CURSO, Data, ID unico(ID da Matricula)
class Certificate
attr_accessor :expires_at
belongs_to :enrollment
belongs_to :category, throught: :enrollment
belongs_to :company, throught: :category
belongs_to :certificate_template, throught: :company
end
class Company
has_one :certificate_template, as: :certificable
end
class CertificateTemplate
belongs_to :certificable, polymorphic: true
has_one :file_upload
end
# ----------------------------------
# [x] - [1 template por empresa] vs [1 template padrao + 1 template por curso]
class Category
belongs_to :company
has_one :certificate_template, as: :certicable
end
class Certificate
attr_accessor :expires_at
belongs_to :enrollment
belongs_to :category, throught: :enrollment
belongs_to :company, throught: :category
end
Certificate.new(certificate_template: find_template)
def find_template
return Category.certificate_template if Category.certificate_template?
Category.company.certificate_template
end
# ------------------------------------
# To install
https://stackoverflow.com/questions/32505951/pdftk-server-on-os-x-10-11
# To generate
pdftk = PdfForms.new('/usr/local/bin/pdftk')
irb(main):002:0> pdftk.fill_form 'ccc.pdf', 'fajefiuafa.pdf', :Nome => 'aaa'
# Documentation
https://github.com/jkraemer/pdf-forms
# ------------------------------------
# ------------------------------------
# ------------------------------------
# Avaliação de Pagina Inteira
# ------------------------------------
# ------------------------------------
# [x] - Tipo de conteúdo novo [tem seu proprio titulo e imagem]
class Form < Content
belongs_to :evaluator, class_name: 'User'
has_many :answers, through: :questions
has_many :worksheets, foreign_key: :lesson_id, dependent: :destroy
accepts_nested_attributes_for :questions, allow_destroy: true, reject_if: proc { |attributes|
attributes['text'].blank?
}
end
# ------------------------------------
# ------------------------------------
# Nubank
# ------------------------------------
# ------------------------------------
# [x] - Alem de configurar o critério de aprovação, a gente define quanto tempo a aprovação tem validade
# [x] - Aprovação tem validade = { verde, vermelho, amarelo, cinza }
class Category
attr_accessor :acceptance_criteria, :acceptance_expires_at
def can_move_on?(user)
return true if acceptance_criteria.blank?
grade(user) >= acceptance_criteria
end
def expired?(user)
return false if acceptance_expirest_at.blank?
enrollments.by_user(user).first.approved_at.days > acceptance_expirest_at.days
end
end
class Enrollment
attr_accessor :approved_at, :has_update_at, :expired_at
enum approved: [:yes, :no, :pending]
enum completed: [:yes, :no]
enum status: [:approved, :expired, :has_update]
scope :refused, -> { where(approved: :true) }
scope :approved, -> { where(approved: :no) }
end
# Alterar o status dos enrollments
Enrollment.all.each do |enrollment|
next if enrollment.category.acceptance_expires_at.blank? || enrollment.status != approved
if enrollment.category.expired?(enrollment.user)
enrollment.expired!
enrollment.expired_at = DateTime.now
end
end
# ------------------------------------
# [x] - Relatório de aprovações expiradas
Enrollment.all.where(status: :expired)
Enrollment.all.where(status: :approved)
Enrollment.all.where(status: :has_update)
# ------------------------------------
# [x] - Ter algum jeito vincular a conclusão ao aceite de um termo.
class Term
attr_accessor :active, :version, :type
# inventei a palavra
belongs_to :termeable, polymorphic: true
has_many :accepted_terms
end
class AcceptedTerm
belongs_to :user
belongs_to :term
end
class CompanyTerm < Term
end
class Company
has_many :company_terms, as: :termeable
end
class CategoryOpenTerm < Term
end
class CategoryFinalTerm < Term
end
class Category
has_many :terms, as: :termeable
has_many :category_open_terms, as: :termeable
has_many :category_final_terms, as: :termeable
end
# ------------------------------------
# ------------------------------------
# ------------------------------------
# Matrícula (enrollment)
# ------------------------------------
# ------------------------------------
# Cenário atual
class Access < ActiveRecord::Base
after_commit :enrollment_refresh, on: :create
def enrollment_refresh
ActiveSupport::Notifications.instrument('enrollment.refresh', options: {
category: lesson.category,
user: user
})
end
end
class Worksheet < ActiveRecord::Base
after_commit :enrollment_refresh, on: [:create, :update]
def enrollment_refresh
ActiveSupport::Notifications.instrument('enrollment.refresh', options: {
category: lesson.category,
user: student
})
end
end
ActiveSupport::Notifications.subscribe('enrollment.refresh') do |_name, _start, _finish, _id, payload|
category = payload[:options][:category]
user = payload[:options][:user]
EnrollmentGradeRefresh.perform_later(category.id, user.id)
EnrollmentAccessRefresh.perform_later(category.id, user.id)
end
# O que teria qeu fazer é chamar o EnrollmentAccessRefresh apenas quando cria o acesses mesmo. E só.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment