cats_core 1.5.15 → 1.5.17

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: 6457c97964fc710efb411ae032843b88a46ce765fbf60464599f792c93207b67
4
- data.tar.gz: 1b53f9c80054286052e21d6b10177b4811c358a4dc6e38cd71c5fb1a794807e6
3
+ metadata.gz: 289a8b8aee41d9ad997ac46f363357ebb9961d983aaac22cd234133fb40a4e7e
4
+ data.tar.gz: c2f3f4c71adbf4d2ffd07fd427d25afda5814459ca6217085882f5b2056049b1
5
5
  SHA512:
6
- metadata.gz: 8acd12651e100d5ebdf42c37aaaaca6d2aff0925a8fe54c44ae10d329a62ca2dc391b19d35fc66fb4955b9de822ebcb6edecead4a9b642ac6f0c7ca682088375
7
- data.tar.gz: 0fbaee0d078bb58773c7e0f0be993b50a922b441a6d08b7f55bf9b843642c85aa098c83b1ce491f7cf718877488852c87762eceb049ee66dddda813853c7878e
6
+ metadata.gz: a48354b502b466fefb8b346eb4cad0453630dac9803afd10737b33e475b7d532c213f8425a29e91658c8b2aacf4a46bb2568eec41d67ff0e4586d10700dfdfac
7
+ data.tar.gz: f7b6788c688d1f6e95a1c182a083a24f6738db33d40ec11dfdc1899c3fe2c8b30b1f413ae489faeb61846974c3f2b5ffe4c74050ca52af20dbb68a1925d3ac18
@@ -9,6 +9,16 @@ module Cats
9
9
  end
10
10
  end
11
11
 
12
+ def create
13
+ authorization = DispatchAuthorization.new(model_params)
14
+ if authorization.save
15
+ AuthorizationService.new.send_dispatch_notification(authorization)
16
+ render json: { success: true, data: serialize(authorization) }, status: :created
17
+ else
18
+ render json: { success: false, error: authorization.errors.full_messages[0] }, status: :unprocessable_entity
19
+ end
20
+ end
21
+
12
22
  def confirm
13
23
  authorization = DispatchAuthorization.find(params[:id])
14
24
  authorization = authorization.confirm
@@ -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_receipt_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
@@ -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,10 +44,10 @@ module Cats
42
44
  update!(status: APPROVED)
43
45
  end
44
46
 
45
- def reserve
46
- raise(StandardError, 'Plan is not approved.') unless status == APPROVED
47
+ def in_progress
48
+ raise(StandardError, 'Plan is not approved.') unless status == APPROVED || status == IN_PROGRESS
47
49
 
48
- self.status = RESERVED
50
+ self.status = IN_PROGRESS
49
51
  save!
50
52
  end
51
53
 
@@ -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 DispatchAuthorizationNotification < Noticed::Base
4
+ deliver_by :database
5
+
6
+ param :dispatch_authorization
7
+
8
+ def message
9
+ authorization = params[:dispatch_authorization]
10
+ dispatch = authorization.dispatch
11
+ commodity = dispatch.dispatch_plan_item.commodity
12
+ title = "Dispatch Authorization Notification - #{commodity.name}"
13
+ date = Date.today
14
+
15
+ body = <<~BODY
16
+ Commodity with the following details is ordered to be dispatched from your store:
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,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,40 @@ module Cats
95
95
  quantity: item.quantity
96
96
  }
97
97
  end
98
+
99
+ def send_receipt_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
115
+
116
+ def send_dispatch_notification(authorization)
117
+ notification_rule = NotificationRule.find_by(code: 'dispatch_authorization')
118
+ error = 'Notification rule not found for dispatch authorization notification.'
119
+ raise(StandardError, error) unless notification_rule
120
+
121
+ users = User.joins(:roles).where(cats_core_roles: { name: notification_rule.roles })
122
+ recipients = users.map do |user|
123
+ details = user.details
124
+
125
+ user if details.key?('stores') && details['stores'].include?(authorization.store_id)
126
+ end.compact
127
+ return if recipients.empty?
128
+
129
+ notification = DispatchAuthorizationNotification.with(dispatch_authorization: authorization)
130
+ notification.deliver(recipients)
131
+ end
98
132
  end
99
133
  end
100
134
  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
 
@@ -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.15'.freeze
3
+ VERSION = '1.5.17'.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.15
4
+ version: 1.5.17
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-30 00:00:00.000000000 Z
11
+ date: 2023-02-07 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
@@ -357,7 +358,10 @@ files:
357
358
  - app/models/cats/core/user.rb
358
359
  - app/models/concerns/cats/core/dispatchable.rb
359
360
  - app/notifications/cats/core/allocation_notification.rb
361
+ - app/notifications/cats/core/dispatch_authorization_notification.rb
360
362
  - app/notifications/cats/core/dispatch_notification.rb
363
+ - app/notifications/cats/core/receipt_authorization_notification.rb
364
+ - app/notifications/cats/core/round_plan_notification.rb
361
365
  - app/notifications/cats/core/simple_notification.rb
362
366
  - app/serializers/cats/core/cash_donation_serializer.rb
363
367
  - app/serializers/cats/core/commodity_category_serializer.rb
@@ -477,6 +481,7 @@ files:
477
481
  - db/migrate/20220923190857_create_cats_core_application_settings.rb
478
482
  - db/migrate/20221024081134_add_reference_no_to_cats_core_receipts.rb
479
483
  - db/migrate/20221024081141_add_reference_no_to_cats_core_dispatch_transactions.rb
484
+ - db/migrate/20230102064317_add_receipt_number_to_cats_core_receipt_transactions.rb
480
485
  - lib/cats/core.rb
481
486
  - lib/cats/core/engine.rb
482
487
  - lib/cats/core/version.rb