cats_core 1.4.23 → 1.4.26

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: 3c58aa13420d9d6df2e5954237e8d8fbfef4db3d620636a49bba9ba2c6d30eb2
4
- data.tar.gz: 6ff8e9bc22538cef900ed1e4ef1d80620699f5b94df2bbf8771f37cf4b0367b1
3
+ metadata.gz: 67116f414334d42cf370f7a2ec48cf137bd1ac0c8d1345e0ce5c99f8fc87c57c
4
+ data.tar.gz: 0fc96065462743887b84a6bc750f97d52bd1f047a32c71fa1b70bb3eda9148cb
5
5
  SHA512:
6
- metadata.gz: caf7a1b4209a0405e22dbf86736424ce82f577ded281348911faed27a1cbc9e232c35eea14cdb768d2655aaa8dcce9fda5362ac3c60ec088b13522a191eeabbc
7
- data.tar.gz: 2992ab176cd20d2e82a56ac9fc178d5aa06cc8870aa67c5c545f42804c9d31dc082203ef5cdebae968b69aee147689056d06401cffe35f4d566d0c5026bf470c
6
+ metadata.gz: 148225081058c17d1435f7888da4076ecfacb458a37154e64fd5eabe1fb3470cc3ff4fcafa696db893eb3d3a70ad90920cb25b408723fd4140b3a6e1f70d02ea
7
+ data.tar.gz: a7ee6bc61afe79bfbb22d65a02852ea00a0872971c023fd0783f30de6f33b59eb47a4807887b239aa8e54996eca58924fdae8321c73c1af2db078e193f39067d
@@ -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
@@ -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,10 +119,16 @@ 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
@@ -129,6 +136,7 @@ Cats::Core::Engine.routes.draw do
129
136
  get 'lost', controller: :lost_commodities, action: :index
130
137
  get 'receipts', controller: :receipts, action: :index
131
138
  post 'confirm', controller: :receipt_authorizations, action: :confirm
139
+ post 'stack'
132
140
  end
133
141
  end
134
142
 
@@ -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.23'.freeze
3
+ VERSION = '1.4.26'.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.23
4
+ version: 1.4.26
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