mumuki-domain 9.0.5 → 9.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/models/application_record.rb +13 -0
- data/app/models/certificate_program.rb +4 -2
- data/app/models/exam_registration.rb +26 -4
- data/app/models/exercise.rb +0 -12
- data/app/models/exercise/problem.rb +19 -1
- data/app/models/notification.rb +5 -0
- data/app/models/organization.rb +6 -0
- data/app/models/user.rb +6 -0
- data/app/models/user_stats.rb +3 -3
- data/db/migrate/20210318194559_add_dates_to_certificate_program.rb +6 -0
- data/db/migrate/20210318195238_rename_certificate_dates.rb +6 -0
- data/db/migrate/20210330175706_create_exam_registration_user_join_table.rb +8 -0
- data/lib/mumuki/domain/evaluation.rb +1 -0
- data/lib/mumuki/domain/evaluation/mixed.rb +12 -0
- data/lib/mumuki/domain/factories/certificate_factory.rb +2 -2
- data/lib/mumuki/domain/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 03cf2d9f0764fe073de42e72cbb94233949692b8e5ef60b97afeca431d374719
|
|
4
|
+
data.tar.gz: 5db8d1777ae3622bf9673b09f9bc06322ffc46af56780f4a47fc19e5f77462f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a3abfa44040d80767963218a039bc1eea419921bffb8a4efbd8908bff4b1d5b395cf9c4d10d1844978ee71caa9d2f783d045f4e3f365e68c69a680c930b9b08f
|
|
7
|
+
data.tar.gz: ec63d6c11722ac7dc29c6d58af654fc3dc72ed71fdc387555e60ac71d1711cf893016aaa16c55903d85c5ad961cff7aa0206dd642074f7e5a5fc6f14a246336a
|
|
@@ -134,6 +134,19 @@ class ApplicationRecord < ActiveRecord::Base
|
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
+
def self.active_between(start_date_field, end_date_field, **options)
|
|
138
|
+
define_singleton_method(:active) do |actually_filter=true|
|
|
139
|
+
if actually_filter
|
|
140
|
+
self.where("(#{start_date_field} IS NULL OR #{start_date_field} < :now) AND (#{end_date_field} IS NULL OR #{end_date_field} > :now)", now: Time.now)
|
|
141
|
+
else
|
|
142
|
+
all
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
aliased_as = options.delete(:aliased_as)
|
|
147
|
+
singleton_class.send(:alias_method, aliased_as, :active) if aliased_as
|
|
148
|
+
end
|
|
149
|
+
|
|
137
150
|
## Partially implements resource-hash protocol, by
|
|
138
151
|
## defining `to_resource_h` and helper methods `resource_fields` and `slice_resource_h`
|
|
139
152
|
## using the given fields
|
|
@@ -2,6 +2,8 @@ class CertificateProgram < ApplicationRecord
|
|
|
2
2
|
belongs_to :organization
|
|
3
3
|
has_many :certificates
|
|
4
4
|
|
|
5
|
+
active_between :start_date, :end_date, aliased_as: :ongoing
|
|
6
|
+
|
|
5
7
|
def friendly
|
|
6
8
|
title
|
|
7
9
|
end
|
|
@@ -23,8 +25,8 @@ class CertificateProgram < ApplicationRecord
|
|
|
23
25
|
}
|
|
24
26
|
</style>
|
|
25
27
|
<!-- You can use interpolations like --
|
|
26
|
-
<%#= certificate.
|
|
27
|
-
<%#= certificate.
|
|
28
|
+
<%#= certificate.started_at %>
|
|
29
|
+
<%#= certificate.ended_at %>
|
|
28
30
|
<%#= user.formal_first_name %>
|
|
29
31
|
<%#= user.formal_last_name %>
|
|
30
32
|
<%#= user.formal_full_name %>
|
|
@@ -5,6 +5,8 @@ class ExamRegistration < ApplicationRecord
|
|
|
5
5
|
belongs_to :organization
|
|
6
6
|
has_and_belongs_to_many :exams
|
|
7
7
|
has_many :authorization_requests, class_name: 'ExamAuthorizationRequest'
|
|
8
|
+
has_and_belongs_to_many :registrees, class_name: 'User'
|
|
9
|
+
has_many :notifications, as: :target
|
|
8
10
|
|
|
9
11
|
enum authorization_criterion_type: %i(none passed_exercises), _prefix: :authorization_criterion
|
|
10
12
|
|
|
@@ -22,8 +24,20 @@ class ExamRegistration < ApplicationRecord
|
|
|
22
24
|
authorization_criterion.ensure_valid!
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
+
def notify_unnotified_registrees!
|
|
28
|
+
unnotified_registrees.each { |registree| notify_registree! registree }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def unnotified_registrees?
|
|
32
|
+
unnotified_registrees.exists?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def register_users!(users)
|
|
36
|
+
users.each { |user| register! user }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def unnotified_registrees
|
|
40
|
+
registrees.where.not(id: Notification.notified_users_ids_for(self, self.organization))
|
|
27
41
|
end
|
|
28
42
|
|
|
29
43
|
def process_requests!
|
|
@@ -38,9 +52,17 @@ class ExamRegistration < ApplicationRecord
|
|
|
38
52
|
ExamAuthorizationRequest.new(exam_registration: self, organization: organization)
|
|
39
53
|
end
|
|
40
54
|
|
|
55
|
+
def register!(user)
|
|
56
|
+
registrees << user unless registered?(user)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def registered?(user)
|
|
60
|
+
registrees.include? user
|
|
61
|
+
end
|
|
62
|
+
|
|
41
63
|
private
|
|
42
64
|
|
|
43
|
-
def
|
|
44
|
-
Notification.create! organization: organization, user:
|
|
65
|
+
def notify_registree!(registree)
|
|
66
|
+
Notification.create! organization: organization, user: registree, target: self
|
|
45
67
|
end
|
|
46
68
|
end
|
data/app/models/exercise.rb
CHANGED
|
@@ -249,18 +249,6 @@ class Exercise < ApplicationRecord
|
|
|
249
249
|
private
|
|
250
250
|
|
|
251
251
|
def evaluation_class
|
|
252
|
-
if manual_evaluation?
|
|
253
|
-
manual_evaluation_class
|
|
254
|
-
else
|
|
255
|
-
automated_evaluation_class
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def manual_evaluation_class
|
|
260
|
-
Mumuki::Domain::Evaluation::Manual
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def automated_evaluation_class
|
|
264
252
|
Mumuki::Domain::Evaluation::Automated
|
|
265
253
|
end
|
|
266
254
|
|
|
@@ -33,13 +33,31 @@ class Problem < QueriableChallenge
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def evaluation_criteria?
|
|
36
|
-
manual_evaluation? ||
|
|
36
|
+
manual_evaluation? || automated_evaluation?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def mixed_evaluation?
|
|
40
|
+
manual_evaluation? && automated_evaluation?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def automated_evaluation?
|
|
44
|
+
expectations? || test.present?
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
def expectations?
|
|
40
48
|
own_expectations.present? || own_custom_expectations.present?
|
|
41
49
|
end
|
|
42
50
|
|
|
51
|
+
def evaluation_class
|
|
52
|
+
if mixed_evaluation?
|
|
53
|
+
Mumuki::Domain::Evaluation::Mixed
|
|
54
|
+
elsif manual_evaluation?
|
|
55
|
+
Mumuki::Domain::Evaluation::Manual
|
|
56
|
+
else
|
|
57
|
+
Mumuki::Domain::Evaluation::Automated
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
43
61
|
# Sets the layout. This method accepts input_kids as a synonym of input_primary
|
|
44
62
|
# for historical reasons
|
|
45
63
|
def layout=(layout)
|
data/app/models/notification.rb
CHANGED
|
@@ -3,6 +3,11 @@ class Notification < ApplicationRecord
|
|
|
3
3
|
belongs_to :organization
|
|
4
4
|
belongs_to :target, polymorphic: true
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
scope :notified_users_ids_for, ->(target, organization=Organization.current) do
|
|
8
|
+
where(target: target, organization: organization).pluck(:user_id)
|
|
9
|
+
end
|
|
10
|
+
|
|
6
11
|
def mark_as_read!
|
|
7
12
|
update read: true
|
|
8
13
|
end
|
data/app/models/organization.rb
CHANGED
|
@@ -21,6 +21,8 @@ class Organization < ApplicationRecord
|
|
|
21
21
|
belongs_to :book
|
|
22
22
|
has_many :usages
|
|
23
23
|
|
|
24
|
+
has_many :certificate_programs
|
|
25
|
+
|
|
24
26
|
validates_presence_of :contact_email, :locale
|
|
25
27
|
validates_presence_of :welcome_email_template, if: :greet_new_users?
|
|
26
28
|
validates :name, uniqueness: true,
|
|
@@ -108,6 +110,10 @@ class Organization < ApplicationRecord
|
|
|
108
110
|
name
|
|
109
111
|
end
|
|
110
112
|
|
|
113
|
+
def ongoing_certificate_programs?
|
|
114
|
+
certificate_programs.ongoing.exists?
|
|
115
|
+
end
|
|
116
|
+
|
|
111
117
|
# Tells if the given user can
|
|
112
118
|
# ask for help in this organization
|
|
113
119
|
#
|
data/app/models/user.rb
CHANGED
|
@@ -302,6 +302,12 @@ class User < ApplicationRecord
|
|
|
302
302
|
certificates.where(certificate_program: certificate_program).exists?
|
|
303
303
|
end
|
|
304
304
|
|
|
305
|
+
def certificate_in(certificate_program, certificate_h)
|
|
306
|
+
return if certificated_in?(certificate_program)
|
|
307
|
+
certificate = certificates.create certificate_h.merge(certificate_program: certificate_program)
|
|
308
|
+
UserMailer.certificate(certificate).deliver_later
|
|
309
|
+
end
|
|
310
|
+
|
|
305
311
|
private
|
|
306
312
|
|
|
307
313
|
def welcome_to_new_organizations!
|
data/app/models/user_stats.rb
CHANGED
|
@@ -16,10 +16,10 @@ class UserStats < ApplicationRecord
|
|
|
16
16
|
exercises: {
|
|
17
17
|
solved_count: organization_exercises
|
|
18
18
|
.joins(:assignments)
|
|
19
|
-
.where(assignments: { top_submission_status: [:passed, :skipped], submitter: user }.merge(date_filter))
|
|
19
|
+
.where(assignments: { top_submission_status: [:passed, :skipped], submitter: user, organization: organization }.merge(date_filter))
|
|
20
20
|
.count,
|
|
21
|
-
count: organization_exercises.count
|
|
22
|
-
|
|
21
|
+
count: organization_exercises.count
|
|
22
|
+
},
|
|
23
23
|
messages: messages_in_discussions_count(date_range)
|
|
24
24
|
}
|
|
25
25
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Mumuki::Domain::Evaluation::Mixed < Mumuki::Domain::Evaluation::Manual
|
|
2
|
+
def evaluate!(assignment, submission)
|
|
3
|
+
evaluation = submission.evaluate! assignment
|
|
4
|
+
if evaluation[:status].passed?
|
|
5
|
+
super
|
|
6
|
+
elsif evaluation[:status].passed_with_warnings?
|
|
7
|
+
evaluation.merge(status: Mumuki::Domain::Status::Submission::Failed)
|
|
8
|
+
else
|
|
9
|
+
evaluation
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
FactoryBot.define do
|
|
2
2
|
factory :certificate do
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
started_at { 1.month.ago }
|
|
4
|
+
ended_at { 1.minute.ago }
|
|
5
5
|
user { build :user, first_name: 'Jane', last_name: 'Doe' }
|
|
6
6
|
certificate_program { build :certificate_program }
|
|
7
7
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mumuki-domain
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.0.
|
|
4
|
+
version: 9.0.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Franco Leonardo Bulgarelli
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-04-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -661,12 +661,16 @@ files:
|
|
|
661
661
|
- db/migrate/20210302181654_add_faqs_to_organizations.rb
|
|
662
662
|
- db/migrate/20210308145910_add_approved_by_and_at_to_message.rb
|
|
663
663
|
- db/migrate/20210310195602_add_delete_account_token_to_user.rb
|
|
664
|
+
- db/migrate/20210318194559_add_dates_to_certificate_program.rb
|
|
665
|
+
- db/migrate/20210318195238_rename_certificate_dates.rb
|
|
666
|
+
- db/migrate/20210330175706_create_exam_registration_user_join_table.rb
|
|
664
667
|
- lib/mumuki/domain.rb
|
|
665
668
|
- lib/mumuki/domain/area.rb
|
|
666
669
|
- lib/mumuki/domain/engine.rb
|
|
667
670
|
- lib/mumuki/domain/evaluation.rb
|
|
668
671
|
- lib/mumuki/domain/evaluation/automated.rb
|
|
669
672
|
- lib/mumuki/domain/evaluation/manual.rb
|
|
673
|
+
- lib/mumuki/domain/evaluation/mixed.rb
|
|
670
674
|
- lib/mumuki/domain/exceptions.rb
|
|
671
675
|
- lib/mumuki/domain/exceptions/blocked_forum_error.rb
|
|
672
676
|
- lib/mumuki/domain/exceptions/disabled_error.rb
|