dscf-marketplace 0.1.7 → 0.1.9

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/dscf/marketplace/application_controller.rb +2 -0
  3. data/app/controllers/dscf/marketplace/categories_controller.rb +26 -0
  4. data/app/controllers/dscf/marketplace/listings_controller.rb +55 -0
  5. data/app/controllers/dscf/marketplace/orders_controller.rb +58 -0
  6. data/app/controllers/dscf/marketplace/products_controller.rb +30 -0
  7. data/app/controllers/dscf/marketplace/quotations_controller.rb +56 -0
  8. data/app/controllers/dscf/marketplace/request_for_quotations_controller.rb +46 -0
  9. data/app/models/dscf/marketplace/category.rb +9 -0
  10. data/app/models/dscf/marketplace/delivery_order.rb +116 -0
  11. data/app/models/dscf/marketplace/delivery_order_item.rb +201 -0
  12. data/app/models/dscf/marketplace/delivery_vehicle.rb +70 -0
  13. data/app/models/dscf/marketplace/listing.rb +9 -0
  14. data/app/models/dscf/marketplace/order.rb +35 -0
  15. data/app/models/dscf/marketplace/order_item.rb +17 -0
  16. data/app/models/dscf/marketplace/product.rb +9 -0
  17. data/app/models/dscf/marketplace/quotation.rb +9 -0
  18. data/app/models/dscf/marketplace/quotation_item.rb +10 -3
  19. data/app/models/dscf/marketplace/request_for_quotation.rb +9 -0
  20. data/app/models/dscf/marketplace/rfq_item.rb +9 -0
  21. data/app/models/dscf/marketplace/supplier_product.rb +9 -0
  22. data/app/models/dscf/marketplace/unit.rb +9 -0
  23. data/app/models/dscf/marketplace/unit_conversion.rb +9 -0
  24. data/app/serializers/dscf/marketplace/category_serializer.rb +11 -0
  25. data/app/serializers/dscf/marketplace/listing_serializer.rb +13 -0
  26. data/app/serializers/dscf/marketplace/order_serializer.rb +15 -0
  27. data/app/serializers/dscf/marketplace/product_serializer.rb +13 -0
  28. data/app/serializers/dscf/marketplace/quotation_serializer.rb +14 -0
  29. data/app/serializers/dscf/marketplace/request_for_quotation_serializer.rb +13 -0
  30. data/config/locales/en.yml +254 -0
  31. data/config/routes.rb +85 -0
  32. data/db/migrate/20250831110907_create_dscf_marketplace_delivery_orders.rb +21 -0
  33. data/db/migrate/20250831110921_create_dscf_marketplace_delivery_order_items.rb +27 -0
  34. data/db/migrate/20250831110933_create_dscf_marketplace_delivery_vehicles.rb +17 -0
  35. data/db/migrate/20250901074509_add_delivery_handoff_fields_to_delivery_order_items.rb +16 -0
  36. data/db/migrate/20250901074746_add_delivery_order_to_orders.rb +7 -0
  37. data/db/migrate/20250901075511_add_delivery_vehicle_to_delivery_orders.rb +7 -0
  38. data/db/migrate/20250901080134_add_fulfillment_type_to_orders.rb +6 -0
  39. data/lib/dscf/marketplace/version.rb +1 -1
  40. data/spec/factories/dscf/core/addresses.rb +15 -0
  41. data/spec/factories/dscf/marketplace/delivery_order_items.rb +46 -0
  42. data/spec/factories/dscf/marketplace/delivery_orders.rb +14 -0
  43. data/spec/factories/dscf/marketplace/delivery_vehicles.rb +37 -0
  44. data/spec/factories/dscf/marketplace/order_items.rb +1 -1
  45. data/spec/factories/dscf/marketplace/orders.rb +10 -1
  46. metadata +29 -3
  47. data/README.md +0 -28
@@ -0,0 +1,70 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class DeliveryVehicle < ApplicationRecord
4
+ enum :vehicle_type, {motorcycle: 0, car: 1, van: 2, truck: 3}
5
+
6
+ belongs_to :driver, class_name: "Dscf::Core::User"
7
+ has_many :delivery_orders, dependent: :nullify
8
+
9
+ validates :driver_id, presence: true
10
+ validates :plate_number, presence: true, uniqueness: true
11
+ validates :vehicle_type, presence: true
12
+ validates :year, numericality: {greater_than: 1900, less_than_or_equal_to: Time.current.year + 1}, allow_nil: true
13
+ validates :brand, length: {maximum: 50}, allow_blank: true
14
+ validates :model, length: {maximum: 50}, allow_blank: true
15
+ validates :color, length: {maximum: 30}, allow_blank: true
16
+
17
+ # Ransack configuration for secure filtering
18
+ def self.ransackable_attributes(_auth_object = nil)
19
+ %w[id driver_id plate_number vehicle_type year brand model color created_at updated_at]
20
+ end
21
+
22
+ def self.ransackable_associations(_auth_object = nil)
23
+ %w[driver delivery_orders]
24
+ end
25
+
26
+ def motorcycle?
27
+ vehicle_type == "motorcycle"
28
+ end
29
+
30
+ def car?
31
+ vehicle_type == "car"
32
+ end
33
+
34
+ def van?
35
+ vehicle_type == "van"
36
+ end
37
+
38
+ def truck?
39
+ vehicle_type == "truck"
40
+ end
41
+
42
+ def display_name
43
+ brand_and_model = [ brand.presence, model.presence ].compact.join(" ")
44
+ brand_and_model = nil if brand_and_model.blank?
45
+ "#{brand_and_model} (#{plate_number})".strip
46
+ end
47
+
48
+ def active_deliveries
49
+ delivery_orders.where.not(status: [ :delivered, :failed ])
50
+ end
51
+
52
+ def completed_deliveries
53
+ delivery_orders.where(status: :delivered)
54
+ end
55
+
56
+ def failed_deliveries
57
+ delivery_orders.where(status: :failed)
58
+ end
59
+
60
+ def total_deliveries
61
+ delivery_orders.count
62
+ end
63
+
64
+ def success_rate
65
+ return 0 if total_deliveries.zero?
66
+ (completed_deliveries.count.to_f / total_deliveries * 100).round(2)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -21,6 +21,15 @@ module Dscf::Marketplace
21
21
  scope :by_business, ->(business_id) { where(business_id: business_id) }
22
22
  scope :owned_by, ->(business) { where(business: business) }
23
23
 
24
+ # Ransack configuration for secure filtering
25
+ def self.ransackable_attributes(_auth_object = nil)
26
+ %w[id business_id supplier_product_id price quantity status created_at updated_at]
27
+ end
28
+
29
+ def self.ransackable_associations(_auth_object = nil)
30
+ %w[business supplier_product order_items]
31
+ end
32
+
24
33
  # Custom methods
25
34
  def total_value
26
35
  price * quantity
@@ -2,19 +2,31 @@ module Dscf::Marketplace
2
2
  class Order < ApplicationRecord
3
3
  enum :order_type, {rfq_based: 0, direct_listing: 1}
4
4
  enum :status, {pending: 0, confirmed: 1, processing: 2, completed: 3, cancelled: 4}
5
+ enum :fulfillment_type, {self_pickup: 0, delivery: 1}
5
6
 
6
7
  belongs_to :quotation, optional: true
7
8
  belongs_to :listing, optional: true
8
9
  belongs_to :user, class_name: "Dscf::Core::User"
10
+ belongs_to :delivery_order, optional: true
9
11
  has_many :order_items, dependent: :destroy
10
12
 
11
13
  validates :order_type, presence: true
12
14
  validates :status, presence: true
15
+ validates :fulfillment_type, presence: true
13
16
  validates :user, presence: true
14
17
  validate :quotation_or_listing_present
15
18
 
16
19
  before_save :calculate_total_amount
17
20
 
21
+ # Ransack configuration for secure filtering
22
+ def self.ransackable_attributes(_auth_object = nil)
23
+ %w[id quotation_id listing_id user_id delivery_order_id order_type status fulfillment_type total_amount created_at updated_at]
24
+ end
25
+
26
+ def self.ransackable_associations(_auth_object = nil)
27
+ %w[quotation listing user delivery_order order_items]
28
+ end
29
+
18
30
  def self.create_from_quotation(quotation)
19
31
  return nil unless quotation.accepted?
20
32
 
@@ -81,6 +93,29 @@ module Dscf::Marketplace
81
93
  end
82
94
  end
83
95
 
96
+ # Fulfillment type methods
97
+ def self_pickup?
98
+ fulfillment_type == "self_pickup"
99
+ end
100
+
101
+ def delivery?
102
+ fulfillment_type == "delivery"
103
+ end
104
+
105
+ def requires_delivery_order?
106
+ delivery? && !completed?
107
+ end
108
+
109
+ def can_be_completed?
110
+ if self_pickup?
111
+ # Self-pickup orders can be completed immediately after confirmation
112
+ confirmed? || processing?
113
+ else
114
+ # Delivery orders require delivery_order association
115
+ delivery_order.present? && delivery_order.delivered?
116
+ end
117
+ end
118
+
84
119
  def confirm!
85
120
  return false unless pending?
86
121
 
@@ -15,10 +15,27 @@ module Dscf::Marketplace
15
15
  validates :unit, presence: true
16
16
  validate :quotation_item_or_listing_present
17
17
 
18
+ # Ransack configuration for secure filtering
19
+ def self.ransackable_attributes(_auth_object = nil)
20
+ %w[id order_id quotation_item_id listing_id product_id unit_id quantity unit_price status created_at updated_at]
21
+ end
22
+
23
+ def self.ransackable_associations(_auth_object = nil)
24
+ %w[order quotation_item listing product unit]
25
+ end
26
+
18
27
  def subtotal
19
28
  quantity * unit_price
20
29
  end
21
30
 
31
+ def product_name
32
+ product&.name
33
+ end
34
+
35
+ def unit_name
36
+ unit&.name
37
+ end
38
+
22
39
  private
23
40
 
24
41
  def quotation_item_or_listing_present
@@ -27,6 +27,15 @@ module Dscf
27
27
  scope :by_category, ->(category_id) { where(category_id: category_id) }
28
28
  scope :by_unit, ->(unit_id) { where(unit_id: unit_id) }
29
29
 
30
+ # Ransack configuration for secure filtering
31
+ def self.ransackable_attributes(_auth_object = nil)
32
+ %w[id sku name description category_id unit_id base_price base_quantity business_only created_at updated_at]
33
+ end
34
+
35
+ def self.ransackable_associations(_auth_object = nil)
36
+ %w[category unit supplier_products listings order_items rfq_items quotation_items]
37
+ end
38
+
30
39
  def display_name
31
40
  "#{name} (#{sku})"
32
41
  end
@@ -22,6 +22,15 @@ module Dscf
22
22
  scope :valid_quotations, -> { where("valid_until > ?", Time.current) }
23
23
  scope :expired_quotations, -> { where("valid_until <= ?", Time.current) }
24
24
 
25
+ # Ransack configuration for secure filtering
26
+ def self.ransackable_attributes(_auth_object = nil)
27
+ %w[id request_for_quotation_id business_id total_price delivery_date valid_until status notes created_at updated_at]
28
+ end
29
+
30
+ def self.ransackable_associations(_auth_object = nil)
31
+ %w[request_for_quotation business quotation_items order]
32
+ end
33
+
25
34
  def calculate_total_price
26
35
  self.total_price = quotation_items.sum(&:subtotal).to_f
27
36
  end
@@ -6,8 +6,6 @@ module Dscf
6
6
  belongs_to :product, class_name: "Dscf::Marketplace::Product"
7
7
  belongs_to :unit, class_name: "Dscf::Marketplace::Unit"
8
8
 
9
-
10
-
11
9
  validates :quotation_id, presence: true
12
10
  validates :rfq_item_id, presence: true
13
11
  validates :product_id, presence: true
@@ -28,6 +26,15 @@ module Dscf
28
26
  scope :by_product, ->(product_id) { where(product_id: product_id) }
29
27
  scope :by_unit, ->(unit_id) { where(unit_id: unit_id) }
30
28
 
29
+ # Ransack configuration for secure filtering
30
+ def self.ransackable_attributes(_auth_object = nil)
31
+ %w[id quotation_id rfq_item_id product_id unit_id quantity unit_price subtotal created_at updated_at]
32
+ end
33
+
34
+ def self.ransackable_associations(_auth_object = nil)
35
+ %w[quotation rfq_item product unit]
36
+ end
37
+
31
38
  def product_name
32
39
  product&.name
33
40
  end
@@ -70,7 +77,7 @@ module Dscf
70
77
  return false unless rfq_item
71
78
 
72
79
  product_id == rfq_item.product_id &&
73
- unit_id == rfq_item.unit_id
80
+ unit_id == rfq_item.unit_id
74
81
  end
75
82
 
76
83
  def can_create_order?
@@ -14,6 +14,15 @@ module Dscf
14
14
  validate :selected_quotation_belongs_to_this_rfq
15
15
  scope :by_user, ->(user_id) { where(user_id: user_id) }
16
16
 
17
+ # Ransack configuration for secure filtering
18
+ def self.ransackable_attributes(_auth_object = nil)
19
+ %w[id user_id selected_quotation_id status notes created_at updated_at]
20
+ end
21
+
22
+ def self.ransackable_associations(_auth_object = nil)
23
+ %w[user selected_quotation rfq_items quotations]
24
+ end
25
+
17
26
  def draft?
18
27
  status == "draft"
19
28
  end
@@ -18,6 +18,15 @@ module Dscf
18
18
  scope :by_product, ->(product_id) { where(product_id: product_id) }
19
19
  scope :by_unit, ->(unit_id) { where(unit_id: unit_id) }
20
20
 
21
+ # Ransack configuration for secure filtering
22
+ def self.ransackable_attributes(_auth_object = nil)
23
+ %w[id request_for_quotation_id product_id unit_id quantity notes created_at updated_at]
24
+ end
25
+
26
+ def self.ransackable_associations(_auth_object = nil)
27
+ %w[request_for_quotation product unit quotation_items]
28
+ end
29
+
21
30
  def product_name
22
31
  product&.name
23
32
  end
@@ -22,6 +22,15 @@ module Dscf::Marketplace
22
22
  scope :by_business, ->(business_id) { where(business_id: business_id) }
23
23
  scope :by_product, ->(product_id) { where(product_id: product_id) }
24
24
 
25
+ # Ransack configuration for secure filtering
26
+ def self.ransackable_attributes(_auth_object = nil)
27
+ %w[id business_id product_id supplier_price available_quantity minimum_order_quantity status created_at updated_at]
28
+ end
29
+
30
+ def self.ransackable_associations(_auth_object = nil)
31
+ %w[business product listings order_items]
32
+ end
33
+
25
34
  # Custom methods
26
35
  def in_stock?
27
36
  available_quantity > 0
@@ -24,6 +24,15 @@ module Dscf
24
24
 
25
25
  scope :by_type, ->(type) { where(unit_type: unit_types[type]) }
26
26
 
27
+ # Ransack configuration for secure filtering
28
+ def self.ransackable_attributes(_auth_object = nil)
29
+ %w[id code name unit_type created_at updated_at]
30
+ end
31
+
32
+ def self.ransackable_associations(_auth_object = nil)
33
+ %w[unit_conversions products supplier_products listings order_items rfq_items quotation_items]
34
+ end
35
+
27
36
  def display_name
28
37
  "#{name} (#{code})"
29
38
  end
@@ -11,6 +11,15 @@ module Dscf
11
11
 
12
12
  validate :units_must_be_different
13
13
 
14
+ # Ransack configuration for secure filtering
15
+ def self.ransackable_attributes(_auth_object = nil)
16
+ %w[id from_unit_id to_unit_id conversion_factor notes created_at updated_at]
17
+ end
18
+
19
+ def self.ransackable_associations(_auth_object = nil)
20
+ %w[from_unit to_unit]
21
+ end
22
+
14
23
  def units_must_be_different
15
24
  return unless from_unit_id && to_unit_id
16
25
 
@@ -0,0 +1,11 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class CategorySerializer < ActiveModel::Serializer
4
+ attributes :id, :name, :description, :parent_id, :created_at, :updated_at
5
+
6
+ belongs_to :parent, serializer: CategorySerializer
7
+ has_many :subcategories, serializer: CategorySerializer
8
+ has_many :products
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class ListingSerializer < ActiveModel::Serializer
4
+ attributes :id, :business_id, :supplier_product_id, :price, :quantity,
5
+ :status, :created_at, :updated_at, :total_value, :margin,
6
+ :margin_percentage, :available?
7
+
8
+ belongs_to :business
9
+ belongs_to :supplier_product
10
+ has_many :order_items
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class OrderSerializer < ActiveModel::Serializer
4
+ attributes :id, :quotation_id, :listing_id, :user_id, :delivery_order_id,
5
+ :order_type, :status, :fulfillment_type, :total_amount,
6
+ :created_at, :updated_at
7
+
8
+ belongs_to :quotation
9
+ belongs_to :listing
10
+ belongs_to :user
11
+ belongs_to :delivery_order
12
+ has_many :order_items
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class ProductSerializer < ActiveModel::Serializer
4
+ attributes :id, :sku, :name, :description, :category_id, :unit_id,
5
+ :base_price, :base_quantity, :business_only, :created_at, :updated_at,
6
+ :display_name, :price_per_unit, :thumbnail_url, :images_urls
7
+
8
+ belongs_to :category
9
+ belongs_to :unit
10
+ has_many :supplier_products
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class QuotationSerializer < ActiveModel::Serializer
4
+ attributes :id, :request_for_quotation_id, :business_id, :total_price,
5
+ :delivery_date, :valid_until, :status, :notes, :created_at,
6
+ :updated_at, :days_until_expiry, :delivery_in_days, :complete?
7
+
8
+ belongs_to :request_for_quotation
9
+ belongs_to :business
10
+ has_many :quotation_items
11
+ has_one :order
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Dscf
2
+ module Marketplace
3
+ class RequestForQuotationSerializer < ActiveModel::Serializer
4
+ attributes :id, :user_id, :selected_quotation_id, :status, :notes,
5
+ :created_at, :updated_at, :total_items, :has_responses?
6
+
7
+ belongs_to :user
8
+ belongs_to :selected_quotation
9
+ has_many :rfq_items
10
+ has_many :quotations
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,254 @@
1
+ # DSCF Marketplace Locale File
2
+ # This file contains I18n messages for automatic message resolution
3
+ # Pattern: {model_name}.{success|errors}.{action_name}
4
+
5
+ en:
6
+ # Core Models
7
+ category:
8
+ success:
9
+ index: "Categories retrieved successfully"
10
+ show: "Category details retrieved successfully"
11
+ create: "Category created successfully"
12
+ update: "Category updated successfully"
13
+ destroy: "Category deleted successfully"
14
+ errors:
15
+ index: "Failed to retrieve categories"
16
+ show: "Failed to retrieve category details"
17
+ create: "Failed to create category"
18
+ update: "Failed to update category"
19
+ destroy: "Failed to delete category"
20
+
21
+ product:
22
+ success:
23
+ index: "Products retrieved successfully"
24
+ show: "Product details retrieved successfully"
25
+ create: "Product created successfully"
26
+ update: "Product updated successfully"
27
+ destroy: "Product deleted successfully"
28
+ errors:
29
+ index: "Failed to retrieve products"
30
+ show: "Failed to retrieve product details"
31
+ create: "Failed to create product"
32
+ update: "Failed to update product"
33
+ destroy: "Failed to delete product"
34
+
35
+ unit:
36
+ success:
37
+ index: "Units retrieved successfully"
38
+ show: "Unit details retrieved successfully"
39
+ create: "Unit created successfully"
40
+ update: "Unit updated successfully"
41
+ destroy: "Unit deleted successfully"
42
+ errors:
43
+ index: "Failed to retrieve units"
44
+ show: "Failed to retrieve unit details"
45
+ create: "Failed to create unit"
46
+ update: "Failed to update unit"
47
+ destroy: "Failed to delete unit"
48
+
49
+ unit_conversion:
50
+ success:
51
+ index: "Unit conversions retrieved successfully"
52
+ show: "Unit conversion details retrieved successfully"
53
+ create: "Unit conversion created successfully"
54
+ update: "Unit conversion updated successfully"
55
+ destroy: "Unit conversion deleted successfully"
56
+ errors:
57
+ index: "Failed to retrieve unit conversions"
58
+ show: "Failed to retrieve unit conversion details"
59
+ create: "Failed to create unit conversion"
60
+ update: "Failed to update unit conversion"
61
+ destroy: "Failed to delete unit conversion"
62
+
63
+ # Trading Models
64
+ supplier_product:
65
+ success:
66
+ index: "Supplier products retrieved successfully"
67
+ show: "Supplier product details retrieved successfully"
68
+ create: "Supplier product created successfully"
69
+ update: "Supplier product updated successfully"
70
+ destroy: "Supplier product deleted successfully"
71
+ errors:
72
+ index: "Failed to retrieve supplier products"
73
+ show: "Failed to retrieve supplier product details"
74
+ create: "Failed to create supplier product"
75
+ update: "Failed to update supplier product"
76
+ destroy: "Failed to delete supplier product"
77
+
78
+ listing:
79
+ success:
80
+ index: "Listings retrieved successfully"
81
+ show: "Listing details retrieved successfully"
82
+ create: "Listing created successfully"
83
+ update: "Listing updated successfully"
84
+ destroy: "Listing deleted successfully"
85
+ errors:
86
+ index: "Failed to retrieve listings"
87
+ show: "Failed to retrieve listing details"
88
+ create: "Failed to create listing"
89
+ update: "Failed to update listing"
90
+ destroy: "Failed to delete listing"
91
+
92
+ request_for_quotation:
93
+ success:
94
+ index: "RFQs retrieved successfully"
95
+ show: "RFQ details retrieved successfully"
96
+ create: "RFQ created successfully"
97
+ update: "RFQ updated successfully"
98
+ destroy: "RFQ deleted successfully"
99
+ errors:
100
+ index: "Failed to retrieve RFQs"
101
+ show: "Failed to retrieve RFQ details"
102
+ create: "Failed to create RFQ"
103
+ update: "Failed to update RFQ"
104
+ destroy: "Failed to delete RFQ"
105
+
106
+ rfq_item:
107
+ success:
108
+ index: "RFQ items retrieved successfully"
109
+ show: "RFQ item details retrieved successfully"
110
+ create: "RFQ item created successfully"
111
+ update: "RFQ item updated successfully"
112
+ destroy: "RFQ item deleted successfully"
113
+ errors:
114
+ index: "Failed to retrieve RFQ items"
115
+ show: "Failed to retrieve RFQ item details"
116
+ create: "Failed to create RFQ item"
117
+ update: "Failed to update RFQ item"
118
+ destroy: "Failed to delete RFQ item"
119
+
120
+ quotation:
121
+ success:
122
+ index: "Quotations retrieved successfully"
123
+ show: "Quotation details retrieved successfully"
124
+ create: "Quotation created successfully"
125
+ update: "Quotation updated successfully"
126
+ destroy: "Quotation deleted successfully"
127
+ accept: "Quotation accepted successfully"
128
+ reject: "Quotation rejected successfully"
129
+ send_quotation: "Quotation sent successfully"
130
+ errors:
131
+ index: "Failed to retrieve quotations"
132
+ show: "Failed to retrieve quotation details"
133
+ create: "Failed to create quotation"
134
+ update: "Failed to update quotation"
135
+ destroy: "Failed to delete quotation"
136
+ accept: "Failed to accept quotation"
137
+ reject: "Failed to reject quotation"
138
+ send_quotation: "Failed to send quotation"
139
+
140
+ quotation_item:
141
+ success:
142
+ index: "Quotation items retrieved successfully"
143
+ show: "Quotation item details retrieved successfully"
144
+ create: "Quotation item created successfully"
145
+ update: "Quotation item updated successfully"
146
+ destroy: "Quotation item deleted successfully"
147
+ errors:
148
+ index: "Failed to retrieve quotation items"
149
+ show: "Failed to retrieve quotation item details"
150
+ create: "Failed to create quotation item"
151
+ update: "Failed to update quotation item"
152
+ destroy: "Failed to delete quotation item"
153
+
154
+ # Order Models
155
+ order:
156
+ success:
157
+ index: "Orders retrieved successfully"
158
+ show: "Order details retrieved successfully"
159
+ create: "Order created successfully"
160
+ update: "Order updated successfully"
161
+ destroy: "Order deleted successfully"
162
+ confirm: "Order confirmed successfully"
163
+ cancel: "Order cancelled successfully"
164
+ errors:
165
+ index: "Failed to retrieve orders"
166
+ show: "Failed to retrieve order details"
167
+ create: "Failed to create order"
168
+ update: "Failed to update order"
169
+ destroy: "Failed to delete order"
170
+ confirm: "Failed to confirm order"
171
+ cancel: "Failed to cancel order"
172
+
173
+ order_item:
174
+ success:
175
+ index: "Order items retrieved successfully"
176
+ show: "Order item details retrieved successfully"
177
+ create: "Order item created successfully"
178
+ update: "Order item updated successfully"
179
+ destroy: "Order item deleted successfully"
180
+ errors:
181
+ index: "Failed to retrieve order items"
182
+ show: "Failed to retrieve order item details"
183
+ create: "Failed to create order item"
184
+ update: "Failed to update order item"
185
+ destroy: "Failed to delete order item"
186
+
187
+ # Delivery Models
188
+ delivery_order:
189
+ success:
190
+ index: "Delivery orders retrieved successfully"
191
+ show: "Delivery order details retrieved successfully"
192
+ create: "Delivery order created successfully"
193
+ update: "Delivery order updated successfully"
194
+ destroy: "Delivery order deleted successfully"
195
+ pickup: "Delivery order picked up successfully"
196
+ start_delivery: "Delivery started successfully"
197
+ complete_delivery: "Delivery completed successfully"
198
+ mark_failed: "Delivery marked as failed"
199
+ errors:
200
+ index: "Failed to retrieve delivery orders"
201
+ show: "Failed to retrieve delivery order details"
202
+ create: "Failed to create delivery order"
203
+ update: "Failed to update delivery order"
204
+ destroy: "Failed to delete delivery order"
205
+ pickup: "Failed to pickup delivery order"
206
+ start_delivery: "Failed to start delivery"
207
+ complete_delivery: "Failed to complete delivery"
208
+ mark_failed: "Failed to mark delivery as failed"
209
+
210
+ delivery_order_item:
211
+ success:
212
+ index: "Delivery order items retrieved successfully"
213
+ show: "Delivery order item details retrieved successfully"
214
+ create: "Delivery order item created successfully"
215
+ update: "Delivery order item updated successfully"
216
+ destroy: "Delivery order item deleted successfully"
217
+ receiver_confirm: "Item confirmed by receiver successfully"
218
+ report_issue: "Issue reported successfully"
219
+ dispute_delivery: "Delivery disputed successfully"
220
+ errors:
221
+ index: "Failed to retrieve delivery order items"
222
+ show: "Failed to retrieve delivery order item details"
223
+ create: "Failed to create delivery order item"
224
+ update: "Failed to update delivery order item"
225
+ destroy: "Failed to delete delivery order item"
226
+ receiver_confirm: "Failed to confirm item"
227
+ report_issue: "Failed to report issue"
228
+ dispute_delivery: "Failed to dispute delivery"
229
+
230
+ delivery_vehicle:
231
+ success:
232
+ index: "Delivery vehicles retrieved successfully"
233
+ show: "Delivery vehicle details retrieved successfully"
234
+ create: "Delivery vehicle created successfully"
235
+ update: "Delivery vehicle updated successfully"
236
+ destroy: "Delivery vehicle deleted successfully"
237
+ errors:
238
+ index: "Failed to retrieve delivery vehicles"
239
+ show: "Failed to retrieve delivery vehicle details"
240
+ create: "Failed to create delivery vehicle"
241
+ update: "Failed to update delivery vehicle"
242
+ destroy: "Failed to delete delivery vehicle"
243
+
244
+ # Global fallback messages
245
+ operations:
246
+ success:
247
+ completed: "Operation completed successfully"
248
+ errors:
249
+ failed: "Operation failed"
250
+
251
+ errors:
252
+ validation_failed: "Validation failed"
253
+ operation_failed: "Operation failed"
254
+ record_not_found: "Record not found"