cats_core 1.3.29 → 1.3.30

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80cc6224c33fc3ce6d25d558a188ae7db720f032ae1dd18c39d2f74f67257eab
4
- data.tar.gz: d866310b1bc91bc269538f80b9f944e3a2a4e1b6338490c209a74d343d897214
3
+ metadata.gz: c112c544d162d0328402147a79d75517f52343b90a2b88e68c467e6538b48c56
4
+ data.tar.gz: 42109ceb645c5b50202888495c3da96baffc0b61e516c979ce909ae2e6291ee7
5
5
  SHA512:
6
- metadata.gz: f79355635f4c3fe924a112d88967a39140c47dd864b6ee3bb565093e8ec6768c8d973695dad89c822a69f2ae1bd5ff77e3650a7a05b4073ebeb73cb60ed04065
7
- data.tar.gz: 0c66c37c48a2791a5726b107d840dcaddb6012f79d8998839d7995535cde0e5e89ca0b0198e5d0da5431d8a4e6e6fedd238c244e2816ae6f7ad24e897f3e17cc
6
+ metadata.gz: aa66e8fcfd14abd48c36d7d923b002bbc399ab6959ec5b56210f918c1fc2a1ab25cfd54807f026641fb8d74142dee9a005f4bb9719bdf654f6af1b3de74eaa16
7
+ data.tar.gz: ccfa85eb0ec3a870608678107c8e23721b2b41d637d0c2b61140c6b71d66d25e9240fef59a1e2ee88b77077c681a85dde90beedc380dd42555d97a01663a10c4
@@ -55,6 +55,8 @@ module Cats
55
55
  @user.add_detail(:warehouse, params[:warehouse_id])
56
56
  when 'hub_manager'
57
57
  @user.add_detail(:hub, params[:hub_id])
58
+ when 'regional_manager'
59
+ @user.add_detail(:region, params[:region_id])
58
60
  end
59
61
 
60
62
  data = ActiveModelSerializers::SerializableResource.new(role)
@@ -64,7 +66,7 @@ module Cats
64
66
  def revoke_role
65
67
  role = Cats::Core::Role.find(params[:role_id])
66
68
  @user.roles.delete(role)
67
- @user.remove_detail(role.name) if %w[warehouse_manager hub_manager].include?(role.name)
69
+ @user.remove_detail(role.name) if %w[warehouse_manager hub_manager regional_manager].include?(role.name)
68
70
  data = ActiveModelSerializers::SerializableResource.new(role)
69
71
  render json: { success: true, data: data }
70
72
  end
@@ -1,13 +1,21 @@
1
1
  module Cats
2
2
  module Core
3
3
  class DispatchPlanItem < ApplicationRecord
4
+ AUTHORIZED = 'Authorized'.freeze
5
+ SOURCE_AUTHORIZED = 'Source Authorized'.freeze
6
+ DESTINATION_AUTHORIZED = 'Destination Authorized'.freeze
7
+ UNAUTHORIZED = 'Unauthorized'.freeze
8
+ STATUSES = [AUTHORIZED, DESTINATION_AUTHORIZED, SOURCE_AUTHORIZED, UNAUTHORIZED].freeze
9
+
4
10
  belongs_to :source, class_name: 'Cats::Core::Location'
5
11
  belongs_to :destination, class_name: 'Cats::Core::Location'
6
12
  belongs_to :dispatch_plan
7
13
  has_many :dispatches
14
+ has_many :hub_authorizations
8
15
 
9
- validates :commodity_status, presence: true, inclusion: { in: Cats::Core::Commodity::COMMODITY_STATUSES }
16
+ validates :commodity_status, presence: true, inclusion: { in: Commodity::COMMODITY_STATUSES }
10
17
  validates :quantity, presence: true, numericality: { greater_than: 0 }
18
+ validates :status, presence: true, inclusion: { in: STATUSES }
11
19
 
12
20
  delegate(:reference_no, to: :dispatch_plan, prefix: :plan, allow_nil: true)
13
21
  delegate(:commodity_batch_no, :commodity_name, to: :dispatch_plan)
@@ -15,6 +23,63 @@ module Cats
15
23
  delegate(:name, to: :destination, prefix: true)
16
24
  delegate(:location_type, to: :source, prefix: true)
17
25
  delegate(:location_type, to: :destination, prefix: true)
26
+
27
+ # Authorize a dispatch plan item if it contains authorization entries
28
+ # under it. A dispatch plan item can be authorized by source hub, or
29
+ # source and destination hub. Hence the status can be `SOURCE_AUTHORIZED`,
30
+ # `AUTHORIZED`, or `UNAUTHORIZED` (default). This method sets those authorization
31
+ # values without any other interference by looking at available data and therefore
32
+ # no parameters are required.
33
+ #
34
+ def authorize
35
+ count = hub_authorizations.count
36
+ raise(StandardError, 'No authorization entries found.') if count.zero?
37
+
38
+ source_auth = hub_authorizations.where(authorization_type: HubAuthorization::SOURCE)
39
+ dest_auth = hub_authorizations.where(authorization_type: HubAuthorization::DESTINATION)
40
+
41
+ if source_auth.count.positive? && dest_auth.count.zero? && status == SOURCE_AUTHORIZED
42
+ raise(
43
+ StandardError,
44
+ 'Plan item already authorized by source. Destination hub authorizations are required.'
45
+ )
46
+ end
47
+
48
+ if source_auth.count.zero? && dest_auth.count.positive? && status == DESTINATION_AUTHORIZED
49
+ raise(
50
+ StandardError,
51
+ 'Plan item already authorized by destination. Source hub authorizations are required.'
52
+ )
53
+ end
54
+
55
+ total_src = source_auth.sum(&:quantity)
56
+ total_dest = dest_auth.sum(&:quantity)
57
+
58
+ if source_auth.count == count
59
+ validate_quantity(total_src, SOURCE_AUTHORIZED)
60
+ self.status = SOURCE_AUTHORIZED
61
+ elsif dest_auth.count == count
62
+ validate_quantity(total_dest, DESTINATION_AUTHORIZED)
63
+ self.status = DESTINATION_AUTHORIZED
64
+ else
65
+ validate_quantity(total_src, SOURCE_AUTHORIZED)
66
+ validate_quantity(total_dest, DESTINATION_AUTHORIZED)
67
+ self.status = AUTHORIZED
68
+ end
69
+ save!
70
+ self
71
+ end
72
+
73
+ def validate_quantity(quantity, type)
74
+ return if quantity == self.quantity
75
+
76
+ diff = self.quantity - quantity
77
+ desc = type.split(' ')[0].downcase
78
+ raise(
79
+ StandardError,
80
+ "Authorized #{desc} quantity is not the same as plan item quantity (#{diff} unaccounted for)."
81
+ )
82
+ end
18
83
  end
19
84
  end
20
85
  end
@@ -0,0 +1,34 @@
1
+ module Cats
2
+ module Core
3
+ class HubAuthorization < ApplicationRecord
4
+ SOURCE = 'Source'.freeze
5
+ DESTINATION = 'Destination'.freeze
6
+ AUTHORIZATION_TYPES = [SOURCE, DESTINATION].freeze
7
+
8
+ belongs_to :dispatch_plan_item, optional: true
9
+ belongs_to :store
10
+ belongs_to :authorized_by, class_name: 'Cats::Core::User'
11
+
12
+ validates :quantity, :authorization_type, presence: true
13
+ validates :quantity, numericality: { greater_than: 0 }
14
+ validates :authorization_type, inclusion: { in: AUTHORIZATION_TYPES }
15
+ validate :validate_quantity, on: %i[create update]
16
+
17
+ def validate_quantity
18
+ return unless quantity
19
+
20
+ return unless dispatch_plan_item
21
+
22
+ total = dispatch_plan_item.quantity
23
+ used = HubAuthorization.where(
24
+ dispatch_plan_item: dispatch_plan_item,
25
+ authorization_type: authorization_type
26
+ ).sum(:quantity)
27
+ used -= quantity_was if quantity_was
28
+
29
+ remaining = total - used
30
+ errors.add(:quantity, "exceeds allocated quantity. Maximum allowed is #{remaining}") if quantity > remaining
31
+ end
32
+ end
33
+ end
34
+ end
@@ -15,6 +15,7 @@ class CreateCatsCoreDispatchPlanItems < ActiveRecord::Migration[6.1]
15
15
  foreign_key: { to_table: :cats_core_locations }
16
16
  t.float :quantity, null: false
17
17
  t.string :commodity_status, null: false, default: 'Good'
18
+ t.string :status, null: false, default: 'Unauthorized'
18
19
 
19
20
  t.timestamps
20
21
  end
@@ -0,0 +1,22 @@
1
+ class CreateCatsCoreHubAuthorizations < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cats_core_hub_authorizations do |t|
4
+ t.references :dispatch_plan_item,
5
+ null: true,
6
+ index: { name: 'dpi_on_ha_indx' },
7
+ foreign_key: { to_table: :cats_core_dispatch_plan_items }
8
+ t.references :store,
9
+ null: false,
10
+ index: { name: 'store_on_ha_indx' },
11
+ foreign_key: { to_table: :cats_core_stores }
12
+ t.float :quantity, null: false
13
+ t.string :authorization_type, null: false
14
+ t.references :authorized_by,
15
+ null: false,
16
+ index: { name: 'ab_on_ha_indx' },
17
+ foreign_key: { to_table: :cats_core_users }
18
+
19
+ t.timestamps
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.3.29'.freeze
3
+ VERSION = '1.3.30'.freeze
4
4
  end
5
5
  end
@@ -5,5 +5,6 @@ FactoryBot.define do
5
5
  dispatch_plan
6
6
  quantity { 100 }
7
7
  commodity_status { Cats::Core::Commodity::GOOD }
8
+ status { Cats::Core::DispatchPlanItem::UNAUTHORIZED }
8
9
  end
9
10
  end
@@ -0,0 +1,9 @@
1
+ FactoryBot.define do
2
+ factory :hub_authorization, class: 'Cats::Core::HubAuthorization' do
3
+ dispatch_plan_item
4
+ store
5
+ quantity { 100 }
6
+ authorization_type { Cats::Core::HubAuthorization::SOURCE }
7
+ authorized_by factory: :user
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cats_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.29
4
+ version: 1.3.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henock L.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-05 00:00:00.000000000 Z
11
+ date: 2022-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -267,6 +267,7 @@ files:
267
267
  - app/models/cats/core/donation.rb
268
268
  - app/models/cats/core/donor.rb
269
269
  - app/models/cats/core/gift_certificate.rb
270
+ - app/models/cats/core/hub_authorization.rb
270
271
  - app/models/cats/core/location.rb
271
272
  - app/models/cats/core/menu.rb
272
273
  - app/models/cats/core/menu_item.rb
@@ -391,6 +392,7 @@ files:
391
392
  - db/migrate/20220107124630_create_cats_core_monthly_rations.rb
392
393
  - db/migrate/20220107125025_create_cats_core_monthly_plan_items.rb
393
394
  - db/migrate/20220107132433_create_cats_core_monthly_plan_item_details.rb
395
+ - db/migrate/20220209083928_create_cats_core_hub_authorizations.rb
394
396
  - lib/cats/core.rb
395
397
  - lib/cats/core/engine.rb
396
398
  - lib/cats/core/version.rb
@@ -411,6 +413,7 @@ files:
411
413
  - spec/factories/cats/core/donations.rb
412
414
  - spec/factories/cats/core/donors.rb
413
415
  - spec/factories/cats/core/gift_certificates.rb
416
+ - spec/factories/cats/core/hub_authorizations.rb
414
417
  - spec/factories/cats/core/locations.rb
415
418
  - spec/factories/cats/core/menu_items.rb
416
419
  - spec/factories/cats/core/menus.rb