diff --git a/__openerp__.py b/__openerp__.py
index 61cdf4e..c5a9482 100644
--- a/__openerp__.py
+++ b/__openerp__.py
@@ -9,7 +9,9 @@
'author': 'Harald Welte',
'depends': ['odoo_shipping_service_apps', 'shipment_packaging'],
'data': [
+ 'views/sc_delivery_carrier.xml',
'views/res_config.xml',
+ 'data/data.xml',
],
'installable': True,
'application': True,
diff --git a/data/data.xml b/data/data.xml
new file mode 100644
index 0000000..4c7a1d8
--- /dev/null
+++ b/data/data.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+ UPS Express (one day)
+ ups
+ one_day
+ pdf_a5
+
+
+ UPS Express (one day early)
+ ups
+ one_day_early
+ pdf_a5
+
+
+ UPS Expedited
+ ups
+ ups_expedited
+ pdf_a5
+
+
+ UPS Returns
+ ups
+ returns
+ pdf_a5
+
+
+
+
+ DPD (one day)
+ dpd
+ one_day
+ pdf_a5
+
+
+ DPD (one day early)
+ dpd
+ one_day_early
+ pdf_a5
+
+
+ DPD Standard
+ dpd
+ standard
+ pdf_a5
+
+
+ DPD Returns
+ ups
+ returns
+ pdf_a5
+
+
+
+
+ GLS Standard
+ gls
+ standard
+ pdf_a5
+
+
+ GLS Express 12:00
+ gls
+ gls_express_1200
+ pdf_a5
+
+
+ GLS Returns
+ gls
+ returns
+ pdf_a5
+
+
+
+
+ DHL Paket
+ dhl
+ standard
+ pdf_a5
+
+
+ DHL Retoure
+ dhl
+ returns
+ pdf_a5
+
+
+
+
+ DHL Express (one day)
+ dhl_express
+ one_day
+ pdf_a5
+
+
+ DHL Express (one day early)
+ dhl_express
+ one_day_early
+ pdf_a5
+
+
+
+
diff --git a/models/shipcloud.py b/models/shipcloud.py
index ff4313e..490f43b 100644
--- a/models/shipcloud.py
+++ b/models/shipcloud.py
@@ -96,6 +96,16 @@ class api(object):
sh = shipment.copy()
sh['create_shipping_label'] = gen_label
res = self._transport.rest_post('/shipments', sh, sandbox)
+ # {u'label_url': u'https://shipping-labels.shipcloud.io/shipments/a948e8c2/e3fb26be59/label/shipping_label_e3fb26be59.pdf', u'price': 0.0, u'id': u'e3fb26be59a68acd04d565dda027efd415ca8117', u'tracking_url': u'https://track.shipcloud.io/e3fb26be59a68acd04d565dda027efd415ca8117', u'carrier_tracking_no': u'1ZV306W00493609016'}
+ if 'label_url' in res:
+ r = requests.get(res['label_url'], stream=True)
+ if r.ok:
+ res['label_bin'] = r.content
+ return res
+
+ def delete_shipment(self, shipment_id):
+ sandbox = True if self._transport._auth_sandbox else False
+ res = self._transport.rest_delete('/shipments/%s' % shipment_id, None, sandbox)
return res
@@ -151,18 +161,18 @@ def gen_package(width_cm, length_cm, height_cm, weight_kgs, value=None, currency
return package
-def gen_shipment(from_addr, to_addr, pkg, ref, descr=None, customs_decl=None, incoterm='dap'):
+def gen_shipment(from_addr, to_addr, pkg, ref, carrier='ups', service='one_day', label_fmt='pdf_a5', descr=None, customs_decl=None, incoterm='dap'):
"""Generate a dict for a shipment in accordance with
https://developers.shipcloud.io/reference/shipments_request_schema.html"""
shipment = {
'from': from_addr,
'to': to_addr,
- 'carrier': 'ups',
- 'service': 'one_day',
+ 'carrier': carrier,
+ 'service': service,
'package' : pkg,
'reference_number': ref,
'label': {
- 'format': 'pdf_a5',
+ 'format': label_fmt,
},
'notification_mail': 'hwelte@sysmocom.de',
'incoterm': incoterm,
diff --git a/models/shipcloud_delivery_carrier.py b/models/shipcloud_delivery_carrier.py
index 7fc54c0..c28dd04 100644
--- a/models/shipcloud_delivery_carrier.py
+++ b/models/shipcloud_delivery_carrier.py
@@ -78,7 +78,7 @@ class SCDeliveryCarrier(models.Model):
"""Convert an Odoo stock.picking or sale.order into a shipcloud package"""
pkg = {}
pkg['type'] = 'parcel'
- pkg['weight'] = self._get_weight(order, picking)
+ pkg['weight'] = self._get_weight_with_tare(order, picking)
if picking:
pkg['length'] = picking.packaging_length
pkg['width'] = picking.packaging_width
@@ -94,14 +94,19 @@ class SCDeliveryCarrier(models.Model):
def build_sc_customs_item(self, line):
"""Generate a shipcloud customs_item from a stock.move (line of a picking)"""
product_uom_obj = self.env['product.uom']
- q = product_uom_obj._compute_qty_obj(self._get_default_uom(), line.product_oum_qty, self.uom_id)
+ q = product_uom_obj._compute_qty_obj(self._get_default_uom(), line.product_uom_qty, self.uom_id)
product = line.product_id
if product:
if product.x_sysmo_customs_code:
hts = product.x_sysmo_customs_code
else:
raise Warning('Product Variant %s has no HTS defined' % (product.name))
- orig = product.x_country_of_origin
+ if product.x_country_of_origin:
+ orig = product.x_country_of_origin.code
+ elif line.product_tmpl_id and line.product_tmpl_id.x_country_of_origin:
+ orig = line.product_tmpl_id.x_country_of_origin.code
+ else:
+ raise Warning('Product Variant %s has no Country of Origin defined' % (product.name))
weight = product.weight
elif line.product_tmpl_id:
ptmpl = line.product_tmpl_id
@@ -109,7 +114,10 @@ class SCDeliveryCarrier(models.Model):
hts = ptempl.x_sysmo_default_customs_code
else:
raise Warning('Product %s has no HTS defined' % (ptempl.name))
- orig = ptempl.x_default_country_of_origin
+ if ptempl.x_country_of_origin:
+ orig = ptempl.x_country_of_origin.code
+ else:
+ raise Warning('Product %s has no Country of Origin defined' % (ptempl.name))
weight = ptempl.weight
res = {
'origin_country': orig,
@@ -119,9 +127,10 @@ class SCDeliveryCarrier(models.Model):
'value_amount': line.price_unit,
'net_weight': weight,
}
+ return res
def build_sc_customs_decl(self, picking):
- items = [build_sc_customs_item(x) for x in picking.move_lines]
+ items = [self.build_sc_customs_item(x) for x in picking.move_lines]
total = 0.0
for i in items:
total += i['value_amount']
@@ -146,13 +155,16 @@ class SCDeliveryCarrier(models.Model):
"""Obtain a shipping quote for the given sale.order"""
recipient = order.partner_shipping_id if order.partner_shipping_id else order.partner_id
warehouse = order.warehouse_id.partner_id
+ carrier_service = self.sudo().sc_carrier_service
# build individual sub-objects of the shipment
from_addr = self.build_sc_addr(warehouse)
to_addr = self.build_sc_addr(recipient)
pkg = self.build_sc_pkg(order=order)
# build the actual shipment object
- shp = shipcloud.gen_shipment(from_addr, to_addr, pkg, order.name)
+ shp = shipcloud.gen_shipment(from_addr, to_addr, pkg, order.name,
+ carrier=carrier_service.carrier, service=carrier_service.service,
+ label_fmt=carrier_service.label_size)
# convert shipment to quote object
api = self._shipcloud_api()
try:
@@ -162,43 +174,53 @@ class SCDeliveryCarrier(models.Model):
# { "shipment_quote": { "price": 42.12 } }
return result['shipment_quote']['price']
-
+ @api.one
def sc_send_shipping(self, pickings):
"""Generate a shipping label from the given stock.picking"""
order = self.env['sale.order'].search([('name','=',pickings.origin)])
recipient = pickings.partner_id
warehouse = pickings.picking_type_id.warehouse_id.partner_id
+ carrier_service = self.sudo().sc_carrier_service
# build individual sub-objects of the shipment
from_addr = self.build_sc_addr(warehouse)
to_addr = self.build_sc_addr(recipient)
- pkg = self.build_sc_pkg(pickings=pickings)
+ pkg = self.build_sc_pkg(picking=pickings)
customs = self.build_sc_customs_decl(pickings)
# build the actual shipment object
- shp = shipcloud.gen_shipment(from_addr, to_addr, pkg, picking.name, customs_decl=customs)
+ shp = shipcloud.gen_shipment(from_addr, to_addr, pkg, pickings.name, customs_decl=customs,
+ carrier=carrier_service.carrier, service=carrier_service.service,
+ label_fmt=carrier_service.label_size)
api = self._shipcloud_api()
try:
- result = api.create_shipment(shp)
+ #print("SHP: %s" % shp)
+ result = api.create_shipment(shp, gen_label=True)
+ #print("RES: %s" % result)
except shipcloud.ApiError as err:
raise Warning(err)
# result = ["id", "carrier_tracking_no", "tracking_url", "label_url", "price"]
- self.update({'sc_shipment_id': result['id'],
- 'sc_tracking_url': result['tracking_url']})
+ # {u'label_url': u'https://shipping-labels.shipcloud.io/shipments/a948e8c2/e3fb26be59/label/shipping_label_e3fb26be59.pdf', u'price': 0.0, u'id': u'e3fb26be59a68acd04d565dda027efd415ca8117', u'tracking_url': u'https://track.shipcloud.io/e3fb26be59a68acd04d565dda027efd415ca8117', u'carrier_tracking_no': u'1ZV306W00493609016'}
+ filename = '%s.pdf' % result['carrier_tracking_no']
+ pickings.update({'sc_shipment_id': result['id'],
+ 'sc_tracking_url': result['tracking_url']})
# TODO: download label from label_url so it can be returned as attachment
res = {'exact_price': result['price'],
'weight': pkg['weight'],
- 'tracking_number': result['carrier_tracking_no'],
- 'attachments': [(filename, label.pdf_bin)]}
+ 'date_delivery': None,
+ 'tracking_number': ' ' + result['carrier_tracking_no'],
+ 'attachments': [(filename, result['label_bin'])]}
return res
- def sc_cancel_shipment(self, pickings):
+ @api.one
+ def sc_cancel_shipment(self, picking):
"""Cancel a shipping label"""
- # TODO: use sc_shipment_id to issue a cancel request in the API
- # DELETE /v1/shipments/:id -> 204 on success
+ api = self._shipcloud_api()
+ api.delete_shipment(picking.sc_shipment_id)
+ @api.one
def sc_get_tracking_link(self, pickings):
"""Return a tracking link for the given picking"""
return pickings.sc_tracking_url
diff --git a/models/shipcloud_shipping_service.py b/models/shipcloud_shipping_service.py
index 7785a07..ee16b6a 100644
--- a/models/shipcloud_shipping_service.py
+++ b/models/shipcloud_shipping_service.py
@@ -4,10 +4,19 @@ from openerp import api, fields, models
class SMCShippingShipcloud(models.Model):
_inherit = 'delivery.carrier'
delivery_type = fields.Selection(selection_add=[('sc', 'shipcloud')])
-
+ sc_carrier_service = fields.Many2one(comodel_name='delivery.carrier.sc.carrier_service',
+ string='Shipcloud Carrier Service')
# extend stock.picking with fields related to shipcloud
class SMCStockPickingShipclodu(models.Model):
_inherit = 'stock.picking'
sc_shipment_id = fields.Char(string='shipcloud shipment ID')
sc_tracking_url = fields.Char(string='shipcloud tracking URL')
+
+
+class SMCShippingScCarrierService(models.Model):
+ _name = 'delivery.carrier.sc.carrier_service'
+ name = fields.Char(string="Name", required=1)
+ carrier = fields.Char(string="shipcloud Carrier", required=1)
+ service = fields.Char(string="shipcloud Service", required=1)
+ label_size = fields.Char(string="shipcloud Label Size", required=1)
diff --git a/views/sc_delivery_carrier.xml b/views/sc_delivery_carrier.xml
new file mode 100644
index 0000000..cc01421
--- /dev/null
+++ b/views/sc_delivery_carrier.xml
@@ -0,0 +1,72 @@
+
+
+
+ delivery.stock.picking_withlabel.form.view
+ stock.picking
+
+
+
+
+
+
+
+
+
+ shipping.sc.form
+ delivery.carrier
+ form
+
+
+
+
+
+
+
+
+
+
+
+ delivery.carrier.sc.carrier_service.form
+ delivery.carrier.sc.carrier_service
+ form
+
+
+
+
+
+ delivery.carrier.sc.carrier_service.tree
+ delivery.carrier.sc.carrier_service
+ tree
+
+
+
+
+
+
+
+
+
+
+ SC Carrier Services
+ delivery.carrier.sc.carrier_service
+ form
+ tree,form
+
+
+
+
+
+