mumuki-domain 8.6.1 → 9.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 339d512e2040015c6556f9671fd00281edf9b651a5dc9db8f860d7607989cd65
4
- data.tar.gz: a03fe1fe26593986af16d89c1df6cc6e9b8f21c3e9e240de41f884482e75c6d7
3
+ metadata.gz: 05b62ff1728ff0d8fd4a807ce4a8de4b7f70c532a6748c91af12db484582fad0
4
+ data.tar.gz: 25810325f5fa2fb294b0c189bd20f77e85e4722e2557d50b8a760df07edd56bf
5
5
  SHA512:
6
- metadata.gz: ea2475a456f0558a61e798d27e88921a7a69b134dc38431c1244033d778dbc1b91ce4a974acaa6abbf77cceed03134430cb378f2e4d4561f39d297a7040a9745
7
- data.tar.gz: 1321dbd879300fb21e87ef044bae0a7bcbca62ff9fc27cf55bfac1e02cc122273952add367a94381a54e1b730e68549659e5abb9762795071e8c7fa89d6a3699
6
+ metadata.gz: f5795882f6b1ed8f8e7b4b66e3f85767c58f72eda7131aae3034a5abe48a27d27b2789e2f97e135f4713da0667769c58baec5ea2b9408ceacf012470439e3dbd
7
+ data.tar.gz: 34514f8787088f9c721fafae973af54a1163d27c00d47029bac4544e78c31d4e8726320ef9d3a81f453090e465c32cd5f10ebb25bad2b4ea9ab6f1227118f270
@@ -0,0 +1,29 @@
1
+ class Certificate < ApplicationRecord
2
+ include WithGeneratedCode
3
+
4
+ belongs_to :user
5
+ belongs_to :certificate_program
6
+
7
+ has_one :organization, through: :certificate_program
8
+
9
+ delegate :title, :description, :template_html_erb, :background_image_url, to: :certificate_program
10
+
11
+ def self.code_size
12
+ 12
13
+ end
14
+
15
+ def filename
16
+ "#{title.parameterize.underscore}.pdf"
17
+ end
18
+
19
+ def template_locals
20
+ { user: user,
21
+ certificate_program: certificate_program,
22
+ organization: organization,
23
+ certificate: self }
24
+ end
25
+
26
+ def for_user?(user)
27
+ self.user == user
28
+ end
29
+ end
@@ -0,0 +1,42 @@
1
+ class CertificateProgram < ApplicationRecord
2
+ belongs_to :organization
3
+ has_many :certificates
4
+
5
+ def friendly
6
+ title
7
+ end
8
+
9
+ def template_html_erb
10
+ self[:template_html_erb] ||= <<HTML
11
+ <style>
12
+ .qr-code {
13
+ bottom: 5px;
14
+ right: 5px;
15
+ height: 15mm;
16
+ width: 15mm;
17
+ }
18
+ .name {
19
+ position: absolute;
20
+ width: 100%;
21
+ top: 380px;
22
+ text-align: center;
23
+ }
24
+ </style>
25
+ <!-- You can use interpolations like --
26
+ <%#= certificate.start_date %>
27
+ <%#= certificate.end_date %>
28
+ <%#= user.formal_first_name %>
29
+ <%#= user.formal_last_name %>
30
+ <%#= user.formal_full_name %>
31
+ <%#= certificate_program.title %>
32
+ <%#= certificate_program.description %>
33
+ <%#= organization.name %>
34
+ <%#= organization.display_name %>
35
+ -- -->
36
+ <section class="name">
37
+ <h1><%= user.formal_full_name %></h1>
38
+ </section>
39
+ HTML
40
+ end
41
+
42
+ end
@@ -19,9 +19,8 @@ module WithAssignments
19
19
  end
20
20
 
21
21
  # TODO: When the organization is used in this one, please change guide.pending_exercises
22
- # TODO: Please do the same on WithAssignmentsBatch
23
- def find_assignment_for(user, _organization)
24
- assignments.find_by(submitter: user)
22
+ def find_assignment_for(user, organization)
23
+ assignments.find_by(submitter: user, organization: organization)
25
24
  end
26
25
 
27
26
  def status_for(user)
@@ -4,13 +4,13 @@
4
4
  module WithAssignmentsBatch
5
5
  extend ActiveSupport::Concern
6
6
 
7
- def find_assignments_for(user, _organization = Organization.current, &block)
7
+ def find_assignments_for(user, organization = Organization.current, &block)
8
8
  block = block_given? ? block : lambda { |it, _e| it }
9
9
 
10
10
  return exercises.map { |it| block.call nil, it } unless user
11
11
 
12
12
  pairs = exercises.map { |it| [it.id, [nil, it]] }.to_h
13
- Assignment.where(submitter: user, exercise: exercises).each do |it|
13
+ Assignment.where(submitter: user, organization: organization, exercise: exercises).each do |it|
14
14
  pairs[it.exercise_id][0] = it
15
15
  end
16
16
 
@@ -0,0 +1,19 @@
1
+ module WithGeneratedCode
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ validates_uniqueness_of :code
6
+
7
+ defaults do
8
+ self.code ||= self.class.generate_code
9
+ end
10
+
11
+ required :code_size
12
+ end
13
+
14
+ class_methods do
15
+ def generate_code
16
+ SecureRandom.urlsafe_base64 code_size
17
+ end
18
+ end
19
+ end
@@ -2,7 +2,7 @@ module WithNotifications
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def unread_messages
5
- messages.where read: false
5
+ messages_in_organization.where read: false
6
6
  end
7
7
 
8
8
  def unread_notifications
data/app/models/course.rb CHANGED
@@ -3,7 +3,7 @@ class Course < ApplicationRecord
3
3
  include Mumuki::Domain::Helpers::Course
4
4
  include Mumuki::Domain::Area
5
5
 
6
- validates_presence_of :slug, :shifts, :code, :days, :period, :description, :organization_id
6
+ validates_presence_of :slug, :period, :code, :description, :organization_id
7
7
  validates_uniqueness_of :slug
8
8
  belongs_to :organization
9
9
 
@@ -35,6 +35,10 @@ class Course < ApplicationRecord
35
35
  end
36
36
  end
37
37
 
38
+ def canonical_code
39
+ "#{period}-#{code}".downcase
40
+ end
41
+
38
42
  def closed?
39
43
  current_invitation.blank? || current_invitation.expired?
40
44
  end
@@ -1,14 +1,10 @@
1
1
  class Invitation < ApplicationRecord
2
- include Mumuki::Domain::Syncable
2
+ include Mumuki::Domain::Syncable,
3
+ WithGeneratedCode
3
4
 
4
5
  belongs_to :course
5
6
 
6
7
  validate :ensure_not_expired, on: :create
7
- validates_uniqueness_of :code
8
-
9
- defaults do
10
- self.code ||= self.class.generate_code
11
- end
12
8
 
13
9
  def ensure_not_expired
14
10
  errors.add(:base, :invitation_expired) if expired?
@@ -51,12 +47,12 @@ class Invitation < ApplicationRecord
51
47
  self
52
48
  end
53
49
 
54
- def self.generate_code
55
- SecureRandom.urlsafe_base64 4
56
- end
57
-
58
50
  private
59
51
 
52
+ def self.code_size
53
+ 4
54
+ end
55
+
60
56
  def course_name
61
57
  course.name
62
58
  end
data/app/models/user.rb CHANGED
@@ -35,6 +35,8 @@ class User < ApplicationRecord
35
35
 
36
36
  has_many :exams, through: :exam_authorizations
37
37
 
38
+ has_many :certificates
39
+
38
40
  enum gender: %i(female male other unspecified)
39
41
  belongs_to :avatar, polymorphic: true, optional: true
40
42
 
@@ -52,6 +54,10 @@ class User < ApplicationRecord
52
54
  last_guide.try(:lesson)
53
55
  end
54
56
 
57
+ def messages_in_organization(organization = Organization.current)
58
+ messages.where('assignments.organization': organization)
59
+ end
60
+
55
61
  def passed_submissions_count_in(organization)
56
62
  assignments.where(top_submission_status: Mumuki::Domain::Status::Submission::Passed.to_i, organization: organization).count
57
63
  end
@@ -275,6 +281,26 @@ class User < ApplicationRecord
275
281
  end
276
282
  end
277
283
 
284
+ def formal_first_name
285
+ verified_first_name || first_name
286
+ end
287
+
288
+ def formal_last_name
289
+ verified_last_name || last_name
290
+ end
291
+
292
+ def formal_full_name
293
+ "#{formal_first_name} #{formal_last_name}"
294
+ end
295
+
296
+ def certificates_in_organization(organization = Organization.current)
297
+ certificates.where certificate_program: CertificateProgram.where(organization: organization)
298
+ end
299
+
300
+ def certificated_in?(certificate_program)
301
+ certificates.where(certificate_program: certificate_program).exists?
302
+ end
303
+
278
304
  private
279
305
 
280
306
  def welcome_to_new_organizations!
@@ -0,0 +1,13 @@
1
+ class CreateCertificatePrograms < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :certificate_programs do |t|
4
+ t.string :title
5
+ t.string :template_html_erb
6
+ t.text :description
7
+ t.string :background_image_url
8
+ t.references :organization, index: true
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateCertificates < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :certificates do |t|
4
+ t.references :user, index: true
5
+ t.references :certificate_program, index: true
6
+ t.datetime :start_date
7
+ t.datetime :end_date
8
+ t.string :code
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -2,6 +2,8 @@ require_relative './factories/api_client_factory'
2
2
  require_relative './factories/assignments_factory'
3
3
  require_relative './factories/avatar_factory'
4
4
  require_relative './factories/book_factory'
5
+ require_relative './factories/certificate_factory'
6
+ require_relative './factories/certificate_program_factory'
5
7
  require_relative './factories/chapter_factory'
6
8
  require_relative './factories/complement_factory'
7
9
  require_relative './factories/course_factory'
@@ -0,0 +1,8 @@
1
+ FactoryBot.define do
2
+ factory :certificate do
3
+ start_date { 1.month.ago }
4
+ end_date { 1.minute.ago }
5
+ user { build :user, first_name: 'Jane', last_name: 'Doe' }
6
+ certificate_program { build :certificate_program }
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :certificate_program do
3
+ title { 'Test' }
4
+ description { 'Certificate program to test' }
5
+ organization { Organization.current }
6
+ end
7
+ end
@@ -29,7 +29,8 @@ FactoryBot.define do
29
29
  book { create(:book, name: 'test', slug: 'mumuki/mumuki-the-book') }
30
30
  end
31
31
 
32
- factory :another_test_organization, parent: :test_organization, traits: [:skip_unique_name_validation] do
32
+ factory :another_test_organization, parent: :test_organization do
33
+ name { 'another-test' }
33
34
  book { create(:book, name: 'another-test', slug: 'mumuki/mumuki-another-book') }
34
35
  end
35
36
 
@@ -8,6 +8,6 @@ module Mumuki::Domain::Helpers::Course
8
8
  ## API Exposure
9
9
 
10
10
  def to_param
11
- slug
11
+ canonical_code
12
12
  end
13
13
  end
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Domain
3
- VERSION = '8.6.1'
3
+ VERSION = '9.0.0'
4
4
  end
5
5
  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: 8.6.1
4
+ version: 9.0.0
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-02-26 00:00:00.000000000 Z
11
+ date: 2021-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '6.1'
131
+ version: '7.0'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '6.1'
138
+ version: '7.0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: mumukit-sync
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -249,6 +249,8 @@ files:
249
249
  - app/models/assignment.rb
250
250
  - app/models/avatar.rb
251
251
  - app/models/book.rb
252
+ - app/models/certificate.rb
253
+ - app/models/certificate_program.rb
252
254
  - app/models/chapter.rb
253
255
  - app/models/complement.rb
254
256
  - app/models/concerns/assistable.rb
@@ -280,6 +282,7 @@ files:
280
282
  - app/models/concerns/with_discussions.rb
281
283
  - app/models/concerns/with_editor.rb
282
284
  - app/models/concerns/with_expectations.rb
285
+ - app/models/concerns/with_generated_code.rb
283
286
  - app/models/concerns/with_language.rb
284
287
  - app/models/concerns/with_layout.rb
285
288
  - app/models/concerns/with_locale.rb
@@ -651,6 +654,8 @@ files:
651
654
  - db/migrate/20210118180941_create_exam_authorization_request.rb
652
655
  - db/migrate/20210118194904_create_notification.rb
653
656
  - db/migrate/20210119160440_add_prevent_manual_evaluation_content_to_organizations.rb
657
+ - db/migrate/20210119174504_create_certificate_programs.rb
658
+ - db/migrate/20210119174835_create_certificates.rb
654
659
  - db/migrate/20210119190204_create_exam_registration_exam_join_table.rb
655
660
  - lib/mumuki/domain.rb
656
661
  - lib/mumuki/domain/area.rb
@@ -680,6 +685,8 @@ files:
680
685
  - lib/mumuki/domain/factories/assignments_factory.rb
681
686
  - lib/mumuki/domain/factories/avatar_factory.rb
682
687
  - lib/mumuki/domain/factories/book_factory.rb
688
+ - lib/mumuki/domain/factories/certificate_factory.rb
689
+ - lib/mumuki/domain/factories/certificate_program_factory.rb
683
690
  - lib/mumuki/domain/factories/chapter_factory.rb
684
691
  - lib/mumuki/domain/factories/complement_factory.rb
685
692
  - lib/mumuki/domain/factories/course_factory.rb