cats_core 1.3.28 → 1.3.32

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: 83f9bfdc22317ca433717055d41463cf8d70aed78994c62a9a924bcead85c561
4
- data.tar.gz: ffcb5a3122bd29126aa6902388af57a8979b414fa8378f5bd9f4c364aea6029d
3
+ metadata.gz: 5ac9b1b8f8a818f2992adf7b2d3fc5ce78340ae1f3ad092c05c90211c52a2d38
4
+ data.tar.gz: 4e2a4269952f62ac0293ac354fe2d84ca4e894b326a8bce6b65b00aa534242ba
5
5
  SHA512:
6
- metadata.gz: 5b77e70633822f0dcc6db6caedd36c1f7baecd232b466a1bc975c02b29c32e7129fd6d767e800a5dd1c7b17ff9e2da9250f74d136797591a9c19043b07bddd8d
7
- data.tar.gz: 2d29e1087a864c93d57a050f5fa6df3ff993abd63b060604f88bc7d2df282aa94ca5f48e1183b852a2974c1e5c0b36d5fd94082f3517181f1a2023363fb819bb
6
+ metadata.gz: 26fbde7964902e432c4c08ce116466052732a66d6b592139426276fd33ab872d8ad8431cd86652d3026a7faa7c2799952f2ffa30ae7a2599c8e49f2e89a0d217
7
+ data.tar.gz: a2097e28a69ea6cdd93f38c58eb8fe7a41e92c2fa5cb0c816e5def3cf7233c53a7d03c7830fa254e17481537be3e82685795f215e50e6ecbed6b949cccb11a01
@@ -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
@@ -19,7 +19,7 @@ module Cats
19
19
  validates :unit_of_measure, presence: true, if: -> { donation_type == KIND }
20
20
 
21
21
  delegate(:name, to: :donor, prefix: true)
22
- delegate(:reference_no, to: :plan, prefix: true)
22
+ delegate(:reference_no, to: :plan, prefix: true, allow_nil: true)
23
23
  delegate(:name, to: :commodity_category, prefix: true, allow_nil: true)
24
24
  delegate(:code, to: :currency, prefix: true, allow_nil: true)
25
25
  delegate(:abbreviation, to: :unit_of_measure, prefix: true, allow_nil: true)
@@ -11,6 +11,7 @@ module Cats
11
11
  validates :quantity, numericality: { greater_than: 0 }
12
12
 
13
13
  delegate(:name, to: :commodity_category, prefix: true)
14
+ delegate(:name, to: :destination_warehouse, prefix: true)
14
15
  delegate(:abbreviation, to: :unit_of_measure, prefix: true)
15
16
 
16
17
  before_validation :set_commodity_category
@@ -0,0 +1,38 @@
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
+ delegate(:plan_reference_no, to: :dispatch_plan_item)
18
+ delegate(:full_name, to: :authorized_by, prefix: true)
19
+ delegate(:name, to: :store, prefix: true)
20
+
21
+ def validate_quantity
22
+ return unless quantity
23
+
24
+ return unless dispatch_plan_item
25
+
26
+ total = dispatch_plan_item.quantity
27
+ used = HubAuthorization.where(
28
+ dispatch_plan_item: dispatch_plan_item,
29
+ authorization_type: authorization_type
30
+ ).sum(:quantity)
31
+ used -= quantity_was if quantity_was
32
+
33
+ remaining = total - used
34
+ errors.add(:quantity, "exceeds allocated quantity. Maximum allowed is #{remaining}") if quantity > remaining
35
+ end
36
+ end
37
+ end
38
+ 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.28'.freeze
3
+ VERSION = '1.3.32'.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.28
4
+ version: 1.3.32
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-18 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