comee_core 0.1.40 → 0.1.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/comee/core/customer_order_items_controller.rb +34 -0
  3. data/app/controllers/comee/core/customer_orders_controller.rb +47 -0
  4. data/app/controllers/comee/core/external_rfqs_controller.rb +13 -0
  5. data/app/controllers/comee/core/products_controller.rb +2 -3
  6. data/app/controllers/comee/core/quotation_request_items_controller.rb +46 -0
  7. data/app/controllers/comee/core/quotation_requests_controller.rb +66 -0
  8. data/app/controllers/comee/core/sales_order_items_controller.rb +25 -0
  9. data/app/controllers/comee/core/sales_orders_controller.rb +45 -0
  10. data/app/models/comee/core/customer_order.rb +10 -1
  11. data/app/models/comee/core/customer_order_item.rb +8 -0
  12. data/app/models/comee/core/external_rfq.rb +8 -0
  13. data/app/models/comee/core/product.rb +6 -34
  14. data/app/models/comee/core/purchase_order.rb +14 -0
  15. data/app/models/comee/core/purchase_order_item.rb +20 -0
  16. data/app/models/comee/core/quotation_request.rb +25 -0
  17. data/app/models/comee/core/quotation_request_item.rb +15 -0
  18. data/app/models/comee/core/sales_order.rb +2 -2
  19. data/app/serializers/comee/core/customer_order_item_serializer.rb +10 -0
  20. data/app/serializers/comee/core/customer_order_serializer.rb +9 -0
  21. data/app/serializers/comee/core/external_rfq_serializer.rb +7 -0
  22. data/app/serializers/comee/core/product_serializer.rb +1 -2
  23. data/app/serializers/comee/core/quotation_request_item_serializer.rb +10 -0
  24. data/app/serializers/comee/core/quotation_request_serializer.rb +8 -0
  25. data/app/serializers/comee/core/sales_order_item_serializer.rb +10 -0
  26. data/app/serializers/comee/core/sales_order_serializer.rb +10 -0
  27. data/app/services/comee/core/customer_order_service.rb +80 -0
  28. data/app/services/comee/core/quotation_request_service.rb +69 -0
  29. data/app/services/comee/core/sales_order_service.rb +141 -0
  30. data/config/routes.rb +57 -3
  31. data/db/migrate/20230728014322_create_comee_core_products.rb +3 -11
  32. data/db/migrate/20230811102708_create_comee_core_customer_order_items.rb +1 -0
  33. data/db/migrate/20230812190652_create_comee_core_sales_orders.rb +4 -4
  34. data/db/migrate/20230812212844_create_comee_core_sales_order_items.rb +2 -1
  35. data/db/migrate/20231121094339_create_comee_core_quotation_requests.rb +15 -0
  36. data/db/migrate/20231121132709_create_comee_core_quotation_request_items.rb +27 -0
  37. data/db/migrate/20231122094424_create_comee_core_external_rfqs.rb +10 -0
  38. data/db/migrate/20231125122723_create_comee_core_purchase_orders.rb +15 -0
  39. data/db/migrate/20231126082907_create_comee_core_purchase_order_items.rb +20 -0
  40. data/lib/comee/core/version.rb +1 -1
  41. data/lib/comee_core.rb +1 -0
  42. data/spec/factories/comee/core/customer_order_items.rb +1 -0
  43. data/spec/factories/comee/core/external_rfqs.rb +6 -0
  44. data/spec/factories/comee/core/products.rb +5 -4
  45. data/spec/factories/comee/core/purchase_order_items.rb +9 -0
  46. data/spec/factories/comee/core/purchase_orders.rb +8 -0
  47. data/spec/factories/comee/core/quotation_request_items.rb +14 -0
  48. data/spec/factories/comee/core/quotation_requests.rb +7 -0
  49. data/spec/factories/comee/core/sales_order_items.rb +2 -1
  50. data/spec/factories/comee/core/sales_orders.rb +0 -1
  51. metadata +49 -7
  52. data/app/controllers/comee/core/product_types_controller.rb +0 -18
  53. data/app/models/comee/core/product_type.rb +0 -19
  54. data/db/migrate/20230728012836_create_comee_core_product_types.rb +0 -13
  55. data/spec/factories/comee/core/product_types.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3977dd0f3b6240767a796a47eea12d0416a294884beab0afcd922ee36fe32fa8
4
- data.tar.gz: 608f811273a984214974ff03f006b01b084cb766478c67da439c144570b89b65
3
+ metadata.gz: d5af8bf8f2c1f9cf058e249237279cb6ae6019d0189c549c8bd5c6f421d4774a
4
+ data.tar.gz: 711689393088d435d720d49497d9e52e5db34cf15e4889fd4a020deb180fa0ae
5
5
  SHA512:
6
- metadata.gz: d39a9af367c1146deb698ae4e1ba4132a355ac5f19cd2b6fa5583492dbb2347450ef90ef907106c32b3a260729c0e45a719494ddb73e8c8bd2ac73850fefc5fa
7
- data.tar.gz: 7d4914e40e9f67cd3dab3199f6a5dfd3551333342901656c70a2308f6862c946c9e01a6c0fbbc6a76b9c6b1e32ad1471ffc09c45f72c0db4368d735c3bcec6b5
6
+ metadata.gz: ce2b456011d92074efffb23b2a1ba2df3f6818bd8d487b888fa5c4a9353ae4cea90af41a7b4fb0e4567070b1583c1f4a11eb308bce465a01fd8666d05eb574b4
7
+ data.tar.gz: ba7e824700d03d946fa3a1e30d4d0189dd0ac0b96a792482d10c611c70823eb345dfd75d8114e3905ffe48435cb231ba140cccbc180f524f92498af8ac2b84f9
@@ -0,0 +1,34 @@
1
+ module Comee
2
+ module Core
3
+ class CustomerOrderItemsController < ApplicationController
4
+ include Common
5
+
6
+ def cancel
7
+ CustomerOrderItem.where(id: params[:ids]).update_all(canceled: true)
8
+ render json: {success: true}
9
+ end
10
+
11
+ def filter
12
+ query = CustomerOrderItem.ransack(params[:q])
13
+ render json: {success: true, data: serialize(query.result.includes(:product))}
14
+ end
15
+
16
+ def destroy
17
+ item = CustomerOrderItem.find(params[:id])
18
+
19
+ if item.customer_order.draft?
20
+ item.destroy
21
+ render json: {success: true}
22
+ else
23
+ render json: {success: false, error: "Customer order should be in draft state."}, status: :forbidden
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def model_params
30
+ params.require(:payload).permit(:quantity, :price, :delivery_date, :canceled, :product_id, :customer_order_id, :unit_id)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,47 @@
1
+ module Comee
2
+ module Core
3
+ class CustomerOrdersController < ApplicationController
4
+ include Common
5
+
6
+ before_action :set_service, only: %i[submit submit_for_confirmation accept cancel]
7
+
8
+ def submit
9
+ order = @service.submit(params[:id])
10
+ render json: {success: true, data: serialize(order)}
11
+ rescue StandardError => e
12
+ render json: {success: false, error: e.message}
13
+ end
14
+
15
+ def submit_for_confirmation
16
+ order = @service.submit_for_confirmation(params[:id])
17
+ render json: {success: true, data: serialize(order)}
18
+ rescue StandardError => e
19
+ render json: {success: false, error: e.message}
20
+ end
21
+
22
+ def accept
23
+ order = @service.accept(params[:id])
24
+ render json: {success: true, data: serialize(order)}
25
+ rescue StandardError => e
26
+ render json: {success: false, error: e.message}
27
+ end
28
+
29
+ def cancel
30
+ order = @service.cancel(params[:id])
31
+ render json: {success: true, data: serialize(order)}
32
+ rescue StandardError => e
33
+ render json: {success: false, error: e.message}
34
+ end
35
+
36
+ private
37
+
38
+ def model_params
39
+ params.require(:payload).permit(:order_number, :order_date, :order_terms, :delivery_address, :invoice_address, :status, :client_id)
40
+ end
41
+
42
+ def set_service
43
+ @service = CustomerOrderService.new
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ module Comee
2
+ module Core
3
+ class ExternalRfqsController < ApplicationController
4
+ include Common
5
+
6
+ private
7
+
8
+ def model_params
9
+ params.require(:payload).permit(:status, data: {})
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,8 +5,7 @@ module Comee
5
5
 
6
6
  def index
7
7
  super do
8
- products = Comee::Core::Product.all
9
- products = products.where(ancestry: nil) if params[:root_only].present?
8
+ products = Product.leafs
10
9
  products.then(&paginate)
11
10
  end
12
11
  end
@@ -14,7 +13,7 @@ module Comee
14
13
  private
15
14
 
16
15
  def model_params
17
- params.required(:payload).permit(:code, :name, :description, :product_type_id, :unit_id, :metadata, :parent_id)
16
+ params.required(:payload).permit(:code, :name, :description, :parent_id)
18
17
  end
19
18
  end
20
19
  end
@@ -0,0 +1,46 @@
1
+ module Comee
2
+ module Core
3
+ class QuotationRequestItemsController < ApplicationController
4
+ include Common
5
+
6
+ def cancel
7
+ QuotationRequestItem.where(id: params[:ids]).update_all(canceled: true)
8
+ render json: {success: true}
9
+ end
10
+
11
+ def filter
12
+ query = QuotationRequestItem.ransack(params[:q])
13
+ render json: {success: true, data: serialize(query.result.includes(:product))}
14
+ end
15
+
16
+ def destroy
17
+ item = QuotationRequestItem.find(params[:id])
18
+ rfq = item.quotation_request
19
+ if QuotationRequest.statuses[rfq.status] == QuotationRequest.statuses[:draft]
20
+ item.destroy
21
+ render json: {success: true}
22
+ else
23
+ render json: {success: false, error: "RFQ should be in draft state first."}, status: :forbidden
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def model_params
30
+ params.require(:payload)
31
+ .permit(
32
+ :price,
33
+ :quantity,
34
+ :discount,
35
+ :valid_from,
36
+ :valid_to,
37
+ :product_id,
38
+ :quotation_request_id,
39
+ :unit_id,
40
+ :expected_delivery_date,
41
+ :canceled
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,66 @@
1
+ module Comee
2
+ module Core
3
+ class QuotationRequestsController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ super do
8
+ QuotationRequest.includes(:client).all
9
+ end
10
+ end
11
+
12
+ def filter
13
+ query = QuotationRequest.ransack(params[:q])
14
+ render json: {success: true, data: serialize(query.result.includes(:client))}
15
+ end
16
+
17
+ def rfq_products_for_client
18
+ client_products = ClientPrice.includes(:product).where(client_id: params[:id]).map(&:product_id)
19
+ root = Product.roots.first
20
+ ids = root.indirect_ids - client_products
21
+ products = Product.where(id: ids)
22
+ render json: {success: true, data: serialize(products)}
23
+ end
24
+
25
+ def create_request_with_items
26
+ service = QuotationRequestService.new
27
+ result = service.create_request_with_items(rfq_params.to_h)
28
+ render json: {success: true, data: serialize(result)}
29
+ end
30
+
31
+ def submit
32
+ service = QuotationRequestService.new
33
+ rfq = service.submit(params[:id])
34
+ render json: {success: true, data: serialize(rfq)}
35
+ rescue StandardError => e
36
+ render json: {success: false, error: e.message}
37
+ end
38
+
39
+ def submit_for_confirmation
40
+ service = QuotationRequestService.new
41
+ rfq = service.submit_for_confirmation(params[:id])
42
+ render json: {success: true, data: serialize(rfq)}
43
+ rescue StandardError => e
44
+ render json: {success: false, error: e.message}
45
+ end
46
+
47
+ def confirm
48
+ service = QuotationRequestService.new
49
+ rfq = service.confirm(params[:id])
50
+ render json: {success: true, data: serialize(rfq)}
51
+ rescue StandardError => e
52
+ render json: {success: false, error: e.message}
53
+ end
54
+
55
+ private
56
+
57
+ def model_params
58
+ params.require(:payload).permit(:reference_no, :status, :client_id)
59
+ end
60
+
61
+ def rfq_params
62
+ params.require(:payload).permit(:client_id, items: %i[product_id unit_id quantity expected_delivery_date])
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,25 @@
1
+ module Comee
2
+ module Core
3
+ class SalesOrderItemsController < ApplicationController
4
+ include Common
5
+
6
+ def index
7
+ super do
8
+ Comee::Core::SalesOrderItem.includes(:customer_order_item).where(sales_order_id: params[:id])
9
+ end
10
+ end
11
+
12
+ def destroy
13
+ Comee::Core::SalesOrderItem.destroy(params[:id])
14
+ render json: {success: true}
15
+ end
16
+
17
+ private
18
+
19
+ def model_params
20
+ params.require(:payload).permit(:sales_order_id, :customer_order_item_id, :unit_id, :quantity, :quantity_delivered, :price,
21
+ :delivery_date, :eb_number)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ module Comee
2
+ module Core
3
+ class SalesOrdersController < ApplicationController
4
+ include Common
5
+ before_action :set_object, only: %i[show update confirm cancel]
6
+
7
+ def confirm
8
+ @obj.confirm
9
+ render json: {success: true, data: serialize(@obj.reload)}
10
+ rescue StandardError => e
11
+ render json: {success: false, error: e.message}
12
+ end
13
+
14
+ def cancel
15
+ @obj.cancel
16
+ render json: {success: true, data: serialize(@obj.reload)}
17
+ rescue StandardError => e
18
+ render json: {success: false, error: e.message}
19
+ end
20
+
21
+ def index
22
+ super do
23
+ Comee::Core::SalesOrder.includes(:sales_order_items).all
24
+ end
25
+ end
26
+
27
+ def filter
28
+ @sales_order = Comee::Core::SalesOrder.ransack(params[:q]).result
29
+ render json: {success: true, data: serialize(@sales_order)}
30
+ end
31
+
32
+ private
33
+
34
+ def model_params
35
+ params.require(:payload).permit(:order_number, :customer_order_id, :payment_penalty, :status,
36
+ :total_price, :amount_paid, :pallete_note, :handover_date, :remark)
37
+ end
38
+
39
+ def back_order_params
40
+ params.permit(payload: [:supplier_id, :order_number, :order_date, :delivery_date, :delivery_address, :invoice_address,
41
+ back_order_items: %i[product_id requested_quantity requested_price supplier_quantity delivery_date]])
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,10 +2,19 @@ module Comee
2
2
  module Core
3
3
  class CustomerOrder < ApplicationRecord
4
4
  belongs_to :client
5
+ has_many :customer_order_items
5
6
 
6
- enum :status, {draft: 0, submitted: 1, accepted: 2, cancelled: 3}
7
+ enum :status, {draft: 0, submitted: 1, awaiting_confirmation: 2, accepted: 3, canceled: 4}
7
8
 
8
9
  validates :order_number, :order_date, :order_terms, :delivery_address, :invoice_address, :status, presence: true
10
+
11
+ def self.ransackable_attributes(_auth_object = nil)
12
+ %w[client_id delivery_address invoice_address order_number status]
13
+ end
14
+
15
+ def self.ransackable_associations(_auth_object = nil)
16
+ %w[client customer_order_items]
17
+ end
9
18
  end
10
19
  end
11
20
  end
@@ -6,6 +6,14 @@ module Comee
6
6
  belongs_to :unit
7
7
 
8
8
  validates :quantity, :price, :delivery_date, presence: true
9
+
10
+ def self.ransackable_attributes(_auth_object = nil)
11
+ %w[customer_order_id product_id unit_id]
12
+ end
13
+
14
+ def self.ransackable_associations(_auth_object = nil)
15
+ %w[customer_order product unit]
16
+ end
9
17
  end
10
18
  end
11
19
  end
@@ -0,0 +1,8 @@
1
+ module Comee
2
+ module Core
3
+ class ExternalRfq < ApplicationRecord
4
+ validates :data, :status, presence: true
5
+ enum :status, {draft: 0, submitted: 1, finalized: 2, cancelled: 3}
6
+ end
7
+ end
8
+ end
@@ -1,46 +1,18 @@
1
1
  module Comee
2
2
  module Core
3
3
  class Product < ApplicationRecord
4
- belongs_to :product_type
5
- belongs_to :unit
6
- has_many :inventories
7
4
  has_ancestry
5
+ after_save :update_parent, if: proc { |product| product.parent && product.parent.leaf? }
8
6
 
9
7
  validates :code, presence: true, uniqueness: true
10
8
  validates :name, presence: true
11
- validate :metadata_must_be_based_on_metadata_schema, if: -> { product_type.present? }
12
9
 
13
- delegate(:code, :name, to: :product_type, prefix: true)
14
- delegate(:code, :name, to: :unit, prefix: true)
10
+ scope :leafs, -> { where(leaf: true) }
15
11
 
16
- def metadata_must_be_based_on_metadata_schema
17
- metadata_schema = product_type.metadata_schema
18
- return unless metadata_schema.present? && metadata.present?
19
-
20
- properties = metadata_schema["properties"]
21
- fields = properties.keys
22
- required = metadata_schema["required"]
23
- diff = metadata.keys - fields
24
- unless diff.empty?
25
- errors.add(:metadata, "holds fields that are not allowed #{diff}.")
26
- return
27
- end
28
-
29
- diff = required - metadata.keys
30
- unless diff.empty?
31
- errors.add(:metadata, "should contain the following required fields #{diff}.")
32
- return
33
- end
34
-
35
- metadata.each do |k, v|
36
- errors.add(:metadata, "contains invalid value for field #{k}.") if v.class.to_s.downcase != properties[k]["type"]
37
- if properties[k].key?("min") && v < properties[k]["min"]
38
- errors.add(:base, "The value of #{k} cannot be lower than #{properties[k]['min']}.")
39
- end
40
- if properties[k].key?("max") && v > properties[k]["max"]
41
- errors.add(:base, "The value of #{k} cannot be higher than #{properties[k]['max']}.")
42
- end
43
- end
12
+ def update_parent
13
+ obj = parent
14
+ obj.leaf = false
15
+ obj.save!
44
16
  end
45
17
  end
46
18
  end
@@ -0,0 +1,14 @@
1
+ module Comee
2
+ module Core
3
+ class PurchaseOrder < ApplicationRecord
4
+ belongs_to :supplier
5
+ validates :order_date, :delivery_address, presence: true
6
+ enum status: {
7
+ draft: 0,
8
+ pending_approval: 1,
9
+ approved: 2,
10
+ submitted_to_supplier: 3
11
+ }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module Comee
2
+ module Core
3
+ class PurchaseOrderItem < ApplicationRecord
4
+ belongs_to :purchase_order
5
+ belongs_to :sales_order_item
6
+ validates :status, :quantity, :delivery_date, presence: true
7
+ validate :sales_order_item_must_have_eb_number
8
+ enum status: {
9
+ active: 0,
10
+ canceled: 1
11
+ }
12
+ def sales_order_item_must_have_eb_number
13
+ return unless sales_order_item
14
+ return if sales_order_item.eb_number
15
+
16
+ errors.add(:sales_order_item, "must have an EB number.")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ module Comee
2
+ module Core
3
+ class QuotationRequest < ApplicationRecord
4
+ before_validation :set_reference_no, if: proc { |rfq| rfq.reference_no.nil? }
5
+
6
+ belongs_to :client
7
+ has_many :quotation_request_items
8
+
9
+ enum :status, {draft: 0, submitted: 1, awaiting_confirmation: 2, confirmed: 3}
10
+
11
+ validates :status, presence: true
12
+
13
+ def self.ransackable_attributes(_auth_object = nil)
14
+ %w[client_id reference_no status]
15
+ end
16
+
17
+ private
18
+
19
+ def set_reference_no
20
+ stamp = DateTime.now.to_i
21
+ self.reference_no = "RFQ-#{client.code}-#{stamp}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module Comee
2
+ module Core
3
+ class QuotationRequestItem < ApplicationRecord
4
+ belongs_to :product
5
+ belongs_to :quotation_request
6
+ belongs_to :unit
7
+
8
+ validates :quantity, :price, :discount, :expected_delivery_date, presence: true
9
+
10
+ def self.ransackable_attributes(_auth_object = nil)
11
+ %w[quotation_request_id product_id unit_id quantity price discount expected_delivery_date]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,10 +6,10 @@ module Comee
6
6
  belongs_to :customer_order
7
7
  has_many :sales_order_items
8
8
 
9
- enum :status, {draft: 0, confirmed: 1, cancelled: 2}
9
+ enum :status, {draft: 0, validated: 1, authorized: 2, approved: 3, cancelled: 4, confirmed: 5, finalized: 6}
10
10
 
11
11
  validates :order_number, presence: true, uniqueness: true
12
- validates :status, :pallete_note, :handover_date, presence: true
12
+ validates :status, presence: true
13
13
  validates :payment_penalty,
14
14
  presence: true,
15
15
  numericality: {greater_than_or_equal_to: 0, less_than_or_equal_to: 100}
@@ -0,0 +1,10 @@
1
+ module Comee
2
+ module Core
3
+ class CustomerOrderItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :quantity, :price, :delivery_date, :canceled
5
+ belongs_to :product
6
+ belongs_to :customer_order
7
+ belongs_to :unit
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Comee
2
+ module Core
3
+ class CustomerOrderSerializer < ActiveModel::Serializer
4
+ attributes :id, :order_number, :order_date, :order_terms, :delivery_address, :invoice_address, :status
5
+ belongs_to :client
6
+ has_many :customer_order_items
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Comee
2
+ module Core
3
+ class ExternalRfqSerializer < ActiveModel::Serializer
4
+ attributes :id, :data, :status
5
+ end
6
+ end
7
+ end
@@ -1,8 +1,7 @@
1
1
  module Comee
2
2
  module Core
3
3
  class ProductSerializer < ActiveModel::Serializer
4
- attributes :id, :code, :name, :description, :product_type_id, :metadata, :unit_code, :unit_name,
5
- :product_type_code, :product_type_name
4
+ attributes :id, :code, :name, :description
6
5
  end
7
6
  end
8
7
  end
@@ -0,0 +1,10 @@
1
+ module Comee
2
+ module Core
3
+ class QuotationRequestItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :price, :discount, :valid_from, :valid_to
5
+ belongs_to :product
6
+ belongs_to :quotation_request
7
+ belongs_to :unit
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module Comee
2
+ module Core
3
+ class QuotationRequestSerializer < ActiveModel::Serializer
4
+ attributes :id, :reference_no, :status
5
+ belongs_to :client
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Comee
2
+ module Core
3
+ class SalesOrderItemSerializer < ActiveModel::Serializer
4
+ attributes :id, :quantity, :quantity_delivered, :price, :delivery_date, :eb_number
5
+ belongs_to :sales_order
6
+ belongs_to :customer_order_item
7
+ belongs_to :unit
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Comee
2
+ module Core
3
+ class SalesOrderSerializer < ActiveModel::Serializer
4
+ attributes :id, :order_number, :payment_penalty, :status, :total_price,
5
+ :amount_paid, :pallete_note, :handover_date, :remark
6
+ belongs_to :customer_order
7
+ has_many :sales_order_items
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,80 @@
1
+ module Comee
2
+ module Core
3
+ class CustomerOrderService
4
+ def submit(id)
5
+ order = CustomerOrder.find_by(id: id)
6
+ raise(StandardError, "Customer order with id `#{id}` not found.") unless order
7
+
8
+ unless CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:draft]
9
+ raise(StandardError, "Customer order should be in draft state.")
10
+ end
11
+
12
+ raise(StandardError, "Customer order should have at least one item.") unless order.customer_order_items.count.positive?
13
+
14
+ order.update!(status: CustomerOrder.statuses[:submitted])
15
+ order
16
+ end
17
+
18
+ def submit_for_confirmation(id)
19
+ order = CustomerOrder.find_by(id: id)
20
+ raise(StandardError, "Customer order with id `#{id}` not found.") unless order
21
+
22
+ unless CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:submitted]
23
+ raise(StandardError, "Customer order should be in submitted state.")
24
+ end
25
+
26
+ raise(StandardError, "Customer order does not have any items.") if order.customer_order_items.count.zero?
27
+
28
+ order.update!(status: CustomerOrder.statuses[:awaiting_confirmation])
29
+ order
30
+ end
31
+
32
+ def accept(id)
33
+ order = CustomerOrder.find_by(id: id)
34
+ raise(StandardError, "Customer order with id `#{id}` not found.") unless order
35
+
36
+ unless CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:submitted]
37
+ raise(StandardError, "Customer order should be in submitted state.")
38
+ end
39
+
40
+ raise(StandardError, "Customer order does not have any items.") if order.customer_order_items.count.zero?
41
+
42
+ sales_order = nil
43
+ CustomerOrder.transaction do
44
+ sales_order = SalesOrder.create!(
45
+ order_number: order.order_number,
46
+ customer_order: order,
47
+ status: SalesOrder.statuses[:draft]
48
+ )
49
+ items = order.customer_order_items.each_with_object([]) do |item, res|
50
+ next if item.canceled?
51
+
52
+ res << {
53
+ sales_order_id: sales_order.id,
54
+ customer_order_item_id: item.id,
55
+ unit_id: item.unit_id,
56
+ quantity: item.quantity,
57
+ price: item.price,
58
+ delivery_date: item.delivery_date
59
+ }
60
+ end
61
+ SalesOrderItem.insert_all!(items)
62
+ order.update!(status: CustomerOrder.statuses[:accepted])
63
+ end
64
+ sales_order
65
+ end
66
+
67
+ def cancel(id)
68
+ order = CustomerOrder.find_by(id: id)
69
+ raise(StandardError, "Customer order with id `#{id}` not found.") unless order
70
+
71
+ if CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:canceled]
72
+ raise(StandardError, "Customer order is already canceled.")
73
+ end
74
+
75
+ order.update!(status: CustomerOrder.statuses[:canceled])
76
+ order
77
+ end
78
+ end
79
+ end
80
+ end