cats_core 1.3.36 → 1.3.39

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.
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