jobshop 0.0.163 → 0.0.167
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +3 -3
- data/Rakefile +8 -17
- data/app/controllers/jobshop/application_controller.rb +5 -4
- data/app/controllers/jobshop/places_controller.rb +0 -4
- data/app/controllers/jobshop/users_controller.rb +0 -3
- data/app/mailers/jobshop/application_mailer.rb +0 -2
- data/app/mailers/jobshop/rfq_responder_mailer.rb +18 -0
- data/app/models/jobshop/ability.rb +1 -1
- data/app/models/jobshop/customer.rb +30 -0
- data/app/models/jobshop/customer/category.rb +19 -0
- data/app/models/jobshop/customer/contact.rb +28 -0
- data/app/models/jobshop/employee.rb +46 -0
- data/app/models/jobshop/employment.rb +25 -0
- data/app/models/jobshop/employment_version.rb +10 -0
- data/app/models/jobshop/inspection/boolean_criterion.rb +2 -2
- data/app/models/jobshop/inspection/deviation_criterion.rb +4 -4
- data/app/models/jobshop/inspection/limit_criterion.rb +6 -4
- data/app/models/jobshop/inspection/report.rb +2 -0
- data/app/models/jobshop/inspection/result.rb +2 -2
- data/app/models/jobshop/mailman.rb +22 -0
- data/app/models/jobshop/order.rb +2 -6
- data/app/models/jobshop/order_line.rb +2 -3
- data/app/models/jobshop/organization.rb +15 -6
- data/app/models/jobshop/place.rb +2 -0
- data/app/models/jobshop/product.rb +0 -3
- data/app/models/jobshop/rfq.rb +12 -6
- data/app/models/jobshop/user.rb +2 -17
- data/app/views/jobshop/rfq_responder_mailer/verified_contact.html.erb +5 -0
- data/app/views/jobshop/rfq_responder_mailer/verified_contact.text.erb +3 -0
- data/app/views/layouts/jobshop/application.html.haml +15 -0
- data/app/views/layouts/jobshop/mailer.html.erb +13 -0
- data/config/initializers/devise.rb +290 -0
- data/config/locales/devise.en.yml +64 -0
- data/config/routes.rb +1 -2
- data/db/migrate/20170311194758_initialize_jobshop.rb +42 -2
- data/db/migrate/20171216021339_create_organizations.rb +1 -4
- data/db/migrate/20171216021400_create_employees.rb +47 -0
- data/db/migrate/20171216021554_create_people.rb +13 -18
- data/db/migrate/20171216021853_create_customers.rb +57 -0
- data/db/migrate/20171216022020_create_places.rb +8 -9
- data/db/migrate/20171216022135_create_products.rb +6 -13
- data/db/migrate/20171216022605_create_orders.rb +19 -36
- data/db/migrate/20171216023018_create_roles.rb +5 -3
- data/db/migrate/20171216035357_create_things.rb +4 -4
- data/db/migrate/20171219022118_create_routing_processes.rb +15 -15
- data/db/migrate/20180107203241_create_inspections.rb +15 -14
- data/db/migrate/20181117023949_create_rfqs.rb +27 -19
- data/db/migrate/20181118014603_create_mailmen.rb +6 -4
- data/db/seeds.rb +126 -0
- data/lib/generators/jobshop/app/app_generator.rb +1 -1
- data/lib/generators/jobshop/app/templates/Procfile.tt +1 -0
- data/lib/generators/jobshop/app/templates/config/database.yml.tt +5 -5
- data/lib/generators/jobshop/{dummy/dummy_generator.rb → canary/canary_generator.rb} +13 -14
- data/lib/generators/jobshop/{dummy → canary}/templates/config/boot.rb.tt +0 -0
- data/lib/jobshop.rb +41 -12
- data/lib/jobshop/cli.rb +16 -82
- data/lib/jobshop/cli/app_generator.rb +38 -0
- data/lib/jobshop/cli/application.rb +14 -0
- data/lib/jobshop/cli/canary.rb +52 -0
- data/lib/jobshop/configuration.rb +16 -11
- data/lib/jobshop/engine.rb +39 -28
- data/lib/jobshop/helpers/migration.rb +78 -2
- data/lib/jobshop/mailroom/base_handler.rb +33 -0
- data/lib/jobshop/mailroom/null_handler.rb +10 -0
- data/lib/jobshop/mailroom/postmaster.rb +77 -0
- data/lib/jobshop/mailroom/rfq_handler.rb +39 -0
- data/lib/jobshop/version.rb +3 -1
- data/lib/tasks/jobshop_tasks.rake +7 -6
- metadata +98 -69
- data/app/controllers/concerns/email_token_validation.rb +0 -59
- data/app/controllers/concerns/jobshop/authentication_handler.rb +0 -15
- data/app/controllers/concerns/jobshop/authorization_handler.rb +0 -29
- data/app/controllers/jobshop/session_activations_controller.rb +0 -13
- data/app/controllers/jobshop/sessions_controller.rb +0 -20
- data/app/email_handlers/jobshop/rfq_handler.rb +0 -43
- data/app/models/jobshop/company.rb +0 -35
- data/app/models/jobshop/company/type.rb +0 -17
- data/app/models/jobshop/company_person.rb +0 -15
- data/app/models/jobshop/person.rb +0 -30
- data/app/models/jobshop/session_activation.rb +0 -30
- data/app/serializers/jobshop/test_user_serializer.rb +0 -10
- data/app/services/jobshop/authentication_service.rb +0 -20
- data/app/services/jobshop/authorization_service.rb +0 -30
- data/app/services/jobshop/jwt_service.rb +0 -17
- data/db/migrate/20171216021853_create_companies.rb +0 -64
- data/db/migrate/20171216023022_create_sessions.rb +0 -23
- data/lib/jobshop/cli/spinner.rb +0 -21
- data/lib/jobshop/dummy_app.rb +0 -190
- data/lib/jobshop/postmaster.rb +0 -89
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6c48065969cc31f4dbc0155fb650a57b8759fe983b7e4d2daa5d459216296d8b
|
4
|
+
data.tar.gz: 25a97a07fdbefc8d1e60d7af5099c8d9d2d2918a8114e0f69303b79687d35e43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
23
|
-
- Rails >= 5.
|
24
|
-
- PostgreSQL >=
|
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
|
-
|
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::
|
3
|
-
|
4
|
-
|
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
|
8
|
+
@current_organization ||= current_user&.organization
|
8
9
|
end
|
9
10
|
end
|
10
11
|
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,
|
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
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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)
|