Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLS FR via REST Web Service #138

Merged
merged 4 commits into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Please use version < 1.0.0 (python2 branch) in that case.
from roulier import roulier

payload= {
"auth": {
"auth": {
"login": "12345",
"password": "password",
},
Expand Down Expand Up @@ -72,6 +72,7 @@ print(roulier.get_carriers_action_available())
* [@hparfr](https://github.com/hparfr) ([Akretion.com](https://akretion.com))
* [@damdam-s](https://github.com/damdam-s) ([Camp2Camp.com](http://camptocamp.com))
* [@bealdav](https://github.com/bealdav) ([Akretion.com](https://akretion.com))
* [@DylannCordel](https://github.com/DylannCordel) ([Webu.coop](https://www.webu.coop))


### Dependencies
Expand Down
3 changes: 2 additions & 1 deletion roulier/carriers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from . import laposte_fr
from . import gls_fr
from .gls_fr import rest as gls_fr_rest
from .gls_fr import glsbox as gls_fr_glsbox
from . import chronopost_fr

# from . import geodis
Expand Down
2 changes: 1 addition & 1 deletion roulier/carriers/chronopost_fr/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def soap_wrap(self, body):
data = template.render(body=body)
return data.encode("utf8")

def _get_requests_headers(self):
def _get_requests_headers(self, payload=None):
return {"content-type": "text/xml"}

def handle_500(self, response):
Expand Down
7 changes: 0 additions & 7 deletions roulier/carriers/gls_fr/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +0,0 @@
__version__ = "0.1.0"

from . import api
from . import decoder
from . import encoder
from . import transport
from . import carrier_action
7 changes: 7 additions & 0 deletions roulier/carriers/gls_fr/glsbox/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
__version__ = "0.1.0"

from . import api
from . import carrier_action
from . import decoder
from . import encoder
from . import transport
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Implementation for Laposte."""
from ...carrier_action import CarrierGetLabel
from ...roulier import factory

from roulier.carrier_action import CarrierGetLabel
from roulier.roulier import factory

from .encoder import GlsEncoder
from .decoder import GlsDecoder
from .transport import GlsTransport
Expand All @@ -20,4 +22,4 @@ class GlsFrGetabel(CarrierGetLabel):
web_service_coding = "ISO-8859-1"


factory.register_builder("gls_fr", "get_label", GlsFrGetabel)
factory.register_builder("gls_fr_glsbox", "get_label", GlsFrGetabel)
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""Gls weird string -> Python"""

import base64
from io import BytesIO
import logging
import os
from io import BytesIO
import re
from string import Template

from roulier.codec import DecoderGetLabel
from roulier.exception import CarrierError

from .encoder import merge_dict
import base64

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -103,8 +106,6 @@ def create_exception(self, result, exception, ctx_except, data_request):
raise CarrierError(result, exc)

def validate_template(self, template_string, available_keys):
import re

keys2match = []
for match in re.findall(r"\$(T[0-9].*) ", template_string):
keys2match.append(match)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Transform input to gls compatible format"""

import logging
from datetime import date

from roulier.codec import Encoder
Expand All @@ -9,9 +8,6 @@

GLS_ACTIONS = ("label",)

_logger = logging.getLogger(__name__)


DELIVERY_MAPPING = {
# 'address': ADDRESS_MODEL,
"T859": "consignee_ref",
Expand Down Expand Up @@ -99,5 +95,4 @@ def dict_to_exotic_serialization(self, data):
if val:
res += "%s:%s|" % (key, val)
res += r"/////GLS/////"
print(res)
return res
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
""" Implementation for GLS """

import logging
from roulier.carrier import Carrier

from .encoder import GlsEncoder
from .decoder import GlsDecoder
from .transport import GlsTransport

log = logging.getLogger(__name__)


class Gls(Carrier):
"""Implementation for GLS"""
Expand Down
1 change: 1 addition & 0 deletions roulier/carriers/gls_fr/glsbox/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_roulier_gls_fr
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from datetime import date
import logging

from roulier import roulier

logger = logging.getLogger(__name__)
Expand All @@ -18,7 +19,7 @@

def test_connexion():
roulier.get(
"gls_fr",
"gls_fr_glsbox",
"get_label",
{
"auth": {"login": credentials["login"], "isTest": credentials["isTest"]},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
""" Implement Gls WS transport"""

import logging
import requests

from roulier.exception import CarrierError
from roulier.transport import RequestsTransport

import logging

log = logging.getLogger(__name__)

Expand All @@ -15,7 +16,7 @@
class GlsTransport(RequestsTransport):
"""Implement Gls WS communication."""

def _get_requests_headers(self):
def _get_requests_headers(self, payload=None):
return {
"content-type": "text/plain;charset=%s" % self.config.web_service_coding
}
Expand Down
7 changes: 7 additions & 0 deletions roulier/carriers/gls_fr/rest/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
__version__ = "0.1.0"

from . import api
from . import carrier_action
from . import decoder
from . import encoder
from . import transport
125 changes: 125 additions & 0 deletions roulier/carriers/gls_fr/rest/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# -*- coding: utf-8 -*-
"""Implementation of Laposte Api."""

from roulier.api import ApiParcel

from .constants import SERVICE_CHOICES
from .constants import SERVICE_STANDARD


class GlsEuApiParcel(ApiParcel):
def _service(self):
schema = super()._service()
schema["language"] = {"default": "en"}
schema["product"].update(
{
"type": "string",
"default": SERVICE_STANDARD,
"allowed": tuple(SERVICE_CHOICES),
}
)
schema["pickupLocationId"] = {"type": "string"}
schema["labelSize"] = {
"type": "string",
"default": "A6",
"allowed": ["A6", "A5", "A4"],
}
schema["labelFormat"].update(
{"type": "string", "default": "PDF", "allowed": ["PDF", "PNG"],}
)
return schema

def _address(self):
string_1_10 = {"type": "string", "minlength": 1, "maxlength": 10}
string_2_35 = {"type": "string", "minlength": 2, "maxlength": 35}
string_0_35 = {"type": "string", "minlength": 0, "maxlength": 35}
schema = super()._address()
schema["name"].update(string_2_35)
schema["street1"].update({"minlength": 3, "maxlength": 35})
schema["country"].update({"minlength": 2, "maxlength": 2})
schema["zip"].update(string_1_10)
schema["phone"].update({"maxlength": 20})
schema["email"].update(
{"required": True, "minlength": 3, "maxlength": 100,}
)
schema["city"].update(string_2_35)
schema.update(
{
"id": {"type": "string", "minlength": 0, "maxlength": 20},
"street2": string_0_35,
"street3": string_0_35,
"blockNo1": string_1_10,
"province": string_2_35,
"contact": string_2_35,
"mobile": schema["phone"],
"incoterm": {
"type": "string",
# "regex": r"^\d{2}$",
# "allowed": ["10", "13", 18", "20", "23", "30", "40", "43", "50", "60"],
},
}
)
return schema

def _opt_schema(self, schema):
return {
"type": "dict",
"required": False,
"schema": schema,
}

def _parcel(self):
schema = super()._parcel()
schema.update(
{
"services": {
"type": "list",
"schema": {
"schema": {
"product": {
"type": "string",
"allowed": tuple(SERVICE_CHOICES),
},
"pickupLocationId": {"type": "string"},
},
"type": "dict",
},
},
"reference2": {"type": "string"},
"comment": {"type": "string", "maxlength": 35},
}
)
return schema

def _returns(self):
return {
"type": "list",
"schema": {
"type": "dict",
"schema": {
"weight": {
"type": "float",
"default": "",
"required": True,
"empty": False,
}
},
},
"empty": False,
"required": False,
}

def _auth(self):
schema = super()._auth()
schema["login"].update({"required": True, "empty": False})
schema["password"].update({"required": True, "empty": False})
return schema

def _schemas(self):
schema = super()._schemas()
schema["returns"] = self._returns()
schema["to_address"] = self._opt_schema(self._to_address())
schema["from_address"] = self._opt_schema(self._address())
schema["return_address"] = self._opt_schema(self._address())
schema["pickup_address"] = self._opt_schema(self._address())
return schema
24 changes: 24 additions & 0 deletions roulier/carriers/gls_fr/rest/carrier_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Implementation for Laposte."""

from roulier.carrier_action import CarrierGetLabel
from roulier.roulier import factory

from .api import GlsEuApiParcel
from .encoder import GlsEuEncoder
from .decoder import GlsEuDecoderGetLabel
from .transport import GlsEuTransport


class GlsEuGetabel(CarrierGetLabel):
"""Implementation for GLS via it's REST WebService."""

ws_url = "https://api.gls-group.eu/public/v1/shipments"
ws_test_url = "https://api-qs.gls-group.eu/public/v1/shipments"
encoder = GlsEuEncoder
decoder = GlsEuDecoderGetLabel
transport = GlsEuTransport
api = GlsEuApiParcel
manage_multi_label = True


factory.register_builder("gls_fr_rest", "get_label", GlsEuGetabel)
50 changes: 50 additions & 0 deletions roulier/carriers/gls_fr/rest/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
SERVICE_STANDARD = "Standard"
"""
Concerne les livraisons pour la France et l’international sans aucun service additionnel,
notre système utilisera le produit adapté en fonction de la destination :
BP (Business Parcel), EBP (Euro Business Parcel) ou GBP (Global Business Parcel)
"""

SERVICE_FDS = "flexDeliveryService"
"""
Pour les livraisons aux particuliers, GLS communique par mail et SMS avec le
destinataire afin d’offrir une interaction avec les modalités de livraison
"""

SERVICE_SHD = "shopdeliveryservice"
"""
livraison du colis dans un point relais
"""

SERVICE_SRS = "shopreturnservice"
"""
Dépôt du colis par le destinataire dans un point relais colis pour une livraison
en retour à l’adresse du donneur d’ordre, identifié par le shipperId utilisé
"""

SERVICE_PandS = "Pick&ShipService"
"""
enlèvement du colis par GLS à une adresse indiquée pour une livraison à une
autre adresse que celle du compte GLS donneur de l’ordre.
ATTENTION, l’une des deux adresses doit être localisé en France
"""

SERVICE_PandR = "Pick&ReturnService"
"""
enlèvement du colis par GLS à une adresse indiquée pour une livraison en
retour à l’adresse du donneur de l’ordre, identifié par le shipperId utilisé.
ATTENTION, l’une des deux adresses doit être localisé en France
"""

SERVICE_CHOICES = {
SERVICE_STANDARD,
SERVICE_FDS,
SERVICE_SHD,
SERVICE_SRS,
SERVICE_PandS,
SERVICE_PandR,
}

FR_ONLY_SERVICES_CHOICES = SERVICE_CHOICES - {
SERVICE_STANDARD,
}
Loading