Merge lp:~camptocamp/carriers-deliveries/7.0-add-delivery_carrier_label_postlogistics-yvr into lp:~stock-logistic-core-editors/carriers-deliveries/7.0

Proposed by Yannick Vaucher @ Camptocamp
Status: Superseded
Proposed branch: lp:~camptocamp/carriers-deliveries/7.0-add-delivery_carrier_label_postlogistics-yvr
Merge into: lp:~stock-logistic-core-editors/carriers-deliveries/7.0
Diff against target: 3697 lines (+3577/-0)
22 files modified
base_delivery_carrier_label/__init__.py (+22/-0)
base_delivery_carrier_label/__openerp__.py (+55/-0)
base_delivery_carrier_label/delivery.py (+84/-0)
base_delivery_carrier_label/delivery_view.xml (+88/-0)
base_delivery_carrier_label/reports.xml (+15/-0)
base_delivery_carrier_label/security/ir.model.access.csv (+7/-0)
base_delivery_carrier_label/stock.py (+154/-0)
base_delivery_carrier_label/stock_view.xml (+77/-0)
delivery_carrier_label_postlogistics/__init__.py (+25/-0)
delivery_carrier_label_postlogistics/__openerp__.py (+111/-0)
delivery_carrier_label_postlogistics/company.py (+47/-0)
delivery_carrier_label_postlogistics/data/barcode_v2_1.wsdl (+249/-0)
delivery_carrier_label_postlogistics/data/barcode_v2_1.xsd (+1198/-0)
delivery_carrier_label_postlogistics/delivery.py (+213/-0)
delivery_carrier_label_postlogistics/delivery_data.xml (+108/-0)
delivery_carrier_label_postlogistics/delivery_view.xml (+61/-0)
delivery_carrier_label_postlogistics/postlogistics/__init__.py (+21/-0)
delivery_carrier_label_postlogistics/postlogistics/web_service.py (+358/-0)
delivery_carrier_label_postlogistics/res_config.py (+403/-0)
delivery_carrier_label_postlogistics/res_config_view.xml (+93/-0)
delivery_carrier_label_postlogistics/res_partner_data.xml (+134/-0)
delivery_carrier_label_postlogistics/stock.py (+54/-0)
To merge this branch: bzr merge lp:~camptocamp/carriers-deliveries/7.0-add-delivery_carrier_label_postlogistics-yvr
Reviewer Review Type Date Requested Status
Guewen Baconnier @ Camptocamp Pending
Review via email: mp+196755@code.launchpad.net

This proposal has been superseded by a proposal from 2013-11-27.

Description of the change

This module implements Swiss PostLogics "Barcode" webservice to generate shipping labels.
http://www.poste.ch/post-barcode-cug.htm

* it connects to WebService using suds SOAP client
* it permits to retrieve all services provided by Postlogistics with translations in available languages with an update button in settings
* options are filtered in carrier in order to improve user experience

Depends on following MP:

https://code.launchpad.net/~camptocamp/carriers-deliveries/7.0-add-base_delivery_carrier_label-yvr/+merge/196753

To post a comment you must log in.
9. By Yannick Vaucher @ Camptocamp

[ADD] external dependency on suds

10. By Yannick Vaucher @ Camptocamp

[IMP] module description

11. By Yannick Vaucher @ Camptocamp

[ADD] technical informations

12. By Guewen Baconnier @ Camptocamp

[MRG] from lp:~camptocamp/carriers-deliveries/7.0-add-base_delivery_carrier_label-yvr

13. By Guewen Baconnier @ Camptocamp

[CHG] pep-8 and pep-257

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

On the name of the module: rename delivery_carrier_label_laposte to delivery_carrier_label_postlogistics: "laposte" has been used for "La Poste" (from France) for the delivery files.

Suds does not have an exception class for the authentication errors? I think that it should, seems to be suds.transport.TransportError

        try:
            res['value'] = request(**kwargs)
            res['success'] = True
        except WebFault, e:
            res['success'] = False
            res['errors'] = [e[0]]
        except Exception, e:

On a side note, the preferred notation now is "except Exception as e:

            # if authentification error
            if isinstance(e[0], tuple) and e[0][0] == 401:
                raise orm.except_orm(
                    _('Error 401'),
                    _('Authorization Required\n\n'
                    'Please verify postlogistics username and password in:\n'
                    'Configuration -> Postlogistics'))
            raise e

"raise e" is wrong, you will mess the traceback (it will start from the current line instead of the original one), to propagate correctly the current exception, the correct idiom is just "raise".

Regarding the comment below, the weight (and weight_net) field already exists on the picking.

        #XXX get weight or set it as an option on picking
        weight = 0

14. By Guewen Baconnier @ Camptocamp

[CHG] contributors is to write in the description

15. By Yannick Vaucher @ Camptocamp

[IMP] rename module delivery_carrier_label_laposte => delivery_carrier_label_postlogistics

16. By Yannick Vaucher @ Camptocamp

[FIX] contributor

17. By Yannick Vaucher @ Camptocamp

[FIX] exception propagation

18. By Yannick Vaucher @ Camptocamp

[IMP] exceptions syntax

19. By Yannick Vaucher @ Camptocamp

[FIX] rename xml id to fit to new module name delivery_carrier_label_postlogistics

20. By Yannick Vaucher @ Camptocamp

[FIX] invert logic of required on postlogistics_service_group_id field in carrier view

21. By Yannick Vaucher @ Camptocamp

[ADD] logging info as updating service can take some times

22. By Yannick Vaucher @ Camptocamp

[REF] make it easier to inherit from _generate_postlogistics_label (renamed from _generate_poste_ch_label)

23. By Yannick Vaucher @ Camptocamp

[ADD] default options for label layout, output format and resolution

24. By Yannick Vaucher @ Camptocamp

[ADD] file_type on shipping label

25. By Yannick Vaucher @ Camptocamp

[FIX] set file format to lower case

26. By Yannick Vaucher @ Camptocamp

[FIX] get code instead of option browse record in format, layout and resolution options

27. By Yannick Vaucher @ Camptocamp

[ADD] fr.po

28. By Joël Grand-Guillaume @ camptocamp

[FIX] When using update_postlogistics_options action, we must take the company contain in the current configuration (res.config) instead of the company of the user

29. By Yannick Vaucher @ Camptocamp

[IMP] adapt delivery_carrier_label_postlogistics to generate a list of label per picking tracking

30. By Yannick Vaucher @ Camptocamp

[IMP] adapt to signature change in base_delivery_carrier_label for generate_pack_labels -> generate_shipping_labels

31. By Yannick Vaucher @ Camptocamp

[IMP] labels on stock.picking instead of stock.picking.out so we can generate pretty PostLogistics labels even for the not yet happy customers who have to return product.

32. By Yannick Vaucher @ Camptocamp

[ADD] pot file

33. By Guewen Baconnier @ Camptocamp

[ADD] missing access rights

34. By Guewen Baconnier @ Camptocamp

[FIX] wrong method name

35. By Yannick Vaucher @ Camptocamp

[IMP] Permits to use multiple basic services

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'base_delivery_carrier_label'
2=== added file 'base_delivery_carrier_label/__init__.py'
3--- base_delivery_carrier_label/__init__.py 1970-01-01 00:00:00 +0000
4+++ base_delivery_carrier_label/__init__.py 2013-11-27 09:30:06 +0000
5@@ -0,0 +1,22 @@
6+# -*- coding: utf-8 -*-
7+##############################################################################
8+#
9+# Author: Yannick Vaucher
10+# Copyright 2013 Camptocamp SA
11+#
12+# This program is free software: you can redistribute it and/or modify
13+# it under the terms of the GNU Affero General Public License as
14+# published by the Free Software Foundation, either version 3 of the
15+# License, or (at your option) any later version.
16+#
17+# This program is distributed in the hope that it will be useful,
18+# but WITHOUT ANY WARRANTY; without even the implied warranty of
19+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+# GNU Affero General Public License for more details.
21+#
22+# You should have received a copy of the GNU Affero General Public License
23+# along with this program. If not, see <http://www.gnu.org/licenses/>.
24+#
25+##############################################################################
26+from . import delivery
27+from . import stock
28
29=== added file 'base_delivery_carrier_label/__openerp__.py'
30--- base_delivery_carrier_label/__openerp__.py 1970-01-01 00:00:00 +0000
31+++ base_delivery_carrier_label/__openerp__.py 2013-11-27 09:30:06 +0000
32@@ -0,0 +1,55 @@
33+# -*- coding: utf-8 -*-
34+##############################################################################
35+#
36+# Author: Yannick Vaucher
37+# Copyright 2013 Camptocamp SA
38+#
39+# This program is free software: you can redistribute it and/or modify
40+# it under the terms of the GNU Affero General Public License as
41+# published by the Free Software Foundation, either version 3 of the
42+# License, or (at your option) any later version.
43+#
44+# This program is distributed in the hope that it will be useful,
45+# but WITHOUT ANY WARRANTY; without even the implied warranty of
46+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47+# GNU Affero General Public License for more details.
48+#
49+# You should have received a copy of the GNU Affero General Public License
50+# along with this program. If not, see <http://www.gnu.org/licenses/>.
51+#
52+##############################################################################
53+{'name': 'Base module for carrier labels',
54+ 'version': '1.0',
55+ 'author': 'Camptocamp',
56+ 'maintainer': 'Camptocamp',
57+ 'contributors': ['Yannick Vaucher <yannick.vaucher@camptocamp.com'],
58+ 'category': 'version',
59+ 'complexity': 'normal',
60+ 'depends': ['stock', 'delivery'],
61+ 'description': """
62+Base module for carrier labels
63+==============================
64+
65+This module adds a button on delivery orders to generate a label as an
66+attachement.
67+
68+.. tip::
69+ It doesn't implement a label. To add a default label, you can install
70+ the module `delivery_carrier_label_default_webkit`
71+
72+It can be used to print specific labels per carrier.
73+
74+.. note::
75+ Inspired by Akretion module delivery_base and delivery_shipping_label
76+
77+ """,
78+ 'website': 'http://www.camptocamp.com/',
79+ 'data': [
80+ 'delivery_view.xml',
81+ 'stock_view.xml',
82+ ],
83+ 'tests': [],
84+ 'installable': True,
85+ 'auto_install': False,
86+ 'license': 'AGPL-3',
87+ 'application': True}
88
89=== added file 'base_delivery_carrier_label/delivery.py'
90--- base_delivery_carrier_label/delivery.py 1970-01-01 00:00:00 +0000
91+++ base_delivery_carrier_label/delivery.py 2013-11-27 09:30:06 +0000
92@@ -0,0 +1,84 @@
93+# -*- coding: utf-8 -*-
94+##############################################################################
95+#
96+# Author: Sébastien BEAU <sebastien.beau@akretion.com>
97+# Copyright (C) 2012-TODAY Akretion <http://www.akretion.com>.
98+#
99+# This program is free software: you can redistribute it and/or modify
100+# it under the terms of the GNU Affero General Public License as
101+# published by the Free Software Foundation, either version 3 of the
102+# License, or (at your option) any later version.
103+#
104+# This program is distributed in the hope that it will be useful,
105+# but WITHOUT ANY WARRANTY; without even the implied warranty of
106+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107+# GNU Affero General Public License for more details.
108+#
109+# You should have received a copy of the GNU Affero General Public License
110+# along with this program. If not, see <http://www.gnu.org/licenses/>.
111+#
112+##############################################################################
113+from openerp.osv import orm, fields
114+
115+
116+class DeliveryCarrierTemplateOption(orm.Model):
117+ """ Available options for a carrier (partner) """
118+ _name = 'delivery.carrier.template.option'
119+ _description = 'Delivery carrier template option'
120+
121+ _columns = {
122+ 'partner_id': fields.many2one('res.partner', 'Partner Carrier'),
123+ 'name': fields.char('Name', size=64),
124+ 'code': fields.char('Code', size=64),
125+ }
126+
127+
128+class DeliveryCarrierOption(orm.Model):
129+ """ Option selected for a carrier method
130+
131+ Those options define the list of available pre-added and available
132+ to be added on delivery orders
133+
134+ """
135+ _name = 'delivery.carrier.option'
136+ _description = 'Delivery carrier option'
137+ _inherits = {'delivery.carrier.template.option': 'tmpl_option_id'}
138+
139+ _columns = {
140+ 'state': fields.selection(
141+ (('mandatory', 'Mandatory'),
142+ ('default_option', 'Optional by Default'),
143+ ('option', 'Optional'),
144+ ),
145+ string='Option Configuration',
146+ help="Ensure you add and define correctly all your options or those won't "
147+ "be available for the packager\n"
148+ "- Mandatory: This option will be copied on carrier and cannot be removed\n"
149+ "- Optional by Default: This option will be copied but can be removed\n"
150+ "- Optional: This option can be added later by the user on the Delivery Order."),
151+ 'tmpl_option_id': fields.many2one(
152+ 'delivery.carrier.template.option',
153+ string='Option', required=True, ondelete="cascade"),
154+ 'carrier_id': fields.many2one('delivery.carrier', 'Carrier'),
155+ }
156+
157+
158+class DeliveryCarrier(orm.Model):
159+ _inherit = 'delivery.carrier'
160+
161+ def _get_carrier_type_selection(self, cr, uid, context=None):
162+ """ To inherit to add carrier type """
163+ return []
164+
165+ _columns = {
166+ 'type': fields.selection(
167+ _get_carrier_type_selection, 'Type',
168+ help="Carrier type (combines several delivery methods)"),
169+ 'code': fields.char(
170+ 'Code', size=10,
171+ help="Delivery Method Code (according to carrier)"),
172+ 'description': fields.text('Description'),
173+ 'available_option_ids': fields.one2many(
174+ 'delivery.carrier.option',
175+ 'carrier_id', 'Option'),
176+ }
177
178=== added file 'base_delivery_carrier_label/delivery_view.xml'
179--- base_delivery_carrier_label/delivery_view.xml 1970-01-01 00:00:00 +0000
180+++ base_delivery_carrier_label/delivery_view.xml 2013-11-27 09:30:06 +0000
181@@ -0,0 +1,88 @@
182+<?xml version="1.0" encoding="UTF-8"?>
183+<openerp>
184+ <data>
185+
186+ <!-- VIEW FOR THE OBJECT : delivery_carrier_template_option -->
187+ <record id="delivery_carrier_template_option_view_form" model="ir.ui.view">
188+ <field name="name">delivery_base.delivery_carrier_option.view_form</field>
189+ <field name="model">delivery.carrier.template.option</field>
190+ <field name="arch" type="xml">
191+ <form string="delivery_carrier_option">
192+ <field name="partner_id" />
193+ <field name="code"/>
194+ <field name="name"/>
195+ </form>
196+ </field>
197+ </record>
198+
199+ <record id="delivery_carrier_template_option_view_tree" model="ir.ui.view">
200+ <field name="name">delivery_base.delivery_carrier_template_option.view_tree</field>
201+ <field name="model">delivery.carrier.template.option</field>
202+ <field name="arch" type="xml">
203+ <tree string="delivery_carrier_option">
204+ <field name="partner_id" />
205+ <field name="code"/>
206+ <field name="name"/>
207+ </tree>
208+ </field>
209+ </record>
210+
211+ <!-- VIEW FOR THE OBJECT : delivery_carrier_option -->
212+ <record id="delivery_carrier_option_view_form" model="ir.ui.view">
213+ <field name="name">delivery_base.delivery_carrier_option.view_form</field>
214+ <field name="model">delivery.carrier.option</field>
215+ <field name="arch" type="xml">
216+ <form string="delivery_carrier_option">
217+ <field name="state"/>
218+ <field name="tmpl_option_id"/>
219+ </form>
220+ </field>
221+ </record>
222+
223+ <record id="delivery_carrier_option_view_tree" model="ir.ui.view">
224+ <field name="name">delivery_base.delivery_carrier_option.view_tree</field>
225+ <field name="model">delivery.carrier.option</field>
226+ <field name="type">tree</field>
227+ <field name="arch" type="xml">
228+ <tree string="delivery_carrier_option">
229+ <field name="state" />
230+ <field name="tmpl_option_id" />
231+ <field name="code" readonly="1"/>
232+ </tree>
233+ </field>
234+ </record>
235+
236+ <!-- INHERITED VIEW FOR THE OBJECT : delivery.carrier -->
237+
238+ <record id="view_delivery_carrier_form" model="ir.ui.view">
239+ <field name="name">delivery_base.delivery.carrier.view_form</field>
240+ <field name="model">delivery.carrier</field>
241+ <field name="inherit_id" ref="delivery.view_delivery_carrier_form"/>
242+ <field name="arch" type="xml">
243+ <field name="pricelist_ids" position="after">
244+ <separator string="Options" colspan="4"/>
245+ <field name="available_option_ids" nolabel="1" colspan="4"/>
246+ </field>
247+ <field name="active" position="after">
248+ <field name="type"/>
249+ <field name="code"/>
250+ <separator name='description' colspan="4" string="Description"/>
251+ <field name="description" colspan="4" nolabel="1"/>
252+ </field>
253+ </field>
254+ </record>
255+
256+ <record id="view_delivery_carrier_tree" model="ir.ui.view">
257+ <field name="name">delivery_carrier_base.tree</field>
258+ <field name="model">delivery.carrier</field>
259+ <field name="inherit_id" ref="delivery.view_delivery_carrier_tree"/>
260+ <field name="arch" type="xml">
261+ <field name="name" position="after">
262+ <field name="type"/>
263+ <field name="code"/>
264+ </field>
265+ </field>
266+ </record>
267+
268+ </data>
269+</openerp>
270
271=== added directory 'base_delivery_carrier_label/i18n'
272=== added file 'base_delivery_carrier_label/reports.xml'
273--- base_delivery_carrier_label/reports.xml 1970-01-01 00:00:00 +0000
274+++ base_delivery_carrier_label/reports.xml 2013-11-27 09:30:06 +0000
275@@ -0,0 +1,15 @@
276+<?xml version="1.0" encoding="utf-8"?>
277+<openerp>
278+ <data>
279+ <report
280+ auto="False"
281+ id="delivery.shipping_label"
282+ model="stock.picking"
283+ name="delivery.shipping.label"
284+ file="base_delivery_carrier_label/report/template/shipping_label.mako"
285+ string="Shipping Label"
286+ attachment_use="1"
287+ multi="False"
288+ report_type="webkit"/>
289+ </data>
290+</openerp>
291
292=== added directory 'base_delivery_carrier_label/security'
293=== added file 'base_delivery_carrier_label/security/ir.model.access.csv'
294--- base_delivery_carrier_label/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
295+++ base_delivery_carrier_label/security/ir.model.access.csv 2013-11-27 09:30:06 +0000
296@@ -0,0 +1,7 @@
297+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
298+access_delivery_carrier_option_salesman,delivery.carrier.option.salesman,model_delivery_carrier_option,base.group_sale_salesman,1,0,0,0
299+access_delivery_carrier_option_manager,delivery.carrier.option.manager,model_delivery_carrier_option,base.group_sale_manager,1,1,1,1
300+access_delivery_carrier_template_option_salesman,delivery.carrier.relation.option.salesman,model_delivery_carrier_template_option,base.group_sale_salesman,1,0,0,0
301+access_delivery_carrier_template_option_manager,delivery.carrier.relation.option.manager,model_delivery_carrier_template_option,base.group_sale_manager,1,1,1,1
302+access_shipping_label_user,shipping.label user,model_shipping_label,stock.group_stock_user,1,1,1,0
303+access_shipping_label_manager,shipping.label manager,model_shipping_label,stock.group_stock_manager,1,1,1,1
304
305=== added file 'base_delivery_carrier_label/stock.py'
306--- base_delivery_carrier_label/stock.py 1970-01-01 00:00:00 +0000
307+++ base_delivery_carrier_label/stock.py 2013-11-27 09:30:06 +0000
308@@ -0,0 +1,154 @@
309+# -*- coding: utf-8 -*-
310+##############################################################################
311+#
312+# Authors: David BEAL <david.beal@akretion.com>
313+# Sébastien BEAU <sebastien.beau@akretion.com>
314+# Copyright (C) 2012-TODAY Akretion <http://www.akretion.com>.
315+# Author: Yannick Vaucher <yannick.vaucher@camptocamp.com>
316+# Copyright 2013 Camptocamp SA
317+#
318+# This program is free software: you can redistribute it and/or modify
319+# it under the terms of the GNU Affero General Public License as
320+# published by the Free Software Foundation, either version 3 of the
321+# License, or (at your option) any later version.
322+#
323+# This program is distributed in the hope that it will be useful,
324+# but WITHOUT ANY WARRANTY; without even the implied warranty of
325+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
326+# GNU Affero General Public License for more details.
327+#
328+# You should have received a copy of the GNU Affero General Public License
329+# along with this program. If not, see <http://www.gnu.org/licenses/>.
330+#
331+##############################################################################
332+from openerp.osv import orm, fields
333+from openerp.tools.translate import _
334+
335+
336+class stock_picking(orm.Model):
337+ """ Define m2m field due to inheritance to have it in stock.picking.out """
338+ _inherit = 'stock.picking'
339+
340+ _columns = {
341+ 'option_ids': fields.many2many('delivery.carrier.option',
342+ string='Options'),
343+ }
344+
345+
346+class stock_picking_out(orm.Model):
347+ _inherit = 'stock.picking.out'
348+
349+ def _get_carrier_type_selection(self, cr, uid, context=None):
350+ carrier_obj = self.pool.get('delivery.carrier')
351+ return carrier_obj._get_carrier_type_selection(cr, uid, context=context)
352+
353+ _columns = {
354+ 'carrier_id': fields.many2one(
355+ 'delivery.carrier', 'Carrier',
356+ states={'done': [('readonly', True)]}),
357+ 'carrier_tracking_ref': fields.char(
358+ 'Carrier Tracking Ref',
359+ size=32,
360+ states={'done': [('readonly', True)]}),
361+ 'carrier_type': fields.related(
362+ 'carrier_id', 'type',
363+ string='Carrier type',
364+ readonly=True,
365+ type='selection',
366+ selection=_get_carrier_type_selection,
367+ help="Carrier type ('group')"),
368+ 'carrier_code': fields.related(
369+ 'carrier_id', 'code',
370+ string='Delivery Method Code',
371+ readonly=True,
372+ type='char',
373+ help="Delivery Method Code (from carrier)"),
374+ 'option_ids': fields.many2many('delivery.carrier.option',
375+ string='Options'),
376+ }
377+
378+ def generate_default_label(self, cr, uid, ids, context=None):
379+ """ Abstract method """
380+ return NotImplementedError
381+
382+ def generate_single_label(self, cr, uid, ids, context=None):
383+ """ Generate a the single label by default """
384+ return self.generate_default_label(cr, uid, ids, context=None)
385+
386+ def action_generate_carrier_label(self, cr, uid, ids, context=None):
387+ shipping_label_obj = self.pool.get('shipping.label')
388+
389+ pickings = self.browse(cr, uid, ids, context=context)
390+
391+ pdf_list = []
392+ for pick in pickings:
393+ pdf = pick.generate_single_label()
394+ pdf_list.append(pdf)
395+ data = {
396+ 'name': pick.name,
397+ 'res_id': pick.id,
398+ 'res_model': 'stock.picking.out',
399+ 'datas': pdf.encode('base64'),
400+ }
401+ context_attachment = context.copy()
402+ # remove default_type setted for stock_picking
403+ # as it would try to define default value of attachement
404+ if 'default_type' in context_attachment:
405+ del context_attachment['default_type']
406+ shipping_label_obj.create(cr, uid, data, context=context_attachment)
407+ return True
408+
409+ def carrier_id_change(self, cr, uid, ids, carrier_id, context=None):
410+ """ Inherit this method in your module """
411+ carrier_obj = self.pool.get('delivery.carrier')
412+ res = {}
413+ if carrier_id:
414+ carrier = carrier_obj.browse(cr, uid, carrier_id, context=context)
415+ # This can look useless as the field carrier_code and
416+ # carrier_type are related field. But it's needed to fill
417+ # this field for using this fields in the view. Indeed the
418+ # module that depend of delivery base can hide some field
419+ # depending of the type or the code
420+
421+ default_option_ids = []
422+ available_option_ids = []
423+ for available_option in carrier.available_option_ids:
424+ available_option_ids.append(available_option.id)
425+ if available_option.state in ['default_option', 'mandatory']:
426+ default_option_ids.append(available_option.id)
427+ res = {
428+ 'value': {'carrier_type': carrier.type,
429+ 'carrier_code': carrier.code,
430+ 'option_ids': default_option_ids,
431+ },
432+ 'domain': {'option_ids': [('id', 'in', available_option_ids)],
433+ },
434+ }
435+ return res
436+
437+ def option_ids_change(self, cr, uid, ids, option_ids, carrier_id, context=None):
438+ carrier_obj = self.pool.get('delivery.carrier')
439+ res = {}
440+ if not carrier_id:
441+ return res
442+ carrier = carrier_obj.browse(cr, uid, carrier_id, context=context)
443+ for available_option in carrier.available_option_ids:
444+ if (available_option.state == 'mandatory'
445+ and not available_option.id in option_ids[0][2]):
446+ res['warning'] = {
447+ 'title': _('User Error !'),
448+ 'message': _("You can not remove a mandatory option."
449+ "\nOptions are reset to default.")
450+ }
451+ default_value = self.carrier_id_change(cr, uid, ids,
452+ carrier_id,
453+ context=context)
454+ res.update(default_value)
455+ return res
456+
457+
458+class ShippingLabel(orm.Model):
459+ """ Child class of ir attachment to identify which are labels """
460+ _inherits = {'ir.attachment': 'attachment_id'}
461+ _name = "shipping.label"
462+ _description = "Shipping Label"
463
464=== added file 'base_delivery_carrier_label/stock_view.xml'
465--- base_delivery_carrier_label/stock_view.xml 1970-01-01 00:00:00 +0000
466+++ base_delivery_carrier_label/stock_view.xml 2013-11-27 09:30:06 +0000
467@@ -0,0 +1,77 @@
468+<?xml version="1.0" encoding="UTF-8"?>
469+<openerp>
470+ <data>
471+ <!-- From DELIVERY module on STOCK.PICKING -->
472+ <!-- FORM -->
473+ <record id="view_picking_out_form" model="ir.ui.view">
474+ <field name="name">delivery.base.stock.picking.form</field>
475+ <field name="model">stock.picking.out</field>
476+ <field name="inherit_id" ref="delivery.view_picking_withcarrier_out_form"/>
477+ <field name="arch" type="xml">
478+ <field name="state" position="before">
479+ <button name="action_generate_carrier_label" states="assigned,confirmed,draft" string="Create Label" type="object"/>
480+ </field>
481+ <field name="carrier_id" position="attributes">
482+ <attribute name="on_change">carrier_id_change(carrier_id, context)</attribute>
483+ </field>
484+ <notebook position='inside'>
485+ <page name="carrier" string="Carrier Info">
486+ <separator string="Delivery"/>
487+ <field name="carrier_type"/>
488+ <field name="carrier_code"/>
489+ <separator string="Options"/>
490+ <field name="option_ids" nolabel="1"
491+ on_change="option_ids_change(option_ids, carrier_id, context)"/>
492+ </page>
493+ </notebook>
494+ </field>
495+ </record>
496+
497+ <!-- TREE -->
498+ <!--<record id="view_picking_out_tree" model="ir.ui.view">-->
499+ <!--<field name="name">stock.picking.tree</field>-->
500+ <!--<field name="model">stock.picking.out</field>-->
501+ <!--<field name="inherit_id" ref="stock.view_picking_out_tree" />-->
502+ <!--<field name="arch" type="xml">-->
503+ <!--<field name="partner_id" position="after">-->
504+ <!--[><field name="carrier_type" string="carrier"/><]-->
505+ <!--<field name="carrier_code" string="code"/>-->
506+ <!--</field>-->
507+ <!--</field>-->
508+ <!--</record>-->
509+
510+ <!--<record id="view_picking_internal_tree" model="ir.ui.view">-->
511+ <!--<field name="name">stock.picking.tree</field>-->
512+ <!--<field name="model">stock.picking</field>-->
513+ <!--<field name="inherit_id" ref="stock.vpicktree" />-->
514+ <!--<field name="arch" type="xml">-->
515+ <!--<field name="partner_id" position="after">-->
516+ <!--<field name="carrier_type"/>-->
517+ <!--</field>-->
518+ <!--</field>-->
519+ <!--</record>-->
520+
521+ <!--<record id="view_picking_out_search" model="ir.ui.view">-->
522+ <!--<field name="name">stock.picking.out.search</field>-->
523+ <!--<field name="model">stock.picking</field>-->
524+ <!--<field name="inherit_id" ref="stock.view_picking_out_search"/>-->
525+ <!--<field name="arch" type="xml">-->
526+ <!--<field name="name" position="before">-->
527+ <!--<field name="carrier_type"/>-->
528+ <!--</field>-->
529+ <!--</field>-->
530+ <!--</record>-->
531+
532+ <!--<record id="view_picking_internal_search" model="ir.ui.view">-->
533+ <!--<field name="name">stock.picking.internal.search</field>-->
534+ <!--<field name="model">stock.picking</field>-->
535+ <!--<field name="inherit_id" ref="stock.view_picking_internal_search"/>-->
536+ <!--<field name="arch" type="xml">-->
537+ <!--<field name="name" position="before">-->
538+ <!--[><field name="carrier_type"/><]-->
539+ <!--</field>-->
540+ <!--</field>-->
541+ <!--</record>-->
542+
543+ </data>
544+</openerp>
545
546=== added directory 'delivery_carrier_label_postlogistics'
547=== added file 'delivery_carrier_label_postlogistics/__init__.py'
548--- delivery_carrier_label_postlogistics/__init__.py 1970-01-01 00:00:00 +0000
549+++ delivery_carrier_label_postlogistics/__init__.py 2013-11-27 09:30:06 +0000
550@@ -0,0 +1,25 @@
551+# -*- coding: utf-8 -*-
552+##############################################################################
553+#
554+# Author: Yannick Vaucher
555+# Copyright 2013 Camptocamp SA
556+#
557+# This program is free software: you can redistribute it and/or modify
558+# it under the terms of the GNU Affero General Public License as
559+# published by the Free Software Foundation, either version 3 of the
560+# License, or (at your option) any later version.
561+#
562+# This program is distributed in the hope that it will be useful,
563+# but WITHOUT ANY WARRANTY; without even the implied warranty of
564+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
565+# GNU Affero General Public License for more details.
566+#
567+# You should have received a copy of the GNU Affero General Public License
568+# along with this program. If not, see <http://www.gnu.org/licenses/>.
569+#
570+##############################################################################
571+from . import company
572+from . import res_config
573+from . import postlogistics
574+from . import delivery
575+from . import stock
576
577=== added file 'delivery_carrier_label_postlogistics/__openerp__.py'
578--- delivery_carrier_label_postlogistics/__openerp__.py 1970-01-01 00:00:00 +0000
579+++ delivery_carrier_label_postlogistics/__openerp__.py 2013-11-27 09:30:06 +0000
580@@ -0,0 +1,111 @@
581+# -*- coding: utf-8 -*-
582+##############################################################################
583+#
584+# Author: Yannick Vaucher
585+# Copyright 2013 Camptocamp SA
586+#
587+# This program is free software: you can redistribute it and/or modify
588+# it under the terms of the GNU Affero General Public License as
589+# published by the Free Software Foundation, either version 3 of the
590+# License, or (at your option) any later version.
591+#
592+# This program is distributed in the hope that it will be useful,
593+# but WITHOUT ANY WARRANTY; without even the implied warranty of
594+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
595+# GNU Affero General Public License for more details.
596+#
597+# You should have received a copy of the GNU Affero General Public License
598+# along with this program. If not, see <http://www.gnu.org/licenses/>.
599+#
600+##############################################################################
601+{'name': 'PostLogistics Labels WebService',
602+ 'version': '1.0',
603+ 'author': 'Camptocamp',
604+ 'maintainer': 'Camptocamp',
605+ 'category': 'version',
606+ 'complexity': 'normal',
607+ 'depends': ['base_delivery_carrier_label'],
608+ 'description': """
609+PostLogistics Labels WebService
610+===============================
611+
612+Description
613+-----------
614+
615+This module uses `PostLogistics BarCodes WebService`_ to generate labels
616+for your Delivery Orders.
617+
618+It adds a `Create label` button on Delivery Orders.
619+A generated label will be an attachement of your Delivery Order.
620+
621+To see it, please install documents module.
622+
623+You can create multiple delivery method to match your diffent package types.
624+
625+
626+Configuration
627+-------------
628+
629+.. important::
630+ A "Swiss Post Business customer" account is required to use this module.
631+
632+ See `Swiss Post E-logistics`_
633+
634+
635+To configure:
636+
637+* Go to `Configurations -> Settings -> Postlogistics`
638+* Set your login informations
639+* launch the Update PostLogistics Services
640+
641+This will load available services and generate carrier options.
642+
643+Now you can create a carrier method for PostLogistics WebService:
644+
645+* First choose a Service group and save
646+* Add a Mandatory Carrier option using a Basic Service
647+* Save Carrier Method (this will update filters to show you only
648+ compatible services)
649+* Then add other `Optional as default` and `Optional` carrier option
650+ from listed
651+* Additional Service and Delivery instructions
652+
653+.. _PostLogistics BarCodes WebService: http://www.poste.ch/post-startseite/post-geschaeftskunden/post-logistik/post-e-log/post-e-log-webservices.htm
654+.. _Swiss Post E-logistics: http://www.poste.ch/en/post-startseite/post-geschaeftskunden/post-logistik/post-e-log.htm
655+
656+Technical references
657+--------------------
658+
659+`"Barcode" web service documentation`_
660+
661+.. _"Barcode" web service documentation: http://www.poste.ch/post-barcode-cug.htm
662+
663+Contributors
664+------------
665+
666+* Yannick Vaucher <yannick.vaucher@camptocamp.com>
667+
668+----
669+
670+*TODO*:
671+
672+* *Add onchange to improve carrier method creation*
673+* *Default options*
674+* *Identify attachement as label*
675+* *Better License management*
676+""",
677+ 'website': 'http://www.camptocamp.com/',
678+ 'data': ['res_partner_data.xml',
679+ 'delivery_data.xml',
680+ 'delivery_view.xml',
681+ 'res_config_view.xml',
682+ ],
683+ 'tests': [],
684+ 'installable': True,
685+ 'auto_install': False,
686+ 'license': 'AGPL-3',
687+ 'application': True,
688+ 'external_dependencies': {
689+ 'python': ['suds'],
690+ }
691+ }
692
693=== added file 'delivery_carrier_label_postlogistics/company.py'
694--- delivery_carrier_label_postlogistics/company.py 1970-01-01 00:00:00 +0000
695+++ delivery_carrier_label_postlogistics/company.py 2013-11-27 09:30:06 +0000
696@@ -0,0 +1,47 @@
697+# -*- coding: utf-8 -*-
698+##############################################################################
699+#
700+# Author: Yannick Vaucher
701+# Copyright 2013 Camptocamp SA
702+#
703+# This program is free software: you can redistribute it and/or modify
704+# it under the terms of the GNU Affero General Public License as
705+# published by the Free Software Foundation, either version 3 of the
706+# License, or (at your option) any later version.
707+#
708+# This program is distributed in the hope that it will be useful,
709+# but WITHOUT ANY WARRANTY; without even the implied warranty of
710+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
711+# GNU Affero General Public License for more details.
712+#
713+# You should have received a copy of the GNU Affero General Public License
714+# along with this program. If not, see <http://www.gnu.org/licenses/>.
715+#
716+##############################################################################
717+from openerp.osv import orm, fields
718+from openerp.tools import file_open
719+
720+
721+class ResCompany(orm.Model):
722+ _inherit = 'res.company'
723+
724+ def _get_wsdl_url(self, cr, uid, ids, field_name, arg, context=None):
725+ wsdl_file, wsdl_path = file_open('delivery_carrier_label_laposte/data/barcode_v2_1.wsdl', pathinfo=True)
726+ wsdl_url = 'file://' + wsdl_path
727+ res = dict.fromkeys(ids, wsdl_url)
728+ return res
729+
730+ _columns = {
731+ 'postlogistics_wsdl_url': fields.function(
732+ _get_wsdl_url,
733+ string='WSDL URL',
734+ type='char'),
735+ 'postlogistics_username': fields.char('Username'),
736+ 'postlogistics_password': fields.char('Password'),
737+ # XXX improve license management
738+ 'postlogistics_license_less_1kg': fields.char('License less than 1kg'),
739+ 'postlogistics_license_more_1kg': fields.char('License more than 1kg'),
740+ 'postlogistics_license_vinolog': fields.char('License VinoLog'),
741+ 'postlogistics_logo': fields.binary('Company logo for PostLogistics'),
742+ 'postlogistics_office': fields.char('Post office'),
743+ }
744
745=== added directory 'delivery_carrier_label_postlogistics/data'
746=== added file 'delivery_carrier_label_postlogistics/data/barcode_v2_1.wsdl'
747--- delivery_carrier_label_postlogistics/data/barcode_v2_1.wsdl 1970-01-01 00:00:00 +0000
748+++ delivery_carrier_label_postlogistics/data/barcode_v2_1.wsdl 2013-11-27 09:30:06 +0000
749@@ -0,0 +1,249 @@
750+<?xml version="1.0" encoding="UTF-8"?>
751+<definitions name="Barcode"
752+ targetNamespace="https://www.mypostbusiness.ch/wsbc/barcode/v2_1"
753+ xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="https://www.mypostbusiness.ch/wsbc/barcode/v2_1"
754+ xmlns:barcode="https://www.mypostbusiness.ch/wsbc/barcode/v2_1/types"
755+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
756+ <types>
757+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
758+ <xsd:import
759+ namespace="https://www.mypostbusiness.ch/wsbc/barcode/v2_1/types"
760+ schemaLocation="barcode_v2_1.xsd" />
761+ </xsd:schema>
762+ </types>
763+
764+ <message name="ValidateCombination">
765+ <part name="body" element="barcode:ValidateCombination" />
766+ </message>
767+ <message name="ValidateCombinationResponse">
768+ <part name="body" element="barcode:ValidateCombinationResponse" />
769+ </message>
770+
771+ <message name="GenerateLabel">
772+ <part name="body" element="barcode:GenerateLabel" />
773+ </message>
774+ <message name="GenerateLabelResponse">
775+ <part name="body" element="barcode:GenerateLabelResponse" />
776+ </message>
777+
778+ <message name="GenerateSingleBarcodes">
779+ <part name="body" element="barcode:GenerateSingleBarcodes" />
780+ </message>
781+ <message name="GenerateSingleBarcodesResponse">
782+ <part name="body" element="barcode:GenerateSingleBarcodesResponse" />
783+ </message>
784+
785+ <message name="ReadServiceGroups">
786+ <part name="body" element="barcode:ReadServiceGroups" />
787+ </message>
788+ <message name="ReadServiceGroupsResponse">
789+ <part name="body" element="barcode:ReadServiceGroupsResponse" />
790+ </message>
791+
792+ <message name="ReadBasicServices">
793+ <part name="body" element="barcode:ReadBasicServices" />
794+ </message>
795+ <message name="ReadBasicServicesResponse">
796+ <part name="body" element="barcode:ReadBasicServicesResponse" />
797+ </message>
798+
799+ <message name="ReadAllowedServicesByFrankingLicense">
800+ <part name="body" element="barcode:ReadAllowedServicesByFrankingLicense" />
801+ </message>
802+ <message name="ReadAllowedServicesByFrankingLicenseResponse">
803+ <part name="body"
804+ element="barcode:ReadAllowedServicesByFrankingLicenseResponse" />
805+ </message>
806+
807+ <message name="ReadAdditionalServices">
808+ <part name="body" element="barcode:ReadAdditionalServices" />
809+ </message>
810+ <message name="ReadAdditionalServicesResponse">
811+ <part name="body" element="barcode:ReadAdditionalServicesResponse" />
812+ </message>
813+
814+ <message name="ReadDeliveryInstructions">
815+ <part name="body" element="barcode:ReadDeliveryInstructions" />
816+ </message>
817+ <message name="ReadDeliveryInstructionsResponse">
818+ <part name="body" element="barcode:ReadDeliveryInstructionsResponse" />
819+ </message>
820+
821+ <message name="ReadLabelLayouts">
822+ <part name="body" element="barcode:ReadLabelLayouts" />
823+ </message>
824+ <message name="ReadLabelLayoutsResponse">
825+ <part name="body" element="barcode:ReadLabelLayoutsResponse" />
826+ </message>
827+
828+ <message name="GenerateBarcode">
829+ <part name="body" element="barcode:GenerateBarcode" />
830+ </message>
831+ <message name="GenerateBarcodeResponse">
832+ <part name="body" element="barcode:GenerateBarcodeResponse" />
833+ </message>
834+
835+ <portType name="BarcodePortType">
836+
837+ <operation name="ValidateCombination">
838+ <input message="tns:ValidateCombination" />
839+ <output message="tns:ValidateCombinationResponse" />
840+ </operation>
841+
842+ <operation name="GenerateLabel">
843+ <input message="tns:GenerateLabel" />
844+ <output message="tns:GenerateLabelResponse" />
845+ </operation>
846+
847+ <operation name="GenerateSingleBarcodes">
848+ <input message="tns:GenerateSingleBarcodes" />
849+ <output message="tns:GenerateSingleBarcodesResponse" />
850+ </operation>
851+
852+ <operation name="ReadServiceGroups">
853+ <input message="tns:ReadServiceGroups" />
854+ <output message="tns:ReadServiceGroupsResponse" />
855+ </operation>
856+
857+ <operation name="ReadBasicServices">
858+ <input message="tns:ReadBasicServices" />
859+ <output message="tns:ReadBasicServicesResponse" />
860+ </operation>
861+
862+ <operation name="ReadAllowedServicesByFrankingLicense">
863+ <input message="tns:ReadAllowedServicesByFrankingLicense" />
864+ <output message="tns:ReadAllowedServicesByFrankingLicenseResponse" />
865+ </operation>
866+
867+ <operation name="ReadAdditionalServices">
868+ <input message="tns:ReadAdditionalServices" />
869+ <output message="tns:ReadAdditionalServicesResponse" />
870+ </operation>
871+
872+ <operation name="ReadDeliveryInstructions">
873+ <input message="tns:ReadDeliveryInstructions" />
874+ <output message="tns:ReadDeliveryInstructionsResponse" />
875+ </operation>
876+
877+ <operation name="ReadLabelLayouts">
878+ <input message="tns:ReadLabelLayouts" />
879+ <output message="tns:ReadLabelLayoutsResponse" />
880+ </operation>
881+
882+ <operation name="GenerateBarcode">
883+ <input message="tns:GenerateBarcode" />
884+ <output message="tns:GenerateBarcodeResponse" />
885+ </operation>
886+
887+ </portType>
888+ <binding name="BarcodeSoapBinding" type="tns:BarcodePortType">
889+ <soap:binding style="document"
890+ transport="http://schemas.xmlsoap.org/soap/http" />
891+
892+ <operation name="ValidateCombination">
893+ <soap:operation soapAction="ValidateCombination" />
894+ <input>
895+ <soap:body use="literal" />
896+ </input>
897+ <output>
898+ <soap:body use="literal" />
899+ </output>
900+ </operation>
901+
902+ <operation name="GenerateLabel">
903+ <soap:operation soapAction="GenerateLabel" />
904+ <input>
905+ <soap:body use="literal" />
906+ </input>
907+ <output>
908+ <soap:body use="literal" />
909+ </output>
910+ </operation>
911+
912+ <operation name="GenerateSingleBarcodes">
913+ <soap:operation soapAction="GenerateSingleBarcodes" />
914+ <input>
915+ <soap:body use="literal" />
916+ </input>
917+ <output>
918+ <soap:body use="literal" />
919+ </output>
920+ </operation>
921+
922+ <operation name="ReadServiceGroups">
923+ <soap:operation soapAction="ReadServiceGroups" />
924+ <input>
925+ <soap:body use="literal" />
926+ </input>
927+ <output>
928+ <soap:body use="literal" />
929+ </output>
930+ </operation>
931+
932+ <operation name="ReadBasicServices">
933+ <soap:operation soapAction="ReadBasicServices" />
934+ <input>
935+ <soap:body use="literal" />
936+ </input>
937+ <output>
938+ <soap:body use="literal" />
939+ </output>
940+ </operation>
941+
942+ <operation name="ReadAllowedServicesByFrankingLicense">
943+ <soap:operation soapAction="ReadAllowedServicesByFrankingLicense" />
944+ <input>
945+ <soap:body use="literal" />
946+ </input>
947+ <output>
948+ <soap:body use="literal" />
949+ </output>
950+ </operation>
951+
952+ <operation name="ReadAdditionalServices">
953+ <soap:operation soapAction="ReadAdditionalServices" />
954+ <input>
955+ <soap:body use="literal" />
956+ </input>
957+ <output>
958+ <soap:body use="literal" />
959+ </output>
960+ </operation>
961+
962+ <operation name="ReadDeliveryInstructions">
963+ <soap:operation soapAction="ReadDeliveryInstructions" />
964+ <input>
965+ <soap:body use="literal" />
966+ </input>
967+ <output>
968+ <soap:body use="literal" />
969+ </output>
970+ </operation>
971+
972+ <operation name="ReadLabelLayouts">
973+ <soap:operation soapAction="ReadLabelLayouts" />
974+ <input>
975+ <soap:body use="literal" />
976+ </input>
977+ <output>
978+ <soap:body use="literal" />
979+ </output>
980+ </operation>
981+
982+ <operation name="GenerateBarcode">
983+ <soap:operation soapAction="GenerateBarcode" />
984+ <input>
985+ <soap:body use="literal" />
986+ </input>
987+ <output>
988+ <soap:body use="literal" />
989+ </output>
990+ </operation>
991+
992+ </binding>
993+ <service name="BarcodeService">
994+ <port name="BarcodePort" binding="tns:BarcodeSoapBinding">
995+ <soap:address location="https://www.mypostbusiness.ch/wsbc/barcode/v2_1" />
996+ </port>
997+ </service>
998+</definitions>
999\ No newline at end of file
1000
1001=== added file 'delivery_carrier_label_postlogistics/data/barcode_v2_1.xsd'
1002--- delivery_carrier_label_postlogistics/data/barcode_v2_1.xsd 1970-01-01 00:00:00 +0000
1003+++ delivery_carrier_label_postlogistics/data/barcode_v2_1.xsd 2013-11-27 09:30:06 +0000
1004@@ -0,0 +1,1198 @@
1005+<?xml version="1.0" encoding="UTF-8"?>
1006+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
1007+ xmlns="https://www.mypostbusiness.ch/wsbc/barcode/v2_1/types"
1008+ targetNamespace="https://www.mypostbusiness.ch/wsbc/barcode/v2_1/types"
1009+ elementFormDefault="qualified" attributeFormDefault="unqualified">
1010+
1011+ <!-- 5.4 Use Case Validiere Kombination (Seite 12) -->
1012+ <xs:element name="ValidateCombination">
1013+ <xs:complexType>
1014+ <xs:sequence>
1015+ <xs:element name="Language" type="Language" />
1016+ <xs:element name="Envelope">
1017+ <xs:complexType>
1018+ <xs:sequence>
1019+ <xs:element name="LabelDefinition" type="LabelDefinition" />
1020+ <xs:element name="Data">
1021+ <xs:complexType>
1022+ <xs:sequence>
1023+ <xs:element name="Provider">
1024+ <xs:complexType>
1025+ <xs:sequence>
1026+ <xs:element name="Sending">
1027+ <xs:complexType>
1028+ <xs:sequence>
1029+ <xs:element name="Item"
1030+ type="ValidateCombinationItem"
1031+ maxOccurs="unbounded" />
1032+ </xs:sequence>
1033+ </xs:complexType>
1034+ </xs:element>
1035+ </xs:sequence>
1036+ </xs:complexType>
1037+ </xs:element>
1038+ </xs:sequence>
1039+ </xs:complexType>
1040+ </xs:element>
1041+ </xs:sequence>
1042+ </xs:complexType>
1043+ </xs:element>
1044+ </xs:sequence>
1045+ </xs:complexType>
1046+ </xs:element>
1047+
1048+ <xs:complexType name="ValidateCombinationItem">
1049+ <xs:sequence>
1050+ <xs:element name="ItemID" type="ItemIDType" minOccurs="0" />
1051+ <xs:element name="Attributes" minOccurs="0">
1052+ <xs:complexType>
1053+ <xs:sequence>
1054+ <xs:element name="PRZL" type="PRZLType"
1055+ minOccurs="1" maxOccurs="unbounded" />
1056+ </xs:sequence>
1057+ </xs:complexType>
1058+ </xs:element>
1059+ <xs:element name="Country" type="CountryType"
1060+ minOccurs="0" />
1061+ </xs:sequence>
1062+ </xs:complexType>
1063+
1064+ <xs:element name="ValidateCombinationResponse">
1065+ <xs:complexType>
1066+ <xs:sequence>
1067+ <xs:element name="Envelope">
1068+ <xs:complexType>
1069+ <xs:sequence>
1070+ <xs:element name="LabelDefinition" type="LabelDefinition" />
1071+ <xs:element name="Data">
1072+ <xs:complexType>
1073+ <xs:sequence>
1074+ <xs:element name="Provider">
1075+ <xs:complexType>
1076+ <xs:sequence>
1077+ <xs:element name="Sending">
1078+ <xs:complexType>
1079+ <xs:sequence>
1080+ <xs:element name="Item"
1081+ type="ResponseItem" maxOccurs="unbounded" />
1082+ <xs:element name="Country"
1083+ type="CountryType" minOccurs="0" />
1084+ </xs:sequence>
1085+ </xs:complexType>
1086+ </xs:element>
1087+ </xs:sequence>
1088+ </xs:complexType>
1089+ </xs:element>
1090+ </xs:sequence>
1091+ </xs:complexType>
1092+ </xs:element>
1093+ </xs:sequence>
1094+ </xs:complexType>
1095+ </xs:element>
1096+ </xs:sequence>
1097+ </xs:complexType>
1098+ </xs:element>
1099+
1100+ <!-- 5.5 Use Case Generiere Adressträger (Seite 34) -->
1101+ <xs:element name="GenerateLabel">
1102+ <xs:complexType>
1103+ <xs:sequence>
1104+ <xs:element name="Language" type="Language" />
1105+ <xs:element name="Envelope">
1106+ <xs:complexType>
1107+ <xs:sequence>
1108+ <xs:element name="LabelDefinition" type="GenerateLabelDefinition" />
1109+ <xs:element name="FileInfos" type="GenerateLabelFileInfos" />
1110+ <xs:element name="Data" type="LabelData" />
1111+ </xs:sequence>
1112+ </xs:complexType>
1113+ </xs:element>
1114+ </xs:sequence>
1115+ </xs:complexType>
1116+ </xs:element>
1117+
1118+ <xs:complexType name="GenerateLabelDefinition">
1119+ <xs:complexContent>
1120+ <xs:extension base="LabelDefinition">
1121+ <xs:sequence>
1122+ <xs:element name="PrintAddresses" type="PrintAddressesType" />
1123+ <xs:element name="ImageFileType" type="ImageFileType" />
1124+ <xs:element name="ImageResolution" type="xs:int" />
1125+ <xs:element name="PrintPreview" type="xs:boolean" />
1126+ </xs:sequence>
1127+ </xs:extension>
1128+ </xs:complexContent>
1129+ </xs:complexType>
1130+
1131+ <xs:simpleType name="PrintAddressesType">
1132+ <xs:annotation>
1133+ <xs:documentation>Enumeration to indicated wheter addresses are
1134+ printet or not.</xs:documentation>
1135+ </xs:annotation>
1136+ <xs:restriction base="xs:string">
1137+ <xs:enumeration value="None">
1138+ <xs:annotation>
1139+ <xs:documentation>No Addresses are printed.</xs:documentation>
1140+ </xs:annotation>
1141+ </xs:enumeration>
1142+ <xs:enumeration value="OnlyRecipient">
1143+ <xs:annotation>
1144+ <xs:documentation>Only recipient's address is printed.
1145+ </xs:documentation>
1146+ </xs:annotation>
1147+ </xs:enumeration>
1148+ <xs:enumeration value="OnlyCustomer">
1149+ <xs:annotation>
1150+ <xs:documentation>Only customer's address is printed.
1151+ </xs:documentation>
1152+ </xs:annotation>
1153+ </xs:enumeration>
1154+ <xs:enumeration value="RecipientAndCustomer">
1155+ <xs:annotation>
1156+ <xs:documentation>Recipient and customer addresses are
1157+ printed.</xs:documentation>
1158+ </xs:annotation>
1159+ </xs:enumeration>
1160+ </xs:restriction>
1161+ </xs:simpleType>
1162+
1163+ <xs:complexType name="GenerateLabelFileInfos">
1164+ <xs:sequence>
1165+ <xs:element name="FrankingLicense" type="FrankingLicenseType" />
1166+ <xs:element name="PpFranking" type="xs:boolean"
1167+ default="false" />
1168+ <xs:element name="Customer" type="GenerateLabelCustomer" />
1169+ <xs:element name="CustomerSystem" type="CustomerSystemType"
1170+ minOccurs="0" />
1171+ </xs:sequence>
1172+ </xs:complexType>
1173+
1174+ <xs:complexType name="GenerateLabelCustomer">
1175+ <xs:sequence>
1176+ <xs:element name="Name1" type="CustomerAddressLineType" />
1177+ <xs:element name="Name2" minOccurs="0"
1178+ type="CustomerAddressLineType" />
1179+ <xs:element name="Street" type="CustomerAddressLineType" />
1180+ <xs:element name="POBox" type="CustomerAddressLineType"
1181+ minOccurs="0" />
1182+ <xs:element name="ZIP">
1183+ <xs:simpleType>
1184+ <xs:restriction base="xs:integer">
1185+ <xs:totalDigits value="6" />
1186+ </xs:restriction>
1187+ </xs:simpleType>
1188+ </xs:element>
1189+ <xs:element name="City" type="CustomerAddressLineType" />
1190+ <xs:element name="Country" type="CountryType"
1191+ minOccurs="0" />
1192+ <xs:element name="Logo" type="xs:base64Binary"
1193+ minOccurs="0" />
1194+ <xs:element name="LogoFormat" minOccurs="0">
1195+ <xs:simpleType>
1196+ <xs:restriction base="CommonPatternStringType">
1197+ <xs:maxLength value="3" />
1198+ </xs:restriction>
1199+ </xs:simpleType>
1200+ </xs:element>
1201+ <xs:element name="DomicilePostOffice" minOccurs="0">
1202+ <xs:simpleType>
1203+ <xs:restriction base="CommonPatternStringType">
1204+ <xs:maxLength value="35" />
1205+ </xs:restriction>
1206+ </xs:simpleType>
1207+ </xs:element>
1208+ </xs:sequence>
1209+ </xs:complexType>
1210+
1211+ <xs:element name="GenerateLabelResponse">
1212+ <xs:complexType>
1213+ <xs:sequence>
1214+ <xs:element name="Envelope">
1215+ <xs:complexType>
1216+ <xs:sequence>
1217+ <xs:element name="LabelDefinition"
1218+ type="GenerateLabelResponseDefinition" />
1219+ <xs:element name="Data">
1220+ <xs:complexType>
1221+ <xs:sequence>
1222+ <xs:element name="Provider">
1223+ <xs:complexType>
1224+ <xs:sequence>
1225+ <xs:element name="Sending">
1226+ <xs:complexType>
1227+ <xs:sequence>
1228+ <xs:element name="SendingID"
1229+ type="SendingIDType" minOccurs="0" />
1230+ <xs:element name="Item"
1231+ type="LabelResponseItem" maxOccurs="unbounded" />
1232+ </xs:sequence>
1233+ </xs:complexType>
1234+ </xs:element>
1235+ </xs:sequence>
1236+ </xs:complexType>
1237+ </xs:element>
1238+ </xs:sequence>
1239+ </xs:complexType>
1240+ </xs:element>
1241+ </xs:sequence>
1242+ </xs:complexType>
1243+ </xs:element>
1244+ </xs:sequence>
1245+ </xs:complexType>
1246+ </xs:element>
1247+
1248+ <xs:complexType name="GenerateLabelResponseDefinition">
1249+ <xs:complexContent>
1250+ <xs:extension base="GenerateLabelDefinition">
1251+ <xs:sequence>
1252+ <xs:element name="ColorPrintRequired" type="xs:boolean" />
1253+ </xs:sequence>
1254+ </xs:extension>
1255+ </xs:complexContent>
1256+ </xs:complexType>
1257+
1258+ <xs:complexType name="LabelResponseItem">
1259+ <xs:complexContent>
1260+ <xs:extension base="ResponseItem">
1261+ <xs:sequence>
1262+ <xs:element name="IdentCode" type="IdentCodeType"
1263+ minOccurs="0" />
1264+ <xs:element name="Label" type="xs:base64Binary"
1265+ minOccurs="0" />
1266+ </xs:sequence>
1267+ </xs:extension>
1268+ </xs:complexContent>
1269+ </xs:complexType>
1270+
1271+ <!-- WSBC 2.1 FaFo 14.1 Labellayout BC -->
1272+ <xs:element name="GenerateSingleBarcodes">
1273+ <xs:complexType>
1274+ <xs:sequence>
1275+ <xs:element name="Language" type="Language" />
1276+ <xs:element name="Envelope">
1277+ <xs:complexType>
1278+ <xs:sequence>
1279+ <xs:element name="BarcodeDefinition" type="SingleBarcodesDefinition" />
1280+ <xs:element name="FileInfos" type="SingleBarcodesFileInfos" />
1281+ <xs:element name="Data" type="LabelData" />
1282+ </xs:sequence>
1283+ </xs:complexType>
1284+ </xs:element>
1285+ </xs:sequence>
1286+ </xs:complexType>
1287+ </xs:element>
1288+
1289+ <xs:complexType name="SingleBarcodesDefinition">
1290+ <xs:sequence>
1291+ <xs:element name="ImageFileType" type="ImageFileType" />
1292+ <xs:element name="ImageResolution" type="xs:int" />
1293+ </xs:sequence>
1294+ </xs:complexType>
1295+
1296+ <xs:complexType name="SingleBarcodesFileInfos">
1297+ <xs:sequence>
1298+ <xs:element name="FrankingLicense" type="FrankingLicenseType" />
1299+ <xs:element name="PpFranking" type="xs:boolean"
1300+ default="false" />
1301+ <xs:element name="Customer" type="SingleBarcodesCustomer" />
1302+ <xs:element name="CustomerSystem" type="CustomerSystemType"
1303+ minOccurs="0" />
1304+ </xs:sequence>
1305+ </xs:complexType>
1306+
1307+ <xs:complexType name="SingleBarcodesCustomer">
1308+ <xs:sequence>
1309+ <xs:element name="Name1" type="CustomerAddressLineType" />
1310+ <xs:element name="Name2" minOccurs="0"
1311+ type="CustomerAddressLineType" />
1312+ <xs:element name="Street" type="CustomerAddressLineType" />
1313+ <xs:element name="POBox" type="CustomerAddressLineType"
1314+ minOccurs="0" />
1315+ <xs:element name="ZIP">
1316+ <xs:simpleType>
1317+ <xs:restriction base="xs:integer">
1318+ <xs:totalDigits value="6" />
1319+ </xs:restriction>
1320+ </xs:simpleType>
1321+ </xs:element>
1322+ <xs:element name="City" type="CustomerAddressLineType" />
1323+ <xs:element name="Country" type="CountryType"
1324+ minOccurs="0" />
1325+ <xs:element name="DomicilePostOffice" minOccurs="0">
1326+ <xs:simpleType>
1327+ <xs:restriction base="CommonPatternStringType">
1328+ <xs:maxLength value="35" />
1329+ </xs:restriction>
1330+ </xs:simpleType>
1331+ </xs:element>
1332+ </xs:sequence>
1333+ </xs:complexType>
1334+
1335+ <xs:element name="GenerateSingleBarcodesResponse">
1336+ <xs:complexType>
1337+ <xs:sequence>
1338+ <xs:element name="Envelope">
1339+ <xs:complexType>
1340+ <xs:sequence>
1341+ <xs:element name="BarcodeDefinition"
1342+ type="SingleBarcodesResponseDefinition" />
1343+ <xs:element name="Data">
1344+ <xs:complexType>
1345+ <xs:sequence>
1346+ <xs:element name="Provider">
1347+ <xs:complexType>
1348+ <xs:sequence>
1349+ <xs:element name="Sending">
1350+ <xs:complexType>
1351+ <xs:sequence>
1352+ <xs:element name="SendingID"
1353+ type="SendingIDType" minOccurs="0" />
1354+ <xs:element name="Item"
1355+ type="SingleBarcodesResponseItem"
1356+ maxOccurs="unbounded" />
1357+ </xs:sequence>
1358+ </xs:complexType>
1359+ </xs:element>
1360+ </xs:sequence>
1361+ </xs:complexType>
1362+ </xs:element>
1363+ </xs:sequence>
1364+ </xs:complexType>
1365+ </xs:element>
1366+ </xs:sequence>
1367+ </xs:complexType>
1368+ </xs:element>
1369+ </xs:sequence>
1370+ </xs:complexType>
1371+ </xs:element>
1372+
1373+ <xs:complexType name="SingleBarcodesResponseDefinition">
1374+ <xs:complexContent>
1375+ <xs:extension base="SingleBarcodesDefinition">
1376+ <xs:sequence>
1377+ <xs:element name="ColorPrintRequired" type="xs:boolean" />
1378+ </xs:sequence>
1379+ </xs:extension>
1380+ </xs:complexContent>
1381+ </xs:complexType>
1382+
1383+ <xs:complexType name="SingleBarcodesResponseItem">
1384+ <xs:complexContent>
1385+ <xs:extension base="ResponseItem">
1386+ <xs:sequence>
1387+ <xs:element name="IdentCode" type="IdentCodeType"
1388+ minOccurs="0" />
1389+ <xs:element name="Barcodes" minOccurs="0">
1390+ <xs:complexType>
1391+ <xs:sequence>
1392+ <xs:element name="Barcode" type="xs:base64Binary"
1393+ maxOccurs="unbounded" />
1394+ </xs:sequence>
1395+ </xs:complexType>
1396+ </xs:element>
1397+ </xs:sequence>
1398+ </xs:extension>
1399+ </xs:complexContent>
1400+ </xs:complexType>
1401+
1402+ <!-- Common datatypes for generate label and generate single barcodes -->
1403+ <xs:simpleType name="CustomerAddressLineType">
1404+ <xs:restriction base="CommonPatternStringType">
1405+ <xs:maxLength value="25" />
1406+ </xs:restriction>
1407+ </xs:simpleType>
1408+
1409+ <xs:complexType name="LabelData">
1410+ <xs:sequence>
1411+ <xs:element name="Provider">
1412+ <xs:complexType>
1413+ <xs:sequence>
1414+ <xs:element name="Sending">
1415+ <xs:complexType>
1416+ <xs:sequence>
1417+ <xs:element name="SendingID" type="SendingIDType"
1418+ minOccurs="0" />
1419+ <xs:element name="Item" type="Item"
1420+ maxOccurs="unbounded" />
1421+ </xs:sequence>
1422+ </xs:complexType>
1423+ </xs:element>
1424+ </xs:sequence>
1425+ </xs:complexType>
1426+ </xs:element>
1427+ </xs:sequence>
1428+ </xs:complexType>
1429+
1430+ <xs:simpleType name="SendingIDType">
1431+ <xs:restriction base="CommonPatternStringType">
1432+ <xs:maxLength value="50" />
1433+ </xs:restriction>
1434+ </xs:simpleType>
1435+
1436+ <xs:complexType name="Item">
1437+ <xs:sequence>
1438+ <xs:element name="ItemID" type="ItemIDType" minOccurs="0" />
1439+ <xs:element name="ItemNumber" type="ItemNumberType"
1440+ minOccurs="0" />
1441+ <xs:element name="IdentCode" type="IdentCodeType"
1442+ minOccurs="0" />
1443+ <xs:element name="Recipient" type="Recipient" />
1444+ <xs:element name="AdditionalINFOS" minOccurs="0">
1445+ <xs:annotation>
1446+ <xs:documentation>ehem. REC_Data bei V2.1 und 2.0
1447+ </xs:documentation>
1448+ </xs:annotation>
1449+ <xs:complexType>
1450+ <xs:sequence>
1451+ <xs:element name="AdditionalData" type="AdditionalData"
1452+ maxOccurs="50" />
1453+ </xs:sequence>
1454+ </xs:complexType>
1455+ </xs:element>
1456+ <xs:element name="Attributes" type="ServiceCodeAttributes"
1457+ minOccurs="0" />
1458+ <xs:element name="Notification" type="Notification"
1459+ minOccurs="0" maxOccurs="15">
1460+ <xs:annotation>
1461+ <xs:documentation>Zusatzinformationen für Dienstleistung
1462+ </xs:documentation>
1463+ </xs:annotation>
1464+ </xs:element>
1465+ </xs:sequence>
1466+ </xs:complexType>
1467+
1468+ <xs:simpleType name="ItemNumberType">
1469+ <xs:restriction base="xs:string">
1470+ <xs:pattern value="[0-9]{1,8}" />
1471+ </xs:restriction>
1472+ </xs:simpleType>
1473+
1474+ <xs:complexType name="Recipient">
1475+ <xs:sequence>
1476+ <xs:element name="PostIdent" minOccurs="0">
1477+ <xs:simpleType>
1478+ <xs:restriction base="CommonPatternStringType">
1479+ <xs:maxLength value="15" />
1480+ </xs:restriction>
1481+ </xs:simpleType>
1482+ </xs:element>
1483+ <xs:element name="Title" type="RecipientAddressType"
1484+ minOccurs="0" />
1485+ <xs:element name="PersonallyAddressed" type="xs:boolean"
1486+ minOccurs="0" />
1487+ <xs:element name="Name1" type="RecipientAddressType" />
1488+ <xs:element name="FirstName" type="RecipientAddressType"
1489+ minOccurs="0" />
1490+ <xs:element name="Name2" type="RecipientAddressType"
1491+ minOccurs="0" />
1492+ <xs:element name="Street" type="RecipientAddressType"
1493+ minOccurs="0" />
1494+ <xs:element name="HouseNo" minOccurs="0">
1495+ <xs:simpleType>
1496+ <xs:restriction base="CommonPatternStringType">
1497+ <xs:maxLength value="5" />
1498+ </xs:restriction>
1499+ </xs:simpleType>
1500+ </xs:element>
1501+ <xs:element name="POBox" type="RecipientAddressType"
1502+ minOccurs="0" />
1503+ <xs:element name="FloorNo" minOccurs="0">
1504+ <xs:simpleType>
1505+ <xs:restriction base="CommonPatternStringType">
1506+ <xs:maxLength value="5" />
1507+ </xs:restriction>
1508+ </xs:simpleType>
1509+ </xs:element>
1510+ <xs:element name="MailboxNo" minOccurs="0">
1511+ <xs:simpleType>
1512+ <xs:restriction base="xs:integer">
1513+ <xs:totalDigits value="10" />
1514+ </xs:restriction>
1515+ </xs:simpleType>
1516+ </xs:element>
1517+ <xs:element name="ZIP" minOccurs="1">
1518+ <xs:simpleType>
1519+ <xs:restriction base="CommonPatternStringType">
1520+ <xs:maxLength value="10" />
1521+ </xs:restriction>
1522+ </xs:simpleType>
1523+ </xs:element>
1524+ <xs:element name="City" type="RecipientAddressType" />
1525+ <xs:element name="Country" type="CountryType"
1526+ minOccurs="0" />
1527+ <xs:element name="Phone" type="PhoneNumberType"
1528+ minOccurs="0" />
1529+ <xs:element name="Mobile" type="PhoneNumberType"
1530+ minOccurs="0" />
1531+ <xs:element name="EMail" type="EMailAddressType"
1532+ minOccurs="0" />
1533+ <xs:element name="LabelAddress" type="LabelAddress"
1534+ minOccurs="0" />
1535+ </xs:sequence>
1536+ </xs:complexType>
1537+
1538+ <xs:complexType name="LabelAddress">
1539+ <xs:annotation>
1540+ <xs:documentation>optional, used to declare a specific address on
1541+ the label. if omitted, the address data of
1542+ the recipient is taken. Useful if the address data of the recipient
1543+ exceeds the length of the label.
1544+ </xs:documentation>
1545+ </xs:annotation>
1546+ <xs:sequence>
1547+ <xs:element name="NameLine" type="RecipientAddressType" />
1548+ <xs:element name="AddressLine" type="RecipientAddressType" />
1549+ </xs:sequence>
1550+ </xs:complexType>
1551+
1552+ <xs:simpleType name="RecipientAddressType">
1553+ <xs:restriction base="CommonPatternStringType">
1554+ <xs:maxLength value="35" />
1555+ </xs:restriction>
1556+ </xs:simpleType>
1557+
1558+ <xs:complexType name="AdditionalData">
1559+ <xs:sequence>
1560+ <xs:element name="Type">
1561+ <xs:simpleType>
1562+ <xs:restriction base="CommonPatternStringType">
1563+ <xs:maxLength value="35" />
1564+ </xs:restriction>
1565+ </xs:simpleType>
1566+ </xs:element>
1567+ <xs:element name="Value">
1568+ <xs:simpleType>
1569+ <xs:restriction base="CommonPatternStringType">
1570+ <xs:maxLength value="50" />
1571+ </xs:restriction>
1572+ </xs:simpleType>
1573+ </xs:element>
1574+ </xs:sequence>
1575+ </xs:complexType>
1576+
1577+ <xs:complexType name="ServiceCodeAttributes">
1578+ <xs:sequence>
1579+ <xs:element name="PRZL" type="PRZLType" minOccurs="1"
1580+ maxOccurs="unbounded" />
1581+ <xs:element name="Amount" type="AmountType" minOccurs="0" />
1582+ <xs:element name="FreeText" minOccurs="0">
1583+ <xs:simpleType>
1584+ <xs:restriction base="CommonPatternStringType">
1585+ <xs:maxLength value="34" />
1586+ </xs:restriction>
1587+ </xs:simpleType>
1588+ </xs:element>
1589+ <xs:element name="DeliveryDate" type="xs:date"
1590+ minOccurs="0" />
1591+ <xs:element name="ParcelNo" type="ParcelAmountType"
1592+ minOccurs="0" />
1593+ <xs:element name="ParcelTotal" type="ParcelAmountType"
1594+ minOccurs="0" />
1595+ <xs:element name="DeliveryPlace" minOccurs="0">
1596+ <xs:simpleType>
1597+ <xs:restriction base="CommonPatternStringType">
1598+ <xs:maxLength value="35" />
1599+ </xs:restriction>
1600+ </xs:simpleType>
1601+ </xs:element>
1602+ <xs:element name="ProClima" type="xs:boolean"
1603+ minOccurs="0" />
1604+ <xs:element name="Dimensions" type="Dimensions"
1605+ minOccurs="0" />
1606+ <xs:element name="UNNumbers" type="UNNumbers"
1607+ minOccurs="0" />
1608+ </xs:sequence>
1609+ </xs:complexType>
1610+
1611+ <xs:simpleType name="ParcelAmountType">
1612+ <xs:restriction base="xs:int">
1613+ <xs:minInclusive value="0" />
1614+ <xs:maxInclusive value="99" />
1615+ </xs:restriction>
1616+ </xs:simpleType>
1617+
1618+ <xs:complexType name="Dimensions">
1619+ <xs:annotation>
1620+ <xs:documentation>Represents the Dimensions attribute of the
1621+ DataTransfer.</xs:documentation>
1622+ </xs:annotation>
1623+ <xs:sequence>
1624+ <xs:element name="Weight">
1625+ <xs:annotation>
1626+ <xs:documentation>Weight in gramms.</xs:documentation>
1627+ </xs:annotation>
1628+ <xs:simpleType>
1629+ <xs:restriction base="xs:integer">
1630+ <xs:totalDigits value="5" />
1631+ </xs:restriction>
1632+ </xs:simpleType>
1633+ </xs:element>
1634+ </xs:sequence>
1635+ </xs:complexType>
1636+
1637+ <xs:complexType name="UNNumbers">
1638+ <xs:annotation>
1639+ <xs:documentation>Represents the UN Numbers for the additional
1640+ service LQ (limited quantities).
1641+ </xs:documentation>
1642+ </xs:annotation>
1643+ <xs:sequence>
1644+ <xs:element name="UNNumber" minOccurs="0" maxOccurs="unbounded">
1645+ <xs:simpleType>
1646+ <xs:restriction base="xs:integer">
1647+ <xs:totalDigits value="4" />
1648+ </xs:restriction>
1649+ </xs:simpleType>
1650+ </xs:element>
1651+ </xs:sequence>
1652+ </xs:complexType>
1653+
1654+ <xs:complexType name="Notification">
1655+ <xs:all>
1656+ <xs:element name="Communication" type="Communication" />
1657+ <xs:element name="Service">
1658+ <xs:annotation>
1659+ <xs:documentation>Avisierungs-Code, welcher die Avisierung
1660+ bezeichnet.</xs:documentation>
1661+ </xs:annotation>
1662+ <xs:simpleType>
1663+ <xs:restriction base="xs:integer">
1664+ <xs:totalDigits value="20" />
1665+ </xs:restriction>
1666+ </xs:simpleType>
1667+ </xs:element>
1668+ <xs:element name="FreeText1" minOccurs="0">
1669+ <xs:annotation>
1670+ <xs:documentation>Individueller Text 1 für Avisierung.
1671+ </xs:documentation>
1672+ </xs:annotation>
1673+ <xs:simpleType>
1674+ <xs:restriction base="CommonPatternStringType">
1675+ <xs:maxLength value="160" />
1676+ </xs:restriction>
1677+ </xs:simpleType>
1678+ </xs:element>
1679+ <xs:element name="FreeText2" minOccurs="0">
1680+ <xs:annotation>
1681+ <xs:documentation>Individueller Text 2 für Avisierung.
1682+ </xs:documentation>
1683+ </xs:annotation>
1684+ <xs:simpleType>
1685+ <xs:restriction base="CommonPatternStringType">
1686+ <xs:maxLength value="512" />
1687+ </xs:restriction>
1688+ </xs:simpleType>
1689+ </xs:element>
1690+ <xs:element name="Language" type="Language" />
1691+ </xs:all>
1692+ <xs:attribute name="Type" type="NotificationType" use="required">
1693+ <xs:annotation>
1694+ <xs:documentation>Angabe des Medium</xs:documentation>
1695+ </xs:annotation>
1696+ </xs:attribute>
1697+ </xs:complexType>
1698+
1699+ <xs:simpleType name="NotificationType">
1700+ <xs:restriction base="xs:string">
1701+ <xs:enumeration value="EMAIL" />
1702+ <xs:enumeration value="SMS" />
1703+ </xs:restriction>
1704+ </xs:simpleType>
1705+
1706+ <xs:complexType name="Communication">
1707+ <xs:choice>
1708+ <xs:element name="Email" type="EMailAddressType" />
1709+ <xs:element name="Mobile" type="PhoneNumberType" />
1710+ </xs:choice>
1711+ </xs:complexType>
1712+
1713+ <!-- 5.6 Use Case Lese Dienstleistungsgruppen -->
1714+ <xs:element name="ReadServiceGroups">
1715+ <xs:complexType>
1716+ <xs:choice>
1717+ <xs:element name="Language" type="Language" />
1718+ </xs:choice>
1719+ </xs:complexType>
1720+ </xs:element>
1721+
1722+ <xs:element name="ReadServiceGroupsResponse">
1723+ <xs:complexType>
1724+ <xs:choice>
1725+ <xs:element name="ServiceGroup" type="ServiceGroup"
1726+ minOccurs="0" maxOccurs="unbounded" />
1727+ <xs:element name="Errors" type="ErrorsType"
1728+ minOccurs="0" />
1729+ </xs:choice>
1730+ </xs:complexType>
1731+ </xs:element>
1732+
1733+ <!-- FAfo-10.1 FTA Page 65 Lese BL einer FRLZ -->
1734+ <xs:element name="ReadAllowedServicesByFrankingLicense">
1735+ <xs:complexType>
1736+ <xs:sequence>
1737+ <xs:element name="FrankingLicense" type="FrankingLicenseType"
1738+ minOccurs="1" />
1739+ <xs:element name="Language" type="Language" />
1740+ </xs:sequence>
1741+ </xs:complexType>
1742+ </xs:element>
1743+
1744+ <!-- FAfo-10.1 FTA Page 65 Lese BL einer FRLZ -->
1745+ <xs:element name="ReadAllowedServicesByFrankingLicenseResponse">
1746+ <xs:complexType>
1747+ <xs:choice>
1748+ <!-- DLGs -->
1749+ <xs:element name="ServiceGroups" type="ReadAllowedServicesServiceGroups"
1750+ minOccurs="0" maxOccurs="unbounded" />
1751+ <xs:element name="Errors" type="ErrorsType"
1752+ minOccurs="0" />
1753+ </xs:choice>
1754+ </xs:complexType>
1755+ </xs:element>
1756+
1757+ <xs:complexType name="ReadAllowedServicesServiceGroups">
1758+ <xs:sequence>
1759+ <xs:element name="ServiceGroup" type="ServiceGroup" />
1760+ <xs:element name="BasicService" type="BasicService"
1761+ maxOccurs="unbounded" />
1762+ </xs:sequence>
1763+ </xs:complexType>
1764+
1765+ <!-- 5.7 Use Case Lese Basisleistungen -->
1766+ <xs:element name="ReadBasicServices">
1767+ <xs:complexType>
1768+ <xs:sequence>
1769+ <xs:element name="Language" type="Language" />
1770+ <xs:element name="ServiceGroupID" type="xs:int" />
1771+ </xs:sequence>
1772+ </xs:complexType>
1773+ </xs:element>
1774+
1775+ <xs:element name="ReadBasicServicesResponse">
1776+ <xs:complexType>
1777+ <xs:choice>
1778+ <xs:element name="BasicService" type="BasicService"
1779+ minOccurs="0" maxOccurs="unbounded" />
1780+ <xs:element name="Errors" type="ErrorsType"
1781+ minOccurs="0" />
1782+ </xs:choice>
1783+ </xs:complexType>
1784+ </xs:element>
1785+
1786+ <!-- 5.8 Use Case Lese Zusatzleistungen -->
1787+ <xs:element name="ReadAdditionalServices">
1788+ <xs:complexType>
1789+ <xs:sequence>
1790+ <xs:element name="Language" type="Language" />
1791+ <xs:element name="PRZL" type="PRZLType" maxOccurs="unbounded" />
1792+ </xs:sequence>
1793+ </xs:complexType>
1794+ </xs:element>
1795+
1796+ <xs:element name="ReadAdditionalServicesResponse">
1797+ <xs:complexType>
1798+ <xs:choice>
1799+ <xs:element name="AdditionalService" type="ServiceCode"
1800+ minOccurs="0" maxOccurs="unbounded" />
1801+ <xs:element name="Errors" type="ErrorsType"
1802+ minOccurs="0" />
1803+ </xs:choice>
1804+ </xs:complexType>
1805+ </xs:element>
1806+
1807+ <!-- 5.9 Use Case Lese Zustellanweisungen -->
1808+ <xs:element name="ReadDeliveryInstructions">
1809+ <xs:complexType>
1810+ <xs:sequence>
1811+ <xs:element name="Language" type="Language" />
1812+ <xs:element name="PRZL" type="PRZLType" maxOccurs="unbounded" />
1813+ </xs:sequence>
1814+ </xs:complexType>
1815+ </xs:element>
1816+
1817+ <xs:element name="ReadDeliveryInstructionsResponse">
1818+ <xs:complexType>
1819+ <xs:choice>
1820+ <xs:element name="DeliveryInstructions" type="ServiceCode"
1821+ minOccurs="0" maxOccurs="unbounded" />
1822+ <xs:element name="Errors" type="ErrorsType"
1823+ minOccurs="0" />
1824+ </xs:choice>
1825+ </xs:complexType>
1826+ </xs:element>
1827+
1828+ <!-- 5.10 Use Case Lese Darstellungsarten -->
1829+ <xs:element name="ReadLabelLayouts">
1830+ <xs:complexType>
1831+ <xs:sequence>
1832+ <xs:element name="Language" type="Language" />
1833+ <xs:element name="PRZL" type="PRZLType" maxOccurs="unbounded" />
1834+ </xs:sequence>
1835+ </xs:complexType>
1836+ </xs:element>
1837+
1838+ <xs:element name="ReadLabelLayoutsResponse">
1839+ <xs:complexType>
1840+ <xs:choice>
1841+ <xs:element name="LabelLayout" type="LabelLayoutResponse"
1842+ minOccurs="0" maxOccurs="unbounded" />
1843+ <xs:element name="Errors" type="ErrorsType"
1844+ minOccurs="0" />
1845+ </xs:choice>
1846+ </xs:complexType>
1847+ </xs:element>
1848+
1849+ <xs:complexType name="LabelLayoutResponse">
1850+ <xs:sequence>
1851+ <xs:element name="LabelLayout" type="LabelLayoutType" />
1852+ <xs:element name="MaxServices" type="xs:int" />
1853+ <xs:element name="MaxDeliveryInstructions" type="xs:int" />
1854+ <xs:element name="FreeTextAllowed" type="xs:boolean" />
1855+ </xs:sequence>
1856+ </xs:complexType>
1857+
1858+ <xs:element name="GenerateBarcode">
1859+ <xs:complexType>
1860+ <xs:sequence>
1861+ <xs:element name="Language" type="Language" />
1862+ <xs:element name="BarcodeDefinition" type="BarcodeDefinition" />
1863+ </xs:sequence>
1864+ </xs:complexType>
1865+ </xs:element>
1866+
1867+ <xs:element name="GenerateBarcodeResponse">
1868+ <xs:complexType>
1869+ <xs:sequence>
1870+ <xs:element name="Data" type="BarcodeResponseData"
1871+ minOccurs="0" />
1872+ </xs:sequence>
1873+ </xs:complexType>
1874+ </xs:element>
1875+
1876+ <xs:complexType name="BarcodeResponseData">
1877+ <xs:sequence>
1878+ <xs:element name="Barcode" type="xs:base64Binary"
1879+ minOccurs="0" />
1880+ <xs:element name="DeliveryNoteRef" minOccurs="0">
1881+ <xs:annotation>
1882+ <xs:documentation>Lieferscheinnummer Barcodeliste BMZ (128-er
1883+ Klartext-Barcode)</xs:documentation>
1884+ </xs:annotation>
1885+ <xs:simpleType>
1886+ <xs:restriction base="xs:string">
1887+ <xs:maxLength value="50" />
1888+ </xs:restriction>
1889+ </xs:simpleType>
1890+ </xs:element>
1891+ <xs:element name="BarcodeDefinition" type="BarcodeDefinition" />
1892+ <xs:element name="ColorPrintRequired" type="xs:boolean" />
1893+ <xs:element name="Errors" type="ErrorsType" minOccurs="0" />
1894+ <xs:element name="Warnings" type="WarningsType"
1895+ minOccurs="0" />
1896+ </xs:sequence>
1897+ </xs:complexType>
1898+
1899+ <xs:complexType name="BarcodeDefinition">
1900+ <xs:annotation>
1901+ <xs:documentation>Represents a BarcodeDefinition for the
1902+ GenerateBarcode Service.</xs:documentation>
1903+ </xs:annotation>
1904+ <xs:sequence>
1905+ <xs:element name="BarcodeType" type="BarcodeType" />
1906+ <xs:element name="ImageFileType" type="ImageFileType" />
1907+ <xs:element name="ImageResolution" type="xs:int" />
1908+ </xs:sequence>
1909+ </xs:complexType>
1910+
1911+ <xs:simpleType name="BarcodeType">
1912+ <xs:annotation>
1913+ <xs:documentation>Enumeration of the different barcode types.
1914+ </xs:documentation>
1915+ </xs:annotation>
1916+ <xs:restriction base="xs:string">
1917+ <xs:enumeration value="LSO_1">
1918+ <xs:annotation>
1919+ <xs:documentation>LSO-1 barcode for delivery notes online.
1920+ </xs:documentation>
1921+ </xs:annotation>
1922+ </xs:enumeration>
1923+ <xs:enumeration value="LSO_2">
1924+ <xs:annotation>
1925+ <xs:documentation>LSO-2 barcode for delivery notes online.
1926+ </xs:documentation>
1927+ </xs:annotation>
1928+ </xs:enumeration>
1929+ <xs:enumeration value="LSO_3">
1930+ <xs:annotation>
1931+ <xs:documentation>LSO-3 barcode for delivery notes online.
1932+ </xs:documentation>
1933+ </xs:annotation>
1934+ </xs:enumeration>
1935+ </xs:restriction>
1936+ </xs:simpleType>
1937+
1938+ <!-- **************************** Gloabal used datastructures **************************** -->
1939+ <xs:complexType name="ServiceCode">
1940+ <xs:annotation>
1941+ <xs:documentation>Represents a service code.</xs:documentation>
1942+ </xs:annotation>
1943+ <xs:sequence>
1944+ <xs:element name="PRZL" type="PRZLType" />
1945+ <xs:element name="Description" type="DescriptionType" />
1946+ </xs:sequence>
1947+ </xs:complexType>
1948+
1949+ <xs:complexType name="BasicService">
1950+ <xs:annotation>
1951+ <xs:documentation>Represents a Basic Service.</xs:documentation>
1952+ </xs:annotation>
1953+ <xs:sequence>
1954+ <xs:element name="PRZL" type="PRZLType" minOccurs="0"
1955+ maxOccurs="unbounded" />
1956+ <xs:element name="Description" type="DescriptionType" />
1957+ </xs:sequence>
1958+ </xs:complexType>
1959+
1960+ <xs:complexType name="ServiceGroup">
1961+ <xs:annotation>
1962+ <xs:documentation>Represents a Service Group.</xs:documentation>
1963+ </xs:annotation>
1964+ <xs:sequence>
1965+ <xs:element name="ServiceGroupID" type="xs:int" />
1966+ <xs:element name="Description" type="DescriptionType" />
1967+ </xs:sequence>
1968+ </xs:complexType>
1969+
1970+ <xs:simpleType name="DescriptionType">
1971+ <xs:annotation>
1972+ <xs:documentation>A common type for descriptions.
1973+ </xs:documentation>
1974+ </xs:annotation>
1975+ <xs:restriction base="xs:string"> <!-- only used as response type -->
1976+ <xs:maxLength value="255" />
1977+ </xs:restriction>
1978+ </xs:simpleType>
1979+
1980+ <xs:complexType name="LabelDefinition">
1981+ <xs:sequence>
1982+ <xs:element name="LabelLayout" type="LabelLayoutType" />
1983+ </xs:sequence>
1984+ </xs:complexType>
1985+
1986+ <xs:complexType name="ResponseItem">
1987+ <xs:sequence>
1988+ <xs:element name="ItemID" type="ItemIDType" minOccurs="0" />
1989+ <xs:element name="Errors" type="ErrorsType" minOccurs="0" />
1990+ <xs:element name="Warnings" type="WarningsType"
1991+ minOccurs="0" />
1992+ </xs:sequence>
1993+ </xs:complexType>
1994+
1995+ <xs:complexType name="ErrorsType">
1996+ <xs:annotation>
1997+ <xs:documentation>Structure containing a list of occurred business
1998+ errors.</xs:documentation>
1999+ </xs:annotation>
2000+ <xs:sequence>
2001+ <xs:element name="Error" type="MessageType" maxOccurs="unbounded" />
2002+ </xs:sequence>
2003+ </xs:complexType>
2004+
2005+ <xs:complexType name="WarningsType">
2006+ <xs:annotation>
2007+ <xs:documentation>Structure containing a list of occurred business
2008+ warnings.</xs:documentation>
2009+ </xs:annotation>
2010+ <xs:sequence>
2011+ <xs:element name="Warning" type="MessageType"
2012+ maxOccurs="unbounded" />
2013+ </xs:sequence>
2014+ </xs:complexType>
2015+
2016+ <xs:complexType name="MessageType">
2017+ <xs:annotation>
2018+ <xs:documentation>Represents a business error or warning. Does not
2019+ include technical errors, those are
2020+ handled by SOAP faults.
2021+ </xs:documentation>
2022+ </xs:annotation>
2023+ <xs:sequence>
2024+ <xs:element name="Code" type="MessageCodeType" />
2025+ <xs:element name="Message" type="MessageTextType" />
2026+ </xs:sequence>
2027+ </xs:complexType>
2028+
2029+ <xs:simpleType name="MessageCodeType">
2030+ <xs:annotation>
2031+ <xs:documentation>Five digit error/warning code. Error codes
2032+ starts with a "E" and warning codes
2033+ with a "W".
2034+ </xs:documentation>
2035+ </xs:annotation>
2036+ <xs:restriction base="xs:string">
2037+ <xs:pattern value="[W,E]{1}[0-9]{4}" />
2038+ </xs:restriction>
2039+ </xs:simpleType>
2040+
2041+ <xs:simpleType name="MessageTextType">
2042+ <xs:annotation>
2043+ <xs:documentation>Descriptive text in user's language for the
2044+ occurred business warning/error.
2045+ </xs:documentation>
2046+ </xs:annotation>
2047+ <!-- only used as response type -->
2048+ <xs:restriction base="xs:string">
2049+ <xs:maxLength value="500" />
2050+ </xs:restriction>
2051+ </xs:simpleType>
2052+
2053+ <xs:simpleType name="Language">
2054+ <xs:annotation>
2055+ <xs:documentation>Represents the end-users language. The service
2056+ returns all localized texts including
2057+ error-messages in the selected language.
2058+ </xs:documentation>
2059+ </xs:annotation>
2060+ <xs:restriction base="xs:string">
2061+ <xs:enumeration value="de">
2062+ <xs:annotation>
2063+ <xs:documentation>German</xs:documentation>
2064+ </xs:annotation>
2065+ </xs:enumeration>
2066+ <xs:enumeration value="fr">
2067+ <xs:annotation>
2068+ <xs:documentation>French</xs:documentation>
2069+ </xs:annotation>
2070+ </xs:enumeration>
2071+ <xs:enumeration value="it">
2072+ <xs:annotation>
2073+ <xs:documentation>Italien</xs:documentation>
2074+ </xs:annotation>
2075+ </xs:enumeration>
2076+ <xs:enumeration value="en">
2077+ <xs:annotation>
2078+ <xs:documentation>English</xs:documentation>
2079+ </xs:annotation>
2080+ </xs:enumeration>
2081+ </xs:restriction>
2082+ </xs:simpleType>
2083+
2084+ <xs:simpleType name="ItemIDType">
2085+ <xs:annotation>
2086+ <xs:documentation>Unique identifier for a specific item defined by
2087+ the consumer.</xs:documentation>
2088+ </xs:annotation>
2089+ <xs:restriction base="CommonPatternStringType">
2090+ <xs:maxLength value="200" />
2091+ </xs:restriction>
2092+ </xs:simpleType>
2093+
2094+ <xs:simpleType name="PRZLType">
2095+ <xs:annotation>
2096+ <xs:documentation>Identifies a PRZL.</xs:documentation>
2097+ </xs:annotation>
2098+ <xs:restriction base="xs:string">
2099+ <xs:pattern value="[a-zA-Z,0-9]{1,7}" />
2100+ </xs:restriction>
2101+ </xs:simpleType>
2102+
2103+ <xs:simpleType name="PhoneNumberType">
2104+ <xs:annotation>
2105+ <xs:documentation>Defines a valid phone number.</xs:documentation>
2106+ </xs:annotation>
2107+ <xs:restriction base="CommonPatternStringType">
2108+ <xs:maxLength value="20" />
2109+ <xs:minLength value="9" />
2110+ </xs:restriction>
2111+ </xs:simpleType>
2112+
2113+ <xs:simpleType name="CountryType">
2114+ <xs:annotation>
2115+ <xs:documentation>The ISO country code.</xs:documentation>
2116+ </xs:annotation>
2117+ <xs:restriction base="xs:string">
2118+ <xs:pattern value="[a-zA-Z]{2}" />
2119+ </xs:restriction>
2120+ </xs:simpleType>
2121+
2122+ <xs:simpleType name="AmountType">
2123+ <xs:annotation>
2124+ <xs:documentation>The amount for COD.</xs:documentation>
2125+ </xs:annotation>
2126+ <xs:restriction base="xs:float">
2127+ <xs:minInclusive value="0.00" />
2128+ <xs:maxInclusive value="99999.99" />
2129+ </xs:restriction>
2130+ </xs:simpleType>
2131+
2132+ <xs:simpleType name="EMailAddressType">
2133+ <xs:annotation>
2134+ <xs:documentation>The email address.</xs:documentation>
2135+ </xs:annotation>
2136+ <xs:restriction base="CommonPatternStringType">
2137+ <xs:maxLength value="160" />
2138+ </xs:restriction>
2139+ </xs:simpleType>
2140+
2141+ <xs:simpleType name="LabelLayoutType">
2142+ <xs:annotation>
2143+ <xs:documentation>Defines valid layouts.</xs:documentation>
2144+ </xs:annotation>
2145+ <xs:restriction base="xs:string">
2146+ <xs:pattern value="[a-zA-Z,0-9]{2}" />
2147+ </xs:restriction>
2148+ </xs:simpleType>
2149+
2150+ <xs:simpleType name="ImageFileType">
2151+ <xs:annotation>
2152+ <xs:documentation>Defines valid formats of images.
2153+ </xs:documentation>
2154+ </xs:annotation>
2155+ <xs:restriction base="xs:string">
2156+ <xs:pattern value="[a-zA-Z,0-9]{1,5}" />
2157+ </xs:restriction>
2158+ </xs:simpleType>
2159+
2160+ <xs:simpleType name="FrankingLicenseType">
2161+ <xs:annotation>
2162+ <xs:documentation>Defines a franking license.</xs:documentation>
2163+ </xs:annotation>
2164+ <xs:restriction base="xs:string">
2165+ <xs:pattern value="[a-zA-Z,0-9]{4}" />
2166+ <xs:pattern value="[0-9]{6}" />
2167+ <xs:pattern value="[0-9]{8}" />
2168+ </xs:restriction>
2169+ </xs:simpleType>
2170+
2171+ <xs:simpleType name="CustomerSystemType">
2172+ <xs:restriction base="CommonPatternStringType">
2173+ <xs:pattern value="[a-zA-Z,0-9,\s]{1,255}" />
2174+ </xs:restriction>
2175+ </xs:simpleType>
2176+
2177+ <xs:simpleType name="IdentCodeType">
2178+ <xs:annotation>
2179+ <xs:documentation>IdentCode is only a valid input for
2180+ Post-internal applications. For Post-external
2181+ applications the IdentCode must not be set.
2182+ </xs:documentation>
2183+ </xs:annotation>
2184+ <xs:restriction base="CommonPatternStringType">
2185+ <xs:pattern value="[0-9]{18}" />
2186+ <xs:pattern value="[0-9]{23}" />
2187+ <xs:pattern value="[a-zA-Z,0-9]{13}" />
2188+ </xs:restriction>
2189+ </xs:simpleType>
2190+
2191+ <xs:simpleType name="CommonPatternStringType">
2192+ <xs:annotation>
2193+ <xs:documentation>Excludes unsupported characters.
2194+ </xs:documentation>
2195+ </xs:annotation>
2196+ <xs:restriction base="xs:string">
2197+ <xs:pattern value="([^\*|\\|\{|\}|\[|\]|=|&gt;|&lt;])*" />
2198+ </xs:restriction>
2199+ </xs:simpleType>
2200+
2201+
2202+</xs:schema>
2203\ No newline at end of file
2204
2205=== added file 'delivery_carrier_label_postlogistics/data/post-barcode-handbuch.pdf'
2206Binary files delivery_carrier_label_postlogistics/data/post-barcode-handbuch.pdf 1970-01-01 00:00:00 +0000 and delivery_carrier_label_postlogistics/data/post-barcode-handbuch.pdf 2013-11-27 09:30:06 +0000 differ
2207=== added file 'delivery_carrier_label_postlogistics/delivery.py'
2208--- delivery_carrier_label_postlogistics/delivery.py 1970-01-01 00:00:00 +0000
2209+++ delivery_carrier_label_postlogistics/delivery.py 2013-11-27 09:30:06 +0000
2210@@ -0,0 +1,213 @@
2211+# -*- coding: utf-8 -*-
2212+##############################################################################
2213+#
2214+# Author: Yannick Vaucher
2215+# Copyright 2013 Camptocamp SA
2216+#
2217+# This program is free software: you can redistribute it and/or modify
2218+# it under the terms of the GNU Affero General Public License as
2219+# published by the Free Software Foundation, either version 3 of the
2220+# License, or (at your option) any later version.
2221+#
2222+# This program is distributed in the hope that it will be useful,
2223+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2224+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2225+# GNU Affero General Public License for more details.
2226+#
2227+# You should have received a copy of the GNU Affero General Public License
2228+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2229+#
2230+##############################################################################
2231+from openerp.osv import orm, fields
2232+
2233+
2234+class PostlogisticsServiceGroup(orm.Model):
2235+ _name = 'postlogistics.service.group'
2236+ _description = 'PostLogistics Service Group'
2237+
2238+ _columns = {
2239+ 'name': fields.char('Description', translate=True, required=True),
2240+ 'group_extid': fields.integer('Group ID', required=True),
2241+ }
2242+
2243+ _sql_constraints = [
2244+ ('group_extid_uniq', 'unique(group_extid)',
2245+ "A service group ID must be unique.")
2246+ ]
2247+
2248+
2249+POSTLOGISTIC_TYPES = [
2250+ ('label_layout', 'Label Layout'),
2251+ ('output_format', 'Output Format'),
2252+ ('resolution', 'Output Resolution'),
2253+ ('basic', 'Basic Service'),
2254+ ('additional', 'Additional Service'),
2255+ ('delivery', 'Delivery Instructions')
2256+]
2257+
2258+
2259+class DeliveryCarrierTemplateOption(orm.Model):
2260+ """ Set name translatable and add service group """
2261+ _inherit = 'delivery.carrier.template.option'
2262+
2263+ _columns = {
2264+ 'name': fields.char('Name', size=64, translate=True),
2265+ 'postlogistics_service_group_id': fields.many2one(
2266+ 'postlogistics.service.group',
2267+ string='PostLogistics Service Group'),
2268+ 'postlogistics_type': fields.selection(
2269+ POSTLOGISTIC_TYPES,
2270+ string="PostLogistics option type"),
2271+ # relation tables to manage compatiblity between basic services
2272+ # and other services
2273+ 'postlogistics_basic_service_ids': fields.many2many(
2274+ 'delivery.carrier.template.option',
2275+ 'postlogistics_compatibility_service_rel',
2276+ 'service_id', 'basic_service_id',
2277+ string="Basic Services",
2278+ domain=[('postlogistics_type', '=', 'basic')],
2279+ help="List of basic service for which this service is compatible"),
2280+ 'postlogistics_additonial_service_ids': fields.many2many(
2281+ 'delivery.carrier.template.option',
2282+ 'postlogistics_compatibility_service_rel',
2283+ 'basic_service_id', 'service_id',
2284+ string="Compatible Additional Services",
2285+ domain=[('postlogistics_type', '=', 'additional')]),
2286+ 'postlogistics_delivery_instruction_ids': fields.many2many(
2287+ 'delivery.carrier.template.option',
2288+ 'postlogistics_compatibility_service_rel',
2289+ 'basic_service_id', 'service_id',
2290+ string="Compatible Delivery Instructions",
2291+ domain=[('postlogistics_type', '=', 'delivery')]),
2292+ }
2293+
2294+ _defaults = {
2295+ 'postlogistics_type': False,
2296+ }
2297+
2298+
2299+class DeliveryCarrierOption(orm.Model):
2300+ """ Set name translatable and add service group """
2301+ _inherit = 'delivery.carrier.option'
2302+
2303+ _columns = {
2304+ 'name': fields.char('Name', size=64, translate=True),
2305+ # to repeat carrier allowed option ids to filter domain set by
2306+ # default from view
2307+ 'allowed_option_ids': fields.related(
2308+ 'carrier_id', 'allowed_option_ids', type='many2many',
2309+ relation='delivery.carrier.template.option',
2310+ string='Allowed and compatible options',
2311+ readonly=True),
2312+ }
2313+
2314+
2315+class DeliveryCarrier(orm.Model):
2316+ """ Add service group """
2317+ _inherit = 'delivery.carrier'
2318+
2319+ def _get_carrier_type_selection(self, cr, uid, context=None):
2320+ """ To inherit to add carrier type """
2321+ res = super(DeliveryCarrier, self)._get_carrier_type_selection(cr, uid, context=context)
2322+ res.append(('postlogistics', 'Postlogistics'))
2323+ return res
2324+
2325+ def _get_basic_service_id(self, cr, uid, ids, field_names, arg, context=None):
2326+ """ Search in all options for the postlogistic basic service if set """
2327+ res = dict.fromkeys(ids, False)
2328+ ir_model_data_obj = self.pool.get('ir.model.data')
2329+
2330+ xmlid = 'delivery_carrier_label_laposte', 'postlogistics'
2331+ postlogistics_partner = ir_model_data_obj.get_object(
2332+ cr, uid, *xmlid, context=context)
2333+
2334+ for carrier in self.browse(cr, uid, ids, context=context):
2335+ if not carrier.partner_id.id == postlogistics_partner.id:
2336+ continue
2337+
2338+ option_ids = [opt.tmpl_option_id.id for opt
2339+ in carrier.available_option_ids
2340+ if opt.postlogistics_type == 'basic']
2341+ if not option_ids:
2342+ continue
2343+ res[carrier.id] = option_ids[0]
2344+ return res
2345+
2346+ def _get_allowed_option_ids(self, cr, uid, ids, field_names, arg, context=None):
2347+ """ Return a list of possible options
2348+
2349+ A domain would be too complicated.
2350+
2351+ We do this to ensure the user first select a basic service. And
2352+ then he adds additional services.
2353+
2354+ :return: {carrier_id: [ids]}
2355+
2356+ """
2357+ res = dict.fromkeys(ids, [])
2358+ option_template_obj = self.pool.get('delivery.carrier.template.option')
2359+ ir_model_data_obj = self.pool.get('ir.model.data')
2360+
2361+ xmlid = 'delivery_carrier_label_laposte', 'postlogistics'
2362+ postlogistics_partner = ir_model_data_obj.get_object(
2363+ cr, uid, *xmlid, context=context)
2364+
2365+ for carrier in self.browse(cr, uid, ids, context=context):
2366+ allowed_ids = []
2367+ if not carrier.partner_id.id == postlogistics_partner.id:
2368+ continue
2369+ service_group_id = carrier.postlogistics_service_group_id.id
2370+ if service_group_id:
2371+ # if there are no basic option set. Show basic options
2372+ basic_service_id = carrier.postlogistics_basic_service_id.id
2373+ if not basic_service_id:
2374+ service_ids = option_template_obj.search(
2375+ cr, uid,
2376+ [('postlogistics_service_group_id' ,'=', service_group_id)],
2377+ context=context)
2378+ else:
2379+ service_ids = option_template_obj.search(
2380+ cr, uid,
2381+ [('postlogistics_basic_service_ids' ,'in', basic_service_id)],
2382+ context=context)
2383+ allowed_ids.extend(service_ids)
2384+
2385+ # Allows to set multiple optional single option in order to
2386+ # let the user select them
2387+ single_option_types = ['label_layout', 'output_format', 'resolution']
2388+ selected_single_options = [opt.tmpl_option_id.postlogistics_type
2389+ for opt in carrier.available_option_ids
2390+ if opt.postlogistics_type in single_option_types
2391+ and opt.state in ['mandatory']]
2392+ if selected_single_options != single_option_types:
2393+ service_ids = option_template_obj.search(
2394+ cr, uid,
2395+ [('postlogistics_type', 'in', single_option_types),
2396+ ('postlogistics_type', 'not in', selected_single_options)],
2397+ context=context)
2398+ allowed_ids.extend(service_ids)
2399+ res[carrier.id] = allowed_ids
2400+ return res
2401+
2402+ _columns = {
2403+ 'type': fields.selection(
2404+ _get_carrier_type_selection, 'Type',
2405+ help="Carrier type (combines several delivery methods)"),
2406+ 'postlogistics_service_group_id': fields.many2one(
2407+ 'postlogistics.service.group',
2408+ string='PostLogistics Service Group',
2409+ help="Service group defines the available options for "
2410+ "this delivery method."),
2411+ 'postlogistics_basic_service_id': fields.function(
2412+ _get_basic_service_id, type='many2one',
2413+ relation='delivery.carrier.template.option',
2414+ string='PostLogistics Service Group',
2415+ help="Basic Service defines the available "
2416+ "additional options for this delivery method",
2417+ readonly=True),
2418+ 'allowed_option_ids': fields.function(
2419+ _get_allowed_option_ids, type="many2many",
2420+ relation='delivery.carrier.template.option',
2421+ string='Allowed options',
2422+ help="Compute allowed options according to selected options."),
2423+ }
2424
2425=== added file 'delivery_carrier_label_postlogistics/delivery_data.xml'
2426--- delivery_carrier_label_postlogistics/delivery_data.xml 1970-01-01 00:00:00 +0000
2427+++ delivery_carrier_label_postlogistics/delivery_data.xml 2013-11-27 09:30:06 +0000
2428@@ -0,0 +1,108 @@
2429+<?xml version="1.0" encoding="utf-8"?>
2430+<openerp>
2431+ <data noupdate="1">
2432+
2433+ <!-- Label layouts -->
2434+ <record id="postlogistics_layout_option_a7" model="delivery.carrier.template.option">
2435+ <field name="name">Format A7</field>
2436+ <field name="code">A7</field>
2437+ <field name="postlogistics_type">label_layout</field>
2438+ <field name="partner_id" ref="postlogistics"></field>
2439+ </record>
2440+
2441+ <record id="postlogistics_layout_option_a6" model="delivery.carrier.template.option">
2442+ <field name="name">Format A6</field>
2443+ <field name="code">A6</field>
2444+ <field name="postlogistics_type">label_layout</field>
2445+ <field name="partner_id" ref="postlogistics"></field>
2446+ </record>
2447+
2448+ <record id="postlogistics_layout_option_a5" model="delivery.carrier.template.option">
2449+ <field name="name">Format A5</field>
2450+ <field name="code">A5</field>
2451+ <field name="postlogistics_type">label_layout</field>
2452+ <field name="partner_id" ref="postlogistics"></field>
2453+ </record>
2454+
2455+ <record id="postlogistics_layout_option_fe" model="delivery.carrier.template.option">
2456+ <field name="name">Format FE</field>
2457+ <field name="code">FE</field>
2458+ <field name="postlogistics_type">label_layout</field>
2459+ <field name="partner_id" ref="postlogistics"></field>
2460+ </record>
2461+
2462+
2463+ <!-- Output formats -->
2464+ <record id="postlogistics_output_format_option_eps" model="delivery.carrier.template.option">
2465+ <field name="name">EPS</field>
2466+ <field name="code">EPS</field>
2467+ <field name="postlogistics_type">output_format</field>
2468+ <field name="partner_id" ref="postlogistics"></field>
2469+ </record>
2470+
2471+ <record id="postlogistics_output_format_option_gif" model="delivery.carrier.template.option">
2472+ <field name="name">GIF</field>
2473+ <field name="code">GIF</field>
2474+ <field name="postlogistics_type">output_format</field>
2475+ <field name="partner_id" ref="postlogistics"></field>
2476+ </record>
2477+
2478+ <record id="postlogistics_output_format_option_jpg" model="delivery.carrier.template.option">
2479+ <field name="name">JPG</field>
2480+ <field name="code">JPG</field>
2481+ <field name="postlogistics_type">output_format</field>
2482+ <field name="partner_id" ref="postlogistics"></field>
2483+ </record>
2484+
2485+ <record id="postlogistics_output_format_option_png" model="delivery.carrier.template.option">
2486+ <field name="name">PNG</field>
2487+ <field name="code">PNG</field>
2488+ <field name="postlogistics_type">output_format</field>
2489+ <field name="partner_id" ref="postlogistics"></field>
2490+ </record>
2491+
2492+ <record id="postlogistics_output_format_option_pdf" model="delivery.carrier.template.option">
2493+ <field name="name">PDF</field>
2494+ <field name="code">PDF</field>
2495+ <field name="postlogistics_type">output_format</field>
2496+ <field name="partner_id" ref="postlogistics"></field>
2497+ </record>
2498+
2499+ <record id="postlogistics_output_format_option_spdf" model="delivery.carrier.template.option">
2500+ <field name="name">sPDF</field>
2501+ <field name="code">sPDF</field>
2502+ <field name="postlogistics_type">output_format</field>
2503+ <field name="partner_id" ref="postlogistics"></field>
2504+ </record>
2505+
2506+ <record id="postlogistics_output_format_option_zpl2" model="delivery.carrier.template.option">
2507+ <field name="name">ZPL2</field>
2508+ <field name="code">ZPL2</field>
2509+ <field name="postlogistics_type">output_format</field>
2510+ <field name="partner_id" ref="postlogistics"></field>
2511+ </record>
2512+
2513+
2514+ <!-- resolutions -->
2515+ <record id="postlogistics_output_resolution_option_200ppp" model="delivery.carrier.template.option">
2516+ <field name="name">200 ppp</field>
2517+ <field name="code">200</field>
2518+ <field name="postlogistics_type">resolution</field>
2519+ <field name="partner_id" ref="postlogistics"></field>
2520+ </record>
2521+
2522+ <record id="postlogistics_output_resolution_option_300ppp" model="delivery.carrier.template.option">
2523+ <field name="name">300 ppp</field>
2524+ <field name="code">300</field>
2525+ <field name="postlogistics_type">resolution</field>
2526+ <field name="partner_id" ref="postlogistics"></field>
2527+ </record>
2528+
2529+ <record id="postlogistics_output_resolution_option_600ppp" model="delivery.carrier.template.option">
2530+ <field name="name">600 ppp</field>
2531+ <field name="code">600</field>
2532+ <field name="postlogistics_type">resolution</field>
2533+ <field name="partner_id" ref="postlogistics"></field>
2534+ </record>
2535+ </data>
2536+</openerp>
2537
2538=== added file 'delivery_carrier_label_postlogistics/delivery_view.xml'
2539--- delivery_carrier_label_postlogistics/delivery_view.xml 1970-01-01 00:00:00 +0000
2540+++ delivery_carrier_label_postlogistics/delivery_view.xml 2013-11-27 09:30:06 +0000
2541@@ -0,0 +1,61 @@
2542+<?xml version="1.0" encoding="UTF-8"?>
2543+<openerp>
2544+ <data>
2545+
2546+ <!-- INHERITED VIEW FOR THE OBJECT : delivery_carrier_template_option -->
2547+ <record id="delivery_carrier_template_option_view_form" model="ir.ui.view">
2548+ <field name="name">delivery_base.delivery_carrier_option.view_form</field>
2549+ <field name="model">delivery.carrier.template.option</field>
2550+ <field name="inherit_id" ref="base_delivery_carrier_label.delivery_carrier_template_option_view_form"/>
2551+ <field name="arch" type="xml">
2552+ <field name="name" position="after">
2553+ <field name="postlogistics_service_group_id"/>
2554+ </field>
2555+ </field>
2556+ </record>
2557+
2558+ <record id="delivery_carrier_template_option_view_tree" model="ir.ui.view">
2559+ <field name="name">delivery_base.delivery_carrier_template_option.view_tree</field>
2560+ <field name="model">delivery.carrier.template.option</field>
2561+ <field name="inherit_id" ref="base_delivery_carrier_label.delivery_carrier_template_option_view_tree"/>
2562+ <field name="arch" type="xml">
2563+ <field name="name" position="after">
2564+ <field name="postlogistics_service_group_id"/>
2565+ </field>
2566+ </field>
2567+ </record>
2568+
2569+ <!-- INHERITED VIEW FOR THE OBJECT : delivery_carrier_option -->
2570+ <record id="delivery_carrier_option_view_form" model="ir.ui.view">
2571+ <field name="name">delivery_base.delivery_carrier_option.view_form</field>
2572+ <field name="model">delivery.carrier.option</field>
2573+ <field name="inherit_id" ref="base_delivery_carrier_label.delivery_carrier_option_view_form" />
2574+ <field name="arch" type="xml">
2575+ <field name="tmpl_option_id" position="before">
2576+ <field name="carrier_id" invisible="1"/>
2577+ <field name="allowed_option_ids" invisible="1"/>
2578+ </field>
2579+ <field name="tmpl_option_id" position="attributes">
2580+ <attribute name="domain">['|', ('partner_id', '!=', %(delivery_carrier_label_laposte.postlogistics)d), ('id', 'in', allowed_option_ids[0][2])]</attribute>
2581+ </field>
2582+ </field>
2583+ </record>
2584+
2585+ <!-- INHERITED VIEW FOR THE OBJECT : delivery.carrier -->
2586+ <record id="view_delivery_carrier_form" model="ir.ui.view">
2587+ <field name="name">delivery_base.delivery.carrier.view_form</field>
2588+ <field name="model">delivery.carrier</field>
2589+ <field name="inherit_id" ref="base_delivery_carrier_label.view_delivery_carrier_form" />
2590+ <field name="arch" type="xml">
2591+ <field name="type" position="after">
2592+ <field name="postlogistics_service_group_id" attrs="{'invisible': [('type', '!=', 'postlogistics')], 'required': [('type', '!=', 'postlogistics')]}"/>
2593+ <field name="allowed_option_ids" invisible="1"/>
2594+ </field>
2595+ <field name="available_option_ids" position="attributes">
2596+ <attribute name="context">{'default_carrier_id': active_id, 'default_allowed_option_ids': allowed_option_ids}</attribute>
2597+ </field>
2598+ </field>
2599+ </record>
2600+
2601+ </data>
2602+</openerp>
2603
2604=== added directory 'delivery_carrier_label_postlogistics/i18n'
2605=== added directory 'delivery_carrier_label_postlogistics/postlogistics'
2606=== added file 'delivery_carrier_label_postlogistics/postlogistics/__init__.py'
2607--- delivery_carrier_label_postlogistics/postlogistics/__init__.py 1970-01-01 00:00:00 +0000
2608+++ delivery_carrier_label_postlogistics/postlogistics/__init__.py 2013-11-27 09:30:06 +0000
2609@@ -0,0 +1,21 @@
2610+# -*- coding: utf-8 -*-
2611+##############################################################################
2612+#
2613+# Author: Yannick Vaucher
2614+# Copyright 2013 Camptocamp SA
2615+#
2616+# This program is free software: you can redistribute it and/or modify
2617+# it under the terms of the GNU Affero General Public License as
2618+# published by the Free Software Foundation, either version 3 of the
2619+# License, or (at your option) any later version.
2620+#
2621+# This program is distributed in the hope that it will be useful,
2622+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2623+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2624+# GNU Affero General Public License for more details.
2625+#
2626+# You should have received a copy of the GNU Affero General Public License
2627+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2628+#
2629+##############################################################################
2630+from . import web_service
2631
2632=== added file 'delivery_carrier_label_postlogistics/postlogistics/web_service.py'
2633--- delivery_carrier_label_postlogistics/postlogistics/web_service.py 1970-01-01 00:00:00 +0000
2634+++ delivery_carrier_label_postlogistics/postlogistics/web_service.py 2013-11-27 09:30:06 +0000
2635@@ -0,0 +1,358 @@
2636+# -*- coding: utf-8 -*-
2637+##############################################################################
2638+#
2639+# Author: Yannick Vaucher
2640+# Copyright 2013 Camptocamp SA
2641+#
2642+# This program is free software: you can redistribute it and/or modify
2643+# it under the terms of the GNU Affero General Public License as
2644+# published by the Free Software Foundation, either version 3 of the
2645+# License, or (at your option) any later version.
2646+#
2647+# This program is distributed in the hope that it will be useful,
2648+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2649+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2650+# GNU Affero General Public License for more details.
2651+#
2652+# You should have received a copy of the GNU Affero General Public License
2653+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2654+#
2655+##############################################################################
2656+import re
2657+from suds.client import Client, WebFault
2658+from suds.transport.http import HttpAuthenticated
2659+from PIL import Image
2660+from StringIO import StringIO
2661+
2662+from openerp.osv import orm
2663+from openerp.tools.translate import _
2664+
2665+_compile_itemid = re.compile('[^0-9A-Za-z+\-_]')
2666+
2667+
2668+class PostlogisticsWebService(object):
2669+ """ Connector with PostLogistics for labels using post.ch Web Services
2670+
2671+ Handbook available here: http://www.poste.ch/post-barcode-cug.htm
2672+
2673+ Allows to generate labels
2674+
2675+ """
2676+
2677+ def __init__(self, company):
2678+ self.init_connection(company)
2679+
2680+ def init_connection(self, company):
2681+ t = HttpAuthenticated(
2682+ username=company.postlogistics_username,
2683+ password=company.postlogistics_password)
2684+ self.client = Client(
2685+ company.postlogistics_wsdl_url,
2686+ transport=t)
2687+
2688+ def _send_request(self, request, **kwargs):
2689+ """ Wrapper for API requests
2690+
2691+ :param request: callback for API request
2692+ :param **kwargs: params forwarded to the callback
2693+
2694+ """
2695+ res = {}
2696+ try:
2697+ res['value'] = request(**kwargs)
2698+ res['success'] = True
2699+ except WebFault, e:
2700+ res['success'] = False
2701+ res['errors'] = [e[0]]
2702+ except Exception, e:
2703+ # if authentification error
2704+ if isinstance(e[0], tuple) and e[0][0] == 401:
2705+ raise orm.except_orm(
2706+ _('Error 401'),
2707+ _('Authorization Required\n\n'
2708+ 'Please verify postlogistics username and password in:\n'
2709+ 'Configuration -> Postlogistics'))
2710+ raise e
2711+ return res
2712+
2713+ def _get_language(self, lang):
2714+ """ Return a language to iso format from openerp format.
2715+
2716+ `iso_code` field in res.lang is not mandatory thus not always set.
2717+ Use partner language if available, otherwise use english
2718+
2719+ :param partner: partner browse record
2720+ :return: language code to use.
2721+
2722+ """
2723+ available_languages = self.client.factory.create('ns0:Language')
2724+ lang_code = lang.split('_')[0]
2725+ if lang_code in available_languages:
2726+ return lang_code
2727+ return 'en'
2728+
2729+ def read_allowed_services_by_franking_license(self, license, company, lang=None):
2730+ """ Get a list of allowed service for a postlogistics licence """
2731+ if not lang:
2732+ lang = company.partner_id.lang
2733+ lang = self._get_language(lang)
2734+ request = self.client.service.ReadAllowedServicesByFrankingLicense
2735+ return self._send_request(request, License=license, Language=lang)
2736+
2737+ def read_service_groups(self, company, lang):
2738+ """ Get group of services """
2739+ if not lang:
2740+ lang = company.partner_id.lang
2741+ lang = self._get_language(lang)
2742+ request = self.client.service.ReadServiceGroups
2743+ return self._send_request(request, Language=lang)
2744+
2745+ def read_basic_services(self, company, service_group_id, lang):
2746+ """ Get basic services for a given service group """
2747+ if not lang:
2748+ lang = company.partner_id.lang
2749+ lang = self._get_language(lang)
2750+ request = self.client.service.ReadBasicServices
2751+ return self._send_request(request, Language=lang, ServiceGroupID=service_group_id)
2752+
2753+ def read_additional_services(self, company, service_code, lang):
2754+ """ Get additional services compatible with a basic services """
2755+ if not lang:
2756+ lang = company.partner_id.lang
2757+ lang = self._get_language(lang)
2758+ request = self.client.service.ReadAdditionalServices
2759+ return self._send_request(request, Language=lang, PRZL=service_code)
2760+
2761+ def read_delivery_instructions(self, company, service_code, lang):
2762+ """ Get delivery instruction 'ZAW' compatible with a base service """
2763+ if not lang:
2764+ lang = company.partner_id.lang
2765+ lang = self._get_language(lang)
2766+ request = self.client.service.ReadDeliveryInstructions
2767+ return self._send_request(request, Language=lang, PRZL=service_code)
2768+
2769+ def _prepare_recipient(self, picking):
2770+ """ Create a ns0:Recipient as a dict from a partner
2771+
2772+ :param partner: partner browse record
2773+ :return a dict containing data for ns0:Recipient
2774+
2775+ """
2776+ partner = picking.partner_id
2777+
2778+ recipient = {
2779+ 'Name1': partner.name,
2780+ 'Street': partner.street,
2781+ 'ZIP': partner.zip,
2782+ 'City': partner.city,
2783+ 'Country': partner.country_id.code,
2784+ 'EMail': partner.email or None,
2785+ }
2786+
2787+ if partner.parent_id:
2788+ recipient['Name2'] = partner.parent_id.name
2789+ recipient['PersonallyAddressed'] = False
2790+
2791+ # Phone and / or mobile should only be diplayed if instruction to
2792+ # Notify delivery by telephone is set
2793+ is_phone_required = [option for option in picking.option_ids
2794+ if option.code == 'ZAW3213']
2795+ if is_phone_required:
2796+ if partner.phone:
2797+ recipient['Phone'] = partner.phone
2798+
2799+ if partner.mobile:
2800+ recipient['Mobile'] = partner.mobile
2801+
2802+ # XXX
2803+ #if partner.POBox
2804+ #customer['POBox'] = partner.email
2805+
2806+ return recipient
2807+
2808+ def _prepare_customer(self, picking):
2809+ """ Create a ns0:Customer as a dict from picking
2810+
2811+ This is the Postlogistic Customer, thus the sender
2812+
2813+ :param picking: picking browse record
2814+ :return a dict containing data for ns0:Customer
2815+
2816+ """
2817+ company = picking.company_id
2818+ partner = company.partner_id
2819+
2820+ customer = {
2821+ 'Name1': partner.name,
2822+ 'Street': partner.street,
2823+ 'ZIP': partner.zip,
2824+ 'City': partner.city,
2825+ 'Country': partner.country_id.code,
2826+ 'DomicilePostOffice': company.postlogistics_office,
2827+ }
2828+ logo_format = None
2829+ logo = company.postlogistics_logo
2830+ if logo:
2831+ logo_image = Image.open(StringIO(logo.decode('base64')))
2832+ logo_format = logo_image.format
2833+ customer['Logo'] = logo
2834+ customer['LogoFormat'] = logo_format
2835+ return customer
2836+
2837+ def _get_single_option(self, picking, option):
2838+ option = [opt.code for opt in picking.option_ids
2839+ if opt.postlogistics_type == option]
2840+ assert len(option) <= 1
2841+ return option and option[0]
2842+
2843+ def _get_label_layout(self, picking):
2844+ return self._get_single_option(picking, 'label_layout')
2845+
2846+ def _get_output_format(self, picking):
2847+ return self._get_single_option(picking, 'output_format')
2848+
2849+ def _get_image_resolution(self, picking):
2850+ return self._get_single_option(picking, 'resolution')
2851+
2852+ def _get_license(self, picking):
2853+ """ Get the right license depending on weight """
2854+ company = picking.company_id
2855+ #XXX get weight or set it as an option on picking
2856+ weight = 0
2857+ if weight > 1.0:
2858+ return company.postlogistics_license_more_1kg
2859+ return company.postlogistics_license_less_1kg
2860+
2861+ def _prepare_attributes(self, picking):
2862+ services = [option.code.split(',') for option in picking.option_ids
2863+ if option.tmpl_option_id.postlogistics_type
2864+ in ('basic', 'additional', 'delivery')]
2865+
2866+ attributes = {
2867+ 'PRZL': services,
2868+ }
2869+ return attributes
2870+
2871+ def _get_itemid(self, picking, pack_no):
2872+ """ Allowed characters are alphanumeric plus `+`, `-` and `_`
2873+ Last `+` separates picking name and package number
2874+
2875+ :return string: itemid
2876+
2877+ """
2878+ name = _compile_itemid.sub('', picking.name)
2879+ return name + '+' + str(pack_no)
2880+
2881+ def _prepare_item_list(self, picking, recipient, attributes):
2882+ """ Return a list of item made from the pickings """
2883+ item_list = []
2884+ for pack_no in range(picking.number_of_packages or 1):
2885+ item_id = self._get_itemid(picking, pack_no)
2886+ item = {
2887+ 'ItemID': item_id,
2888+ 'Recipient': recipient,
2889+ 'Attributes': attributes,
2890+ }
2891+
2892+ item_list.append(item)
2893+
2894+ return item_list
2895+
2896+ def _prepare_data(self, item_list):
2897+ sending = {
2898+ 'Item': item_list,
2899+ }
2900+ provider = {
2901+ 'Sending': sending
2902+ }
2903+ data = {
2904+ 'Provider': provider,
2905+ }
2906+ return data
2907+
2908+ def _prepare_envelope(self, picking, post_customer, data):
2909+ """ Define envelope for label request """
2910+ label_layout = self._get_label_layout(picking)
2911+ output_format = self._get_output_format(picking)
2912+ image_resolution = self._get_image_resolution(picking)
2913+
2914+ label_definitions = {
2915+ 'LabelLayout': label_layout,
2916+ 'PrintAddresses': 'RecipientAndCustomer',
2917+ 'ImageFileType': output_format,
2918+ 'ImageResolution': image_resolution, #XXX
2919+ 'PrintPreview': False,
2920+ }
2921+ license = self._get_license(picking)
2922+ file_infos = {
2923+ 'FrankingLicense': license,
2924+ 'PpFranking': False,
2925+ 'CustomerSystem': 'OpenERP',
2926+ 'Customer': post_customer,
2927+ }
2928+
2929+ envelope = {
2930+ 'LabelDefinition': label_definitions,
2931+ 'FileInfos': file_infos,
2932+ 'Data': data,
2933+ }
2934+ return envelope
2935+
2936+ def generate_label(self, picking, user_lang='en_US'):
2937+ """ Generate a label for a picking
2938+
2939+ :param picking: picking browse record
2940+ :param lang: OpenERP language code
2941+ :return: {
2942+ value: [{item_id: pack id
2943+ binary: file returned by API
2944+ tracking_number: id number for tracking
2945+ }
2946+ ]
2947+ errors: list of error message if any
2948+ warnings: list of warning message if any
2949+ }
2950+
2951+ """
2952+ # get options
2953+ lang = self._get_language(user_lang)
2954+ post_customer = self._prepare_customer(picking)
2955+
2956+ attributes = self._prepare_attributes(picking)
2957+
2958+ recipient = self._prepare_recipient(picking)
2959+ item_list = self._prepare_item_list(picking, recipient, attributes)
2960+ data = self._prepare_data(item_list)
2961+
2962+ envelope = self._prepare_envelope(picking, post_customer, data)
2963+
2964+ res = {'value': []}
2965+ request = self.client.service.GenerateLabel
2966+ response = self._send_request(request, Language=lang, Envelope=envelope)
2967+
2968+ if not response['success']:
2969+ return response
2970+ error_messages = []
2971+ warning_messages = []
2972+ for item in response['value'].Data.Provider.Sending.Item:
2973+ if hasattr(item, 'Errors') and item.Errors:
2974+ for error in item.Errors.Error:
2975+ message = '[%s] %s' % (error.Code, error.Message)
2976+ error_messages.append(message)
2977+ else:
2978+ res['value'].append({
2979+ 'item_id': item.ItemID,
2980+ 'binary': item.Label,
2981+ 'tracking_number': item.IdentCode,
2982+ })
2983+
2984+ if hasattr(item, 'Warnings') and item.Warnings:
2985+ for warning in item.Warnings:
2986+ message = '[%s] %s' % (warning.Code, warning.Message)
2987+ warning_messages.append(message)
2988+
2989+ if error_messages:
2990+ res['errors'] = error_messages
2991+ if warning_messages:
2992+ res['warnings'] = warning_messages
2993+ return res
2994
2995=== added file 'delivery_carrier_label_postlogistics/res_config.py'
2996--- delivery_carrier_label_postlogistics/res_config.py 1970-01-01 00:00:00 +0000
2997+++ delivery_carrier_label_postlogistics/res_config.py 2013-11-27 09:30:06 +0000
2998@@ -0,0 +1,403 @@
2999+# -*- coding: utf-8 -*-
3000+##############################################################################
3001+#
3002+# Author: Yannick Vaucher
3003+# Copyright 2013 Camptocamp SA
3004+#
3005+# This program is free software: you can redistribute it and/or modify
3006+# it under the terms of the GNU Affero General Public License as
3007+# published by the Free Software Foundation, either version 3 of the
3008+# License, or (at your option) any later version.
3009+#
3010+# This program is distributed in the hope that it will be useful,
3011+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3012+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3013+# GNU Affero General Public License for more details.
3014+#
3015+# You should have received a copy of the GNU Affero General Public License
3016+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3017+#
3018+##############################################################################
3019+from openerp.osv import orm, fields
3020+from openerp.tools.translate import _
3021+
3022+from postlogistics.web_service import PostlogisticsWebService
3023+
3024+
3025+class PostlogisticsConfigSettings(orm.TransientModel):
3026+ _name = 'postlogistics.config.settings'
3027+ _inherit = 'res.config.settings'
3028+
3029+ _columns = {
3030+ 'company_id': fields.many2one('res.company', 'Company', required=True),
3031+ 'wsdl_url': fields.related(
3032+ 'company_id', 'postlogistics_wsdl_url',
3033+ string='WSDL URL', type='char'),
3034+ 'username': fields.related(
3035+ 'company_id', 'postlogistics_username',
3036+ string='Username', type='char'),
3037+ 'password': fields.related(
3038+ 'company_id', 'postlogistics_password',
3039+ string='Password', type='char'),
3040+ 'license_less_1kg': fields.related(
3041+ 'company_id', 'postlogistics_license_less_1kg',
3042+ string='License less than 1kg', type='char'),
3043+ 'license_more_1kg': fields.related(
3044+ 'company_id', 'postlogistics_license_more_1kg',
3045+ string='License more than 1kg', type='char'),
3046+ 'license_vinolog': fields.related(
3047+ 'company_id', 'postlogistics_license_vinolog',
3048+ string='License VinoLog', type='char'),
3049+ 'logo': fields.related(
3050+ 'company_id', 'postlogistics_logo',
3051+ string='Company Logo on Post labels', type='binary',
3052+ help="Optional company logo to show on label.\n"
3053+ "If using an image / logo, please note the following:\n"
3054+ "– Image width: 47 mm\n"
3055+ "– Image height: 25 mm\n"
3056+ "– File size: max. 30 kb\n"
3057+ "– File format: GIF or PNG\n"
3058+ "– Colour table: indexed colours, max. 200 colours\n"
3059+ "– The logo will be printed rotated counter-clockwise by 90°\n"
3060+ "We recommend using a black and white logo for printing in the\n"
3061+ "ZPL2 format."
3062+ ),
3063+ 'office': fields.related(
3064+ 'company_id', 'postlogistics_office',
3065+ string='Domicile Post office', type='char',
3066+ help="Post office which will receive the shipped goods"),
3067+ #'default_postlogistics_logo_layout': fields.related(
3068+ #'company_id', 'default_postlogistics_logo_layout',
3069+ #string='Domicile Post office', type='char',
3070+ #help="Post office which will receive the shipped goods"),
3071+ #'default_postlogistics_output_format': fields.related(
3072+ #'company_id', 'default_postlogistics_logo_layout',
3073+ #string='Domicile Post office', type='char',
3074+ #help="Post office which will receive the shipped goods"),
3075+ #'default_postlogistics_output_format': fields.related(
3076+ #'company_id', 'default_postlogistics_logo_layout',
3077+ #string='Domicile Post office', type='char',
3078+ #help="Post office which will receive the shipped goods"),
3079+ }
3080+
3081+ def _default_company(self, cr, uid, context=None):
3082+ user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
3083+ return user.company_id.id
3084+
3085+ _defaults = {
3086+ 'company_id': _default_company,
3087+ }
3088+
3089+ def create(self, cr, uid, values, context=None):
3090+ id = super(PostlogisticsConfigSettings, self).create(cr, uid, values, context)
3091+ # Hack: to avoid some nasty bug, related fields are not written
3092+ # upon record creation. Hence we write on those fields here.
3093+ vals = {}
3094+ for fname, field in self._columns.iteritems():
3095+ if isinstance(field, fields.related) and fname in values:
3096+ vals[fname] = values[fname]
3097+ self.write(cr, uid, [id], vals, context)
3098+ return id
3099+
3100+ def onchange_company_id(self, cr, uid, ids, company_id, context=None):
3101+ # update related fields
3102+ values = {}
3103+ values['currency_id'] = False
3104+ if not company_id:
3105+ return {'value': values}
3106+ company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
3107+ values = {
3108+ 'username': company.postlogistics_username,
3109+ 'password': company.postlogistics_password,
3110+ 'license_less_1kg': company.postlogistics_license_less_1kg,
3111+ 'license_more_1kg': company.postlogistics_license_more_1kg,
3112+ 'license_vinolog': company.postlogistics_license_vinolog,
3113+ 'logo': company.postlogistics_logo,
3114+ 'office': company.postlogistics_office,
3115+ }
3116+ return {'value': values}
3117+
3118+ def _get_delivery_instructions(self, cr, uid, ids, web_service,
3119+ company, service_code, context=None):
3120+ if context is None:
3121+ context = {}
3122+
3123+ lang = context.get('lang', 'en')
3124+ service_code_list = service_code.split(',')
3125+ res = web_service.read_delivery_instructions(company, service_code_list, lang)
3126+ if 'errors' in res:
3127+ errors = '\n'.join(res['errors'])
3128+ error_message = (_('Could not retrieve Postlogistics delivery'
3129+ 'instructions:\n%s') % errors)
3130+ raise orm.except_orm(_('Error'), error_message)
3131+
3132+ if not res['value']:
3133+ return {}
3134+
3135+ if hasattr(res['value'], 'Errors') and res['value'].Errors:
3136+ for error in res['value'].Errors.Error:
3137+ message = '[%s] %s' % (error.Code, error.Message)
3138+ raise orm.except_orm('Error', message)
3139+
3140+ delivery_instructions = {}
3141+ for service in res['value'].DeliveryInstructions:
3142+ service_code = service.PRZL
3143+ delivery_instructions[service_code] = {'name': service.Description}
3144+
3145+ return delivery_instructions
3146+
3147+ def _update_delivery_instructions(self, cr, uid, ids, web_service,
3148+ additional_services, context=None):
3149+ if context is None:
3150+ context = {}
3151+ ir_model_data_obj = self.pool.get('ir.model.data')
3152+ carrier_option_obj = self.pool.get('delivery.carrier.template.option')
3153+
3154+ xmlid = 'delivery_carrier_label_laposte', 'postlogistics'
3155+ postlogistics_partner = ir_model_data_obj.get_object(
3156+ cr, uid, *xmlid, context=context)
3157+
3158+ for service_code, data in additional_services.iteritems():
3159+
3160+ option_ids = carrier_option_obj.search(
3161+ cr, uid,
3162+ [('code', '=', service_code),
3163+ ('postlogistics_type', '=', 'delivery')
3164+ ],
3165+ context=context)
3166+
3167+ if option_ids:
3168+ carrier_option_obj.write(cr, uid, option_ids, data, context=context)
3169+ else:
3170+ data.update(code=service_code,
3171+ postlogistics_type='delivery',
3172+ partner_id=postlogistics_partner.id)
3173+ carrier_option_obj.create(cr, uid, data, context=context)
3174+
3175+ def _get_additional_services(self, cr, uid, ids, web_service,
3176+ company, service_code, context=None):
3177+ if context is None:
3178+ context = {}
3179+
3180+ lang = context.get('lang', 'en')
3181+ service_code_list = service_code.split(',')
3182+ res = web_service.read_additional_services(company, service_code_list, lang)
3183+ if 'errors' in res:
3184+ errors = '\n'.join(res['errors'])
3185+ error_message = (_('Could not retrieve Postlogistics base '
3186+ 'services:\n%s') % errors)
3187+ raise orm.except_orm(_('Error'), error_message)
3188+
3189+ if not res['value']:
3190+ return {}
3191+
3192+ if hasattr(res['value'], 'Errors') and res['value'].Errors:
3193+ for error in res['value'].Errors.Error:
3194+ message = '[%s] %s' % (error.Code, error.Message)
3195+ raise orm.except_orm('Error', message)
3196+
3197+ additional_services = {}
3198+ for service in res['value'].AdditionalService:
3199+ service_code = service.PRZL
3200+ additional_services[service_code] = {'name': service.Description}
3201+
3202+ return additional_services
3203+
3204+ def _update_additional_services(self, cr, uid, ids, web_service,
3205+ additional_services, context=None):
3206+ if context is None:
3207+ context = {}
3208+ ir_model_data_obj = self.pool.get('ir.model.data')
3209+ carrier_option_obj = self.pool.get('delivery.carrier.template.option')
3210+
3211+ postlogistics_partner = ir_model_data_obj.get_object(
3212+ cr, uid, 'delivery_carrier_label_laposte', 'postlogistics', context=context)
3213+
3214+ for service_code, data in additional_services.iteritems():
3215+
3216+ option_ids = carrier_option_obj.search(cr, uid, [
3217+ ('code', '=', service_code),
3218+ ('postlogistics_type', '=', 'additional')
3219+ ], context=context)
3220+
3221+ if option_ids:
3222+ carrier_option_obj.write(cr, uid, option_ids, data, context=context)
3223+ else:
3224+ data.update(code=service_code,
3225+ postlogistics_type='additional',
3226+ partner_id=postlogistics_partner.id)
3227+ carrier_option_obj.create(cr, uid, data, context=context)
3228+
3229+ def _update_basic_services(self, cr, uid, ids, web_service, company, group_id, context=None):
3230+ """ Update of basic services
3231+
3232+ A basic service can be part only of one service group
3233+
3234+ :return: {additional_services: {<service_code>: service_data}
3235+ delivery_instructions: {<service_code>: service_data}
3236+ }
3237+
3238+ """
3239+ if context is None:
3240+ context = {}
3241+ ir_model_data_obj = self.pool.get('ir.model.data')
3242+ service_group_obj = self.pool.get('postlogistics.service.group')
3243+ carrier_option_obj = self.pool.get('delivery.carrier.template.option')
3244+
3245+ xmlid = 'delivery_carrier_label_laposte', 'postlogistics'
3246+ postlogistics_partner = ir_model_data_obj.get_object(
3247+ cr, uid, *xmlid, context=context)
3248+ lang = context.get('lang', 'en')
3249+
3250+ group = service_group_obj.browse(cr, uid, group_id, context=context)
3251+
3252+ res = web_service.read_basic_services(company, group.group_extid, lang)
3253+ if 'errors' in res:
3254+ errors = '\n'.join(res['errors'])
3255+ error_message = (_('Could not retrieve Postlogistics base '
3256+ 'services:\n%s') % errors)
3257+ raise orm.except_orm(_('Error'), error_message)
3258+
3259+ additional_services = {}
3260+ delivery_instructions = {}
3261+ # Create or update basic service
3262+ for service in res['value'].BasicService:
3263+ service_code = ','.join(service.PRZL)
3264+ option_ids = carrier_option_obj.search(cr, uid, [
3265+ ('code', '=', service_code),
3266+ ('postlogistics_service_group_id', '=', group_id),
3267+ ('postlogistics_type', '=', 'basic')
3268+ ], context=context)
3269+ data = {'name': service.Description}
3270+ if option_ids:
3271+ carrier_option_obj.write(cr, uid, option_ids, data, context=context)
3272+ option_id = option_ids[0]
3273+ else:
3274+ data.update(code=service_code,
3275+ postlogistics_service_group_id=group_id,
3276+ partner_id=postlogistics_partner.id,
3277+ postlogistics_type='basic')
3278+ option_id = carrier_option_obj.create(cr, uid, data, context=context)
3279+
3280+ # Get related services
3281+ allowed_services = self._get_additional_services(
3282+ cr, uid, ids, web_service, company, service_code, context=context)
3283+ for key, value in additional_services.iteritems():
3284+ if key in allowed_services:
3285+ additional_services[key]['postlogistics_basic_service_ids'][0][2].append(option_id)
3286+ del allowed_services[key]
3287+ for key, value in allowed_services.iteritems():
3288+ additional_services[key] = value
3289+ additional_services[key]['postlogistics_basic_service_ids'] = [(6, 0, [option_id])]
3290+
3291+ allowed_services = self._get_delivery_instructions(
3292+ cr, uid, ids, web_service, company, service_code, context=context)
3293+ for key, value in delivery_instructions.iteritems():
3294+ if key in allowed_services:
3295+ delivery_instructions[key]['postlogistics_basic_service_ids'][0][2].append(option_id)
3296+ del allowed_services[key]
3297+ for key, value in allowed_services.iteritems():
3298+ delivery_instructions[key] = value
3299+ delivery_instructions[key]['postlogistics_basic_service_ids'] = [(6, 0, [option_id])]
3300+
3301+ return {'additional_services': additional_services,
3302+ 'delivery_instructions': delivery_instructions}
3303+
3304+ def _update_service_groups(self, cr, uid, ids, web_service, company, context=None):
3305+ """ Also updates additional services and delivery instructions
3306+ as they are shared between groups
3307+
3308+ """
3309+ if context is None:
3310+ context = {}
3311+ service_group_obj = self.pool.get('postlogistics.service.group')
3312+
3313+ lang = context.get('lang', 'en')
3314+
3315+ res = web_service.read_service_groups(company, lang)
3316+ if 'errors' in res:
3317+ errors = '\n'.join(res['errors'])
3318+ error_message = (_('Could not retrieve Postlogistics group '
3319+ 'services:\n%s') % errors)
3320+ raise orm.except_orm(_('Error'), error_message)
3321+
3322+ additional_services = {}
3323+ delivery_instructions = {}
3324+
3325+ # Create or update groups
3326+ for group in res['value'].ServiceGroup:
3327+ group_extid = group.ServiceGroupID
3328+ group_ids = service_group_obj.search(
3329+ cr, uid, [('group_extid', '=', group_extid)], context=context)
3330+ data = {'name': group.Description}
3331+ if group_ids:
3332+ service_group_obj.write(cr, uid, group_ids, data, context=context)
3333+ group_id = group_ids[0]
3334+ else:
3335+ data['group_extid'] = group_extid
3336+ group_id = service_group_obj.create(cr, uid, data, context=context)
3337+
3338+ # Get related services for all basic services of this group
3339+ res = self._update_basic_services(cr, uid, ids, web_service,
3340+ company, group_id, context=context)
3341+
3342+ allowed_services = res.get('additional_services', {})
3343+ for key, value in additional_services.iteritems():
3344+ if key in allowed_services:
3345+ option_ids = allowed_services[key]['postlogistics_basic_service_ids'][0][2]
3346+ additional_services[key]['postlogistics_basic_service_ids'][0][2].extend(option_ids)
3347+ del allowed_services[key]
3348+ additional_services.update(allowed_services)
3349+
3350+ allowed_services = res.get('delivery_instructions', {})
3351+ for key, value in delivery_instructions.iteritems():
3352+ if key in allowed_services:
3353+ option_ids = allowed_services[key]['postlogistics_basic_service_ids'][0][2]
3354+ delivery_instructions[key]['postlogistics_basic_service_ids'][0][2].extend(option_ids)
3355+ del allowed_services[key]
3356+ delivery_instructions.update(allowed_services)
3357+
3358+ # Update related services
3359+ self._update_additional_services(cr, uid, ids, web_service,
3360+ additional_services, context=context)
3361+ self._update_delivery_instructions(cr, uid, ids, web_service,
3362+ delivery_instructions, context=context)
3363+
3364+ def update_postlogistics_options(self, cr, uid, ids, context=None):
3365+ """ This action will update all postlogistics option by
3366+ importing services from PostLogistics WebService API
3367+
3368+ The object we create are 'delivey.carrier.template.option'
3369+
3370+ """
3371+ if context is None:
3372+ context = {}
3373+ user_obj = self.pool.get('res.users')
3374+
3375+ company = user_obj.browse(cr, uid, uid, context=context).company_id
3376+
3377+ web_service = PostlogisticsWebService(company)
3378+
3379+ # make sure we create source text in en_US
3380+ ctx = context.copy()
3381+ ctx['lang'] = 'en_US'
3382+ self._update_service_groups(cr, uid, ids, web_service, company, context=ctx)
3383+
3384+ language_obj = self.pool.get('res.lang')
3385+ language_ids = language_obj.search(cr, uid, [], context=context)
3386+
3387+ languages = language_obj.browse(cr, uid, language_ids, context=context)
3388+
3389+ # handle translations
3390+ # we call the same methode with a different language context
3391+ for lang_br in languages:
3392+ lang = lang_br.code
3393+ ctx = context.copy()
3394+ ctx['lang'] = lang_br.code
3395+ postlogistics_lang = web_service._get_language(lang)
3396+ # add translations only for languages that exists on postlogistics
3397+ # english source will be kept for other languages
3398+ if postlogistics_lang == 'en':
3399+ continue
3400+ self._update_service_groups(cr, uid, ids, web_service, company, context=ctx)
3401+ return True
3402
3403=== added file 'delivery_carrier_label_postlogistics/res_config_view.xml'
3404--- delivery_carrier_label_postlogistics/res_config_view.xml 1970-01-01 00:00:00 +0000
3405+++ delivery_carrier_label_postlogistics/res_config_view.xml 2013-11-27 09:30:06 +0000
3406@@ -0,0 +1,93 @@
3407+<?xml version="1.0" encoding="utf-8"?>
3408+<openerp>
3409+ <data>
3410+
3411+ <record id="view_postlogistics_config_settings" model="ir.ui.view">
3412+ <field name="name">postlogistics settings</field>
3413+ <field name="model">postlogistics.config.settings</field>
3414+ <field name="arch" type="xml">
3415+ <form string="Configure Postlogistics" version="7.0" class="oe_form_configuration">
3416+ <header>
3417+ <button string="Apply" type="object" name="execute" class="oe_highlight"/>
3418+ or
3419+ <button string="Cancel" type="object" name="cancel" class="oe_link"/>
3420+ </header>
3421+
3422+ <group groups="base.group_multi_company">
3423+ <div>
3424+ <div>
3425+ <label for="company_id" string="Select Company"/>
3426+ <field name="company_id"
3427+ widget="selection"
3428+ on_change="onchange_company_id(company_id, context)"
3429+ class="oe_inline"/>
3430+ </div>
3431+ </div>
3432+ </group>
3433+ <separator string="Web Service Authentification"/>
3434+ <group>
3435+ <div>
3436+ <div>
3437+ <label for="username"/>
3438+ <field name="username" class="oe_inline"/>
3439+ </div>
3440+ <div>
3441+ <label for="password"/>
3442+ <field name="password" class="oe_inline"/>
3443+ </div>
3444+ </div>
3445+ </group>
3446+ <separator string="Licenses"/>
3447+ <group>
3448+ <div>
3449+ <div>
3450+ <label for="license_less_1kg"/>
3451+ <field name="license_less_1kg" class="oe_inline"/>
3452+ </div>
3453+ <div>
3454+ <label for="license_more_1kg"/>
3455+ <field name="license_more_1kg" class="oe_inline"/>
3456+ </div>
3457+ <div>
3458+ <label for="license_vinolog"/>
3459+ <field name="license_vinolog" class="oe_inline"/>
3460+ </div>
3461+ </div>
3462+ </group>
3463+ <separator string="Sender Informations"/>
3464+ <group>
3465+ <div>
3466+ <div>
3467+ <label for="logo"/>
3468+ <field name="logo" widget="image"/>
3469+ </div>
3470+ <div>
3471+ <label for="office"/>
3472+ <field name="office" class="oe_inline"/>
3473+ </div>
3474+ </div>
3475+ </group>
3476+ <group>
3477+ <div>
3478+ <div>
3479+ <button string="Update PostLogistics Services" type="object" name="update_postlogistics_options" class="oe_highlight"/>
3480+ </div>
3481+ </div>
3482+ </group>
3483+ </form>
3484+ </field>
3485+ </record>
3486+
3487+ <record id="action_postlogistics_config" model="ir.actions.act_window">
3488+ <field name="name">Configure Postlogistics</field>
3489+ <field name="type">ir.actions.act_window</field>
3490+ <field name="res_model">postlogistics.config.settings</field>
3491+ <field name="view_mode">form</field>
3492+ <field name="target">inline</field>
3493+ </record>
3494+
3495+ <menuitem id="menu_postlogistics_config" name="Postlogistics" parent="base.menu_config"
3496+ sequence="20" action="action_postlogistics_config"/>
3497+
3498+ </data>
3499+</openerp>
3500
3501=== added file 'delivery_carrier_label_postlogistics/res_partner_data.xml'
3502--- delivery_carrier_label_postlogistics/res_partner_data.xml 1970-01-01 00:00:00 +0000
3503+++ delivery_carrier_label_postlogistics/res_partner_data.xml 2013-11-27 09:30:06 +0000
3504@@ -0,0 +1,134 @@
3505+<?xml version="1.0" encoding="utf-8"?>
3506+<openerp>
3507+ <data noupdate="1">
3508+ <record id="postlogistics" model="res.partner">
3509+ <field name="image">/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsK
3510+CwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQU
3511+FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCABkAMMDASIA
3512+AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
3513+AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
3514+ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
3515+p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
3516+AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
3517+BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
3518+U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
3519+uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD69ooo
3520+r/No/YAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA
3521+5b4p+NW+Gvw38ReKRafbm0m0a6+yvLt83b/Du/hr5B0v/gp7CbmH+1fhzPb6ez7WuLTUN7f8B3Kq
3522+t/31X0r+1ASf2dfiN7aLPzXzR8Mb3wqn/BO3VY/EUun/AHNR+yxXDJ5v2rzW8ryv4t2/bX7Nwrle
3523+U18q+s47De2lKtGn7rkuVSXkfP42rWjX5KcuX3eY+zPA/jbSPiR4T0zxLoN39s0nUYvNgl27X/2k
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
3631+/9k=</field>
3632+ <field name="name">PostLogistics</field>
3633+ <field name="customer" eval="False"/>
3634+ <field name="supplier" eval="False"/>
3635+ <field name="email">webservice@post.ch</field>
3636+ </record>
3637+ </data>
3638+</openerp>
3639
3640=== added file 'delivery_carrier_label_postlogistics/stock.py'
3641--- delivery_carrier_label_postlogistics/stock.py 1970-01-01 00:00:00 +0000
3642+++ delivery_carrier_label_postlogistics/stock.py 2013-11-27 09:30:06 +0000
3643@@ -0,0 +1,54 @@
3644+# -*- coding: utf-8 -*-
3645+##############################################################################
3646+#
3647+# Author: Yannick Vaucher
3648+# Copyright 2013 Camptocamp SA
3649+#
3650+# This program is free software: you can redistribute it and/or modify
3651+# it under the terms of the GNU Affero General Public License as
3652+# published by the Free Software Foundation, either version 3 of the
3653+# License, or (at your option) any later version.
3654+#
3655+# This program is distributed in the hope that it will be useful,
3656+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3657+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3658+# GNU Affero General Public License for more details.
3659+#
3660+# You should have received a copy of the GNU Affero General Public License
3661+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3662+#
3663+##############################################################################
3664+from openerp.osv import orm
3665+
3666+from postlogistics.web_service import PostlogisticsWebService
3667+
3668+
3669+class stock_picking_out(orm.Model):
3670+ _inherit = 'stock.picking.out'
3671+
3672+ def _generate_poste_ch_label(self, cr, uid, picking, context=None):
3673+ user_obj = self.pool.get('res.users')
3674+ user = user_obj.browse(cr, uid, uid, context=context)
3675+ company = user.company_id
3676+ web_service = PostlogisticsWebService(company)
3677+ res = web_service.generate_label(picking, user.lang)
3678+
3679+ if 'errors' in res:
3680+ raise orm.except_orm('Error', '\n'.join(res['errors']))
3681+ # XXX What with multiple pack for one picking ?
3682+ tracking_number = res['value'][0]['tracking_number']
3683+ # write tracking number on picking XXX multi ?
3684+ self.write(cr, uid, picking.id,
3685+ {'carrier_tracking_ref': tracking_number},
3686+ context=context)
3687+ return res['value'][0]['binary'].decode('base64')
3688+
3689+ def generate_single_label(self, cr, uid, ids, context=None):
3690+ """ Add label generation for Postlogistics """
3691+ if isinstance(ids, (long, int)):
3692+ ids = [ids]
3693+ assert len(ids) == 1
3694+ picking = self.browse(cr, uid, ids[0], context=context)
3695+ if picking.carrier_id.type == 'postlogistics':
3696+ return self._generate_poste_ch_label(cr, uid, picking, context=context)
3697+ return super(stock_picking_out, self).generate_single_label(cr, uid, ids, context=None)

Subscribers

People subscribed via source and target branches