spree_pluggto 0.0.1 → 1.0.0
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.
- checksums.yaml +4 -4
- data/app/controllers/spree/admin/pluggto_fields_controller.rb +27 -0
- data/app/controllers/spree/admin/pluggto_settings_controller.rb +2 -1
- data/app/controllers/spree/api/v1/pluggto_controller.rb +30 -0
- data/app/jobs/spree_pluggto/order_created_job.rb +23 -0
- data/app/jobs/spree_pluggto/order_updated_job.rb +7 -0
- data/app/jobs/spree_pluggto/product_updated_job.rb +7 -0
- data/app/jobs/spree_pluggto/sku_deleted_job.rb +7 -0
- data/app/jobs/spree_pluggto/update_pluggto_order_job.rb +8 -0
- data/app/jobs/spree_pluggto/upsert_all_products_job.rb +1 -1
- data/app/jobs/spree_pluggto/upsert_product_job.rb +3 -3
- data/app/models/spree_pluggto/spree/product_decorator.rb +6 -3
- data/app/models/spree_pluggto/spree/shipment_decorator.rb +24 -0
- data/app/overrides/add_pluggto_id_to_order_summary.rb +14 -0
- data/app/overrides/add_pluggto_tab_to_order_sidebar.rb +11 -0
- data/app/services/spree_pluggto/{oauth.rb → api/oauth.rb} +1 -1
- data/app/services/spree_pluggto/api/order.rb +112 -0
- data/app/services/spree_pluggto/{product.rb → api/product.rb} +20 -16
- data/app/services/spree_pluggto/{request.rb → api/request.rb} +2 -2
- data/app/services/spree_pluggto/create_spree_order.rb +122 -0
- data/app/services/spree_pluggto/delete_spree_product_reference.rb +15 -0
- data/app/services/spree_pluggto/send_integration_errors.rb +24 -0
- data/app/services/spree_pluggto/update_spree_order.rb +50 -0
- data/app/services/spree_pluggto/update_spree_product.rb +17 -0
- data/app/views/spree/admin/pluggto_fields/index.html.erb +33 -0
- data/config/locales/pt-BR.yml +1 -0
- data/config/routes.rb +13 -0
- data/db/migrate/20210713194303_add_pluggto_id_to_spree_products.rb +5 -0
- data/db/migrate/20210805194730_add_pluggto_name_to_spree_products.rb +5 -0
- data/db/migrate/20210812182652_add_pluggto_id_to_spree_shipments.rb +5 -0
- data/db/migrate/20210812190431_add_sync_with_pluggto_to_products.rb +5 -0
- data/lib/spree_pluggto/version.rb +2 -2
- metadata +26 -6
- data/app/services/spree_pluggto/api.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fe48703fbef832cd6c4fcf7336be85d018b872b44e6f299575ae2a24d04ee92
|
4
|
+
data.tar.gz: bc238a43d02ead868d093f66acec13b970f246cf04a24c66d4566382cd6abf6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c1838f27d41d18720aec4a75c0de557f864f354bc87e16ee484d2e6627b34d61114ebafb11407b9f8ac42741499d3de33c5aa558a6e4220ae5639d753e50ecb
|
7
|
+
data.tar.gz: d831df2e340db48a77c3b3660bdc92449c87ee88ebadc2df4fdbb311943fb0d26fd0b80344280c76d63f1f43d60d112f1bf512de2f1545b6e368a830a8db0940
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Spree
|
2
|
+
module Admin
|
3
|
+
class PluggtoFieldsController < ResourceController
|
4
|
+
before_action :load_product
|
5
|
+
|
6
|
+
def index
|
7
|
+
end
|
8
|
+
|
9
|
+
def update
|
10
|
+
end
|
11
|
+
|
12
|
+
def location_after_save
|
13
|
+
admin_product_pluggto_fields_url(@product)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def load_product
|
19
|
+
@product = Spree::Product.friendly.find(params[:product_id])
|
20
|
+
end
|
21
|
+
|
22
|
+
def model_class
|
23
|
+
@model_class ||= Spree::Product
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -12,12 +12,13 @@ module Spree
|
|
12
12
|
|
13
13
|
def update
|
14
14
|
@pluggto_settings.update(pluggto_settings_params)
|
15
|
+
flash[:success] = Spree.t(:pluggto_settings_updated)
|
15
16
|
redirect_to edit_admin_pluggto_settings_path
|
16
17
|
end
|
17
18
|
|
18
19
|
def upload_all_products
|
19
|
-
flash[:success] = Spree.t(:pluggto_products_being_uploaded)
|
20
20
|
::SpreePluggto::UpsertAllProductsJob.perform_later
|
21
|
+
flash[:success] = Spree.t(:pluggto_products_being_uploaded)
|
21
22
|
redirect_to edit_admin_pluggto_settings_path
|
22
23
|
end
|
23
24
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class PluggtoController < Spree::Api::BaseController
|
5
|
+
skip_before_action :authenticate_user
|
6
|
+
|
7
|
+
# The post will be send in the following format:
|
8
|
+
# {"type":"PRODUCTS/SKUS/ORDERS","id":"PLUGGTO_ID","action":"UPDATEORCREATE","user":1120, "changes" : {"status" : false,"stock" : false,"price":false }}
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# { "user" : 129, "id" : "5b9169c309eacd415056aa3a", "changes" : { "status" : false, "stock" : false, "price" : false }, "type" : "products", "action" : "updated" }
|
12
|
+
|
13
|
+
def notifications
|
14
|
+
puts "Notification received from PluggTo: #{notification_params}"
|
15
|
+
service_class = "spree_pluggto/#{notification_params[:type].singularize}_#{notification_params[:action]}_job".camelize
|
16
|
+
puts "Service: #{service_class}"
|
17
|
+
service_class.constantize.perform_later(notification_params[:id])
|
18
|
+
head :ok
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def notification_params
|
24
|
+
params.require(:pluggto).permit!
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SpreePluggto
|
2
|
+
class OrderCreatedJob < ActiveJob::Base
|
3
|
+
|
4
|
+
|
5
|
+
# sidekiq_retries_exhausted do |msg, ex|
|
6
|
+
# message = "Failed #{msg['class']} with #{msg['args']}: #{msg['error_message']}"
|
7
|
+
# ::SpreePluggto::SendIntegrationErrors.new(msg['args']).call(message)
|
8
|
+
# end
|
9
|
+
# https://edgeguides.rubyonrails.org/active_job_basics.html#exceptions
|
10
|
+
# https://stackoverflow.com/questions/32193144/in-activejob-how-to-catch-any-exception
|
11
|
+
# https://github.com/mperham/sidekiq/issues/4496#issuecomment-600714253
|
12
|
+
# https://stackoverflow.com/questions/29085458/how-to-access-perform-parameters-in-activejob-rescue
|
13
|
+
rescue_from(StandardError) do |exception|
|
14
|
+
puts "--- Problem creating plugg_to order #{arguments} ---"
|
15
|
+
puts exception
|
16
|
+
::SpreePluggto::SendIntegrationErrors.new(arguments.first).call(exception)
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform(pluggto_id)
|
20
|
+
::SpreePluggto::CreateSpreeOrder.new(pluggto_id).call
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module SpreePluggto
|
2
|
-
class UpsertProductJob <
|
2
|
+
class UpsertProductJob < ActiveJob::Base
|
3
3
|
# UPSERT => Updates the record if it exists, inserts if it is new
|
4
4
|
def perform(product_id)
|
5
|
-
product = Spree::Product.find
|
6
|
-
SpreePluggto::Product.upsert(product)
|
5
|
+
product = ::Spree::Product.find(product_id)
|
6
|
+
::SpreePluggto::Api::Product.upsert(product)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -1,15 +1,18 @@
|
|
1
1
|
module SpreePluggto
|
2
2
|
module Spree
|
3
3
|
module ProductDecorator
|
4
|
+
|
5
|
+
# https://guides.spreecommerce.org/developer/customization/logic.html
|
6
|
+
# self.prepended is needed to access class-level methods, like has_many, scopes and callbacks
|
4
7
|
def self.prepended(base)
|
5
|
-
base.after_create :upsert_pluggto_product
|
6
|
-
base.after_update :upsert_pluggto_product
|
8
|
+
base.after_create :upsert_pluggto_product, if: :sync_with_pluggto?
|
9
|
+
base.after_update :upsert_pluggto_product, if: :sync_with_pluggto?
|
7
10
|
end
|
8
11
|
|
9
12
|
private
|
10
13
|
|
11
14
|
def upsert_pluggto_product
|
12
|
-
::SpreePluggto::UpsertProductJob.perform_later(
|
15
|
+
::SpreePluggto::UpsertProductJob.perform_later(self.id)
|
13
16
|
end
|
14
17
|
|
15
18
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SpreePluggto
|
2
|
+
module Spree
|
3
|
+
module ShipmentDecorator
|
4
|
+
|
5
|
+
# https://guides.spreecommerce.org/developer/customization/logic.html
|
6
|
+
# self.prepended is needed to access class-level methods, like has_many, scopes and callbacks
|
7
|
+
def self.prepended(base)
|
8
|
+
base.state_machine.after_transition to: :shipped, do: :update_pluggto_order, if: :pluggto_order?
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def update_pluggto_order
|
14
|
+
::SpreePluggto::UpdatePluggtoOrderJob.perform_later(order.number)
|
15
|
+
end
|
16
|
+
|
17
|
+
def pluggto_order?
|
18
|
+
order.channel == "pluggto"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Spree::Shipment.prepend(SpreePluggto::Spree::ShipmentDecorator)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/admin/shared/_order_summary',
|
3
|
+
name: 'add_pluggto_id_to_order_summary',
|
4
|
+
insert_bottom: '[id="order_tab_summary"]'
|
5
|
+
) do
|
6
|
+
<<-HTML
|
7
|
+
<% if @order.pluggto_id %>
|
8
|
+
<tr>
|
9
|
+
<td><strong>Plugg.to id</strong></td>
|
10
|
+
<td><%= @order.pluggto_id %></td>
|
11
|
+
</tr>
|
12
|
+
<% end %>
|
13
|
+
HTML
|
14
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
virtual_path: 'spree/admin/shared/_product_tabs',
|
3
|
+
name: 'add_pluggto_tab_to_order_sidebar',
|
4
|
+
insert_bottom: '[data-hook="admin_product_tabs"]'
|
5
|
+
) do
|
6
|
+
<<-HTML
|
7
|
+
<%= content_tag :li, class: ('active' if current == :pluggto_fields) do %>
|
8
|
+
<%= link_to_with_icon "transfer", "Plugg.to", spree.admin_product_pluggto_fields_url(@product) %>
|
9
|
+
<% end %>
|
10
|
+
HTML
|
11
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module SpreePluggto::Api
|
2
|
+
class Order
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def find(pluggto_id)
|
6
|
+
response = ::SpreePluggto::Api::Request.new.get("/orders/#{pluggto_id}")
|
7
|
+
response["Order"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def update(spree_order)
|
11
|
+
response = ::SpreePluggto::Api::Request.new.put("/orders/#{spree_order.pluggto_id}", params(spree_order).to_json)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def pluggto_status(spree_order)
|
17
|
+
return 'canceled' if spree_order.canceled?
|
18
|
+
return 'shipping_informed' if spree_order.shipped?
|
19
|
+
return 'approved' if spree_order.shipment_state == 'ready'
|
20
|
+
return 'partial_payment' if spree_order.payment_state == 'credit_owed'
|
21
|
+
return 'pending'
|
22
|
+
end
|
23
|
+
|
24
|
+
def phone_area(number)
|
25
|
+
ddd_regex = /\((?<DDD>\d\d)\)/
|
26
|
+
ddd_regex.match(number)["DDD"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def phone_without_area(number)
|
30
|
+
number.sub(/\(..\)/, '').strip
|
31
|
+
end
|
32
|
+
|
33
|
+
def params(spree_order)
|
34
|
+
{
|
35
|
+
"status": pluggto_status(spree_order),
|
36
|
+
"subtotal": spree_order.amount,
|
37
|
+
"total": spree_order.total,
|
38
|
+
"total_paid": spree_order.payment_total.to_s,
|
39
|
+
"shipping": spree_order.shipment_total,
|
40
|
+
"discount": spree_order.adjustment_total,
|
41
|
+
"external": spree_order.number,
|
42
|
+
|
43
|
+
"receiver_email": spree_order.email,
|
44
|
+
"receiver_name": spree_order.ship_address.firstname,
|
45
|
+
"receiver_lastname": spree_order.ship_address.lastname,
|
46
|
+
"receiver_address": spree_order.ship_address.address1,
|
47
|
+
"receiver_address_number": spree_order.ship_address.street_number,
|
48
|
+
"receiver_address_complement": spree_order.ship_address.address2,
|
49
|
+
"receiver_city": spree_order.ship_address.city,
|
50
|
+
"receiver_neighborhood": spree_order.ship_address.neighborhood,
|
51
|
+
"receiver_state": spree_order.ship_address.state.abbr,
|
52
|
+
"receiver_zipcode": spree_order.ship_address.zipcode,
|
53
|
+
"receiver_phone": phone_without_area(spree_order.ship_address.phone),
|
54
|
+
"receiver_phone_area": phone_area(spree_order.ship_address.phone),
|
55
|
+
|
56
|
+
"payer_email": spree_order.email,
|
57
|
+
"payer_name": spree_order.bill_address.firstname,
|
58
|
+
"payer_lastname": spree_order.bill_address.lastname,
|
59
|
+
"payer_address": spree_order.bill_address.address1,
|
60
|
+
"payer_address_number": spree_order.bill_address.street_number,
|
61
|
+
"payer_address_complement": spree_order.bill_address.address2,
|
62
|
+
"payer_city": spree_order.bill_address.city,
|
63
|
+
"payer_neighborhood": spree_order.bill_address.neighborhood,
|
64
|
+
"payer_state": spree_order.bill_address.state.abbr,
|
65
|
+
"payer_zipcode": spree_order.bill_address.zipcode,
|
66
|
+
"payer_phone": phone_without_area(spree_order.bill_address.phone),
|
67
|
+
"payer_phone_area": phone_area(spree_order.bill_address.phone),
|
68
|
+
"payer_cpf": spree_order.cpf,
|
69
|
+
|
70
|
+
"shipments": spree_order.shipments.map { |shipment|
|
71
|
+
{
|
72
|
+
"id": shipment.pluggto_id,
|
73
|
+
"estimate_delivery_date": (shipment.expected_delivery_date if shipment.shipped?),
|
74
|
+
"nfe_date": (shipment.shipped_at.to_date if shipment.shipped?),
|
75
|
+
"nfe_key": (shipment.get_invoice_key if shipment.shipped?),
|
76
|
+
"track_url": (shipment.tracking_url_with_code if shipment.shipped?),
|
77
|
+
"nfe_link": (shipment.get_invoice_pdf if shipment.shipped?),
|
78
|
+
"external": shipment.number,
|
79
|
+
"shipping_company": shipment.shipping_method.name,
|
80
|
+
"shipping_method": shipment.shipping_method.name,
|
81
|
+
"track_code": shipment.tracking,
|
82
|
+
"date_shipped": shipment.shipped_at&.to_date,
|
83
|
+
"nfe_number": shipment.nf_number&.split("/")&.first,
|
84
|
+
"nfe_serie": shipment.nf_number&.split("/")&.last,
|
85
|
+
"shipping_items": shipment.line_items.map { |line_item|
|
86
|
+
{
|
87
|
+
"sku": line_item.sku,
|
88
|
+
"quantity": line_item.quantity
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
},
|
93
|
+
|
94
|
+
"items": spree_order.line_items.map { |line_item|
|
95
|
+
{
|
96
|
+
"quantity": line_item.quantity,
|
97
|
+
"sku": line_item.sku,
|
98
|
+
"price": line_item.price,
|
99
|
+
"total": line_item.total,
|
100
|
+
"name": line_item.name,
|
101
|
+
"variation": {
|
102
|
+
"sku": line_item.sku
|
103
|
+
},
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
}.compact
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -1,31 +1,34 @@
|
|
1
|
-
module SpreePluggto
|
1
|
+
module SpreePluggto::Api
|
2
2
|
class Product
|
3
3
|
class << self
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def find(pluggto_id)
|
6
|
+
response = ::SpreePluggto::Api::Request.new.get("/products/#{pluggto_id}")
|
7
|
+
response["Product"]
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# UPSERT => Updates the record if it exists, inserts if it is a new record
|
11
|
+
def upsert(spree_product)
|
12
|
+
response = ::SpreePluggto::Api::Request.new.put("/skus/#{spree_product.sku}", params(spree_product).to_json)
|
13
|
+
spree_product.update_columns(pluggto_id: response.dig("Product","id"))
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
private
|
15
17
|
|
16
18
|
def params(product)
|
19
|
+
description = ::ActionView::Helpers::TextHelper.simple_format(product.description) + "<br/><u>MAIS INFORMAÇÕES:</u><br/>".html_safe + product.info.html_safe
|
17
20
|
{
|
18
21
|
"sku": product.sku,
|
19
|
-
"name": product.name,
|
20
|
-
"special_price": product.on_sale? ? product.sale_price :
|
22
|
+
"name": product.pluggto_name.present? ? product.pluggto_name : product.name,
|
23
|
+
"special_price": product.on_sale? ? product.sale_price : product.price,
|
21
24
|
"price": product.price,
|
22
|
-
"description":
|
23
|
-
"brand":
|
25
|
+
"description": description,
|
26
|
+
"brand": "Nordweg",
|
24
27
|
"warranty_time": product.try(:months_of_warranty),
|
25
28
|
"warranty_message": product.lifetime_warranty? ? "Garantia vitalícia" : "",
|
26
29
|
"link": "#{::Rails.application.routes.url_helpers.spree_url}products/#{product.slug}",
|
27
30
|
"categories": product.taxons.map { |taxon| {"name": taxon.name } },
|
28
|
-
"handling_time": Spree::Config.try(:handling_time),
|
31
|
+
"handling_time": ::Spree::Config.try(:handling_time),
|
29
32
|
"ean_not_mandatory": true,
|
30
33
|
"dimension": {
|
31
34
|
"length": product.depth,
|
@@ -36,8 +39,8 @@ module SpreePluggto
|
|
36
39
|
"photos": product.images.map { |image|
|
37
40
|
{
|
38
41
|
"url": image.attachment.url(:big),
|
39
|
-
"name": name,
|
40
|
-
"title": name,
|
42
|
+
"name": product.name,
|
43
|
+
"title": product.name,
|
41
44
|
"order": image.position,
|
42
45
|
"external": image.attachment.url(:big)
|
43
46
|
}
|
@@ -47,8 +50,9 @@ module SpreePluggto
|
|
47
50
|
"sku": variant.sku,
|
48
51
|
"name": variant.name,
|
49
52
|
"quantity": variant.total_on_hand.finite? ? variant.total_on_hand : 99,
|
50
|
-
"special_price": variant.product.on_sale? ? variant.product.sale_price :
|
53
|
+
"special_price": variant.product.on_sale? ? variant.product.sale_price : variant.price,
|
51
54
|
"price": variant.price,
|
55
|
+
"ean_not_mandatory": true,
|
52
56
|
"attributes": variant.option_values.map { |option_value|
|
53
57
|
{
|
54
58
|
"code": option_value.option_type.name,
|
@@ -56,7 +60,7 @@ module SpreePluggto
|
|
56
60
|
"value": { "code": option_value.name, "label": option_value.name }
|
57
61
|
}
|
58
62
|
},
|
59
|
-
"photos":
|
63
|
+
"photos": variant.images.map { |image|
|
60
64
|
{
|
61
65
|
"url": image.attachment.url(:big),
|
62
66
|
"name": variant.name,
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Creates on Spree e new order after it was created on Pluggto
|
2
|
+
module SpreePluggto
|
3
|
+
class CreateSpreeOrder
|
4
|
+
attr_reader :pluggto_id
|
5
|
+
|
6
|
+
def initialize(pluggto_id)
|
7
|
+
@pluggto_id = pluggto_id
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
# Skip creation if the order was already created on Spree
|
12
|
+
return if ::Spree::Order.find_by(pluggto_id: pluggto_id)
|
13
|
+
|
14
|
+
# Get info Plugg
|
15
|
+
pluggto_order = ::SpreePluggto::Api::Order.find(pluggto_id)
|
16
|
+
|
17
|
+
# Create the order on Spree
|
18
|
+
spree_order = ::Spree::Order.create(
|
19
|
+
channel: "pluggto",
|
20
|
+
pluggto_id: pluggto_order["id"],
|
21
|
+
user: ::Spree::User.find_by(email: pluggto_order["receiver_email"]),
|
22
|
+
email: pluggto_order["receiver_email"],
|
23
|
+
cpf: pluggto_order["receiver_cpf"] || pluggto_order["payer_cpf"],
|
24
|
+
)
|
25
|
+
|
26
|
+
# Add line items
|
27
|
+
pluggto_order["items"].each do |pluggto_item|
|
28
|
+
spree_order.line_items.new(
|
29
|
+
variant: ::Spree::Variant.find_by!(sku: pluggto_item["sku"]),
|
30
|
+
quantity: pluggto_item["quantity"],
|
31
|
+
price: pluggto_item["price"]
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Go to Addres
|
36
|
+
spree_order.next
|
37
|
+
|
38
|
+
# Add ship_address
|
39
|
+
spree_order.ship_address = ::Spree::Address.new(
|
40
|
+
firstname: pluggto_order["receiver_name"],
|
41
|
+
lastname: pluggto_order["receiver_lastname"],
|
42
|
+
address1: pluggto_order["receiver_address"],
|
43
|
+
address2: "#{pluggto_order["receiver_address_complement"]} - #{pluggto_order["receiver_address_reference"]}",
|
44
|
+
neighborhood: pluggto_order["receiver_neighborhood"],
|
45
|
+
street_number: pluggto_order["receiver_address_number"],
|
46
|
+
city: pluggto_order["receiver_city"],
|
47
|
+
zipcode: pluggto_order["receiver_zipcode"],
|
48
|
+
phone: "(#{pluggto_order['receiver_phone_area']}) #{pluggto_order['receiver_phone']}",
|
49
|
+
state_name: pluggto_order["receiver_state"],
|
50
|
+
state: ::Spree::State.find_by(abbr: pluggto_order["receiver_state"]),
|
51
|
+
alternative_phone: "(#{pluggto_order['receiver_phone2_area']}) #{pluggto_order['receiver_phone2']}",
|
52
|
+
country: ::Spree::Country.find_by(iso: "BR")
|
53
|
+
)
|
54
|
+
|
55
|
+
# Add bill_address
|
56
|
+
spree_order.bill_address = ::Spree::Address.new(
|
57
|
+
firstname: pluggto_order["payer_name"],
|
58
|
+
lastname: pluggto_order["payer_lastname"],
|
59
|
+
address1: pluggto_order["payer_address"],
|
60
|
+
address2: "#{pluggto_order["payer_address_complement"]} - #{pluggto_order["payer_address_reference"]}",
|
61
|
+
neighborhood: pluggto_order["payer_neighborhood"],
|
62
|
+
street_number: pluggto_order["payer_address_number"],
|
63
|
+
city: pluggto_order["payer_city"],
|
64
|
+
zipcode: pluggto_order["payer_zipcode"],
|
65
|
+
phone: "(#{pluggto_order['payer_phone_area']}) #{pluggto_order['payer_phone']}",
|
66
|
+
state_name: pluggto_order["payer_state"],
|
67
|
+
state: ::Spree::State.find_by(abbr: pluggto_order["payer_state"]),
|
68
|
+
alternative_phone: "(#{pluggto_order['payer_phone2_area']}) #{pluggto_order['payer_phone2']}",
|
69
|
+
country: ::Spree::Country.find_by(iso: "BR")
|
70
|
+
)
|
71
|
+
|
72
|
+
# Go to delivery
|
73
|
+
spree_order.next!
|
74
|
+
|
75
|
+
# Go to payment
|
76
|
+
spree_order.next!
|
77
|
+
|
78
|
+
# By calling 'next' the first shipping option was selected,
|
79
|
+
# we need to set it up according to what we received from Pluggto
|
80
|
+
spree_order.shipments.first.update_columns(
|
81
|
+
cost: pluggto_order["shipping"],
|
82
|
+
pluggto_id: pluggto_order.dig("shipments",0,"id")
|
83
|
+
)
|
84
|
+
spree_order.update_columns(
|
85
|
+
shipment_total: pluggto_order["shipping"]
|
86
|
+
)
|
87
|
+
|
88
|
+
# Add discounts
|
89
|
+
if pluggto_order["discount"].present? && pluggto_order["discount"] > 0
|
90
|
+
spree_order.adjustments.create(
|
91
|
+
order: spree_order,
|
92
|
+
label: "Desconto via Plugg.to",
|
93
|
+
amount: pluggto_order["discount"] * -1,
|
94
|
+
eligible: true
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Update the total after discounts
|
99
|
+
spree_order.update_totals
|
100
|
+
|
101
|
+
# Add payments
|
102
|
+
pluggto_order["payments"].each do |pluggto_payment|
|
103
|
+
spree_order.payments.create(
|
104
|
+
payment_method: ::Spree::PaymentMethod.find_by(type:"Spree::PaymentMethod::StoreCredit"), # Not ideal - we should define a specific payment method referring to PluggTo
|
105
|
+
installments: pluggto_payment["payment_installments"],
|
106
|
+
amount: pluggto_payment["payment_total"],
|
107
|
+
state: "completed"
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Completes the order
|
112
|
+
# The "Pending" on Pluggto is NOT "Paid", even if it has payments
|
113
|
+
# We should force the payments status according to the plugg_order status
|
114
|
+
spree_order.update_columns(
|
115
|
+
state: 'complete',
|
116
|
+
completed_at: DateTime.now,
|
117
|
+
payment_state: pluggto_order["status"] == 'approved' ? 'paid' : 'balance_due'
|
118
|
+
)
|
119
|
+
spree_order.fulfill! if spree_order.paid?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# When a product is deleted on Plugg, we remove the pluggto_id reference on Spree
|
2
|
+
module SpreePluggto
|
3
|
+
class DeleteSpreeProductReference
|
4
|
+
attr_accessor :spree_product
|
5
|
+
|
6
|
+
def initialize(sku)
|
7
|
+
variant = ::Spree::Variant.find_by!(sku: sku)
|
8
|
+
@spree_product = variant.product
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
spree_product.update_columns(pluggto_id: nil)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SpreePluggto
|
2
|
+
class SendIntegrationErrors
|
3
|
+
attr_reader :pluggto_id
|
4
|
+
|
5
|
+
def initialize(pluggto_id)
|
6
|
+
@pluggto_id = pluggto_id
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(error)
|
10
|
+
::SpreePluggto::Api::Request.new.put("/orders/#{pluggto_id}", params(error).to_json)
|
11
|
+
end
|
12
|
+
|
13
|
+
def params(error)
|
14
|
+
{
|
15
|
+
"log_history": [
|
16
|
+
{
|
17
|
+
"message": "#{error}",
|
18
|
+
"date": "#{DateTime.now}"
|
19
|
+
}
|
20
|
+
]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Gets updates from an order on Pluggto and updates the order on Spree
|
2
|
+
module SpreePluggto
|
3
|
+
class UpdateSpreeOrder
|
4
|
+
attr_reader :pluggto_order
|
5
|
+
attr_accessor :spree_order
|
6
|
+
|
7
|
+
def initialize(pluggto_id)
|
8
|
+
@pluggto_order = ::SpreePluggto::Api::Order.find(pluggto_id)
|
9
|
+
@spree_order = ::Spree::Order.find_by!(pluggto_id: pluggto_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
case pluggto_order["status"]
|
14
|
+
when 'pending'
|
15
|
+
update_payments
|
16
|
+
when 'approved'
|
17
|
+
update_payments
|
18
|
+
set_as_paid
|
19
|
+
if !spree_order.shipped?
|
20
|
+
set_as_ready
|
21
|
+
spree_order.fulfill!
|
22
|
+
end
|
23
|
+
when 'canceled'
|
24
|
+
spree_order.update_columns(state: 'canceled')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def update_payments
|
31
|
+
pluggto_order["payments"].each do |pluggto_payment|
|
32
|
+
spree_order.payments.find_or_create_by(
|
33
|
+
payment_method: ::Spree::PaymentMethod.find_by(type:"Spree::PaymentMethod::StoreCredit"), # Not ideal - we should define a specific payment method referring to PluggTo
|
34
|
+
amount: pluggto_payment["payment_total"],
|
35
|
+
installments: pluggto_payment["payment_installments"],
|
36
|
+
state: "completed"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_as_ready
|
42
|
+
spree_order.update_columns(shipment_state: 'ready')
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_as_paid
|
46
|
+
spree_order.update_columns(payment_state: 'paid')
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Gets updates from a product on Pluggto and updates the product on Spree
|
2
|
+
module SpreePluggto
|
3
|
+
class UpdateSpreeProduct
|
4
|
+
attr_reader :pluggto_product
|
5
|
+
attr_accessor :spree_product
|
6
|
+
|
7
|
+
def initialize(pluggto_id)
|
8
|
+
@pluggto_product = SpreePluggto::Api::Product.find(pluggto_id)
|
9
|
+
@spree_product = ::Spree::Product.find_by!(pluggto_id: pluggto_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
# Logic here to define what we want to update on Spree when PluggTo say a product was updated
|
14
|
+
# Only stock?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%= render partial: 'spree/admin/shared/product_tabs', locals: { current: :pluggto_fields } %>
|
2
|
+
|
3
|
+
<%= form_for [:admin, @product], method: :put do |f| %>
|
4
|
+
|
5
|
+
<fieldset>
|
6
|
+
<div class="row">
|
7
|
+
<div class="col-xs-12 col-md-8" data-hook="admin_product_pluggto_fields">
|
8
|
+
<%= f.field_container :pluggto_id, class: ['form-group'] do %>
|
9
|
+
<%= f.label :sync_with_pluggto, "Sincronizar com Plugg.to" %>
|
10
|
+
<%= f.check_box :sync_with_pluggto %>
|
11
|
+
<%= f.error_message_on :sync_with_pluggto %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= f.field_container :pluggto_name, class: ['form-group'] do %>
|
15
|
+
<%= f.label :pluggto_name, "Nome no Plugg.to" %>
|
16
|
+
<%= f.text_field :pluggto_name, class: 'form-control', placeholder: "Deixe em branco para usar o nome original do produto" %>
|
17
|
+
<%= f.error_message_on :pluggto_name %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<%= f.field_container :pluggto_id, class: ['form-group'] do %>
|
21
|
+
<%= f.label :pluggto_id, "ID no Plugg.to" %>
|
22
|
+
<%= f.text_field :pluggto_id, class: 'form-control', readonly: true %>
|
23
|
+
<%= f.error_message_on :pluggto_id %>
|
24
|
+
<% end %>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
|
29
|
+
<%= render partial: 'spree/admin/shared/edit_resource_links' %>
|
30
|
+
|
31
|
+
</fieldset>
|
32
|
+
|
33
|
+
<% end %>
|
data/config/locales/pt-BR.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -3,5 +3,18 @@ Spree::Core::Engine.routes.draw do
|
|
3
3
|
resource :pluggto_settings do
|
4
4
|
get :upload_all_products
|
5
5
|
end
|
6
|
+
resources :products do
|
7
|
+
resources :pluggto_fields, except: [:destroy]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :api do
|
12
|
+
namespace :v1 do
|
13
|
+
namespace :pluggto, defaults: {format: :json} do
|
14
|
+
post :notifications
|
15
|
+
end
|
16
|
+
end
|
6
17
|
end
|
18
|
+
|
19
|
+
# post "/pluggto/api/pluggto/notifications", to: 'api/v1/pluggto#notifications'
|
7
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_pluggto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Kuhn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spree_core
|
@@ -280,22 +280,42 @@ files:
|
|
280
280
|
- app/assets/javascripts/spree/frontend/spree_pluggto.js
|
281
281
|
- app/assets/stylesheets/spree/backend/spree_pluggto.css
|
282
282
|
- app/assets/stylesheets/spree/frontend/spree_pluggto.css
|
283
|
+
- app/controllers/spree/admin/pluggto_fields_controller.rb
|
283
284
|
- app/controllers/spree/admin/pluggto_settings_controller.rb
|
285
|
+
- app/controllers/spree/api/v1/pluggto_controller.rb
|
286
|
+
- app/jobs/spree_pluggto/order_created_job.rb
|
287
|
+
- app/jobs/spree_pluggto/order_updated_job.rb
|
288
|
+
- app/jobs/spree_pluggto/product_updated_job.rb
|
289
|
+
- app/jobs/spree_pluggto/sku_deleted_job.rb
|
290
|
+
- app/jobs/spree_pluggto/update_pluggto_order_job.rb
|
284
291
|
- app/jobs/spree_pluggto/upsert_all_products_job.rb
|
285
292
|
- app/jobs/spree_pluggto/upsert_product_job.rb
|
286
293
|
- app/models/pluggto_settings.rb
|
287
294
|
- app/models/spree_pluggto/spree/product_decorator.rb
|
295
|
+
- app/models/spree_pluggto/spree/shipment_decorator.rb
|
296
|
+
- app/overrides/add_pluggto_id_to_order_summary.rb
|
297
|
+
- app/overrides/add_pluggto_tab_to_order_sidebar.rb
|
288
298
|
- app/overrides/add_settings_to_admin_configurations.rb
|
289
|
-
- app/services/spree_pluggto/api.rb
|
290
|
-
- app/services/spree_pluggto/
|
291
|
-
- app/services/spree_pluggto/product.rb
|
292
|
-
- app/services/spree_pluggto/request.rb
|
299
|
+
- app/services/spree_pluggto/api/oauth.rb
|
300
|
+
- app/services/spree_pluggto/api/order.rb
|
301
|
+
- app/services/spree_pluggto/api/product.rb
|
302
|
+
- app/services/spree_pluggto/api/request.rb
|
303
|
+
- app/services/spree_pluggto/create_spree_order.rb
|
304
|
+
- app/services/spree_pluggto/delete_spree_product_reference.rb
|
305
|
+
- app/services/spree_pluggto/send_integration_errors.rb
|
306
|
+
- app/services/spree_pluggto/update_spree_order.rb
|
307
|
+
- app/services/spree_pluggto/update_spree_product.rb
|
308
|
+
- app/views/spree/admin/pluggto_fields/index.html.erb
|
293
309
|
- app/views/spree/admin/pluggto_settings/edit.html.erb
|
294
310
|
- bin/rails
|
295
311
|
- config/locales/en.yml
|
296
312
|
- config/locales/pt-BR.yml
|
297
313
|
- config/routes.rb
|
298
314
|
- db/migrate/20210706173803_create_pluggto_settings.rb
|
315
|
+
- db/migrate/20210713194303_add_pluggto_id_to_spree_products.rb
|
316
|
+
- db/migrate/20210805194730_add_pluggto_name_to_spree_products.rb
|
317
|
+
- db/migrate/20210812182652_add_pluggto_id_to_spree_shipments.rb
|
318
|
+
- db/migrate/20210812190431_add_sync_with_pluggto_to_products.rb
|
299
319
|
- lib/generators/spree_pluggto/install/install_generator.rb
|
300
320
|
- lib/spree_pluggto.rb
|
301
321
|
- lib/spree_pluggto/engine.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module SpreePluggto
|
2
|
-
class Api
|
3
|
-
def find_product(spree_product)
|
4
|
-
SpreePluggto::Request.new.get("/products/{pluggto_product_id}")
|
5
|
-
end
|
6
|
-
|
7
|
-
def upset_product(spree_product)
|
8
|
-
SpreePluggto::Request.new.put("/skus/#{product.sku}", product.pluggto_product.to_json)
|
9
|
-
end
|
10
|
-
|
11
|
-
def upsert_variant(spree_variant)
|
12
|
-
SpreePluggto::Request.new.put("/skus/#{spree_variant.sku}", body)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|