jobshop 0.0.157 → 0.0.163

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/app/email_handlers/jobshop/rfq_handler.rb +43 -0
  4. data/app/models/jobshop/collection.rb +6 -11
  5. data/app/models/jobshop/company.rb +25 -12
  6. data/app/models/jobshop/company/type.rb +17 -0
  7. data/app/models/jobshop/company_person.rb +15 -0
  8. data/app/models/jobshop/inspection.rb +2 -0
  9. data/app/models/jobshop/inspection/boolean_criterion.rb +13 -10
  10. data/app/models/jobshop/inspection/criterion.rb +8 -11
  11. data/app/models/jobshop/inspection/deviation_criterion.rb +13 -10
  12. data/app/models/jobshop/inspection/limit_criterion.rb +9 -7
  13. data/app/models/jobshop/inspection/report.rb +11 -15
  14. data/app/models/jobshop/inspection/result.rb +9 -5
  15. data/app/models/jobshop/inspection/tuple.rb +7 -3
  16. data/app/models/jobshop/mailman.rb +11 -0
  17. data/app/models/jobshop/order.rb +12 -14
  18. data/app/models/jobshop/order_line.rb +10 -5
  19. data/app/models/jobshop/organization.rb +35 -8
  20. data/app/models/jobshop/person.rb +30 -0
  21. data/app/models/jobshop/place.rb +3 -1
  22. data/app/models/jobshop/product.rb +10 -12
  23. data/app/models/jobshop/rfq.rb +22 -0
  24. data/app/models/jobshop/rfq_line.rb +12 -0
  25. data/app/models/jobshop/role.rb +6 -13
  26. data/app/models/jobshop/role_assignment.rb +4 -2
  27. data/app/models/jobshop/routing_process.rb +8 -11
  28. data/app/models/jobshop/routing_step.rb +4 -2
  29. data/app/models/jobshop/thing.rb +6 -11
  30. data/app/models/jobshop/user.rb +10 -17
  31. data/db/migrate/20170311194758_initialize_jobshop.rb +3 -1
  32. data/db/migrate/20171216021339_create_organizations.rb +4 -2
  33. data/db/migrate/20171216021554_create_people.rb +48 -0
  34. data/db/migrate/20171216021853_create_companies.rb +47 -8
  35. data/db/migrate/20171216022020_create_places.rb +3 -3
  36. data/db/migrate/20171216022135_create_products.rb +5 -3
  37. data/db/migrate/20171216022605_create_orders.rb +9 -7
  38. data/db/migrate/20171216023018_create_roles.rb +18 -16
  39. data/db/migrate/20171216023022_create_sessions.rb +9 -7
  40. data/db/migrate/20171216035357_create_things.rb +7 -5
  41. data/db/migrate/20171219022118_create_routing_processes.rb +10 -8
  42. data/db/migrate/{20180107203241_create_inspection.rb → 20180107203241_create_inspections.rb} +21 -16
  43. data/db/migrate/20181117023949_create_rfqs.rb +40 -0
  44. data/db/migrate/20181118014603_create_mailmen.rb +29 -0
  45. data/exe/jobshop +1 -1
  46. data/lib/generators/jobshop/app/app_generator.rb +12 -23
  47. data/lib/generators/jobshop/app/templates/Procfile.tt +1 -0
  48. data/lib/generators/jobshop/config/templates/config/initializers/jobshop.rb.tt +5 -0
  49. data/lib/generators/jobshop/dummy/dummy_generator.rb +4 -5
  50. data/lib/jobshop.rb +8 -4
  51. data/lib/jobshop/cli.rb +58 -47
  52. data/lib/jobshop/configuration.rb +17 -5
  53. data/lib/jobshop/dummy_app.rb +27 -15
  54. data/lib/jobshop/engine.rb +28 -15
  55. data/lib/jobshop/helpers/migration.rb +6 -2
  56. data/lib/jobshop/postmaster.rb +89 -0
  57. data/lib/jobshop/version.rb +2 -2
  58. data/lib/tasks/jobshop_tasks.rake +11 -0
  59. metadata +83 -16
  60. data/db/migrate/20171216021717_create_users.rb +0 -30
@@ -1,13 +1,18 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class OrderLine < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :order_id, :order_line_id]
5
+ self.primary_keys = %i[ organization_id order_id order_line_id ]
4
6
 
5
7
  belongs_to :organization
6
- belongs_to :created_by, class_name: "Jobshop::User",
7
- foreign_key: [ :organization_id, :created_by_id ]
8
+
9
+ belongs_to :created_by, class_name: "Jobshop::Person",
10
+ foreign_key: %i[ organization_id created_by_id ]
11
+
8
12
  belongs_to :order, inverse_of: :order_lines,
9
- foreign_key: [ :organization_id, :order_id ]
13
+ foreign_key: %i[ organization_id order_id ]
14
+
10
15
  belongs_to :product,
11
- foreign_key: [ :organization_id, :product_id ]
16
+ foreign_key: %i[ organization_id product_id ]
12
17
  end
13
18
  end
@@ -1,26 +1,53 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class Organization < ApplicationRecord
3
5
  self.primary_key = :organization_id
4
6
 
5
- has_many :users, inverse_of: :organization,
6
- dependent: :restrict_with_exception
7
- has_many :roles, inverse_of: :organization,
8
- dependent: :restrict_with_exception
9
- has_many :places, inverse_of: :organization,
10
- dependent: :restrict_with_exception
11
7
  has_many :collections, inverse_of: :organization,
12
8
  dependent: :restrict_with_exception
13
- has_many :things, inverse_of: :organization,
9
+
10
+ has_many :companies, inverse_of: :organization,
11
+ dependent: :restrict_with_exception
12
+
13
+ has_many :company_types, inverse_of: :organization,
14
+ dependent: :restrict_with_exception,
15
+ class_name: "Jobshop::Company::Type"
16
+
17
+ has_many :inspection_reports, inverse_of: :organization,
18
+ dependent: :restrict_with_exception,
19
+ class_name: "Jobshop::Inspection::Report"
20
+
21
+ has_many :mailmen, inverse_of: :organization,
14
22
  dependent: :restrict_with_exception
23
+
15
24
  has_many :orders, inverse_of: :organization,
16
25
  dependent: :restrict_with_exception
17
- has_many :companies, inverse_of: :organization,
26
+
27
+ has_many :people, inverse_of: :organization,
18
28
  dependent: :restrict_with_exception
29
+
30
+ has_many :places, inverse_of: :organization,
31
+ dependent: :restrict_with_exception
32
+
19
33
  has_many :products, inverse_of: :organization,
20
34
  dependent: :restrict_with_exception
35
+
36
+ has_many :rfqs, inverse_of: :organization,
37
+ dependent: :restrict_with_exception
38
+
39
+ has_many :roles, inverse_of: :organization,
40
+ dependent: :restrict_with_exception
41
+
21
42
  has_many :routing_processes, inverse_of: :organization,
22
43
  dependent: :restrict_with_exception
23
44
 
45
+ has_many :things, inverse_of: :organization,
46
+ dependent: :restrict_with_exception
47
+
48
+ has_many :users, inverse_of: :organization,
49
+ dependent: :restrict_with_exception
50
+
24
51
  scope :grouped_by_email, ->(email_addresses) {
25
52
  Jobshop::User
26
53
  .where(email: email_addresses)
@@ -0,0 +1,30 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class Person < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id person_id ]
6
+
7
+ after_initialize { self.person_id ||= SecureRandom.uuid if new_record? }
8
+
9
+ belongs_to :organization, inverse_of: :people
10
+
11
+ has_one :company_person, inverse_of: :person,
12
+ foreign_key: %i[ organization_id person_id ]
13
+
14
+ has_one :company, through: :company_person,
15
+ foreign_key: %i[ organization_id company_id ]
16
+
17
+ validates :email,
18
+ presence: { if: :email_required? },
19
+ format: { if: :email_required?, with: /\A[^@\s]+@[^@\s]+\z/ },
20
+ uniqueness: { if: :email_changed?, scope: :organization_id, case_sensitive: false }
21
+
22
+ def name
23
+ @name = [ forename, surname ].join(" ")
24
+ end
25
+
26
+ private def email_required?
27
+ true
28
+ end
29
+ end
30
+ end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class Place < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :place_id ]
5
+ self.primary_keys = %i[ organization_id place_id ]
4
6
 
5
7
  belongs_to :organization, inverse_of: :places
6
8
 
@@ -1,21 +1,19 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class Product < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :product_id ]
5
+ self.primary_keys = %i[ organization_id product_id ]
4
6
 
5
- after_create do
6
- self.class.connection.clear_query_cache
7
- @attributes = self.class.unscoped {
8
- self.class.find_by!(organization: organization, name: name)
9
- }.instance_variable_get(:@attributes)
10
- @new_record = false
11
- self
12
- end
7
+ after_initialize { self.product_id ||= SecureRandom.uuid if new_record? }
13
8
 
14
9
  belongs_to :organization, inverse_of: :products
15
- belongs_to :created_by, class_name: "Jobshop::User",
16
- foreign_key: [ :organization_id, :created_by_id ]
10
+
11
+ belongs_to :created_by, class_name: "Jobshop::Person",
12
+ foreign_key: %i[ organization_id created_by_id ]
13
+
17
14
  has_one :routing_process, inverse_of: :product,
18
- foreign_key: [ :organization_id, :product_id ]
15
+ foreign_key: %i[ organization_id product_id ]
16
+
19
17
  has_many :routing_steps, through: :routing_process
20
18
 
21
19
  validates :name, presence: true
@@ -0,0 +1,22 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class RFQ < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id rfq_id ]
6
+
7
+ before_validation(on: :create) { self.rfq_id ||= SecureRandom.uuid }
8
+
9
+ belongs_to :organization, inverse_of: :rfqs
10
+
11
+ belongs_to :company, inverse_of: :rfqs, optional: true,
12
+ foreign_key: %i[ organization_id company_id ]
13
+
14
+ has_many :rfq_lines, inverse_of: :rfq,
15
+ foreign_key: %i[ organization_id rfq_id ]
16
+
17
+ def company=(value)
18
+ company_id = (Jobshop::Company === value) ? value.company_id : value
19
+ write_attribute(:company_id, company_id)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class RFQLine < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id rfq_id rfq_line_id ]
6
+
7
+ belongs_to :organization
8
+
9
+ belongs_to :rfq, inverse_of: :rfq_lines,
10
+ foreign_key: %i[ organization_id rfq_id ]
11
+ end
12
+ end
@@ -1,23 +1,16 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class Role < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :role_id ]
4
-
5
- after_create do
6
- self.class.connection.clear_query_cache
7
-
8
- fresh_record = self.class.unscoped {
9
- self.class.find_by!(organization: organization, name: name) }
5
+ self.primary_keys = %i[ organization_id role_id ]
10
6
 
11
- @attributes = fresh_record.instance_variable_get(:@attributes)
12
- @new_record = false
13
- self
14
- end
7
+ after_initialize { self.role_id ||= SecureRandom.uuid if new_record? }
15
8
 
16
9
  belongs_to :organization, inverse_of: :roles,
17
- primary_key: [ :organization_id, :role_id ]
10
+ primary_key: %i[ organization_id role_id ]
18
11
 
19
12
  has_many :role_assignments, inverse_of: :role,
20
- foreign_key: [ :organization_id, :role_id ]
13
+ foreign_key: %i[ organization_id role_id ]
21
14
 
22
15
  validates :name, presence: true
23
16
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class RoleAssignment < ApplicationRecord
3
5
  belongs_to :organization
4
- belongs_to :user, foreign_key: [ :organization_id, :user_id ]
5
- belongs_to :role, foreign_key: [ :organization_id, :role_id ]
6
+ belongs_to :user, foreign_key: %i[ organization_id user_id ]
7
+ belongs_to :role, foreign_key: %i[ organization_id role_id ]
6
8
  end
7
9
  end
@@ -1,20 +1,17 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class RoutingProcess < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :routing_process_id ]
5
+ self.primary_keys = %i[ organization_id routing_process_id ]
4
6
 
5
- after_create do
6
- self.class.connection.clear_query_cache
7
- @attributes = self.class.unscoped {
8
- self.class.find_by!(organization: organization, product_id: product_id)
9
- }.instance_variable_get(:@attributes)
10
- @new_record = false
11
- self
12
- end
7
+ after_initialize { self.routing_process_id ||= SecureRandom.uuid if new_record? }
13
8
 
14
9
  belongs_to :organization, inverse_of: :routing_processes
10
+
15
11
  belongs_to :product, inverse_of: :routing_process,
16
- foreign_key: [ :organization_id, :product_id ]
12
+ foreign_key: %i[ organization_id product_id ]
13
+
17
14
  has_many :routing_steps, inverse_of: :routing_process,
18
- foreign_key: [ :organization_id, :routing_process_id ]
15
+ foreign_key: %i[ organization_id routing_process_id ]
19
16
  end
20
17
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class RoutingStep < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :routing_step_id ]
5
+ self.primary_keys = %i[ organization_id routing_step_id ]
4
6
 
5
7
  belongs_to :organization
6
8
  belongs_to :routing_process, inverse_of: :routing_steps,
7
- foreign_key: [ :organization_id, :routing_process_id ]
9
+ foreign_key: %i[ organization_id routing_process_id ]
8
10
 
9
11
  validates :name, presence: true
10
12
  end
@@ -1,20 +1,15 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class Thing < ApplicationRecord
3
- self.primary_keys = [ :organization_id, :thing_id ]
5
+ self.primary_keys = %i[ organization_id thing_id ]
4
6
 
5
- after_create do
6
- self.class.connection.clear_query_cache
7
- fresh_thing = self.class.unscoped {
8
- self.class.find_by!(organization: organization, collection: collection, name: name)
9
- }
10
- @attributes = fresh_thing.instance_variable_get(:@attributes)
11
- @new_record = false
12
- self
13
- end
7
+ after_initialize { self.thing_id ||= SecureRandom.uuid if new_record? }
14
8
 
15
9
  belongs_to :organization, inverse_of: :things
10
+
16
11
  belongs_to :collection, inverse_of: :things,
17
- foreign_key: [ :organization_id, :collection_id ]
12
+ foreign_key: %i[ organization_id collection_id ]
18
13
 
19
14
  validates :name, presence: true,
20
15
  uniqueness: { scope: :organization_id, case_sensitive: false }
@@ -1,24 +1,20 @@
1
+ # frozen_string_literals: true
2
+
1
3
  module Jobshop
2
4
  class User < ApplicationRecord
3
- self.primary_keys = :organization_id, :user_id
5
+ self.primary_keys = %i[ organization_id user_id ]
4
6
 
5
- has_secure_password
6
-
7
- after_create do
8
- self.class.connection.clear_query_cache
9
- @attributes = self.class.unscoped {
10
- self.class.find_by!(organization: organization, email: email)
11
- }.instance_variable_get(:@attributes)
12
- @new_record = false
13
- self
14
- end
7
+ after_initialize { self.user_id ||= SecureRandom.uuid if new_record? }
15
8
 
16
9
  belongs_to :organization, inverse_of: :users
10
+
17
11
  has_many :role_assignments, inverse_of: :user,
18
- foreign_key: [ :organization_id, :user_id ]
12
+ foreign_key: %i[ organization_id user_id ]
13
+
19
14
  has_many :roles, through: :role_assignments
15
+
20
16
  has_many :sessions, inverse_of: :user, dependent: :destroy,
21
- foreign_key: [ :organization_id, :user_id ]
17
+ foreign_key: %i[ organization_id user_id ]
22
18
 
23
19
  validates :email,
24
20
  presence: { if: :email_required? },
@@ -31,10 +27,7 @@ module Jobshop
31
27
  presence: { if: :password_required? },
32
28
  confirmation: { if: :password_required? }
33
29
 
34
-
35
- def name
36
- @name = [ forename, surname ].join(" ")
37
- end
30
+ has_secure_password
38
31
 
39
32
  def activate_session
40
33
  session_activations.activate(SecureRandom.hex).activation_token
@@ -1,4 +1,6 @@
1
- class InitializeJobshop < ActiveRecord::Migration[5.1]
1
+ # frozen_string_literals: true
2
+
3
+ class InitializeJobshop < ActiveRecord::Migration[5.2]
2
4
  def change
3
5
  enable_extension "pgcrypto" unless extension_enabled? "pgcrypto"
4
6
  enable_extension "citext" unless extension_enabled? "citext"
@@ -1,6 +1,8 @@
1
+ # frozen_string_literals: true
2
+
1
3
  require "jobshop/helpers/migration.rb"
2
4
 
3
- class CreateOrganizations < ActiveRecord::Migration[5.1]
5
+ class CreateOrganizations < ActiveRecord::Migration[5.2]
4
6
  include Jobshop::Helpers::Migration
5
7
 
6
8
  def change
@@ -10,7 +12,7 @@ class CreateOrganizations < ActiveRecord::Migration[5.1]
10
12
  name: :idx_jobshop_organizations_pkey
11
13
 
12
14
  t.citext :name, index: true
13
- t.index [ :organization_id, :name ], unique: true
15
+ t.index %i[ organization_id name ], unique: true
14
16
 
15
17
  t.timestamps
16
18
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literals: true
2
+
3
+ require "jobshop/helpers/migration.rb"
4
+
5
+ class CreatePeople < ActiveRecord::Migration[5.2]
6
+ include Jobshop::Helpers::Migration
7
+
8
+ def change # rubocop:disable Metrics/MethodLength
9
+ create_table :jobshop_people, id: false do |t|
10
+ t.uuid :organization_id, null: false
11
+ t.uuid :person_id, null: false, default: "gen_random_uuid()"
12
+ t.index %i[ organization_id person_id ], unique: true,
13
+ name: :idx_jobshop_people_pkey
14
+
15
+ t.citext :email, null: false
16
+ t.index %i[ organization_id email ], unique: true
17
+
18
+ t.string :job_title
19
+ t.string :forename
20
+ t.string :surname
21
+
22
+ t.timestamps
23
+ end
24
+
25
+ idx_table_name_pkey :jobshop_people
26
+ fk_organization_id :jobshop_people
27
+
28
+ create_table :jobshop_users, id: false do |t|
29
+ t.uuid :organization_id, null: false
30
+ t.uuid :user_id, null: false, default: "gen_random_uuid()"
31
+ t.index %i[ organization_id user_id ], unique: true,
32
+ name: :idx_jobshop_users_pkey
33
+
34
+ t.citext :email, null: false
35
+ t.index %i[ organization_id email ], unique: true
36
+
37
+ t.string :email_authentication_token, index: { unique: true }
38
+ t.datetime :email_authentication_token_sent_at, :datetime
39
+
40
+ t.string :password_digest, null: false, default: ""
41
+
42
+ t.timestamps
43
+ end
44
+
45
+ idx_table_name_pkey "jobshop_users"
46
+ fk_organization_id "jobshop_users"
47
+ end
48
+ end
@@ -1,25 +1,64 @@
1
+ # frozen_string_literals: true
2
+
1
3
  require "jobshop/helpers/migration.rb"
2
4
 
3
- class CreateCompanies < ActiveRecord::Migration[5.1]
5
+ class CreateCompanies < ActiveRecord::Migration[5.2]
4
6
  include Jobshop::Helpers::Migration
5
7
 
6
- def change
8
+ def change # rubocop:disable Metrics/MethodLength
9
+ create_table :jobshop_company_types, id: false do |t|
10
+ t.uuid :organization_id, null: false
11
+ t.uuid :type_id, null: false, default: "gen_random_uuid()"
12
+ t.index %i[ organization_id type_id ],
13
+ name: :idx_jobshop_company_types_pkey, unique: true
14
+
15
+ t.citext :name, null: false
16
+ t.index %i[ organization_id name ], unique: true
17
+
18
+ t.text :description
19
+ end
20
+
21
+ idx_table_name_pkey :jobshop_company_types
22
+ fk_organization_id :jobshop_company_types
23
+
7
24
  create_table :jobshop_companies, id: false do |t|
8
25
  t.uuid :organization_id, null: false
9
26
  t.uuid :company_id, null: false, default: "gen_random_uuid()"
10
- t.index [ :organization_id, :company_id ], unique: true,
11
- name: "idx_jobshop_companies_pkey"
27
+ t.index %i[ organization_id company_id ], unique: true,
28
+ name: :idx_jobshop_companies_pkey
12
29
 
13
30
  t.uuid :created_by_id, null: false
14
31
 
32
+ t.uuid :type_id, null: false
33
+
15
34
  t.citext :name, null: false
16
- t.index [ :organization_id, :name ], unique: true
35
+ t.index %i[ organization_id name ], unique: true
17
36
 
18
37
  t.timestamps
19
38
  end
20
39
 
21
- idx_table_name_pkey "jobshop_companies"
22
- fk_organization_id "jobshop_companies"
23
- fk_created_by_id "jobshop_companies"
40
+ idx_table_name_pkey :jobshop_companies
41
+ fk_organization_id :jobshop_companies
42
+ fk_created_by_id :jobshop_companies
43
+ foreign_key :jobshop_companies, :jobshop_company_types,
44
+ %i[ organization_id type_id ]
45
+
46
+ create_table :jobshop_company_people, id: false do |t|
47
+ t.uuid :organization_id, null: false
48
+ t.uuid :company_id, null: false
49
+ t.uuid :person_id, null: false
50
+ t.index %i[ organization_id company_id person_id ],
51
+ name: :idx_jobshop_company_people_pkey, unique: true
52
+
53
+ t.index %i[ organization_id company_id ],
54
+ name: :idx_jobshop_company_organization_company_ids
55
+ end
56
+
57
+ idx_table_name_pkey :jobshop_company_people
58
+ fk_organization_id :jobshop_company_people
59
+ foreign_key :jobshop_company_people, :jobshop_companies,
60
+ %i[ organization_id company_id ]
61
+ foreign_key :jobshop_company_people, :jobshop_people,
62
+ %i[ organization_id person_id ]
24
63
  end
25
64
  end