jobshop 0.0.163 → 0.0.167

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.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -3
  3. data/Rakefile +8 -17
  4. data/app/controllers/jobshop/application_controller.rb +5 -4
  5. data/app/controllers/jobshop/places_controller.rb +0 -4
  6. data/app/controllers/jobshop/users_controller.rb +0 -3
  7. data/app/mailers/jobshop/application_mailer.rb +0 -2
  8. data/app/mailers/jobshop/rfq_responder_mailer.rb +18 -0
  9. data/app/models/jobshop/ability.rb +1 -1
  10. data/app/models/jobshop/customer.rb +30 -0
  11. data/app/models/jobshop/customer/category.rb +19 -0
  12. data/app/models/jobshop/customer/contact.rb +28 -0
  13. data/app/models/jobshop/employee.rb +46 -0
  14. data/app/models/jobshop/employment.rb +25 -0
  15. data/app/models/jobshop/employment_version.rb +10 -0
  16. data/app/models/jobshop/inspection/boolean_criterion.rb +2 -2
  17. data/app/models/jobshop/inspection/deviation_criterion.rb +4 -4
  18. data/app/models/jobshop/inspection/limit_criterion.rb +6 -4
  19. data/app/models/jobshop/inspection/report.rb +2 -0
  20. data/app/models/jobshop/inspection/result.rb +2 -2
  21. data/app/models/jobshop/mailman.rb +22 -0
  22. data/app/models/jobshop/order.rb +2 -6
  23. data/app/models/jobshop/order_line.rb +2 -3
  24. data/app/models/jobshop/organization.rb +15 -6
  25. data/app/models/jobshop/place.rb +2 -0
  26. data/app/models/jobshop/product.rb +0 -3
  27. data/app/models/jobshop/rfq.rb +12 -6
  28. data/app/models/jobshop/user.rb +2 -17
  29. data/app/views/jobshop/rfq_responder_mailer/verified_contact.html.erb +5 -0
  30. data/app/views/jobshop/rfq_responder_mailer/verified_contact.text.erb +3 -0
  31. data/app/views/layouts/jobshop/application.html.haml +15 -0
  32. data/app/views/layouts/jobshop/mailer.html.erb +13 -0
  33. data/config/initializers/devise.rb +290 -0
  34. data/config/locales/devise.en.yml +64 -0
  35. data/config/routes.rb +1 -2
  36. data/db/migrate/20170311194758_initialize_jobshop.rb +42 -2
  37. data/db/migrate/20171216021339_create_organizations.rb +1 -4
  38. data/db/migrate/20171216021400_create_employees.rb +47 -0
  39. data/db/migrate/20171216021554_create_people.rb +13 -18
  40. data/db/migrate/20171216021853_create_customers.rb +57 -0
  41. data/db/migrate/20171216022020_create_places.rb +8 -9
  42. data/db/migrate/20171216022135_create_products.rb +6 -13
  43. data/db/migrate/20171216022605_create_orders.rb +19 -36
  44. data/db/migrate/20171216023018_create_roles.rb +5 -3
  45. data/db/migrate/20171216035357_create_things.rb +4 -4
  46. data/db/migrate/20171219022118_create_routing_processes.rb +15 -15
  47. data/db/migrate/20180107203241_create_inspections.rb +15 -14
  48. data/db/migrate/20181117023949_create_rfqs.rb +27 -19
  49. data/db/migrate/20181118014603_create_mailmen.rb +6 -4
  50. data/db/seeds.rb +126 -0
  51. data/lib/generators/jobshop/app/app_generator.rb +1 -1
  52. data/lib/generators/jobshop/app/templates/Procfile.tt +1 -0
  53. data/lib/generators/jobshop/app/templates/config/database.yml.tt +5 -5
  54. data/lib/generators/jobshop/{dummy/dummy_generator.rb → canary/canary_generator.rb} +13 -14
  55. data/lib/generators/jobshop/{dummy → canary}/templates/config/boot.rb.tt +0 -0
  56. data/lib/jobshop.rb +41 -12
  57. data/lib/jobshop/cli.rb +16 -82
  58. data/lib/jobshop/cli/app_generator.rb +38 -0
  59. data/lib/jobshop/cli/application.rb +14 -0
  60. data/lib/jobshop/cli/canary.rb +52 -0
  61. data/lib/jobshop/configuration.rb +16 -11
  62. data/lib/jobshop/engine.rb +39 -28
  63. data/lib/jobshop/helpers/migration.rb +78 -2
  64. data/lib/jobshop/mailroom/base_handler.rb +33 -0
  65. data/lib/jobshop/mailroom/null_handler.rb +10 -0
  66. data/lib/jobshop/mailroom/postmaster.rb +77 -0
  67. data/lib/jobshop/mailroom/rfq_handler.rb +39 -0
  68. data/lib/jobshop/version.rb +3 -1
  69. data/lib/tasks/jobshop_tasks.rake +7 -6
  70. metadata +98 -69
  71. data/app/controllers/concerns/email_token_validation.rb +0 -59
  72. data/app/controllers/concerns/jobshop/authentication_handler.rb +0 -15
  73. data/app/controllers/concerns/jobshop/authorization_handler.rb +0 -29
  74. data/app/controllers/jobshop/session_activations_controller.rb +0 -13
  75. data/app/controllers/jobshop/sessions_controller.rb +0 -20
  76. data/app/email_handlers/jobshop/rfq_handler.rb +0 -43
  77. data/app/models/jobshop/company.rb +0 -35
  78. data/app/models/jobshop/company/type.rb +0 -17
  79. data/app/models/jobshop/company_person.rb +0 -15
  80. data/app/models/jobshop/person.rb +0 -30
  81. data/app/models/jobshop/session_activation.rb +0 -30
  82. data/app/serializers/jobshop/test_user_serializer.rb +0 -10
  83. data/app/services/jobshop/authentication_service.rb +0 -20
  84. data/app/services/jobshop/authorization_service.rb +0 -30
  85. data/app/services/jobshop/jwt_service.rb +0 -17
  86. data/db/migrate/20171216021853_create_companies.rb +0 -64
  87. data/db/migrate/20171216023022_create_sessions.rb +0 -23
  88. data/lib/jobshop/cli/spinner.rb +0 -21
  89. data/lib/jobshop/dummy_app.rb +0 -190
  90. data/lib/jobshop/postmaster.rb +0 -89
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 72d9c251b2bcc65848a33510d25bdee8d14ca55b
4
- data.tar.gz: b0e53706a8d59d0824affb1a416fb519786a520b
2
+ SHA256:
3
+ metadata.gz: 6c48065969cc31f4dbc0155fb650a57b8759fe983b7e4d2daa5d459216296d8b
4
+ data.tar.gz: 25a97a07fdbefc8d1e60d7af5099c8d9d2d2918a8114e0f69303b79687d35e43
5
5
  SHA512:
6
- metadata.gz: 3a442988c2fcc8dc15e7bca171754a7d1ef608cf55a1021354b0be3c189ec1eadac472ffbb33c69371a8a9caceff0513dde3d7624aadf69f07fa5c6cbfe15c53
7
- data.tar.gz: 1aff3bac63832e1f71be8cb40ae5949b8f45966d9752a78f0c2e7a89e8f1e3b01c70b5c58c02ab2b4d034ee419a49fe72f7f562da98bd863046d728e0886fc2b
6
+ metadata.gz: ebabad19298eeb8bcadf77fe19cce8f71dccc97eaf3ecc1b83244a832b10f4c60f0286ae03436808ff641d7aa04a18de5cd741487ee2a26d51b654ac4c374c90
7
+ data.tar.gz: 5953bb253466f946f598b52b500a8be51cb124d9968e725c2c87663b3eae920a4da6f84d6cc76b37842fbf6a685447df84f1e129dca5aac65826488f5f4199bf
data/README.md CHANGED
@@ -19,9 +19,9 @@ manufacturing execution system and put it within reach of the average job shop.
19
19
 
20
20
  Jobshop only requires a few things:
21
21
 
22
- - Ruby >= 2.4
23
- - Rails >= 5.0
24
- - PostgreSQL >= 9.5
22
+ - Ruby >= 2.6
23
+ - Rails >= 5.2
24
+ - PostgreSQL >= 11.0
25
25
 
26
26
  ## Quick Installation
27
27
 
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  begin
2
2
  require "bundler/setup"
3
+ require "bundler/gem_tasks"
3
4
  rescue LoadError
4
5
  puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
6
  end
@@ -14,28 +15,18 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
15
  rdoc.rdoc_files.include("lib/**/*.rb")
15
16
  end
16
17
 
17
- require "jobshop/dummy_app"
18
+ APP_RAKEFILE = File.expand_path("spec/canary/Rakefile", __dir__)
19
+ load "rails/tasks/engine.rake"
18
20
  load "rails/tasks/statistics.rake"
19
-
20
- APP_RAKEFILE = Jobshop::DummyApp.rakefile
21
- require "bundler/gem_tasks"
22
-
23
- load "rails/tasks/engine.rake" if File.exist?(APP_RAKEFILE)
24
-
25
- Bundler::GemHelper.install_tasks
26
-
27
- require "rspec/core"
28
- require "rspec/core/rake_task"
21
+ load "rspec/rails/tasks/rspec.rake"
29
22
 
30
23
  desc "Verify that all FactoryBot factories are valid"
31
24
  task lint: :environment do
25
+ FACTORY_PATH = File.expand_path("spec/factories", __dir__)
26
+ FactoryBot.definition_file_paths = [ FACTORY_PATH ]
27
+ FactoryBot.find_definitions
28
+
32
29
  DatabaseCleaner.cleaning do
33
- FactoryBot.definition_file_paths = Jobshop::DummyApp.factory_paths
34
- FactoryBot.find_definitions
35
30
  FactoryBot.lint traits: true
36
31
  end
37
32
  end
38
-
39
- desc "Run all specs"
40
- RSpec::Core::RakeTask.new(:spec)
41
- task default: :spec
@@ -1,10 +1,11 @@
1
1
  module Jobshop
2
- class ApplicationController < ActionController::API
3
- include Jobshop::AuthorizationHandler
4
- include Jobshop::AuthenticationHandler
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+
5
+ layout "jobshop/application"
5
6
 
6
7
  def current_organization
7
- @current_organization ||= current_user && current_user.organization
8
+ @current_organization ||= current_user&.organization
8
9
  end
9
10
  end
10
11
  end
@@ -4,9 +4,5 @@ module Jobshop
4
4
  class PlacesController < ApplicationController
5
5
  def show
6
6
  end
7
-
8
- private def session_activations
9
- current_user.session_activations
10
- end
11
7
  end
12
8
  end
@@ -2,8 +2,5 @@ require_dependency "jobshop/application_controller"
2
2
 
3
3
  module Jobshop
4
4
  class UsersController < ApplicationController
5
- def current
6
- render(json: Jobshop::TestUserSerializer.new(current_user))
7
- end
8
5
  end
9
6
  end
@@ -1,7 +1,5 @@
1
1
  module Jobshop
2
2
  class ApplicationMailer < ActionMailer::Base
3
- default from: "jobshop-lookup@example.com"
4
-
5
3
  layout "mailer"
6
4
  end
7
5
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class RFQResponderMailer < ApplicationMailer
5
+
6
+ # Subject can be set in your I18n file at config/locales/en.yml
7
+ # with the following lookup:
8
+ #
9
+ # en.rfq_responder_mailer.verified_contact.subject
10
+ #
11
+ def verified_contact
12
+ @to = params[:customer_contact]
13
+ @greeting = "RFQ Received"
14
+
15
+ mail(to: @to.email)
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,6 @@
1
1
  module Jobshop
2
2
  class Ability < ApplicationRecord
3
- belongs_to :organization, class_name: "Jobshop::Organization"
3
+ belongs_to :organization, -> { readonly }
4
4
  has_many :role_abilities, -> (object) { where(organization_id: object.organization_id) }
5
5
  has_many :roles, through: :role_abilities
6
6
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop # :nodoc:
4
+ class Customer < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id customer_id ]
6
+
7
+ after_initialize { self.customer_id ||= SecureRandom.uuid if new_record? }
8
+ after_create { reload }
9
+
10
+ belongs_to :organization, -> { readonly }, inverse_of: :customers
11
+
12
+ belongs_to :category, inverse_of: :customers,
13
+ foreign_key: %i[ organization_id category_id ]
14
+
15
+ has_many :contacts, inverse_of: :customer,
16
+ foreign_key: %i[ organization_id customer_id ]
17
+
18
+ has_many :orders, inverse_of: :customer,
19
+ foreign_key: %i[ organization_id customer_id ]
20
+
21
+ has_many :rfqs, inverse_of: :customer,
22
+ foreign_key: %i[ organization_id customer_id ]
23
+
24
+ validates :name, presence: true
25
+ end
26
+ end
27
+
28
+ # TODO: CreatedBy Implementation
29
+ # belongs_to :created_by, polymorphic: true,
30
+ # foreign_key: %i[ organization_id created_by_id ]
@@ -0,0 +1,19 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class Customer::Category < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id category_id ]
6
+
7
+ after_initialize { self.category_id ||= SecureRandom.uuid if new_record? }
8
+ after_create { reload }
9
+
10
+ belongs_to :organization, -> { readonly }, inverse_of: :customer_categories
11
+
12
+ has_many :customers, inverse_of: :category,
13
+ foreign_key: %i[ organization_id category_id ]
14
+
15
+ validates :name, uniqueness: {
16
+ case_insensitive: true, scope: :organization_id
17
+ }
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop # :nodoc:
4
+ class Customer::Contact < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id customer_id contact_id ]
6
+
7
+ after_initialize { self.contact_id ||= SecureRandom.uuid if new_record? }
8
+ after_create { reload }
9
+
10
+ belongs_to :organization, inverse_of: :customer_contacts
11
+ belongs_to :customer, inverse_of: :contacts,
12
+ foreign_key: %i[ organization_id customer_id ]
13
+
14
+ validates :email,
15
+ presence: { if: :email_required? },
16
+ format: { if: :email_required?, with: /\A[^@\s]+@[^@\s]+\z/ },
17
+ uniqueness: { if: :email_changed?, scope: :organization_id,
18
+ case_sensitive: false }
19
+
20
+ def full_name
21
+ @name = [ forename, surname ].join(" ")
22
+ end
23
+
24
+ private def email_required?
25
+ true
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop # :nodoc:
4
+ class Employee < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id employee_id ]
6
+
7
+ after_initialize { self.employee_id ||= SecureRandom.uuid if new_record? }
8
+ after_create { reload }
9
+
10
+ belongs_to :organization, -> { readonly }, inverse_of: :employees
11
+
12
+ has_many :employments, inverse_of: :employee,
13
+ foreign_key: %i[ organization_id employee_id ],
14
+ dependent: :restrict_with_exception
15
+
16
+ validates :email,
17
+ presence: { if: :email_required? },
18
+ format: { if: :email_required?, with: /\A[^@\s]+@[^@\s]+\z/ },
19
+ uniqueness: { if: :email_changed?, scope: :organization_id,
20
+ case_sensitive: false }
21
+
22
+ scope :active, -> {
23
+ joins(:employments).merge(Jobshop::Employment.active)
24
+ }
25
+
26
+ scope :inactive, -> {
27
+ joins(:employments).merge(Jobshop::Employment.inactive)
28
+ }
29
+
30
+ def active?
31
+ !!employments.active.first
32
+ end
33
+
34
+ def inactive?
35
+ !employments.active.first
36
+ end
37
+
38
+ def name
39
+ @name = [ forename, surname ].join(" ")
40
+ end
41
+
42
+ private def email_required?
43
+ true
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class Employment < ApplicationRecord
5
+ self.primary_keys = %i[ organization_id employment_id ]
6
+
7
+ after_initialize { self.employment_id ||= SecureRandom.uuid if new_record? }
8
+ after_create { reload }
9
+
10
+ belongs_to :organization, inverse_of: :employments
11
+
12
+ belongs_to :employee, inverse_of: :employments,
13
+ foreign_key: %i[ organization_id employee_id ]
14
+
15
+ default_scope { order(ended_on: :desc, started_on: :desc) }
16
+
17
+ scope :active, -> {
18
+ where(ended_on: nil)
19
+ }
20
+
21
+ scope :inactive, -> {
22
+ where.not(ended_on: nil)
23
+ }
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literals: true
2
+
3
+ module Jobshop
4
+ class EmploymentVersion < ApplicationRecord
5
+ private_class_method :new, :create
6
+
7
+ self.table_name = :jobshop_employment_auditing
8
+ self.primary_key = :auditing_id
9
+ end
10
+ end
@@ -21,11 +21,11 @@ module Jobshop
21
21
  end
22
22
 
23
23
  delegate :name, :name=, :position, :position=, to: :criterion
24
-
24
+ =begin
25
25
  def specification
26
26
  @specification ||= "#{condition}\nPASS/FAIL"
27
27
  end
28
-
28
+ =end
29
29
  def tolerance
30
30
  @tolerance ||= condition
31
31
  end
@@ -66,7 +66,7 @@ module Jobshop
66
66
  errors[:base] << "minimum must be less than maximum"
67
67
  end
68
68
  end
69
-
69
+ =begin
70
70
  def specification
71
71
  @specfication ||= if symmetric?
72
72
  "#{nominal}±#{abs(upper)}"
@@ -74,7 +74,7 @@ module Jobshop
74
74
  "#{nominal}\n#{lower}/#{upper}"
75
75
  end
76
76
  end
77
-
77
+ =end
78
78
  def symmetric?
79
79
  @symmetrical ||= lower == upper * -1
80
80
  end
@@ -92,7 +92,7 @@ module Jobshop
92
92
  Unitwise(value.truncate(4), self[:unit])
93
93
  end
94
94
 
95
- private def oversize?(value)
95
+ def oversize?(value)
96
96
  value = if value.respond_to?(:unit)
97
97
  value.convert_to(self[:unit])
98
98
  else
@@ -102,7 +102,7 @@ module Jobshop
102
102
  value > upper || false
103
103
  end
104
104
 
105
- private def undersize?(value)
105
+ def undersize?(value)
106
106
  value = if value.respond_to?(:unit)
107
107
  value.convert_to(self[:unit])
108
108
  else
@@ -48,13 +48,13 @@ module Jobshop
48
48
  self[:maximum] = value
49
49
  end
50
50
  end
51
-
51
+ =begin
52
52
  def specification
53
53
  @specification ||= [
54
54
  qualifier, [ minimum, maximum ].compact.join("/")
55
55
  ].compact.join("\n")
56
56
  end
57
-
57
+ =end
58
58
  def qualifier
59
59
  @qualifier ||= if minimum && !maximum
60
60
  "Minimum"
@@ -77,18 +77,19 @@ module Jobshop
77
77
  !undersize?(value) && !oversize?(value)
78
78
  end
79
79
 
80
- private def oversize?(value)
80
+ def oversize?(value)
81
81
  value = Unitwise(value, self[:unit]) unless value.respond_to?(:unit)
82
82
  maximum && value > maximum || false
83
83
  end
84
84
 
85
- private def undersize?(value)
85
+ def undersize?(value)
86
86
  value = Unitwise(value, self[:unit]) unless value.respond_to?(:unit)
87
87
  minimum && value < minimum || false
88
88
  end
89
89
 
90
90
  # Generate a random value that has a 90% chance of being in spec.
91
91
  # TODO: This needs to go in the tests somewhere, not really in the model.
92
+ # :nocov:
92
93
  def random
93
94
  value = if bound?
94
95
  rand(self[:minimum].to_f..self[:maximum].to_f) * 1.1
@@ -100,6 +101,7 @@ module Jobshop
100
101
 
101
102
  Unitwise(value, self[:unit])
102
103
  end
104
+ # :nocov:
103
105
 
104
106
  private def minimum_or_maximum_or_both
105
107
  unless minimum || maximum
@@ -17,6 +17,7 @@ module Jobshop
17
17
  has_many :tuples, -> { order(:position) }, inverse_of: :report,
18
18
  foreign_key: %i[ organization_id report_id ]
19
19
 
20
+ =begin
20
21
  def ascii
21
22
  require "terminal-table"
22
23
  table = Terminal::Table.new do |t|
@@ -33,5 +34,6 @@ module Jobshop
33
34
 
34
35
  puts table
35
36
  end
37
+ =end
36
38
  end
37
39
  end
@@ -19,7 +19,7 @@ module Jobshop
19
19
 
20
20
  def value
21
21
  if self[:unit] == "boolean"
22
- !!self[:value]
22
+ FALSE_VALUES.exclude?(self[:value])
23
23
  else
24
24
  self[:value] && Unitwise(self[:value].truncate(4), self[:unit])
25
25
  end
@@ -27,7 +27,7 @@ module Jobshop
27
27
 
28
28
  def value=(value)
29
29
  if criterion.unit == "boolean"
30
- self[:value] = value
30
+ self[:value] = FALSE_VALUES.exclude?(value)
31
31
  self[:unit] = "boolean"
32
32
  else
33
33
  if value.respond_to?(:unit)