cats_core 1.3.29 → 1.3.30

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: 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