cats_core 1.3.27 → 1.3.31

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: 1076d840160f1faee39901d7f1d9ccf7926c0413739ebed870a740c66f2e2f08
4
- data.tar.gz: cfb54300abc22e4889a0cd75c83c47bf355f089cf84ca7645f743ee65ea4b69a
3
+ metadata.gz: bf517b4f0fd512472ced053c4f283d19c661fe849c7331163cf6e321ddd5ebe6
4
+ data.tar.gz: 7b09f3a11ad9ef8d5ded20a2c5e7d4b7b09b1e27a06565462fc5f59d7fed163e
5
5
  SHA512:
6
- metadata.gz: 6e68a5e3f35ea31220701ca97df067eb03a16983ff8b32431b7a04c415d1ca1ea09b1943149cd098d52b3c704ca2a5ca0b9ca363e2bc3db5a92d1871e2202a11
7
- data.tar.gz: 5d90ebf4ed67ee13e9a351e7feea4d90429f6299e40a7349d23faf033ec1a41bcf6aed6c7023bb965451378d28242675c6af099a0d67d331ca053466b624f1c7
6
+ metadata.gz: '0818b51b0f8b75240043aff989521a71d641be5b4c4a0dc7eec7c47f40643a867c692cdee3faca3adc279503df252a2e2d68d453ec3f7a230f9f06a42d6b537e'
7
+ data.tar.gz: dfe92285182fd027eb1f0d87186e3a122301c0d611748bb05708d76891e1dc8832b56c0b3ea8ab44adc557a0a3b27b99b6981ae815c4e7331bcce9c44c28d984
@@ -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
@@ -4,12 +4,14 @@ module Cats
4
4
  belongs_to :donation, optional: true
5
5
  belongs_to :commodity_category
6
6
  belongs_to :unit_of_measure
7
+ belongs_to :destination_warehouse, class_name: 'Cats::Core::Location'
7
8
 
8
9
  validates :reference_no, presence: true, uniqueness: true
9
- validates :gift_date, :quantity, presence: true
10
+ validates :gift_date, :quantity, :requested_by, :request_reference, presence: true
10
11
  validates :quantity, numericality: { greater_than: 0 }
11
12
 
12
13
  delegate(:name, to: :commodity_category, prefix: true)
14
+ delegate(:name, to: :destination_warehouse, prefix: true)
13
15
  delegate(:abbreviation, to: :unit_of_measure, prefix: true)
14
16
 
15
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
@@ -4,6 +4,7 @@ class CreateCatsCoreDonations < ActiveRecord::Migration[6.1]
4
4
  t.string :reference_no, unique: true
5
5
  t.string :description
6
6
  t.string :donation_type, null: false
7
+ t.string :shipping_reference
7
8
  t.date :donated_on, null: false
8
9
  t.string :agency, null: false
9
10
  t.references :donor,
@@ -24,8 +24,15 @@ class CreateCatsCoreGiftCertificates < ActiveRecord::Migration[6.1]
24
24
  null: false,
25
25
  index: { name: 'uom_on_gc_indx' },
26
26
  foreign_key: { to_table: :cats_core_unit_of_measures }
27
+ t.references :destination_warehouse,
28
+ null: false,
29
+ index: { name: 'dw_on_gc_indx' },
30
+ foreign_key: { to_table: :cats_core_locations }
27
31
  t.float :estimated_price
28
32
  t.float :estimated_tax
33
+ t.string :registration_no
34
+ t.string :requested_by, null: false
35
+ t.string :request_reference, null: false
29
36
 
30
37
  t.timestamps
31
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.27'.freeze
3
+ VERSION = '1.3.31'.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
@@ -3,6 +3,7 @@ FactoryBot.define do
3
3
  reference_no { FFaker::Name.name }
4
4
  description { FFaker::Name.name }
5
5
  donation_type { Cats::Core::Donation::KIND }
6
+ shipping_reference { FFaker::Name.name }
6
7
  donated_on { Date.today }
7
8
  agency { 'WFP' }
8
9
  donor
@@ -5,6 +5,7 @@ FactoryBot.define do
5
5
  donation
6
6
  commodity_category { donation.commodity_category }
7
7
  unit_of_measure
8
+ destination_warehouse factory: :warehouse
8
9
  vessel { FFaker::Name.name }
9
10
  port { FFaker::Name.name }
10
11
  customs_declaration_no { FFaker::Name.name }
@@ -14,5 +15,8 @@ FactoryBot.define do
14
15
  quantity { 1.5 }
15
16
  estimated_price { 1.5 }
16
17
  estimated_tax { 1.5 }
18
+ registration_no { FFaker::Name.name }
19
+ requested_by { FFaker::Name.name }
20
+ request_reference { FFaker::Name.name }
17
21
  end
18
22
  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.27
4
+ version: 1.3.31
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