Skip to content

Commit

Permalink
Integrate envialia courier
Browse files Browse the repository at this point in the history
  • Loading branch information
pdrowr authored Nov 26, 2021
1 parent 3144135 commit 4d7b362
Show file tree
Hide file tree
Showing 13 changed files with 1,729 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.2.0] - 2021-11-03
### Added
- `Address` can now include a custom id for couriers that support it (currently only Correos Express).
- Envialia courier integration

## [0.1.1] - 2021-10-11
### Fixed
Expand All @@ -25,4 +26,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[0.2.1]: https://github.com/ecommerce-ventures/deliveries/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/ecommerce-ventures/deliveries/compare/v0.1.1...v0.2.0
[0.1.1]: https://github.com/ecommerce-ventures/deliveries/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/ecommerce-ventures/deliveries/releases/tag/v0.1.0
[0.1.0]: https://github.com/ecommerce-ventures/deliveries/releases/tag/v0.1.0
93 changes: 93 additions & 0 deletions lib/deliveries/couriers/envialia.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
require_relative 'envialia/authentication'
require_relative 'envialia/shipments/create'
require_relative 'envialia/shipments/trace/format_response'
require_relative 'envialia/shipments/trace'
require_relative 'envialia/pickups/trace/format_response'
require_relative 'envialia/pickups/trace'
require_relative 'envialia/pickups/create'
require_relative 'envialia/labels/generate'

module Deliveries
module Couriers
module Envialia
extend Courier

Config = Struct.new(
:username,
:password,
:agency_code
)

ENVIALIA_LOGIN_ENDPOINT_LIVE = 'http://ws.envialia.com/SOAP?service=LoginService'.freeze
ENVIALIA_LOGIN_ENDPOINT_TEST = 'http://wstest.envialia.com:9085/SOAP?service=LoginService'.freeze
ENVIALIA_ENDPOINT_LIVE = 'http://ws.envialia.com/SOAP?service=WebServService'.freeze
ENVIALIA_ENDPOINT_TEST = 'http://wstest.envialia.com:9085/SOAP?service=WebServService'.freeze

module_function

def create_shipment(sender:, receiver:, parcels:, reference_code:, collection_point: nil, shipment_date: nil, remarks: nil, **)
Shipments::Create.new(
sender: sender,
receiver: receiver,
collection_point: collection_point,
shipment_date: shipment_date,
parcels: parcels,
reference_code: reference_code,
remarks: remarks
).execute
end

def create_pickup(sender:, receiver:, parcels:, reference_code:, pickup_date: nil, remarks: nil, tracking_code: nil, **)
Pickups::Create.new(
sender: sender,
receiver: receiver,
parcels: parcels,
reference_code: reference_code,
pickup_date: pickup_date,
remarks: remarks,
tracking_code: tracking_code
).execute
end

def shipment_info(tracking_code:, **)
response = Shipments::Trace.new(
tracking_code: tracking_code
).execute

tracking_info_params = Shipments::Trace::FormatResponse.new(response: response).execute
tracking_info_params.merge!({ tracking_code: tracking_code })
Deliveries::TrackingInfo.new(**tracking_info_params)
end

def pickup_info(tracking_code:, **)
response = Pickups::Trace.new(
tracking_code: tracking_code
).execute

tracking_info_params = Pickups::Trace::FormatResponse.new(response: response).execute
tracking_info_params.merge!({ tracking_code: tracking_code })
Deliveries::TrackingInfo.new(**tracking_info_params)
end

def get_label(tracking_code:, **)
pdf = Labels::Generate.new(
tracking_codes: tracking_code
).execute.first

Deliveries::Label.new(raw: pdf)
end

def get_labels(tracking_codes:, **)
labels = Deliveries::Labels.new

Labels::Generate.new(
tracking_codes: tracking_codes
).execute.each do |pdf|
labels << pdf
end

labels
end
end
end
end
50 changes: 50 additions & 0 deletions lib/deliveries/couriers/envialia/authentication.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'httparty'

module Deliveries
module Couriers
module Envialia
module Authentication
include HTTParty

def session_id
response = HTTParty.post(
login_endpoint,
body: login_body,
headers: login_headers,
debug_output: Deliveries.debug ? Deliveries.logger : nil
)

raise Deliveries::ClientError unless response.success?

response.dig('Envelope', 'Header', 'ROClientIDHeader', 'ID')
end

def login_body
<<~XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<tns:LoginWSService___LoginCli2 xmlns:tns="http://tempuri.org/">
<strCodAge>#{Deliveries.courier(:envialia).config(:agency_code)}</strCodAge>
<strCliente>#{Deliveries.courier(:envialia).config(:username)}</strCliente>
<strPass>#{Deliveries.courier(:envialia).config(:password)}</strPass>
</tns:LoginWSService___LoginCli2>
</soapenv:Body>
</soapenv:Envelope>
XML
end

def login_headers
{ 'Content-Type' => 'application/json;charset=UTF-8', 'Accept' => 'application/json' }
end

def login_endpoint
if Envialia.live?
Envialia::ENVIALIA_LOGIN_ENDPOINT_LIVE
else
Envialia::ENVIALIA_LOGIN_ENDPOINT_TEST
end
end
end
end
end
end
88 changes: 88 additions & 0 deletions lib/deliveries/couriers/envialia/labels/generate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
require 'httparty'

module Deliveries
module Couriers
module Envialia
module Labels
class Generate
include HTTParty
include Authentication

attr_accessor :tracking_codes

def initialize(tracking_codes:)
self.tracking_codes = tracking_codes.respond_to?(:each) ? tracking_codes : [tracking_codes]
end

def execute
decoded_labels = []

tracking_codes.each do |tracking_code|
response = self.class.post(
api_endpoint,
body: body(tracking_code),
headers: headers,
debug_output: Deliveries.debug ? Deliveries.logger : nil
)

raise Deliveries::ClientError unless response.success?

labels = response.dig('Envelope', 'Body', 'WebServService___ConsEtiquetaEnvio6Response', 'strEtiquetas')

if labels.blank?
raise Deliveries::APIError.new(
'No hay etiqutas disponibles',
404
)
else
decoded_labels << Base64.decode64(labels).force_encoding('binary')
end
end

decoded_labels
end

private

def body(tracking_code)
<<~XML
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ROClientIDHeader xmlns="http://tempuri.org/">
<ID>#{session_id}</ID>
</ROClientIDHeader>
</soap:Header>
<soap:Body>
<WebServService___ConsEtiquetaEnvio6>
<strCodAgeOri>#{Deliveries.courier(:envialia).config(:agency_code)}</strCodAgeOri>
<strAlbaran>#{tracking_code}</strAlbaran>
<strBulto></strBulto>
<boPaginaA4>false</boPaginaA4>
<intNumEtiqImpresasA4>0</intNumEtiqImpresasA4>
<strFormato>PDF</strFormato>
</WebServService___ConsEtiquetaEnvio6>
</soap:Body>
</soap:Envelope>
XML
end

def headers
{ 'Content-Type' => 'application/json;charset=UTF-8', 'Accept' => 'application/json' }
end

def api_endpoint
if Envialia.live?
Envialia::ENVIALIA_ENDPOINT_LIVE
else
Envialia::ENVIALIA_ENDPOINT_TEST
end
end
end
end
end
end
end
147 changes: 147 additions & 0 deletions lib/deliveries/couriers/envialia/pickups/create.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
require 'httparty'

module Deliveries
module Couriers
module Envialia
module Pickups
class Create
include HTTParty
include Authentication

attr_accessor :sender, :receiver, :parcels,
:reference_code, :pickup_date, :remarks, :tracking_code

def initialize(sender:, receiver:, parcels:,
reference_code:, pickup_date:, remarks:, tracking_code:)

self.sender = sender
self.receiver = receiver
self.parcels = parcels
self.reference_code = reference_code
self.pickup_date = pickup_date
self.remarks = remarks
self.tracking_code = tracking_code
end

def execute
response = self.class.post(
api_endpoint,
body: body,
headers: headers,
debug_output: Deliveries.debug ? Deliveries.logger : nil
)

raise Deliveries::ClientError unless response.success?

pickup_number = response.dig('Envelope', 'Body', 'WebServService___GrabaRecogida3Response', 'strCodOut')

if pickup_number
Deliveries::Pickup.new(
courier_id: 'envialia',
sender: sender,
receiver: receiver,
parcels: parcels,
reference_code: reference_code,
tracking_code: pickup_number,
pickup_date: pickup_date
)
else
exception = response.dig('Envelope', 'Body', 'Fault')

if exception['faultcode'].eql?('Exception')
exception_code, exception_str = exception['faultstring'].split(':')
else
exception_code = 400
exception_str = exception['faultstring']
end

raise Deliveries::APIError.new(
exception_str.strip,
exception_code.to_i
)
end
end

private

def body
<<~XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<ROClientIDHeader xmlns="http://tempuri.org/">
<ID>#{session_id}</ID>
</ROClientIDHeader>
</soap:Header>
<soap:Body>
<WebServService___GrabaRecogida3 xmlns="http://tempuri.org/">
<strCod></strCod>
<strAlbaran>#{tracking_code}</strAlbaran>
<strCodAgeCargo>#{Deliveries.courier(:envialia).config(:agency_code)}</strCodAgeCargo>
<strCodAgeOri></strCodAgeOri>
<dtFecRec>#{pickup_date.strftime('%Y/%m/%d')}</dtFecRec>
<strNomOri>#{sender.name}</strNomOri>
<strPobOri>#{sender.city}</strPobOri>
<strDirOri>#{sender.street}</strDirOri>
<strCPOri>#{format_postcode(sender.postcode, sender.country)}</strCPOri>
<strTlfOri>#{sender.phone}</strTlfOri>
<strNomDes>#{receiver.name}</strNomDes>
<strPobDes>#{receiver.city}</strPobDes>
<strDirDes>#{receiver.street}</strDirDes>
<strCPDes>#{format_postcode(receiver.postcode, receiver.country)}</strCPDes>
<strTlfDes>#{receiver.phone}</strTlfDes>
<strCodPais>#{receiver.country}</strCodPais>
<intBul>#{parcels}</intBul>
<strCodTipoServ>72</strCodTipoServ>
<dPesoOri>0</dPesoOri>
<dAltoOri>0</dAltoOri>
<dAnchoOri>0</dAnchoOri>
<dLargoOri>0</dLargoOri>
<dReembolso>0</dReembolso>
<dValor>0</dValor>
<dAnticipo>0</dAnticipo>
<dCobCli>0</dCobCli>
<strObs>#{remarks}</strObs>
<boSabado>false</boSabado>
<boRetorno>false</boRetorno>
<boGestOri>false</boGestOri>
<boGestDes>false</boGestDes>
<boAnulado>false</boAnulado>
<boAcuse>false</boAcuse>
<strRef>#{reference_code}</strRef>
<dBaseImp>0</dBaseImp>
<dImpuesto>0</dImpuesto>
<boPorteDebCli>false</boPorteDebCli>
<strDesDirEmails>#{receiver.email}</strDesDirEmails>
<boCampo5>false</boCampo5>
<boPagoDUAImp>false</boPagoDUAImp>
<boPagoImpDes>false</boPagoImpDes>
</WebServService___GrabaRecogida3>
</soap:Body>
</soap:Envelope>
XML
end

def headers
{ 'Content-Type' => 'application/json;charset=UTF-8', 'Accept' => 'application/json' }
end

def api_endpoint
if Envialia.live?
Envialia::ENVIALIA_ENDPOINT_LIVE
else
Envialia::ENVIALIA_ENDPOINT_TEST
end
end

def format_postcode(postcode, country)
if country.to_sym.downcase == :pt
postcode&.split('-')&.first
else
postcode
end
end
end
end
end
end
end
Loading

0 comments on commit 4d7b362

Please sign in to comment.