cats_core 1.5.14 → 1.5.16

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: 6e2ffcd4caf018a81ee3d83fabd7b7e20ddf97c9f6309a66a005805c78c41bc4
4
- data.tar.gz: 4d139393006f70306d84cbef40f273e1e578cf855783f63dc1ee37ff2d2e979f
3
+ metadata.gz: 279f9103030fd0c0a858e6d2d5c2f71b69644f17b3654b7e8cd6226deeefabb3
4
+ data.tar.gz: 58431c85a8824cd879b58f550fa28969b1f45bd9ba04cb16ab69553a6e01c3d3
5
5
  SHA512:
6
- metadata.gz: '0309049d3508085b5cacfb155388fab2de02480a91b7869b9b2f1f5e8a51e6f574a70955e04aaa8b9524fd3f374410a27c864217d524557015eaf08b293ff57c'
7
- data.tar.gz: 3667ef926f2952820d2b6c73c20fe3515ccdd411f7e8b91605e90f7e3bcaba7507611f74f76a2f389e4236eb96ca63ab4e6ef10da74c146b97b753dc5dec595f
6
+ metadata.gz: e3f8d565b6b939cadff349df0add73ba2e50ae4eef45629d412748754e307aaf7952b69bf3138232c549c560766f23e8dcfbceb5b14ae3f7b3ddccb9c428ab92
7
+ data.tar.gz: e3d1c7576b48388d6f8144401218b47fd2d40b0320f1ffbe6f9ef674e70d2ab295aed46fb2ac6d9571ca0c99d611f529dc047d3e073bde557d9e02a9c726fb77
@@ -11,6 +11,16 @@ module Cats
11
11
  end
12
12
  end
13
13
 
14
+ def create
15
+ authorization = ReceiptAuthorization.new(model_params)
16
+ if authorization.save
17
+ AuthorizationService.new.send_notification(authorization)
18
+ render json: { success: true, data: serialize(authorization) }, status: :created
19
+ else
20
+ render json: { success: false, error: authorization.errors.full_messages[0] }, status: :unprocessable_entity
21
+ end
22
+ end
23
+
14
24
  def confirm
15
25
  authorization = ReceiptAuthorization.find(params[:id])
16
26
  authorization.confirm
@@ -18,8 +18,8 @@ module Cats
18
18
  private
19
19
 
20
20
  def model_params
21
- params.require(:payload).permit(:receipt_authorization_id, :destination_id, :transaction_date, :quantity,
22
- :unit_id)
21
+ params.require(:payload).permit(:receipt_authorization_id, :receipt_number, :destination_id,
22
+ :transaction_date, :quantity, :unit_id)
23
23
  end
24
24
  end
25
25
  end
@@ -0,0 +1,25 @@
1
+ module Cats
2
+ module Core
3
+ class StackTransactionsController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ super do
8
+ StackTransaction.joins({ source: :store }, :unit)
9
+ .where(cats_core_stacks: { cats_core_stores: { warehouse_id: params[:id] } })
10
+ end
11
+ end
12
+
13
+ def filter
14
+ query = StackTransaction.ransack(params[:q])
15
+ render json: { success: true, data: serialize(query.result) }
16
+ end
17
+
18
+ private
19
+
20
+ def model_params
21
+ params.require(:payload).permit(:source_id, :destination_id, :transaction_date, :quantity, :unit_id)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -25,6 +25,7 @@ module Cats
25
25
  store_keeper.details['stores'] ||= []
26
26
  store_keeper.details['stores'] += store_params[:store_ids]
27
27
  store_keeper.save!
28
+
28
29
  render json: { success: true, data: serialize(store_keeper) }
29
30
  end
30
31
 
@@ -23,16 +23,17 @@ module Cats
23
23
  end
24
24
 
25
25
  after_save do |plan|
26
- plan.dispatchable&.reserve if status == DRAFT
26
+ plan.dispatchable&.complete if status == DRAFT && dispatchable.instance_of?(RhnRequest)
27
+ plan.dispatchable&.in_progress if status == DRAFT && dispatchable.instance_of?(RoundPlan)
27
28
  end
28
29
 
29
30
  def validate_dispatchable
30
- # Check if dispatchable is already reserved and raise error if so.
31
+ # Check if dispatchable is already completed and raise error if so.
31
32
  return unless dispatchable
32
33
 
33
34
  return if dispatchable.status == RhnRequest::APPROVED
34
35
 
35
- errors.add(:dispatchable, 'is already reserved.') if id.nil? && dispatchable.status == Dispatchable::RESERVED
36
+ errors.add(:dispatchable, 'is already completed.') if id.nil? && dispatchable.status == Dispatchable::COMPLETED
36
37
  end
37
38
 
38
39
  def approve
@@ -7,7 +7,7 @@ module Cats
7
7
  belongs_to :dispatch_authorization
8
8
 
9
9
  validates :source_id, uniqueness: { scope: :dispatch_authorization_id }
10
- validates :reference_no, presence: true
10
+ # validates :reference_no, presence: true
11
11
  validate :validate_dispatch
12
12
  validate :validate_source_quantity, :validate_authorized_quantity, unless: :skip_quantity_validation
13
13
 
@@ -9,7 +9,7 @@ module Cats
9
9
  validates :commodity_status, presence: true, inclusion: { in: Commodity::COMMODITY_STATUSES }
10
10
  validates :commodity_grade, inclusion: { in: Commodity::COMMODITY_GRADES }, allow_nil: true
11
11
  validates :quantity, presence: true, numericality: { greater_than: 0 }
12
- validates :reference_no, presence: true
12
+ # validates :reference_no, presence: true
13
13
  validate :validate_quantity
14
14
 
15
15
  delegate(:abbreviation, to: :unit, prefix: true)
@@ -8,6 +8,7 @@ module Cats
8
8
 
9
9
  validates :transaction_date, presence: true
10
10
  validates :quantity, presence: true, numericality: { greater_than: 0 }
11
+ validates :receipt_number, presence: true
11
12
  validate :validate_receipt, :validate_quantity
12
13
 
13
14
  delegate(:code, to: :destination, prefix: true)
@@ -67,15 +67,15 @@ module Cats
67
67
  save!
68
68
  end
69
69
 
70
- def reserve
70
+ def complete
71
71
  raise(StandardError, 'Request is not approved.') unless status == APPROVED
72
72
 
73
- self.status = RESERVED
73
+ self.status = COMPLETED
74
74
  save!
75
75
  end
76
76
 
77
77
  def allocate
78
- raise(StandardError, 'Request is not reserved.') unless status == RESERVED
78
+ raise(StandardError, 'Request is not completed.') unless status == COMPLETED
79
79
 
80
80
  self.status = ALLOCATED
81
81
  save!
@@ -4,8 +4,10 @@ module Cats
4
4
  include Dispatchable
5
5
 
6
6
  NEEDS_APPROVED = 'Needs Approved'.freeze
7
+ IN_PROGRESS = 'In Progress'.freeze
7
8
 
8
9
  STATUSES << NEEDS_APPROVED
10
+ STATUSES << IN_PROGRESS
9
11
 
10
12
  belongs_to :plan
11
13
  belongs_to :region, class_name: 'Cats::Core::Location'
@@ -42,17 +44,17 @@ module Cats
42
44
  update!(status: APPROVED)
43
45
  end
44
46
 
45
- def reserve
47
+ def in_progress
46
48
  raise(StandardError, 'Plan is not approved.') unless status == APPROVED
47
49
 
48
- self.status = RESERVED
50
+ self.status = IN_PROGRESS
49
51
  save!
50
52
  end
51
53
 
52
54
  def validate_rounds
53
55
  return unless rounds && plan
54
56
 
55
- errors.add(:rounds, 'cannot be an empty list') if rounds.length.zero?
57
+ errors.add(:rounds, 'cannot be an empty list') if rounds.empty?
56
58
 
57
59
  existing_rounds = plan.round_plans.where(region: region).map(&:rounds).sum([])
58
60
  rounds.each do |round|
@@ -6,7 +6,8 @@ module Cats
6
6
  belongs_to :unit_of_measure
7
7
  belongs_to :round_plan
8
8
 
9
- validates :quantity, :no_of_days, presence: true, numericality: { greater_than: 0 }
9
+ validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 }
10
+ validates :no_of_days, presence: true, numericality: { greater_than: 0 }
10
11
 
11
12
  delegate(:name, to: :commodity_category, prefix: true)
12
13
  delegate(:name, to: :beneficiary_category, prefix: true)
@@ -29,7 +29,7 @@ module Cats
29
29
  delegate :batch_no, to: :commodity, prefix: true
30
30
  delegate :abbreviation, to: :unit, prefix: true
31
31
 
32
- after_save :update_store_space
32
+ after_save :update_store_space, :destroy_stack
33
33
 
34
34
  def validate_coordinates
35
35
  return unless store.present? && length.present? && width.present? && start_x.present? && start_y.present?
@@ -169,6 +169,13 @@ module Cats
169
169
  }
170
170
  end
171
171
  end
172
+
173
+ def destroy_stack
174
+ return unless stack_status == Cats::Core::Stack::ALLOCATED && quantity.zero?
175
+
176
+ self.stack_status = Cats::Core::Stack::DESTROYED
177
+ save!
178
+ end
172
179
  end
173
180
  end
174
181
  end
@@ -1,6 +1,6 @@
1
1
  # A concern to represent entities that lead to dispatch plan.
2
2
  # All classes including this concern must implement `request_reference()`,
3
- # `reserve()`, and `request_quantity()` methods, which will be used to generate
3
+ # `complete()`, and `request_quantity()` methods, which will be used to generate
4
4
  # reference information in dispatch plan serializer.
5
5
  module Cats
6
6
  module Core
@@ -9,10 +9,10 @@ module Cats
9
9
 
10
10
  DRAFT = 'Draft'.freeze
11
11
  APPROVED = 'Approved'.freeze
12
- RESERVED = 'Reserved'.freeze
12
+ COMPLETED = 'Completed'.freeze
13
13
 
14
14
  # rubocop:disable Style/MutableConstant
15
- STATUSES = [DRAFT, APPROVED, RESERVED]
15
+ STATUSES = [DRAFT, APPROVED, COMPLETED]
16
16
  # rubocop:enable Style/MutableConstant
17
17
 
18
18
  included do
@@ -0,0 +1,31 @@
1
+ module Cats
2
+ module Core
3
+ class ReceiptAuthorizationNotification < Noticed::Base
4
+ deliver_by :database
5
+
6
+ param :receipt_authorization
7
+
8
+ def message
9
+ authorization = params[:receipt_authorization]
10
+ dispatch = authorization.dispatch
11
+ commodity = dispatch.dispatch_plan_item.commodity
12
+ title = "Receipt Authorization Notification - #{commodity.name}"
13
+ date = Date.today
14
+
15
+ body = <<~BODY
16
+ Commodity with the following details has been dispatched to you:
17
+ Authorization no. = #{dispatch.dispatch_plan_item.reference_no}
18
+ Dispatch Ref. = #{dispatch.reference_no}
19
+ Batch No. = #{commodity.batch_no}
20
+ Commodity = #{commodity.name}
21
+ Quantity = #{authorization.quantity}
22
+ Unit = #{authorization.unit.abbreviation}
23
+ Truck Plate No. = #{dispatch.plate_no}
24
+ Driver Name = #{dispatch.driver_name}
25
+ Driver Phone = #{dispatch.driver_phone}
26
+ BODY
27
+ { title: title, date: date, body: body }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ module Cats
2
+ module Core
3
+ class RoundPlanNotification < Noticed::Base
4
+ deliver_by :database
5
+
6
+ param :round_plan
7
+
8
+ def message
9
+ round_plan = params[:round_plan]
10
+ plan = round_plan.plan
11
+ title = "Round Plan - #{round_plan.reference_no}"
12
+ date = Date.today
13
+ body = <<~BODY
14
+ A round plan with the following specifications needs your approval:
15
+ Reference No. = #{round_plan.reference_no}
16
+ Status = #{round_plan.status}
17
+ Region = #{round_plan.region.name}
18
+ Rounds = #{round_plan.rounds}
19
+ Program = #{plan.program.name}
20
+ Year = #{plan.year}
21
+ Season = #{plan.season}
22
+ BODY
23
+ { title: title, date: date, body: body }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,7 +1,8 @@
1
1
  module Cats
2
2
  module Core
3
3
  class ReceiptTransactionSerializer < ActiveModel::Serializer
4
- attributes :id, :receipt_authorization_id, :dispatch_reference_no, :destination_id, :destination_code, :quantity,
4
+ attributes :id, :receipt_authorization_id, :receipt_number,
5
+ :dispatch_reference_no, :destination_id, :destination_code, :quantity,
5
6
  :transaction_date, :status, :unit_id, :unit_abbreviation
6
7
  end
7
8
  end
@@ -95,6 +95,23 @@ module Cats
95
95
  quantity: item.quantity
96
96
  }
97
97
  end
98
+
99
+ def send_notification(authorization)
100
+ notification_rule = NotificationRule.find_by(code: 'receipt_authorization')
101
+ error = 'Notification rule not found for receipt authorization notification.'
102
+ raise(StandardError, error) unless notification_rule
103
+
104
+ users = User.joins(:roles).where(cats_core_roles: { name: notification_rule.roles })
105
+ recipients = users.map do |user|
106
+ details = user.details
107
+
108
+ user if details.key?('stores') && details['stores'].include?(authorization.store_id)
109
+ end.compact
110
+ return if recipients.empty?
111
+
112
+ notification = ReceiptAuthorizationNotification.with(receipt_authorization: authorization)
113
+ notification.deliver(recipients)
114
+ end
98
115
  end
99
116
  end
100
117
  end
@@ -96,6 +96,7 @@ module Cats
96
96
  }
97
97
  end
98
98
  Cats::Core::BeneficiaryRoundPlanItem.insert_all!(ben_round_plan_items, record_timestamps: true)
99
+ send_approval_notification(round_plan)
99
100
  round_plan
100
101
  end
101
102
 
@@ -186,8 +187,38 @@ module Cats
186
187
  else
187
188
  plan.approve
188
189
  end
190
+ send_approved_notification(plan)
189
191
  plan
190
192
  end
193
+
194
+ def send_approval_notification(round_plan)
195
+ notification_rule = NotificationRule.find_by(code: 'round_plan_approval')
196
+ error = 'Notification rule not found for round plan approval notification.'
197
+ raise(StandardError, error) unless notification_rule
198
+
199
+ users = User.joins(:roles).where(cats_core_roles: { name: notification_rule.roles })
200
+ return if users.empty?
201
+
202
+ notification = RoundPlanNotification.with(round_plan: round_plan)
203
+ notification.deliver(users)
204
+ end
205
+
206
+ def send_approved_notification(round_plan)
207
+ notification_rule = NotificationRule.find_by(code: 'round_plan_approved')
208
+ error = 'Notification rule not found for round plan approved notification.'
209
+ raise(StandardError, error) unless notification_rule
210
+
211
+ users = User.joins(roles: :application_module).where(
212
+ cats_core_roles: {
213
+ name: notification_rule.roles,
214
+ cats_core_application_modules: { prefix: 'CATS-TMS' }
215
+ }
216
+ )
217
+ return if users.empty?
218
+
219
+ notification = RoundPlanNotification.with(round_plan: round_plan)
220
+ notification.deliver(users)
221
+ end
191
222
  end
192
223
  end
193
224
  end
data/config/routes.rb CHANGED
@@ -56,6 +56,9 @@ Cats::Core::Engine.routes.draw do
56
56
  to: 'spaces#available_space',
57
57
  as: :warehouse_space,
58
58
  defaults: { level: Cats::Core::SpaceService::WAREHOUSE }
59
+ get '/warehouses/:id/stack_transactions',
60
+ to: 'stack_transactions#index',
61
+ as: :warehouse_stack_transactions
59
62
  get '/stores/:id/space',
60
63
  to: 'spaces#available_space',
61
64
  as: :store_space,
@@ -184,6 +187,7 @@ Cats::Core::Engine.routes.draw do
184
187
  resources :dispatch_transactions, except: %i[index new edit destroy]
185
188
  post '/receipt_transactions/filter', controller: :receipt_transactions, action: :filter
186
189
  resources :receipt_transactions, except: %i[index new edit destroy]
190
+ resources :stack_transactions, except: %i[index new edit destroy]
187
191
  resources :lost_commodities, except: %i[index destroy]
188
192
  get '/plans/:id/round_plans', controller: :round_plans, action: :index, as: :round_plans_plan
189
193
 
@@ -1,5 +1,5 @@
1
1
  class AddReferenceNoToCatsCoreReceipts < ActiveRecord::Migration[7.0]
2
2
  def change
3
- add_column :cats_core_receipts, :reference_no, :string, null: false
3
+ add_column :cats_core_receipts, :reference_no, :string, null: true
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  class AddReferenceNoToCatsCoreDispatchTransactions < ActiveRecord::Migration[7.0]
2
2
  def change
3
- add_column :cats_core_dispatch_transactions, :reference_no, :string, null: false
3
+ add_column :cats_core_dispatch_transactions, :reference_no, :string, null: true
4
4
  end
5
5
  end
@@ -0,0 +1,5 @@
1
+ class AddReceiptNumberToCatsCoreReceiptTransactions < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :cats_core_receipt_transactions, :receipt_number, :string
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.5.14'.freeze
3
+ VERSION = '1.5.16'.freeze
4
4
  end
5
5
  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.5.14
4
+ version: 1.5.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henock L.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-29 00:00:00.000000000 Z
11
+ date: 2023-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -270,6 +270,7 @@ files:
270
270
  - app/controllers/cats/core/round_plans_controller.rb
271
271
  - app/controllers/cats/core/routes_controller.rb
272
272
  - app/controllers/cats/core/spaces_controller.rb
273
+ - app/controllers/cats/core/stack_transactions_controller.rb
273
274
  - app/controllers/cats/core/stacks_controller.rb
274
275
  - app/controllers/cats/core/stores_controller.rb
275
276
  - app/controllers/cats/core/swaps_controller.rb
@@ -358,6 +359,8 @@ files:
358
359
  - app/models/concerns/cats/core/dispatchable.rb
359
360
  - app/notifications/cats/core/allocation_notification.rb
360
361
  - app/notifications/cats/core/dispatch_notification.rb
362
+ - app/notifications/cats/core/receipt_authorization_notification.rb
363
+ - app/notifications/cats/core/round_plan_notification.rb
361
364
  - app/notifications/cats/core/simple_notification.rb
362
365
  - app/serializers/cats/core/cash_donation_serializer.rb
363
366
  - app/serializers/cats/core/commodity_category_serializer.rb
@@ -477,6 +480,7 @@ files:
477
480
  - db/migrate/20220923190857_create_cats_core_application_settings.rb
478
481
  - db/migrate/20221024081134_add_reference_no_to_cats_core_receipts.rb
479
482
  - db/migrate/20221024081141_add_reference_no_to_cats_core_dispatch_transactions.rb
483
+ - db/migrate/20230102064317_add_receipt_number_to_cats_core_receipt_transactions.rb
480
484
  - lib/cats/core.rb
481
485
  - lib/cats/core/engine.rb
482
486
  - lib/cats/core/version.rb