cats_core 1.4.24 → 1.4.27

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: 3dd00b147a4dfa4ab46e10d7961b4291fbdb39ed68e49a0766e69a4a4d22704a
4
- data.tar.gz: 1c37f11f41f76263cb197cdd881b820475a38e8addf1424fce593287ab1e30ad
3
+ metadata.gz: 9fddf0547d798ce7e1b0807f6a41c63d7b9d4cd65aa8647fcdfb67ca47326b41
4
+ data.tar.gz: 1784fbfd4ab5dd5af00f07c07dd2aef0f561d49381ab2bf8dbf4726dc9b3d85d
5
5
  SHA512:
6
- metadata.gz: ce78191aa4dde60ba521f32f95a87088f7e9380fcba3e3a05f2cb570c4fd722b6b1962ddff54ab76ea0278552b1640f3a72b0e96571e0160b096bc49b00abd56
7
- data.tar.gz: f5e36206d35c62b26cd16bdcaeea9f11c711d90c2c68b6f5c5eeb4e174621c4ad6e8ef28f0082ad74cb505e82bbc44876cd67da9be92b045beebfd0f22c1b269
6
+ metadata.gz: 45e67cd0b18c50abbd5d08698ad47312dfbc8b735327a3645906d16f60db5addb24edef7180a9adb2a1ce9c8ea69858e63dd600c3aaeb1767de3f022c3a2b598
7
+ data.tar.gz: d46af8e447713c4981e3b5d8796f246fc13c0a294b15239adbbeccede51b76e68f5e7d1d24ab9ecfb0f93f586f8f5d015396a0bc6dc51bca58d06ace5081f1c3
@@ -10,8 +10,8 @@ module Cats
10
10
  end
11
11
 
12
12
  def confirm
13
- service = AuthorizationService.new
14
- authorization = service.confirm(params[:id])
13
+ authorization = DispatchAuthorization.find(params[:id])
14
+ authorization = authorization.confirm
15
15
  render json: { success: true, data: serialize(authorization) }
16
16
  rescue StandardError => e
17
17
  render json: { success: false, error: e.message }
@@ -2,8 +2,8 @@ module Cats
2
2
  module Core
3
3
  class DispatchesController < ApplicationController
4
4
  include Common
5
-
6
- before_action :set_service, only: %i[create_receipt_authorization approve start search confirm]
5
+ skip_before_action :authenticate, only: %i[start_with_pin]
6
+ before_action :set_service, only: %i[create_receipt_authorization approve start start_with_pin search confirm]
7
7
 
8
8
  def index
9
9
  super do
@@ -35,6 +35,13 @@ module Cats
35
35
  render json: { success: false, error: e.message }
36
36
  end
37
37
 
38
+ def start_with_pin
39
+ dispatch = @service.start_with_pin(params[:id], start_with_pin_params[:pin])
40
+ render json: { success: true, data: serialize(dispatch) }
41
+ rescue StandardError => e
42
+ render json: { success: false, error: e.message }
43
+ end
44
+
38
45
  def confirm
39
46
  dispatch = set_object
40
47
  dispatch.confirm
@@ -68,6 +75,10 @@ module Cats
68
75
  params.require(:payload).permit(:reference_no, :dispatch_plan_item_id, :transporter_id, :plate_no, :unit_id,
69
76
  :driver_name, :driver_phone, :remark)
70
77
  end
78
+
79
+ def start_with_pin_params
80
+ params.require(:payload).permit(:pin)
81
+ end
71
82
  end
72
83
  end
73
84
  end
@@ -17,6 +17,23 @@ module Cats
17
17
  render json: { success: false, error: e.message }
18
18
  end
19
19
 
20
+ def stack
21
+ service = AuthorizationService.new
22
+ authorization = ReceiptAuthorization.find(params[:id])
23
+ authorization = service.stack(authorization.id)
24
+ render json: { success: true, data: serialize(authorization) }
25
+ rescue StandardError => e
26
+ render json: { success: false, error: e.message }
27
+ end
28
+
29
+ def storekeeper_authorizations
30
+ storekeeper = User.find(params[:id])
31
+ status = params[:status]
32
+ stores = storekeeper.stores
33
+ authorizations = ReceiptAuthorization.where(store: stores, status: status)
34
+ render json: { success: true, data: serialize(authorizations) }
35
+ end
36
+
20
37
  private
21
38
 
22
39
  def model_params
@@ -29,8 +29,8 @@ module Cats
29
29
 
30
30
  def receipt_stacks
31
31
  service = StackService.new
32
- receipt = Receipt.find(params[:id])
33
- stacks = service.receipt_stacks(receipt)
32
+ authorization = ReceiptAuthorization.find(params[:id])
33
+ stacks = service.receipt_stacks(authorization.id)
34
34
  render json: { success: true, data: serialize(stacks) }
35
35
  end
36
36
 
@@ -46,11 +46,19 @@ module Cats
46
46
 
47
47
  def confirm
48
48
  if instance_of?(DispatchAuthorization)
49
- raise(StandardError, 'Authorization does not have transactions.') if transactions.blank?
50
-
51
- transactions.each(&:commit)
52
- # count = transactions.where(status: Transaction::DRAFT).count
53
- # raise(StandardError, 'There are uncommitted transactions.') if count.positive?
49
+ ActiveRecord::Base.transaction do
50
+ raise(StandardError, 'Authorization does not have transactions.') if transactions.blank?
51
+
52
+ transactions.each(&:commit)
53
+ self.status = CONFIRMED
54
+ save!
55
+ if dispatch.all_authorizations_confirmed?
56
+ dispatch.generate_pin
57
+ dispatch.quantity = dispatch.dispatch_transactions.sum(:quantity)
58
+ dispatch.dispatch_status = Dispatch::READY_TO_START
59
+ dispatch.save!
60
+ end
61
+ end
54
62
  elsif instance_of?(ReceiptAuthorization)
55
63
  raise(StandardError, 'Authorization does not have receipts.') unless receipts.count.positive?
56
64
 
@@ -60,8 +68,16 @@ module Cats
60
68
  raise(StandardError, "A quantity of #{diff} is unaccounted for.") unless diff.zero?
61
69
 
62
70
  self.received_quantity = total_received
71
+ self.status = CONFIRMED
72
+ save!
73
+ generate_pin
63
74
  end
64
- self.status = CONFIRMED
75
+ self
76
+ end
77
+
78
+ def generate_pin
79
+ pin = SecureRandom.hex(10)
80
+ self.auth_details = { pin: pin, active: true, expires_at: DateTime.now + 1.hour }
65
81
  save!
66
82
  end
67
83
 
@@ -5,11 +5,10 @@ module Cats
5
5
  APPROVED = 'Approved'.freeze
6
6
  READY_TO_START = 'Ready to Start'.freeze
7
7
  STARTED = 'Started'.freeze
8
- ARRIVED = 'Arrived'.freeze
9
- UNLOADED = 'Unloaded'.freeze
10
8
  RECEIVED = 'Received'.freeze
9
+ STACKED = 'Stacked'.freeze
11
10
 
12
- DISPATCH_STATUSES = [DRAFT, APPROVED, READY_TO_START, STARTED, ARRIVED, UNLOADED, RECEIVED].freeze
11
+ DISPATCH_STATUSES = [DRAFT, APPROVED, READY_TO_START, STARTED, RECEIVED, STACKED].freeze
13
12
 
14
13
  belongs_to :prepared_by, class_name: 'Cats::Core::User'
15
14
  belongs_to :transporter
@@ -73,12 +72,24 @@ module Cats
73
72
  save!
74
73
  end
75
74
 
75
+ def receive
76
+ raise(StandardError, 'Dispatch is not started.') unless dispatch_status == Dispatch::STARTED
77
+
78
+ self.dispatch_status = RECEIVED
79
+ save!
80
+ end
81
+
82
+ def stack
83
+ self.dispatch_status = STACKED
84
+ save!
85
+ end
86
+
76
87
  def self.search_commodity(batch_no)
77
88
  commodity = Commodity.find_by(batch_no: batch_no)
78
89
  dispatches = Dispatch.includes(:dispatch_transactions)
79
90
  .joins(:transporter)
80
91
  .where(
81
- dispatch_status: [APPROVED, STARTED, ARRIVED, UNLOADED]
92
+ dispatch_status: [APPROVED, STARTED]
82
93
  )
83
94
  dispatches.map do |dispatch|
84
95
  {
@@ -92,6 +103,12 @@ module Cats
92
103
  }
93
104
  end
94
105
  end
106
+
107
+ def generate_pin
108
+ pin = SecureRandom.hex(10)
109
+ self.auth_details = { pin: pin, active: true, expires_at: DateTime.now + 1.hour }
110
+ save!
111
+ end
95
112
  end
96
113
  end
97
114
  end
@@ -2,7 +2,7 @@ module Cats
2
2
  module Core
3
3
  class DispatchAuthorizationSerializer < ActiveModel::Serializer
4
4
  attributes :id, :dispatch_id, :dispatch_reference_no, :store_id, :store_name, :quantity, :authorized_by_id,
5
- :authorizer_full_name, :dispatch_status, :plate_no, :driver_name
5
+ :authorizer_full_name, :dispatch_status, :plate_no, :driver_name, :status
6
6
  end
7
7
  end
8
8
  end
@@ -3,7 +3,7 @@ module Cats
3
3
  class DispatchSerializer < ActiveModel::Serializer
4
4
  attributes :id, :reference_no, :dispatch_plan_item_id, :transporter_id, :transporter_name, :plate_no,
5
5
  :driver_name, :driver_phone, :quantity, :remark, :prepared_by_id, :prepared_by_email,
6
- :dispatch_status, :destination
6
+ :dispatch_status, :destination, :auth_details
7
7
 
8
8
  def destination
9
9
  object.dispatch_plan_item.destination.name
@@ -2,7 +2,7 @@ module Cats
2
2
  module Core
3
3
  class ReceiptAuthorizationSerializer < ActiveModel::Serializer
4
4
  attributes :id, :dispatch_id, :dispatch_reference_no, :store_id, :store_name, :quantity, :received_quantity,
5
- :remark, :status, :authorized_by_id, :authorizer_full_name
5
+ :remark, :status, :authorized_by_id, :authorizer_full_name, :auth_details
6
6
  end
7
7
  end
8
8
  end
@@ -1,23 +1,45 @@
1
1
  module Cats
2
2
  module Core
3
3
  class AuthorizationService
4
- # A method to confirm a dispatch authorization. This method
5
- # also checks if all authorizations under a dispatch are confirmed
6
- # and if so it sets the dispatch status to READY_TO_START.
7
- def confirm(id)
8
- authorization = DispatchAuthorization.find(id)
9
-
10
- ActiveRecord::Base.transaction do
11
- authorization.confirm
12
-
13
- # Check if all authorizations under the dispatch are confirmed.
14
- dispatch = authorization.dispatch
15
- if dispatch.all_authorizations_confirmed?
16
- dispatch.quantity = dispatch.dispatch_transactions.sum(:quantity)
17
- dispatch.dispatch_status = Dispatch::READY_TO_START
18
- dispatch.save!
19
- end
4
+ def driver_confirm(authorization_id, pin)
5
+ authorization = ReceiptAuthorization.find(authorization_id)
6
+ if authorization.status == Authorization::AUTHORIZED
7
+ raise(StandardError, 'Authorization not confirmed by storekeeper.')
20
8
  end
9
+
10
+ raise(StandardError, 'No pin has been generated for receipt.') if authorization.auth_details.nil?
11
+
12
+ raise(StandardError, 'Incorrect pin.') unless pin == authorization.auth_details['pin']
13
+
14
+ raise(StandardError, 'Pin is not active.') unless authorization.auth_details['active']
15
+
16
+ if DateTime.now > authorization.auth_details['expires_at']
17
+ authorization.auth_details[:active] = false
18
+ authorization.save!
19
+ raise(StandardError, 'Pin has expired.')
20
+ end
21
+
22
+ authorization.driver_confirmed = true
23
+ authorization.save!
24
+ statuses = authorization.dispatch.receipt_authorizations.map(&:driver_confirmed).uniq
25
+ authorization.dispatch.receive if statuses.length == 1 && statuses[0]
26
+
27
+ authorization
28
+ end
29
+
30
+ def stack(authorization_id)
31
+ authorization = ReceiptAuthorization.find(authorization_id)
32
+ unless authorization.dispatch.dispatch_status == Dispatch::RECEIVED
33
+ raise(StandardError, 'Dispatch is not received.')
34
+ end
35
+
36
+ total = authorization.transactions.sum(:quantity)
37
+ if total != authorization.received_quantity
38
+ raise(StandardError, 'Received quantity is not the same as quantity to be stacked.')
39
+ end
40
+
41
+ authorization.transactions.each(&:commit)
42
+ authorization.dispatch.stack
21
43
  authorization
22
44
  end
23
45
  end
@@ -37,6 +37,28 @@ module Cats
37
37
  dispatch
38
38
  end
39
39
 
40
+ def start_with_pin(dispatch_id, pin)
41
+ dispatch = Dispatch.find(dispatch_id)
42
+ raise(StandardError, 'Dispatch is already started.') if dispatch.dispatch_status == Dispatch::STARTED
43
+
44
+ raise(StandardError, 'No pin has been generated for dispatch.') if dispatch.auth_details.nil?
45
+
46
+ raise(StandardError, 'Incorrect pin.') unless pin == dispatch.auth_details['pin']
47
+
48
+ raise(StandardError, 'Pin is not active.') unless dispatch.auth_details['active']
49
+
50
+ if DateTime.now > dispatch.auth_details['expires_at']
51
+ dispatch.auth_details[:active] = false
52
+ dispatch.save!
53
+ raise(StandardError, 'Pin has expired.')
54
+ end
55
+ dispatch.start
56
+ send_notification(dispatch)
57
+ dispatch.auth_details = nil
58
+ dispatch.save!
59
+ dispatch
60
+ end
61
+
40
62
  def send_notification(dispatch)
41
63
  notification_rule = Cats::Core::NotificationRule.find_by(code: 'dispatch')
42
64
  raise(StandardError, 'Notification rule not found for dispatch notification.') unless notification_rule
@@ -34,13 +34,10 @@ module Cats
34
34
  end
35
35
  end
36
36
 
37
- def receipt_stacks(receipt)
38
- location = receipt.dispatch.dispatch_plan_item.destination
39
- warehouses = location.children
40
- stores = Store.where(warehouse: warehouses)
41
-
42
- commodity = receipt.dispatch.dispatch_plan_item.commodity
43
- Stack.where(commodity: commodity, store: stores)
37
+ def receipt_stacks(authorization_id)
38
+ authorization = ReceiptAuthorization.find(authorization_id)
39
+ commodity = authorization.dispatch.dispatch_plan_item.commodity
40
+ Stack.where(commodity: commodity, store_id: authorization.store_id)
44
41
  end
45
42
 
46
43
  def dispatch_stacks(dispatch)
data/config/routes.rb CHANGED
@@ -107,6 +107,7 @@ Cats::Core::Engine.routes.draw do
107
107
  post 'approve'
108
108
  post 'start'
109
109
  post 'confirm'
110
+ post 'start_with_pin'
110
111
  end
111
112
  end
112
113
 
@@ -118,17 +119,25 @@ Cats::Core::Engine.routes.draw do
118
119
  end
119
120
 
120
121
  get(
121
- '/storekeeper/:id/authorizations',
122
+ '/storekeeper/:id/dispatch_authorizations',
122
123
  controller: :dispatch_authorizations,
123
124
  action: :storekeeper_authorizations,
124
- as: :storekeeper_authorizations
125
+ as: :storekeeper_dispatch_authorizations
126
+ )
127
+ get(
128
+ '/storekeeper/:id/receipt_authorizations',
129
+ controller: :receipt_authorizations,
130
+ action: :storekeeper_authorizations,
131
+ as: :storekeeper_receipt_authorizations
125
132
  )
126
133
  resources :receipt_authorizations, except: %i[index destroy] do
127
134
  member do
128
135
  get 'transactions', controller: :receipt_transactions, action: :index
129
136
  get 'lost', controller: :lost_commodities, action: :index
130
137
  get 'receipts', controller: :receipts, action: :index
138
+ get 'stacks', controller: :stacks, action: :receipt_stacks
131
139
  post 'confirm', controller: :receipt_authorizations, action: :confirm
140
+ post 'stack'
132
141
  end
133
142
  end
134
143
 
@@ -25,6 +25,7 @@ class CreateCatsCoreDispatches < ActiveRecord::Migration[6.1]
25
25
  index: { name: 'pb_on_dispatches_indx' },
26
26
  foreign_key: { to_table: :cats_core_users }
27
27
  t.string :dispatch_status, null: false
28
+ t.jsonb :auth_details
28
29
 
29
30
  t.timestamps
30
31
  end
@@ -13,6 +13,8 @@ class CreateCatsCoreReceiptAuthorizations < ActiveRecord::Migration[6.1]
13
13
  t.float :received_quantity, null: false, default: 0
14
14
  t.string :status, null: false, default: 'Authorized'
15
15
  t.string :remark
16
+ t.jsonb :auth_details
17
+ t.boolean :driver_confirmed, null: false, default: false
16
18
  t.references :authorized_by,
17
19
  null: false,
18
20
  index: { name: 'ab_on_receipt_authorizations_indx' },
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.4.24'.freeze
3
+ VERSION = '1.4.27'.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.4.24
4
+ version: 1.4.27
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-05-28 00:00:00.000000000 Z
11
+ date: 2022-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers