Class: Workarea::Fulfillment

Inherits:
Object
  • Object
show all
Includes:
ApplicationDocument
Defined in:
app/models/workarea/fulfillment.rb,
app/models/workarea/fulfillment/sku.rb,
app/models/workarea/fulfillment/item.rb,
app/models/workarea/fulfillment/event.rb,
app/models/workarea/fulfillment/token.rb,
app/models/workarea/fulfillment/status.rb,
app/models/workarea/fulfillment/package.rb,
app/models/workarea/fulfillment/policies/base.rb,
app/models/workarea/fulfillment/policies/download.rb,
app/models/workarea/fulfillment/policies/shipping.rb

Defined Under Namespace

Modules: Policies, Status Classes: Event, Item, Package, Sku, Token

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ApplicationDocument

#releasable?

Methods included from Sidekiq::Callbacks

add_worker, assert_valid_config!, async, caching_classes?, disable, enable, inline, #run_callbacks, workers, workers_list

Methods included from Mongoid::Document

#embedded_children

Class Method Details

.find_statuses(*ids) ⇒ Hash

Finds statuses of fulfillments based on multiple order ids Used when displaying account order history.

Parameters:

Returns:

  • (Hash)


16
17
18
19
20
21
22
23
24
25
# File 'app/models/workarea/fulfillment.rb', line 16

def self.find_statuses(*ids)
  fulfillments = any_in(id: ids).to_a

  ids.inject({}) do |memo, id|
    fulfillment = fulfillments.detect { |f| f.id == id }

    memo[id] = fulfillment ? fulfillment.status : :not_available
    memo
  end
end

Instance Method Details

#cancel_items(canceled_items) ⇒ Boolean

Cancel items in the fulfillment

The hashes should contain ‘id’, the order_item_id and ‘quantity’ the amount to be canceled, any other key/values will be stored on the Fulfillment::Event#data

cancel_items([

{ 'id' => '1234', 'quantity' => 4, 'replacement_sku' => '9999' },
{ 'id' => '4321', 'quantity' => 1 }

])

Parameters:

  • canceled_items (Array<Hash>)

Returns:

  • (Boolean)


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'app/models/workarea/fulfillment.rb', line 131

def cancel_items(canceled_items)
  return false unless canceled_items.present?

  occured_at = Time.current

  canceled_items = canceled_items.map do |canceled_item|
    canceled_item = canceled_item.with_indifferent_access
    next unless canceled_item['quantity'].to_i > 0

    item = items.detect { |i| i.order_item_id == canceled_item['id'].to_s }
    next unless item.present?

    item.events.build(
      status: 'canceled',
      quantity: canceled_item['quantity'],
      created_at: occured_at,
      updated_at: occured_at,
      data: canceled_item.except('id', 'quantity')
    )
    [canceled_item['id'].to_s, canceled_item['quantity']]
  end.compact

  return unless canceled_items.present?

  result = save

  if result && Workarea.config.send_transactional_emails
    Storefront::FulfillmentMailer
      .canceled(id, Hash[canceled_items])
      .deliver_later
  end

  result
end

#canceled_itemsObject



58
59
60
# File 'app/models/workarea/fulfillment.rb', line 58

def canceled_items
  items.select { |i| i.quantity_canceled > 0 }
end

#eventsObject



40
41
42
# File 'app/models/workarea/fulfillment.rb', line 40

def events
  items.map(&:events).flatten
end

#find_package(tracking_number) ⇒ Object



44
45
46
47
48
# File 'app/models/workarea/fulfillment.rb', line 44

def find_package(tracking_number)
  packages.detect do |package|
    package.tracking_number.to_s.casecmp?(tracking_number.to_s)
  end
end

#mark_item_shipped(data) ⇒ Workarea::Fulfillment::Event

Add shipped event to a Item. Does not persist the changes.

Parameters:

  • data (Hash)

    data used to generate event

Options Hash (data):

  • :id (String)

    The order item’s id

  • :quantity (Integer)

    The quantity to be marked shipped

  • :tracking_number (String)

    Tracking number for shipping

Returns:



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/models/workarea/fulfillment.rb', line 72

def mark_item_shipped(data)
  data = data.with_indifferent_access
  occured_at = Time.current

  item = items.detect { |i| i.order_item_id == data[:id].to_s }
  return if item.blank? || data[:quantity].to_i < 1

  item.events.build(
    status: 'shipped',
    quantity: data[:quantity].to_i,
    created_at: occured_at,
    updated_at: occured_at,
    data: data.except(:id, :quantity)
  )
end

#nameString

For compatibility with admin features, models must respond to this method

Returns:



31
32
33
# File 'app/models/workarea/fulfillment.rb', line 31

def name
  id
end

#packagesObject



50
51
52
# File 'app/models/workarea/fulfillment.rb', line 50

def packages
  Package.create(events)
end

#pending_itemsObject



54
55
56
# File 'app/models/workarea/fulfillment.rb', line 54

def pending_items
  items.select { |i| i.quantity_pending > 0 }
end

#ship_items(tracking_number, shipped_items) ⇒ Boolean

Ship items in the fulfillment

The hashes should contain ‘id’, the order_item_id and ‘quantity’ the amount being shipped, any other key/values will be stored on the Fulfillment::Event#data

ship_items(‘1Z923A’, [

{ 'id' => '1234', 'quantity' => 1, 'serial_number' => '1234' },
{ 'id' => '4321', 'quantity' => 2 }

])

Parameters:

  • tracking_number (String)
  • shipped_items (Array<Hash>)

Returns:

  • (Boolean)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'app/models/workarea/fulfillment.rb', line 102

def ship_items(tracking_number, shipped_items)
  shipped_items.each do |shipped_item|
    mark_item_shipped(
      shipped_item.merge(tracking_number: tracking_number.downcase)
    )
  end

  save.tap do |result|
    if result && Workarea.config.send_transactional_emails
      Storefront::FulfillmentMailer
        .shipped(id, tracking_number)
        .deliver_later
    end
  end
end

#statusObject



35
36
37
38
# File 'app/models/workarea/fulfillment.rb', line 35

def status
  calculators = Workarea.config.fulfillment_status_calculators.map(&:constantize)
  StatusCalculator.new(calculators, self).result
end