cats_core 1.3.36 → 1.3.39

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/cats/core/commodities_controller.rb +41 -0
  3. data/app/controllers/cats/core/dispatch_plan_items_controller.rb +5 -0
  4. data/app/controllers/cats/core/dispatch_transactions_controller.rb +22 -2
  5. data/app/controllers/cats/core/dispatches_controller.rb +0 -8
  6. data/app/controllers/cats/core/lost_commodities_controller.rb +2 -2
  7. data/app/controllers/cats/core/monthly_plans_controller.rb +62 -0
  8. data/app/controllers/cats/core/receipt_transactions_controller.rb +3 -3
  9. data/app/controllers/cats/core/receipts_controller.rb +8 -18
  10. data/app/controllers/cats/core/stacks_controller.rb +37 -0
  11. data/app/controllers/cats/core/transporters_controller.rb +5 -0
  12. data/app/models/cats/core/dispatch.rb +16 -10
  13. data/app/models/cats/core/dispatch_transaction.rb +3 -2
  14. data/app/models/cats/core/lost_commodity.rb +1 -1
  15. data/app/models/cats/core/receipt.rb +2 -2
  16. data/app/models/cats/core/receipt_transaction.rb +19 -1
  17. data/app/models/cats/core/stack.rb +1 -0
  18. data/app/models/cats/core/stack_transaction.rb +11 -0
  19. data/app/models/cats/core/transaction.rb +14 -9
  20. data/app/serializers/cats/core/commodity_category_serializer.rb +5 -1
  21. data/app/serializers/cats/core/dispatch_plan_item_serializer.rb +2 -1
  22. data/app/serializers/cats/core/dispatch_transaction_serializer.rb +1 -1
  23. data/app/serializers/cats/core/lost_commodity_serializer.rb +1 -1
  24. data/app/serializers/cats/core/monthly_plan_serializer.rb +8 -0
  25. data/app/serializers/cats/core/receipt_transaction_serializer.rb +3 -3
  26. data/app/serializers/cats/core/stack_serializer.rb +8 -0
  27. data/app/services/cats/core/dispatch_plan_service.rb +21 -1
  28. data/app/services/cats/core/dispatch_service.rb +17 -80
  29. data/app/services/cats/core/monthly_plan_service.rb +86 -0
  30. data/app/services/cats/core/receipt_service.rb +23 -1
  31. data/app/services/cats/core/stack_service.rb +59 -0
  32. data/config/routes.rb +33 -5
  33. data/db/migrate/20210718045516_create_cats_core_dispatches.rb +1 -1
  34. data/db/migrate/20210718202957_create_cats_core_dispatch_transactions.rb +1 -1
  35. data/db/migrate/{20220221041505_create_cats_core_lost_commodities.rb → 20210728041505_create_cats_core_lost_commodities.rb} +3 -3
  36. data/db/migrate/20210814160628_create_cats_core_receipt_transactions.rb +1 -1
  37. data/lib/cats/core/version.rb +1 -1
  38. data/spec/factories/cats/core/dispatch_transactions.rb +10 -2
  39. data/spec/factories/cats/core/dispatches.rb +9 -1
  40. data/spec/factories/cats/core/lost_commodities.rb +1 -1
  41. data/spec/factories/cats/core/receipt_transactions.rb +23 -3
  42. data/spec/factories/cats/core/receipts.rb +1 -2
  43. metadata +10 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7d2738616bb04e122c03cb503fe91bb1d8cb818c2ef909516d2e506efcad01c
4
- data.tar.gz: 7363415368111fa228b7d552f030bdce90009940c62365a27b9408d29745a21b
3
+ metadata.gz: 16a8d6fe8ce3bada8611add7e2b8669608072f40609445223966652619c16844
4
+ data.tar.gz: 291b4d451c1027375e203245717680ae5419306ef01707c40abdb66d3ec880c0
5
5
  SHA512:
6
- metadata.gz: c04a0d21b349fe67c2367204df7dc876bd0ec250753124873583b387f035fe1290a7bb503f8aad9184dd8df6fddd787aaa785fd0f1e281e12c4b0f2a6320871f
7
- data.tar.gz: d0104ee1c25f2fa50e196c0daa671c30fbed484cb370116919bc01403e68d736595a0ab17c83f2b2f0921bff87d319840035f99ee6cfd3d20c55d93817a29595
6
+ metadata.gz: eab2450cce0646b1914dc800938af63f96eea3439c8377a35c2eaef56574d970dcaded1c250b9bf1d59be929b7a428fce9a790f3956adeab6461f0ec94074ffd
7
+ data.tar.gz: 663adc2701e5fc8a374eb037b66fba8116049f2c49b5d7a7d09640de12b90d55150387db85113f5a6a047792f24a098a83918ab48a0898e32f6a782cb314e1ba
@@ -0,0 +1,41 @@
1
+ module Cats
2
+ module Core
3
+ class CommoditiesController < ApplicationController
4
+ include Common
5
+
6
+ def approve
7
+ commodity = Cats::Core::Commodity.find(params[:id])
8
+ result = commodity.approve
9
+ render json: { success: result, data: serialize(commodity) }
10
+ rescue StandardError => e
11
+ render json: { success: false, error: e.message }
12
+ end
13
+
14
+ def update
15
+ if @obj.status == Cats::Core::Commodity::APPROVED
16
+ render json: { success: false, error: 'An approved record cannot be edited.' }
17
+ return
18
+ end
19
+
20
+ if @obj.update(model_params)
21
+ render json: { success: true, data: serialize(@obj) }
22
+ else
23
+ render json: { success: false, error: @obj.errors.full_messages[0] }, status: :unprocessable_entity
24
+ end
25
+ end
26
+
27
+ def filter
28
+ query = Cats::Core::Commodity.ransack(params[:q])
29
+ render json: { success: true, data: serialize(query.result) }
30
+ end
31
+
32
+ private
33
+
34
+ def model_params
35
+ params.require(:payload).permit(:batch_no, :description, :unit_of_measure_id, :source_id,
36
+ :source_type, :quantity, :best_use_before, :volume_per_metric_ton,
37
+ :arrival_status)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -8,6 +8,11 @@ module Cats
8
8
  render json: { success: true, data: serialize(items) }
9
9
  end
10
10
 
11
+ def filter
12
+ query = Cats::Core::DispatchPlanItem.ransack(params[:q])
13
+ render json: { success: true, data: serialize(query.result) }
14
+ end
15
+
11
16
  private
12
17
 
13
18
  def model_params
@@ -4,14 +4,34 @@ module Cats
4
4
  include Common
5
5
 
6
6
  def index
7
- transactions = Cats::Core::DispatchTransaction.where(destination_id: params[:id])
7
+ transactions = Cats::Core::DispatchTransaction.where(dispatch_id: params[:id])
8
8
  render json: { success: true, data: serialize(transactions) }
9
9
  end
10
10
 
11
+ # This end-point is used to create upstream dispatch transactions.
12
+ # We need a specific method like this because for upstream the source
13
+ # stack is a dummy one and we need to use that without waiting for the
14
+ # user to give us a source.
15
+ def create_allocation
16
+ dispatch = Dispatch.find(model_params[:dispatch_id])
17
+ commodity = dispatch.dispatch_plan_item.dispatch_plan.commodity
18
+ transaction = DispatchTransaction.new(model_params)
19
+
20
+ # Fetch supplier stack by commodity
21
+ stack = Stack.joins(:store).find_by(commodity: commodity, store: { code: 'SUP-STORE' })
22
+ transaction.source = stack
23
+
24
+ if transaction.save
25
+ render json: { success: true, data: serialize(transaction) }, status: :created
26
+ else
27
+ render json: { success: false, error: transaction.errors.full_messages[0] }, status: :unprocessable_entity
28
+ end
29
+ end
30
+
11
31
  private
12
32
 
13
33
  def model_params
14
- params.require(:payload).permit(:source_id, :destination_id, :transaction_date, :quantity)
34
+ params.require(:payload).permit(:source_id, :dispatch_id, :transaction_date, :quantity)
15
35
  end
16
36
  end
17
37
  end
@@ -22,14 +22,6 @@ module Cats
22
22
  end
23
23
  end
24
24
 
25
- def create_receipt_authorization
26
- item = Cats::Core::DispatchPlanItem.find(params[:id])
27
- dispatch = @service.create_receipt_authorization(
28
- params[:reference_no], item, params[:quantity], params[:remark], current_user
29
- )
30
- render json: { success: true, data: serialize(dispatch) }
31
- end
32
-
33
25
  def approve
34
26
  @dispatch.approve
35
27
  render json: { success: true, data: serialize(@dispatch) }
@@ -4,12 +4,12 @@ module Cats
4
4
  include Common
5
5
 
6
6
  def index
7
- data = LostCommodity.where(receipt_id: params[:id])
7
+ data = LostCommodity.where(dispatch_id: params[:id])
8
8
  render json: { success: true, data: serialize(data) }
9
9
  end
10
10
 
11
11
  def model_params
12
- params.require(:payload).permit(:receipt_id, :quantity, :commodity_status, :remark)
12
+ params.require(:payload).permit(:dispatch_id, :quantity, :commodity_status, :remark)
13
13
  end
14
14
  end
15
15
  end
@@ -0,0 +1,62 @@
1
+ module Cats
2
+ module Core
3
+ class MonthlyPlansController < ApplicationController
4
+ include Common
5
+
6
+ before_action :set_service, only: %i[generate remove_items generate_monthly_needs]
7
+
8
+ def index
9
+ plans = Cats::Core::MonthlyPlan.where(plan: params[:id])
10
+ render json: { success: true, data: serialize(plans) }
11
+ end
12
+
13
+ def filter
14
+ query = Cats::Core::MonthlyPlan.ransack(params[:q])
15
+ render json: { success: true, data: serialize(query.result) }
16
+ end
17
+
18
+ def approve
19
+ plan = Cats::Core::MonthlyPlan.find(params[:id])
20
+ if plan.monthly_plan_items.count.zero?
21
+ render json: { success: false, error: 'Empty plan cannot be approved.' }, status: :unprocessable_entity
22
+ return
23
+ end
24
+ plan.update(status: Cats::Core::Plan::APPROVED)
25
+ render json: { success: true, data: serialize(plan) }
26
+ end
27
+
28
+ def generate
29
+ plan = @service.generate_monthly_plan(model_params)
30
+ render json: { success: true, data: serialize(plan) }
31
+ end
32
+
33
+ def generate_monthly_needs
34
+ plan = @service.generate_monthly_needs(params[:id])
35
+ render json: { success: true, data: serialize(plan) }
36
+ rescue StandardError => e
37
+ render json: { success: false, error: e.message }
38
+ end
39
+
40
+ def remove_items
41
+ plan = @service.remove_items(params[:id], remove_params)
42
+ render json: { success: true, data: serialize(plan) }
43
+ rescue StandardError => e
44
+ render json: { success: false, error: e.message }
45
+ end
46
+
47
+ private
48
+
49
+ def model_params
50
+ params.require(:payload).permit(:reference_no, :status, :plan_id, :region_id, :month, :no_of_days)
51
+ end
52
+
53
+ def set_service
54
+ @service = MonthlyPlanService.new
55
+ end
56
+
57
+ def remove_params
58
+ params.permit(ids: [])
59
+ end
60
+ end
61
+ end
62
+ end
@@ -4,7 +4,7 @@ module Cats
4
4
  include Common
5
5
 
6
6
  def index
7
- transactions = Cats::Core::ReceiptTransaction.where(source_id: params[:id])
7
+ transactions = Cats::Core::ReceiptTransaction.where(receipt_id: params[:id])
8
8
  render json: { success: true, data: serialize(transactions) }
9
9
  end
10
10
 
@@ -13,7 +13,7 @@ module Cats
13
13
 
14
14
  # Look for a transaction with the same destination as incoming
15
15
  transaction = Cats::Core::ReceiptTransaction.find_by(
16
- source_id: p[:source_id],
16
+ receipt_id: p[:receipt_id],
17
17
  destination_id: p[:destination_id]
18
18
  )
19
19
  if transaction
@@ -32,7 +32,7 @@ module Cats
32
32
  private
33
33
 
34
34
  def model_params
35
- params.require(:payload).permit(:source_id, :destination_id, :transaction_date, :quantity)
35
+ params.require(:payload).permit(:receipt_id, :destination_id, :transaction_date, :quantity)
36
36
  end
37
37
  end
38
38
  end
@@ -9,26 +9,16 @@ module Cats
9
9
  end
10
10
 
11
11
  def create
12
- p = model_params
13
- receipt = Cats::Core::Receipt.find_by(
14
- dispatch_id: p[:dispatch_id],
15
- commodity_status: p[:commodity_status]
16
- )
17
- if receipt
18
- receipt.quantity += p[:quantity]
19
- if receipt.save
20
- render json: { success: true, data: serialize(receipt) }
21
- else
22
- render json: { success: false, error: receipt.errors.full_messages[0] }, status: :unprocessable_entity
23
- end
12
+ service = ReceiptService.new
13
+ receipt = service.init(model_params)
14
+
15
+ if receipt.save
16
+ render json: { success: true, data: serialize(receipt) }
24
17
  else
25
- obj = Cats::Core::Receipt.new(model_params)
26
- if obj.save
27
- render json: { success: true, data: serialize(obj) }, status: :created
28
- else
29
- render json: { success: false, error: obj.errors.full_messages[0] }, status: :unprocessable_entity
30
- end
18
+ render json: { success: false, error: receipt.errors.full_messages[0] }, status: :unprocessable_entity
31
19
  end
20
+ rescue StandardError => e
21
+ render json: { success: false, error: e.message }
32
22
  end
33
23
 
34
24
  def start_stacking
@@ -0,0 +1,37 @@
1
+ module Cats
2
+ module Core
3
+ class StacksController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ stacks = Stack.where(store_id: params[:id])
8
+ render json: { success: true, data: serialize(stacks) }
9
+ end
10
+
11
+ def filter
12
+ query = Stack.where(store_id: params[:id]).ransack(params[:q])
13
+ render json: { success: true, data: serialize(query.result) }
14
+ end
15
+
16
+ def commodity_for_location
17
+ service = StackService.new
18
+ commodities = service.commodity_for_location(current_user)
19
+ render json: { success: true, data: serialize(commodities) }
20
+ end
21
+
22
+ def receipt_stacks
23
+ service = StackService.new
24
+ receipt = Receipt.find(params[:id])
25
+ stacks = service.receipt_stacks(receipt)
26
+ render json: { success: true, data: serialize(stacks) }
27
+ end
28
+
29
+ private
30
+
31
+ def model_params
32
+ params.require(:payload).permit(:code, :length, :width, :height, :start_x, :start_y, :commodity_id, :store_id,
33
+ :commodity_status, :stack_status, :quantity)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -3,6 +3,11 @@ module Cats
3
3
  class TransportersController < ApplicationController
4
4
  include Cats::Core::Common
5
5
 
6
+ def filter
7
+ query = Cats::Core::Transporter.ransack(params[:q])
8
+ render json: { success: true, data: serialize(query.result) }
9
+ end
10
+
6
11
  private
7
12
 
8
13
  def model_params
@@ -14,17 +14,23 @@ module Cats
14
14
  belongs_to :transporter
15
15
  belongs_to :dispatch_plan_item
16
16
  has_many :receipts
17
+ has_many :dispatch_transactions
18
+ has_many :lost_commodities
17
19
 
18
20
  validates :reference_no, :plate_no, :driver_name, :driver_phone, :quantity, :commodity_status, presence: true
19
21
  validates :dispatch_status, presence: true, inclusion: { in: DISPATCH_STATUSES }
20
22
  validates :reference_no, uniqueness: true
21
- validates :quantity, numericality: { greater_than: 0 }
23
+ validates :quantity, numericality: { greater_than_or_equal_to: 0 }
22
24
  validates :commodity_status, inclusion: { in: Cats::Core::Commodity::COMMODITY_STATUSES }
23
25
  validate :validate_quantity, :validate_dispatch_plan_status
24
26
 
25
27
  delegate(:name, to: :transporter, prefix: true)
26
28
  delegate(:email, to: :prepared_by, prefix: true)
27
29
 
30
+ def total_quantity
31
+ dispatch_transactions.sum(:quantity)
32
+ end
33
+
28
34
  def validate_quantity
29
35
  return unless quantity && dispatch_plan_item
30
36
 
@@ -46,14 +52,16 @@ module Cats
46
52
  def approve
47
53
  raise(StandardError, 'Dispatch has to be in draft state.') unless dispatch_status == Dispatch::DRAFT
48
54
 
49
- count = DispatchTransaction.where(destination_id: id).count
50
- raise(StandardError, 'Dispatch has no transactions.') unless count.positive?
55
+ # Check if dispatch has transactions
56
+ raise(StandardError, 'Dispatch has no transactions.') unless dispatch_transactions.count.positive?
51
57
 
52
- quantity = DispatchTransaction.where(destination_id: id).sum(:quantity)
53
- raise(StandardError, 'Transactions quantity is not equal to dispatch quantity.') if self.quantity != quantity
54
-
55
- self.dispatch_status = Dispatch::APPROVED
56
- save!
58
+ Dispatch.transaction do
59
+ # Commit transactions
60
+ dispatch_transactions.each(&:commit)
61
+ self.quantity = total_quantity
62
+ self.dispatch_status = Dispatch::APPROVED
63
+ save!
64
+ end
57
65
  end
58
66
 
59
67
  def start
@@ -61,8 +69,6 @@ module Cats
61
69
 
62
70
  self.dispatch_status = Dispatch::STARTED
63
71
  save!
64
- transactions = DispatchTransaction.where(destination_id: id)
65
- transactions.each(&:commit)
66
72
  end
67
73
 
68
74
  def confirm
@@ -2,15 +2,16 @@ module Cats
2
2
  module Core
3
3
  class DispatchTransaction < Transaction
4
4
  belongs_to :source, class_name: 'Cats::Core::Stack'
5
- belongs_to :destination, class_name: 'Cats::Core::Dispatch'
5
+ belongs_to :dispatch
6
6
 
7
7
  delegate(:code, to: :source, prefix: true)
8
- delegate(:reference_no, to: :destination, prefix: true)
8
+ delegate(:reference_no, to: :dispatch, prefix: true)
9
9
 
10
10
  def commit
11
11
  Transaction.transaction do
12
12
  source.quantity -= quantity
13
13
  source.save!
14
+
14
15
  self.status = COMMITTED
15
16
  save!
16
17
  end
@@ -1,7 +1,7 @@
1
1
  module Cats
2
2
  module Core
3
3
  class LostCommodity < ApplicationRecord
4
- belongs_to :receipt
4
+ belongs_to :dispatch
5
5
 
6
6
  validates :quantity, presence: true
7
7
  validates :commodity_status, presence: true, inclusion: { in: Commodity::COMMODITY_STATUSES }
@@ -10,7 +10,7 @@ module Cats
10
10
 
11
11
  belongs_to :dispatch
12
12
  belongs_to :prepared_by, class_name: 'Cats::Core::User'
13
- has_many :receipt_transactions, foreign_key: :source_id
13
+ has_many :receipt_transactions
14
14
 
15
15
  validates :quantity, :commodity_status, :status, presence: true
16
16
  validates :quantity, numericality: { greater_than: 0 }
@@ -33,7 +33,7 @@ module Cats
33
33
  def validate_total_quantity
34
34
  return unless dispatch && quantity
35
35
 
36
- received = dispatch.receipts.sum(:quantity)
36
+ received = dispatch.receipts.sum(:quantity) + dispatch.lost_commodities.sum(:quantity)
37
37
  diff = dispatch.quantity - received
38
38
  diff += quantity_was if quantity_was
39
39
 
@@ -1,11 +1,29 @@
1
1
  module Cats
2
2
  module Core
3
3
  class ReceiptTransaction < Transaction
4
- belongs_to :source, class_name: 'Cats::Core::Receipt'
4
+ belongs_to :receipt
5
5
  belongs_to :destination, class_name: 'Cats::Core::Stack'
6
6
 
7
7
  delegate(:code, to: :destination, prefix: true)
8
8
 
9
+ def validate_quantity
10
+ return unless quantity.present? && destination.present? && receipt.present?
11
+
12
+ authorized = receipt.dispatch.dispatch_plan_item.hub_authorizations.where(
13
+ store: destination.store
14
+ ).sum(:quantity)
15
+ received = self.class.joins(:destination).where(
16
+ destination: { store_id: destination.store_id }
17
+ ).sum(:quantity)
18
+
19
+ received -= quantity_was if quantity_was
20
+
21
+ # Get quantity in hub authorization for source
22
+ available = authorized - received
23
+
24
+ errors.add(:quantity, "exceeds authorized quantity (Max = #{available}).") if quantity > available
25
+ end
26
+
9
27
  def commit
10
28
  ReceiptTransaction.transaction do
11
29
  destination.quantity += quantity
@@ -71,6 +71,7 @@ module Cats
71
71
  return unless store.present? && length.present? && width.present? && start_x.present? && start_y.present?
72
72
 
73
73
  stacks = store.stacks.where(stack_status: [RESERVED, ALLOCATED]).where.not(id: id)
74
+
74
75
  stacks.each do |s|
75
76
  errors.add(:base, message: "#{code} overlaps with #{s.code}") if overlaps?(self, s)
76
77
  end
@@ -3,6 +3,17 @@ module Cats
3
3
  class StackTransaction < Transaction
4
4
  belongs_to :source, class_name: 'Cats::Core::Stack'
5
5
  belongs_to :destination, class_name: 'Cats::Core::Stack'
6
+
7
+ def validate_quantity
8
+ return unless quantity.present? && source.present?
9
+
10
+ dispatched = StackTransaction.where(source: source, status: DRAFT).sum(:quantity)
11
+
12
+ available = source.quantity - dispatched
13
+ available += quantity_was if quantity_was
14
+
15
+ errors.add(:quantity, "total is higher than source quantity (Max = #{available}).") if quantity > available
16
+ end
6
17
  end
7
18
  end
8
19
  end
@@ -15,14 +15,19 @@ module Cats
15
15
  validate :validate_quantity, unless: :skip_quantity_validation
16
16
 
17
17
  def validate_quantity
18
- return unless quantity.present? && source.present?
18
+ return unless quantity.present? && source.present? && dispatch.present?
19
19
 
20
- dispatched = self.class.where(source: source, status: DRAFT).sum(:quantity)
20
+ dispatched = self.class.joins(:source, :dispatch).where(
21
+ source: { store_id: source.store_id },
22
+ dispatch: { dispatch_plan_item_id: dispatch.dispatch_plan_item_id }
23
+ ).sum(:quantity)
24
+ dispatched -= quantity_was if quantity_was
21
25
 
22
- available = source.quantity - dispatched
23
- available += quantity_was if quantity_was
26
+ # Get quantity in hub authorization for source
27
+ authorized = dispatch.dispatch_plan_item.hub_authorizations.where(store_id: source.store_id).sum(:quantity)
28
+ available = authorized - dispatched
24
29
 
25
- errors.add(:quantity, "total is higher than source quantity (Max = #{available}).") if quantity > available
30
+ errors.add(:quantity, "exceeds authorized quantity (Max = #{available}).") if quantity > available
26
31
  end
27
32
 
28
33
  def commit
@@ -33,12 +38,12 @@ module Cats
33
38
  # Quantity validation should be skipped if we are commiting transactions.
34
39
  (
35
40
  instance_of?(Cats::Core::DispatchTransaction) &&
36
- destination &&
37
- destination.dispatch_status == Cats::Core::Dispatch::STARTED
41
+ dispatch &&
42
+ status == COMMITTED
38
43
  ) || (
39
44
  instance_of?(Cats::Core::ReceiptTransaction) &&
40
- source &&
41
- source.status == Cats::Core::Receipt::STACKING
45
+ receipt &&
46
+ receipt.status == Cats::Core::Receipt::STACKING
42
47
  )
43
48
  end
44
49
 
@@ -1,7 +1,11 @@
1
1
  module Cats
2
2
  module Core
3
3
  class CommodityCategorySerializer < ActiveModel::Serializer
4
- attributes :id, :code, :name, :description, :parent_id
4
+ attributes :id, :code, :name, :description, :parent_id, :leaf
5
+
6
+ def leaf
7
+ !object.has_children?
8
+ end
5
9
  end
6
10
  end
7
11
  end
@@ -2,7 +2,8 @@ module Cats
2
2
  module Core
3
3
  class DispatchPlanItemSerializer < ActiveModel::Serializer
4
4
  attributes :id, :dispatch_plan_id, :plan_reference_no, :source_id, :source_name, :destination_id,
5
- :destination_name, :quantity, :source_location_type, :destination_location_type, :commodity_status
5
+ :destination_name, :quantity, :source_location_type, :destination_location_type, :commodity_status,
6
+ :status
6
7
  end
7
8
  end
8
9
  end
@@ -1,7 +1,7 @@
1
1
  module Cats
2
2
  module Core
3
3
  class DispatchTransactionSerializer < ActiveModel::Serializer
4
- attributes :id, :source_id, :source_code, :destination_id, :destination_reference_no, :quantity,
4
+ attributes :id, :source_id, :source_code, :dispatch_id, :dispatch_reference_no, :quantity,
5
5
  :transaction_date, :status
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module Cats
2
2
  module Core
3
3
  class LostCommoditySerializer < ActiveModel::Serializer
4
- attributes :id, :receipt_id, :quantity, :commodity_status, :remark
4
+ attributes :id, :dispatch_id, :quantity, :commodity_status, :remark
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,8 @@
1
+ module Cats
2
+ module Core
3
+ class MonthlyPlanSerializer < ActiveModel::Serializer
4
+ attributes :id, :reference_no, :status, :plan_id, :plan_reference_no, :region_id, :region_name, :month,
5
+ :no_of_days
6
+ end
7
+ end
8
+ end
@@ -1,11 +1,11 @@
1
1
  module Cats
2
2
  module Core
3
3
  class ReceiptTransactionSerializer < ActiveModel::Serializer
4
- attributes :id, :source_id, :dispatch_reference, :destination_id, :destination_code, :quantity, :transaction_date,
5
- :status
4
+ attributes :id, :receipt_id, :dispatch_reference, :destination_id, :destination_code, :quantity,
5
+ :transaction_date, :status
6
6
 
7
7
  def dispatch_reference
8
- object.source.dispatch.reference_no
8
+ object.receipt.dispatch.reference_no
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,8 @@
1
+ module Cats
2
+ module Core
3
+ class StackSerializer < ActiveModel::Serializer
4
+ attributes :id, :code, :length, :width, :height, :start_x, :start_y, :commodity_id, :store_id, :commodity_status,
5
+ :stack_status, :quantity, :commodity_batch_no
6
+ end
7
+ end
8
+ end
@@ -4,7 +4,27 @@ module Cats
4
4
  def approve(plan)
5
5
  plan.approve
6
6
 
7
- plan.dispatchable.allocate if plan.dispatchable_type == RhnRequest.name
7
+ if plan.upstream
8
+ # Create source hub authorizations for each item and
9
+ # put them in a `Source Authorized` state
10
+ store = Store.find_by(code: 'SUP-STORE')
11
+ keeper = User.find_by(first_name: 'SUP-Storekeeper')
12
+ authorizations = []
13
+ plan.dispatch_plan_items.each do |item|
14
+ authorizations << {
15
+ dispatch_plan_item_id: item.id,
16
+ store_id: store.id,
17
+ quantity: item.quantity,
18
+ authorization_type: HubAuthorization::SOURCE,
19
+ authorized_by_id: keeper.id,
20
+ created_at: Date.today,
21
+ updated_at: Date.today
22
+ }
23
+ end
24
+ HubAuthorization.insert_all(authorizations)
25
+ plan.dispatch_plan_items.update_all(status: DispatchPlanItem::SOURCE_AUTHORIZED)
26
+ plan.dispatchable.allocate
27
+ end
8
28
  # send_notification(plan)
9
29
  plan
10
30
  end
@@ -1,47 +1,6 @@
1
1
  module Cats
2
2
  module Core
3
3
  class DispatchService
4
- def create_receipt_authorization(reference_no, plan_item, quantity, remark, user)
5
- raise(StandardError, 'Dispatch plan is not an upstream plan.') unless plan_item.dispatch_plan.upstream?
6
-
7
- transporter = Cats::Core::Transporter.find_by(code: 'SUP-TRANS')
8
- raise(StandardError, 'Supplier transporter does not exist.') unless transporter
9
-
10
- store = Cats::Core::Store.find_by(code: 'SUP-STORE')
11
- raise(StandardError, 'Supplier store does not exist.') unless store
12
-
13
- commodity = plan_item.dispatch_plan.commodity
14
- stack = store.stacks.find_by(commodity: commodity)
15
-
16
- raise(StandardError, 'Commodity not found in supplier store.') unless stack
17
-
18
- dispatch = nil
19
- ApplicationRecord.transaction do
20
- dispatch = Cats::Core::Dispatch.create!(
21
- reference_no: reference_no,
22
- dispatch_plan_item: plan_item,
23
- transporter: transporter,
24
- plate_no: 'Supplier plate no',
25
- driver_name: 'Supplier driver',
26
- driver_phone: 'Supplier driver phone',
27
- quantity: quantity,
28
- remark: remark,
29
- prepared_by: user,
30
- dispatch_status: Cats::Core::Dispatch::DRAFT
31
- )
32
-
33
- # Create a dispatch transaction
34
- Cats::Core::DispatchTransaction.create!(
35
- source: stack,
36
- destination: dispatch,
37
- transaction_date: Date.today,
38
- quantity: quantity,
39
- status: Cats::Core::Transaction::DRAFT
40
- )
41
- end
42
- dispatch
43
- end
44
-
45
4
  def search(user, status)
46
5
  details = user.details
47
6
 
@@ -49,44 +8,20 @@ module Cats
49
8
  raise(StandardError, 'User does not have associated location.')
50
9
  end
51
10
 
52
- if details['stores']
53
- warehouse = Cats::Core::Store.find(details['stores'][0]).warehouse
54
- hub = warehouse.parent
55
-
56
- dispatches = Cats::Core::Dispatch.joins(:dispatch_plan_item)
57
- .where(
58
- dispatch_plan_item: { destination: hub },
59
- dispatch_status: status
60
- ).or(
61
- Cats::Core::Dispatch.joins(:dispatch_plan_item)
62
- .where(
63
- dispatch_plan_item: { destination: warehouse },
64
- dispatch_status: status
65
- )
66
- )
67
- elsif details['warehouse']
68
- warehouse = Cats::Core::Location.find(details['warehouse'])
69
- hub = warehouse.parent
70
- dispatches = Cats::Core::Dispatch.joins(:dispatch_plan_item)
71
- .where(
72
- dispatch_plan_item: { destination: hub },
73
- dispatch_status: status
74
- ).or(
75
- Cats::Core::Dispatch.joins(:dispatch_plan_item)
76
- .where(
77
- dispatch_plan_item: { destination: warehouse },
78
- dispatch_status: status
79
- )
80
- )
81
- elsif details['hub']
82
- hub = Cats::Core::Location.find(details['hub'])
83
- dispatches = Cats::Core::Dispatch.joins(:dispatch_plan_item)
84
- .where(
85
- dispatch_plan_item: { destination: hub },
86
- dispatch_status: status
87
- )
88
- end
89
- dispatches
11
+ # Get user's hub
12
+ hub = if details['stores']
13
+ Cats::Core::Store.find(details['stores'][0]).warehouse.parent
14
+ elsif details['warehouse']
15
+ Cats::Core::Location.find(details['warehouse']).parent
16
+ else
17
+ Cats::Core::Location.find(details['hub'])
18
+ end
19
+
20
+ Cats::Core::Dispatch.joins(:dispatch_plan_item)
21
+ .where(
22
+ dispatch_plan_item: { destination: hub },
23
+ dispatch_status: status
24
+ )
90
25
  end
91
26
 
92
27
  def start(dispatch)
@@ -101,9 +36,11 @@ module Cats
101
36
 
102
37
  users = Cats::Core::User.joins(:roles).where(cats_core_roles: { name: notification_rule.roles })
103
38
  location_id = dispatch.dispatch_plan_item.destination_id
39
+ hub = Cats::Core::Location.find(location_id)
104
40
  recipients = users.map do |user|
105
41
  details = user.details
106
- if (details.key?('warehouse') && details['warehouse'] == location_id) ||
42
+
43
+ if (details.key?('warehouse') && hub.child_ids.include?(details['warehouse'])) ||
107
44
  (details.key?('hub') && details['hub'] == location_id)
108
45
  user
109
46
  end
@@ -0,0 +1,86 @@
1
+ module Cats
2
+ module Core
3
+ class MonthlyPlanService
4
+ def generate_monthly_needs(plan_id)
5
+ plan = Cats::Core::MonthlyPlan.find(plan_id)
6
+ raise(StandardError, 'Plan has no rations.') if plan.monthly_rations.count.zero?
7
+
8
+ raise(StandardError, 'Plan has no plan items.') if plan.monthly_plan_items.count.zero?
9
+
10
+ plan.monthly_plan_item_details.delete_all if plan.monthly_plan_item_details.count.positive?
11
+
12
+ details = []
13
+ plan.monthly_plan_items.each do |plan_item|
14
+ plan.monthly_rations.each do |ration|
15
+ details << {
16
+ monthly_plan_item_id: plan_item.id,
17
+ monthly_ration_id: ration.id,
18
+ amount: (plan.no_of_days / ration.no_of_days * ration.amount) * plan_item.beneficiaries,
19
+ created_at: Date.today,
20
+ updated_at: Date.today
21
+ }
22
+ end
23
+ end
24
+
25
+ Cats::Core::MonthlyPlanItemDetail.insert_all!(details)
26
+ plan
27
+ end
28
+
29
+ def generate_monthly_plan(params)
30
+ region = Cats::Core::Location.find(params[:region_id])
31
+ plan = Cats::Core::Plan.includes(plan_items: :plan_item_details).find(params[:plan_id])
32
+ rations = Cats::Core::RationItem.where(ration_id: plan.ration_id)
33
+ monthly_plan = Cats::Core::MonthlyPlan.create!(
34
+ plan_id: plan.id,
35
+ reference_no: params[:reference_no],
36
+ region_id: params[:region_id],
37
+ status: Cats::Core::Plan::DRAFT,
38
+ month: params[:month],
39
+ no_of_days: params[:no_of_days]
40
+ )
41
+ ration_items = rations.map do |ration|
42
+ {
43
+ commodity_category_id: ration.commodity_category_id,
44
+ amount: ration.amount,
45
+ unit_of_measure_id: ration.unit_of_measure_id,
46
+ no_of_days: ration.no_of_days,
47
+ monthly_plan_id: monthly_plan.id,
48
+ created_at: Date.today,
49
+ updated_at: Date.today
50
+ }
51
+ end
52
+ Cats::Core::MonthlyRation.insert_all!(ration_items)
53
+
54
+ plan_items = plan.plan_items.where(woreda_id: region.descendant_ids).map do |plan_item|
55
+ {
56
+ monthly_plan_id: monthly_plan.id,
57
+ beneficiaries: plan_item.beneficiaries,
58
+ plan_item_id: plan_item.id,
59
+ created_at: Date.today,
60
+ updated_at: Date.today
61
+ }
62
+ end
63
+ Cats::Core::MonthlyPlanItem.insert_all!(plan_items)
64
+ monthly_plan
65
+ end
66
+
67
+ def remove_items(plan_id, ids)
68
+ raise(StandardError, 'No plan items specified.') if ids.count.zero?
69
+
70
+ begin
71
+ plan = Cats::Core::MonthlyPlan.find(plan_id)
72
+ rescue ActiveRecord::RecordNotFound
73
+ raise(StandardError, 'Monthly plan not found.') unless plan
74
+ end
75
+
76
+ plans = Cats::Core::MonthlyPlan.includes(:monthly_plan_items).where(monthly_plan_items: { id: ids })
77
+ raise(StandardError, 'Plan items should be from the same plan.') if plans.count > 1
78
+
79
+ raise(StandardError, 'Items are not from the given monthly plan.') unless plan_id == plans[0].id
80
+
81
+ Cats::Core::MonthlyPlanItem.delete_by(id: ids)
82
+ plan
83
+ end
84
+ end
85
+ end
86
+ end
@@ -16,11 +16,33 @@ module Cats
16
16
  raise(StandardError, 'Receipt should be in stacking state.')
17
17
  end
18
18
 
19
+ receipt.receipt_transactions.each(&:commit)
19
20
  receipt.status = Cats::Core::Receipt::STACKED
20
21
  receipt.save!
21
- receipt.receipt_transactions.each(&:commit)
22
22
  receipt
23
23
  end
24
+
25
+ def init(params)
26
+ receipt = Cats::Core::Receipt.find_by(
27
+ dispatch_id: params[:dispatch_id],
28
+ commodity_status: params[:commodity_status]
29
+ )
30
+
31
+ if receipt
32
+ # We can assume that the plan item is destination authorized.
33
+ # Therefore no need for checking destination authorization.
34
+ receipt.quantity += params[:quantity]
35
+ return receipt
36
+ end
37
+
38
+ # Check if plan item is destination authorized
39
+ dispatch = Dispatch.find(params[:dispatch_id])
40
+ status = dispatch.dispatch_plan_item.status
41
+ statuses = [DispatchPlanItem::DESTINATION_AUTHORIZED, DispatchPlanItem::AUTHORIZED]
42
+ raise(StandardError, 'Plan item is not destination authorized.') unless statuses.include?(status)
43
+
44
+ Receipt.new(params)
45
+ end
24
46
  end
25
47
  end
26
48
  end
@@ -0,0 +1,59 @@
1
+ module Cats
2
+ module Core
3
+ class StackService
4
+ def commodity_for_location(user)
5
+ details = user.details
6
+
7
+ key_available = details.keys.any? { |key| %w[stores warehouse hub].include?(key) }
8
+ raise(StandardError, 'User does not have associated location.') unless key_available
9
+
10
+ if details['hub']
11
+ hub = Cats::Core::Location.find(details['hub'])
12
+ allocation_items =
13
+ Cats::Core::AllocationItem
14
+ .joins(allocation: :commodity)
15
+ .where(destination: hub, allocation: { allocation_status: Cats::Core::Allocation::APPROVED })
16
+ else
17
+ if details['stores']
18
+ warehouse = Cats::Core::Store.find(details['stores'][0]).warehouse
19
+ hub = warehouse.parent
20
+ elsif details['warehouse']
21
+ warehouse = Cats::Core::Location.find(details['warehouse'])
22
+ hub = warehouse.parent
23
+ end
24
+ allocation_items =
25
+ Cats::Core::AllocationItem
26
+ .joins(allocation: :commodity)
27
+ .where(destination: hub, allocation: { allocation_status: Cats::Core::Allocation::APPROVED })
28
+ .or(
29
+ Cats::Core::AllocationItem
30
+ .joins(allocation: :commodity)
31
+ .where(destination: warehouse, allocation: { allocation_status: Cats::Core::Allocation::APPROVED })
32
+ )
33
+ end
34
+
35
+ allocation_items.map do |item|
36
+ {
37
+ reference_no: item.allocation.reference_no,
38
+ source: item.allocation.source.name,
39
+ destination: item.destination.name,
40
+ quantity: item.quantity,
41
+ batch_no: item.allocation.commodity.batch_no,
42
+ commodity_id: item.allocation.commodity_id,
43
+ commodity_name: item.allocation.commodity.name,
44
+ unit: item.allocation.commodity.unit_of_measure.abbreviation
45
+ }
46
+ end
47
+ end
48
+
49
+ def receipt_stacks(receipt)
50
+ location = receipt.dispatch.dispatch_plan_item.destination
51
+ warehouses = location.children
52
+ stores = Cats::Core::Store.where(warehouse: warehouses)
53
+
54
+ commodity = receipt.dispatch.dispatch_plan_item.dispatch_plan.commodity
55
+ Cats::Core::Stack.where(commodity: commodity, store: stores)
56
+ end
57
+ end
58
+ end
59
+ end
data/config/routes.rb CHANGED
@@ -65,8 +65,16 @@ Cats::Core::Engine.routes.draw do
65
65
  get 'children'
66
66
  end
67
67
  end
68
+ post '/commodities/filter', controller: :commodities, action: :filter
69
+ resources :commodities, except: %i[destroy] do
70
+ member do
71
+ post 'approve'
72
+ end
73
+ end
68
74
  resources :currencies, except: %i[destroy]
69
75
  resources :unit_of_measures, except: %i[destroy]
76
+
77
+ post '/transporters/filter', controller: :transporters, action: :filter
70
78
  resources :transporters, except: %i[destroy]
71
79
 
72
80
  post '/routes/filter', controller: :routes, action: :filter
@@ -82,32 +90,52 @@ Cats::Core::Engine.routes.draw do
82
90
 
83
91
  resources :dispatch_plan_items, except: %i[index destroy]
84
92
 
93
+ post '/dispatch_plan_items/filter', controller: :dispatch_plan_items, action: :filter
85
94
  get '/dispatch_plan_items/:id/dispatches', controller: :dispatches, action: :index, as: :dispatches_plan_item
86
- post '/dispatch_plan_items/:id/receipt_authorizaton',
87
- controller: :dispatches,
88
- action: :create_receipt_authorization,
89
- as: :receipt_authorization_plan_item
90
95
 
91
96
  get '/dispatches/search', controller: :dispatches, action: :search, as: :search_dispatches
92
97
  resources :dispatches, except: %i[index destroy] do
93
98
  member do
94
99
  get 'transactions', controller: :dispatch_transactions, action: :index
95
100
  get 'receipts', controller: :receipts, action: :index
101
+ get 'lost', controller: :lost_commodities, action: :index
96
102
  get 'commodity'
97
103
  post 'approve'
98
104
  post 'start'
99
105
  post 'confirm'
100
106
  end
101
107
  end
108
+
109
+ post(
110
+ 'dispatch_transactions/allocation',
111
+ controller: :dispatch_transactions,
112
+ action: :create_allocation,
113
+ as: :allocation_transaction
114
+ )
102
115
  resources :dispatch_transactions, except: %i[index new edit destroy]
103
116
  resources :receipts, except: %i[index new edit destroy] do
104
117
  member do
105
118
  get 'transactions', controller: :receipt_transactions, action: :index
106
- get 'lost', controller: :lost_commodities, action: :index
107
119
  post 'start_stacking'
108
120
  post 'finish_stacking'
109
121
  end
110
122
  end
111
123
  resources :receipt_transactions, except: %i[index new edit destroy]
112
124
  resources :lost_commodities, except: %i[index destroy]
125
+ get '/plans/:id/monthly_plans', controller: :monthly_plans, action: :index, as: :monthly_plans_plan
126
+ post '/monthly_plans/generate'
127
+ post '/monthly_plans/filter'
128
+ resources :monthly_plans, except: %i[index destroy] do
129
+ member do
130
+ post 'remove_items'
131
+ post 'generate_monthly_needs'
132
+ post 'approve'
133
+ end
134
+ end
135
+
136
+ get '/stores/:id/stacks', controller: :stacks, action: :index, as: :stacks_store
137
+ post '/stores/:id/stacks', controller: :stacks, action: :filter
138
+ get '/stacks/commodity_for_location', controller: :stacks, action: :commodity_for_location, as: :commodity_for_location
139
+ get '/receipts/:id/stacks', controller: :stacks, action: :receipt_stacks, as: :receipt_stacks
140
+ resources :stacks, only: %i[show index create update]
113
141
  end
@@ -13,7 +13,7 @@ class CreateCatsCoreDispatches < ActiveRecord::Migration[6.1]
13
13
  t.string :plate_no, null: false
14
14
  t.string :driver_name, null: false
15
15
  t.string :driver_phone, null: false
16
- t.float :quantity, null: false
16
+ t.float :quantity, null: false, default: 0
17
17
  t.string :commodity_status, null: false, default: 'Good'
18
18
  t.string :remark
19
19
  t.references :prepared_by,
@@ -5,7 +5,7 @@ class CreateCatsCoreDispatchTransactions < ActiveRecord::Migration[6.1]
5
5
  null: false,
6
6
  index: { name: 'stack_on_dt_indx' },
7
7
  foreign_key: { to_table: :cats_core_stacks }
8
- t.references :destination,
8
+ t.references :dispatch,
9
9
  null: false,
10
10
  index: { name: 'dispatch_on_dt_indx' },
11
11
  foreign_key: { to_table: :cats_core_dispatches }
@@ -1,10 +1,10 @@
1
1
  class CreateCatsCoreLostCommodities < ActiveRecord::Migration[7.0]
2
2
  def change
3
3
  create_table :cats_core_lost_commodities do |t|
4
- t.references :receipt,
4
+ t.references :dispatch,
5
5
  null: false,
6
- index: { name: 'lc_on_receipt_indx' },
7
- foreign_key: { to_table: :cats_core_receipts }
6
+ index: { name: 'lc_on_dispatch_indx' },
7
+ foreign_key: { to_table: :cats_core_dispatches }
8
8
  t.float :quantity, null: false
9
9
  t.string :commodity_status, null: false
10
10
  t.string :remark
@@ -1,7 +1,7 @@
1
1
  class CreateCatsCoreReceiptTransactions < ActiveRecord::Migration[6.1]
2
2
  def change
3
3
  create_table :cats_core_receipt_transactions do |t|
4
- t.references :source,
4
+ t.references :receipt,
5
5
  null: false,
6
6
  index: { name: 'receipt_on_rt_indx' },
7
7
  foreign_key: { to_table: :cats_core_receipts }
@@ -1,5 +1,5 @@
1
1
  module Cats
2
2
  module Core
3
- VERSION = '1.3.36'.freeze
3
+ VERSION = '1.3.39'.freeze
4
4
  end
5
5
  end
@@ -1,7 +1,15 @@
1
1
  FactoryBot.define do
2
2
  factory :dispatch_transaction, class: 'Cats::Core::DispatchTransaction' do
3
- source factory: :stack
4
- destination factory: :dispatch
3
+ transient do
4
+ stack { create(:stack) }
5
+ end
6
+ source { stack }
7
+ dispatch do
8
+ plan_item = create(:dispatch_plan_item, quantity: 100)
9
+ plan_item.dispatch_plan.approve
10
+ create(:hub_authorization, dispatch_plan_item: plan_item, quantity: 100, store: stack.store)
11
+ create(:dispatch, dispatch_plan_item: plan_item, transaction?: false)
12
+ end
5
13
  transaction_date { Date.today }
6
14
  quantity { 10 }
7
15
  status { Cats::Core::Transaction::DRAFT }
@@ -1,18 +1,26 @@
1
1
  FactoryBot.define do
2
2
  factory :dispatch, class: 'Cats::Core::Dispatch' do
3
+ transient do
4
+ stack { create(:stack, quantity: 100) }
5
+ transaction? { true }
6
+ end
3
7
  reference_no { FFaker::Name.name }
4
8
  dispatch_plan_item do
5
9
  plan_item = create(:dispatch_plan_item, quantity: 100)
6
10
  plan_item.dispatch_plan.approve
11
+ create(:hub_authorization, dispatch_plan_item: plan_item, quantity: 100, store: stack.store)
7
12
  plan_item
8
13
  end
9
14
  transporter
10
15
  plate_no { FFaker::Name.name }
11
16
  driver_name { FFaker::Name.name }
12
17
  driver_phone { FFaker::Name.name }
13
- quantity { 50 }
14
18
  remark { FFaker::Name.name }
15
19
  prepared_by factory: :user
16
20
  dispatch_status { Cats::Core::Dispatch::DRAFT }
21
+
22
+ after :create do |dispatch, options|
23
+ create(:dispatch_transaction, dispatch: dispatch, source: options.stack, quantity: 100) if options.transaction?
24
+ end
17
25
  end
18
26
  end
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :lost_commodity, class: 'Cats::Core::LostCommodity' do
3
- receipt
3
+ dispatch
4
4
  quantity { 100 }
5
5
  commodity_status { Cats::Core::Commodity::DAMAGED }
6
6
  remark { FFaker::Name.name }
@@ -1,9 +1,29 @@
1
1
  FactoryBot.define do
2
2
  factory :receipt_transaction, class: 'Cats::Core::ReceiptTransaction' do
3
- source factory: :receipt
4
- destination factory: :stack
3
+ transient do
4
+ dispatch { create(:dispatch) }
5
+ end
6
+ transient do
7
+ stack { create(:stack) }
8
+ end
9
+
10
+ destination { stack }
11
+ receipt do
12
+ dispatch.approve
13
+ dispatch.start
14
+ receipt = create(:receipt, dispatch: dispatch)
15
+ dispatch.confirm
16
+ create(
17
+ :hub_authorization,
18
+ authorization_type: Cats::Core::HubAuthorization::DESTINATION,
19
+ dispatch_plan_item: dispatch.dispatch_plan_item,
20
+ store: stack.store,
21
+ quantity: 100
22
+ )
23
+ receipt
24
+ end
5
25
  transaction_date { Date.today }
6
- quantity { 10 }
26
+ quantity { 100 }
7
27
  status { Cats::Core::Transaction::DRAFT }
8
28
  end
9
29
  end
@@ -2,12 +2,11 @@ FactoryBot.define do
2
2
  factory :receipt, class: 'Cats::Core::Receipt' do
3
3
  dispatch do
4
4
  dispatch = create(:dispatch)
5
- create(:dispatch_transaction, destination: dispatch, quantity: 50)
6
5
  dispatch.approve
7
6
  dispatch.start
8
7
  dispatch
9
8
  end
10
- quantity { 50 }
9
+ quantity { 100 }
11
10
  commodity_status { Cats::Core::Commodity::GOOD }
12
11
  status { Cats::Core::Receipt::DRAFT }
13
12
  remark { FFaker::Name.name }
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.36
4
+ version: 1.3.39
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-21 00:00:00.000000000 Z
11
+ date: 2022-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -232,6 +232,7 @@ files:
232
232
  - Rakefile
233
233
  - app/controllers/cats/core/access_controller.rb
234
234
  - app/controllers/cats/core/application_controller.rb
235
+ - app/controllers/cats/core/commodities_controller.rb
235
236
  - app/controllers/cats/core/commodity_categories_controller.rb
236
237
  - app/controllers/cats/core/currencies_controller.rb
237
238
  - app/controllers/cats/core/dispatch_plan_items_controller.rb
@@ -241,12 +242,14 @@ files:
241
242
  - app/controllers/cats/core/locations_controller.rb
242
243
  - app/controllers/cats/core/lost_commodities_controller.rb
243
244
  - app/controllers/cats/core/menus_controller.rb
245
+ - app/controllers/cats/core/monthly_plans_controller.rb
244
246
  - app/controllers/cats/core/notifications_controller.rb
245
247
  - app/controllers/cats/core/receipt_transactions_controller.rb
246
248
  - app/controllers/cats/core/receipts_controller.rb
247
249
  - app/controllers/cats/core/roles_controller.rb
248
250
  - app/controllers/cats/core/routes_controller.rb
249
251
  - app/controllers/cats/core/spaces_controller.rb
252
+ - app/controllers/cats/core/stacks_controller.rb
250
253
  - app/controllers/cats/core/transporters_controller.rb
251
254
  - app/controllers/cats/core/unit_of_measures_controller.rb
252
255
  - app/controllers/cats/core/users_controller.rb
@@ -323,20 +326,24 @@ files:
323
326
  - app/serializers/cats/core/dispatch_transaction_serializer.rb
324
327
  - app/serializers/cats/core/location_serializer.rb
325
328
  - app/serializers/cats/core/lost_commodity_serializer.rb
329
+ - app/serializers/cats/core/monthly_plan_serializer.rb
326
330
  - app/serializers/cats/core/receipt_serializer.rb
327
331
  - app/serializers/cats/core/receipt_transaction_serializer.rb
328
332
  - app/serializers/cats/core/role_menu_serializer.rb
329
333
  - app/serializers/cats/core/role_serializer.rb
330
334
  - app/serializers/cats/core/route_serializer.rb
335
+ - app/serializers/cats/core/stack_serializer.rb
331
336
  - app/serializers/cats/core/transporter_serializer.rb
332
337
  - app/serializers/cats/core/unit_of_measure_serializer.rb
333
338
  - app/serializers/cats/core/user_serializer.rb
334
339
  - app/services/cats/core/dispatch_plan_service.rb
335
340
  - app/services/cats/core/dispatch_service.rb
336
341
  - app/services/cats/core/menu_service.rb
342
+ - app/services/cats/core/monthly_plan_service.rb
337
343
  - app/services/cats/core/notification_service.rb
338
344
  - app/services/cats/core/receipt_service.rb
339
345
  - app/services/cats/core/space_service.rb
346
+ - app/services/cats/core/stack_service.rb
340
347
  - app/services/cats/core/token_auth_service.rb
341
348
  - config/routes.rb
342
349
  - db/migrate/20210715114238_create_cats_core_application_modules.rb
@@ -376,6 +383,7 @@ files:
376
383
  - db/migrate/20210719133710_create_cats_core_stacking_rules.rb
377
384
  - db/migrate/20210724074657_create_cats_core_notifications.rb
378
385
  - db/migrate/20210727074646_create_cats_core_receipts.rb
386
+ - db/migrate/20210728041505_create_cats_core_lost_commodities.rb
379
387
  - db/migrate/20210814160628_create_cats_core_receipt_transactions.rb
380
388
  - db/migrate/20210814175406_create_cats_core_stack_transactions.rb
381
389
  - db/migrate/20211002050739_create_cats_core_notification_rules.rb
@@ -396,7 +404,6 @@ files:
396
404
  - db/migrate/20220107125025_create_cats_core_monthly_plan_items.rb
397
405
  - db/migrate/20220107132433_create_cats_core_monthly_plan_item_details.rb
398
406
  - db/migrate/20220209083928_create_cats_core_hub_authorizations.rb
399
- - db/migrate/20220221041505_create_cats_core_lost_commodities.rb
400
407
  - lib/cats/core.rb
401
408
  - lib/cats/core/engine.rb
402
409
  - lib/cats/core/version.rb