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

Proposed by Yannick Vaucher @ Camptocamp
Status: Merged
Approved by: Guewen Baconnier @ Camptocamp
Approved revision: 12
Merged at revision: 12
Proposed branch: lp:~camptocamp/carriers-deliveries/7.0-delivery_carrier_label_postlogistics-imp-licenses-yvr
Merge into: lp:~stock-logistic-core-editors/carriers-deliveries/7.0
Diff against target: 311 lines (+138/-33)
8 files modified
delivery_carrier_label_postlogistics/__openerp__.py (+8/-8)
delivery_carrier_label_postlogistics/company.py (+4/-4)
delivery_carrier_label_postlogistics/delivery.py (+25/-0)
delivery_carrier_label_postlogistics/delivery_view.xml (+1/-0)
delivery_carrier_label_postlogistics/postlogistics/web_service.py (+21/-8)
delivery_carrier_label_postlogistics/res_config.py (+69/-3)
delivery_carrier_label_postlogistics/res_config_view.xml (+8/-10)
delivery_carrier_label_postlogistics/security/ir.model.access.csv (+2/-0)
To merge this branch: bzr merge lp:~camptocamp/carriers-deliveries/7.0-delivery_carrier_label_postlogistics-imp-licenses-yvr
Reviewer Review Type Date Requested Status
Guewen Baconnier @ Camptocamp Approve
Leonardo Pistone code review Approve
Romain Deheele - Camptocamp (community) code review, no tests Approve
Review via email: mp+202334@code.launchpad.net

Description of the change

Implements license management for postlogistics label web service

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

[ADD] security groups for postlogistics licenses

Revision history for this message
Romain Deheele - Camptocamp (romaindeheele) wrote :

LGTM,

Romain

review: Approve (code review, no tests)
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :
Revision history for this message
Leonardo Pistone (lepistone) wrote :

Yannick,

is the field picking.carrier_id required?

review: Needs Information
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

carrier_id isn't required.

If you are asking for that line:
151 + license = picking.carrier_id.postlogistics_license_id

orm.browse_null

Implements __getattr__ that way.
    def __getattr__(self, name):
        return None # XXX: return self ?

So even if carrier_id returns orm.browse_null asking for one of its attributes is None

Revision history for this message
Leonardo Pistone (lepistone) wrote :

Yes Yannick, I was asking about that!

So if you reckon we handle the empty field properly, I approve.

Thanks!

review: Approve (code review)
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'delivery_carrier_label_postlogistics/__openerp__.py'
2--- delivery_carrier_label_postlogistics/__openerp__.py 2013-12-23 10:54:36 +0000
3+++ delivery_carrier_label_postlogistics/__openerp__.py 2014-01-23 10:39:04 +0000
4@@ -73,6 +73,13 @@
5 .. _PostLogistics BarCodes WebService: http://www.poste.ch/post-startseite/post-geschaeftskunden/post-logistik/post-e-log/post-e-log-webservices.htm
6 .. _Swiss Post E-logistics: http://www.poste.ch/en/post-startseite/post-geschaeftskunden/post-logistik/post-e-log.htm
7
8+
9+Recommended modules
10+-------------------
11+
12+* PostLogistics labels - logo per Shop
13+ If you have multiple shops configure one logo per shop
14+
15 Technical references
16 --------------------
17
18@@ -80,18 +87,11 @@
19
20 .. _"Barcode" web service documentation: http://www.poste.ch/post-barcode-cug.htm
21
22+
23 Contributors
24 ------------
25
26 * Yannick Vaucher <yannick.vaucher@camptocamp.com>
27-
28-----
29-
30-*TODO*:
31-
32-* *Add onchange to improve carrier method creation*
33-* *Identify attachement as label*
34-* *Better License management*
35 """,
36 'website': 'http://www.camptocamp.com/',
37 'data': ['res_partner_data.xml',
38
39=== modified file 'delivery_carrier_label_postlogistics/company.py'
40--- delivery_carrier_label_postlogistics/company.py 2013-12-03 17:18:48 +0000
41+++ delivery_carrier_label_postlogistics/company.py 2014-01-23 10:39:04 +0000
42@@ -38,10 +38,10 @@
43 type='char'),
44 'postlogistics_username': fields.char('Username'),
45 'postlogistics_password': fields.char('Password'),
46- # XXX improve license management
47- 'postlogistics_license_less_1kg': fields.char('License less than 1kg'),
48- 'postlogistics_license_more_1kg': fields.char('License more than 1kg'),
49- 'postlogistics_license_vinolog': fields.char('License VinoLog'),
50+ 'postlogistics_license_ids': fields.one2many(
51+ 'postlogistics.license',
52+ 'company_id',
53+ 'PostLogistics Frankling License'),
54 'postlogistics_logo': fields.binary('Company logo for PostLogistics'),
55 'postlogistics_office': fields.char('Post office'),
56
57
58=== modified file 'delivery_carrier_label_postlogistics/delivery.py'
59--- delivery_carrier_label_postlogistics/delivery.py 2014-01-13 11:23:21 +0000
60+++ delivery_carrier_label_postlogistics/delivery.py 2014-01-23 10:39:04 +0000
61@@ -20,6 +20,22 @@
62 ##############################################################################
63 from openerp.osv import orm, fields
64
65+class PostlogisticsLicense(orm.Model):
66+ _name = 'postlogistics.license'
67+ _description = 'PostLogistics Franking License'
68+
69+ _order = 'sequence'
70+
71+ _columns = {
72+ 'name': fields.char('Description', translate=True, required=True),
73+ 'number': fields.char('Number', required=True),
74+ 'company_id': fields.many2one('res.company', 'Company', required=True),
75+ 'sequence': fields.integer(
76+ 'Sequence',
77+ help="Gives the sequence on company to define priority on license"
78+ " when multiple license are available for the same group of "
79+ "service."),
80+ }
81
82 class PostlogisticsServiceGroup(orm.Model):
83 _name = 'postlogistics.service.group'
84@@ -28,6 +44,12 @@
85 _columns = {
86 'name': fields.char('Description', translate=True, required=True),
87 'group_extid': fields.integer('Group ID', required=True),
88+ 'postlogistics_license_ids': fields.many2many(
89+ 'postlogistics.license',
90+ 'postlogistics_license_service_groups_rel',
91+ 'license_id',
92+ 'group_id',
93+ 'PostLogistics Frankling License'),
94 }
95
96 _sql_constraints = [
97@@ -194,6 +216,9 @@
98 'type': fields.selection(
99 _get_carrier_type_selection, 'Type',
100 help="Carrier type (combines several delivery methods)"),
101+ 'postlogistics_license_id': fields.many2one(
102+ 'postlogistics.license',
103+ string='PostLogistics Frankling License'),
104 'postlogistics_service_group_id': fields.many2one(
105 'postlogistics.service.group',
106 string='PostLogistics Service Group',
107
108=== modified file 'delivery_carrier_label_postlogistics/delivery_view.xml'
109--- delivery_carrier_label_postlogistics/delivery_view.xml 2013-11-29 08:19:33 +0000
110+++ delivery_carrier_label_postlogistics/delivery_view.xml 2014-01-23 10:39:04 +0000
111@@ -49,6 +49,7 @@
112 <field name="arch" type="xml">
113 <field name="type" position="after">
114 <field name="postlogistics_service_group_id" attrs="{'invisible': [('type', '!=', 'postlogistics')], 'required': [('type', '=', 'postlogistics')]}"/>
115+ <field name="postlogistics_license_id" attrs="{'invisible': [('type', '!=', 'postlogistics')]}"/>
116 <field name="allowed_option_ids" invisible="1"/>
117 </field>
118 <field name="available_option_ids" position="attributes">
119
120=== modified file 'delivery_carrier_label_postlogistics/postlogistics/web_service.py'
121--- delivery_carrier_label_postlogistics/postlogistics/web_service.py 2013-12-17 07:45:50 +0000
122+++ delivery_carrier_label_postlogistics/postlogistics/web_service.py 2014-01-23 10:39:04 +0000
123@@ -97,7 +97,7 @@
124 lang = company.partner_id.lang
125 lang = self._get_language(lang)
126 request = self.client.service.ReadAllowedServicesByFrankingLicense
127- return self._send_request(request, License=license, Language=lang)
128+ return self._send_request(request, FrankingLicense=license, Language=lang)
129
130 def read_service_groups(self, company, lang):
131 """ Get group of services """
132@@ -223,13 +223,26 @@
133 return resolution
134
135 def _get_license(self, picking):
136- """ Get the right license depending on weight """
137- company = picking.company_id
138- #XXX get weight or set it as an option on picking
139- weight = 0
140- if weight > 1.0:
141- return company.postlogistics_license_more_1kg
142- return company.postlogistics_license_less_1kg
143+ """ Get the license
144+
145+ Take it from carrier and if not defined get the first license
146+ depending on service group. This needs to have associated
147+ licenses to groups.
148+
149+ :return: license number
150+ """
151+ license = picking.carrier_id.postlogistics_license_id
152+ if not license:
153+ company_licenses = picking.company_id.postlogistics_license_ids
154+ group = picking.carrier_id.postlogistics_service_group_id
155+ if not company_licenses or not group:
156+ return None
157+ group_license_ids = [l.id for l in group.postlogistics_license_ids]
158+ if not group_license_ids:
159+ return None
160+ license = [l for l in company_licenses
161+ if l.id in group_license_ids][0]
162+ return license.number
163
164 def _prepare_attributes(self, picking):
165 services = [option.code.split(',') for option in picking.option_ids
166
167=== modified file 'delivery_carrier_label_postlogistics/res_config.py'
168--- delivery_carrier_label_postlogistics/res_config.py 2013-12-13 13:44:03 +0000
169+++ delivery_carrier_label_postlogistics/res_config.py 2014-01-23 10:39:04 +0000
170@@ -43,6 +43,11 @@
171 'password': fields.related(
172 'company_id', 'postlogistics_password',
173 string='Password', type='char'),
174+ 'license_ids': fields.related(
175+ 'company_id', 'postlogistics_license_ids',
176+ string='Frankling Licenses',
177+ type='one2many',
178+ relation='postlogistics.license'),
179 'license_less_1kg': fields.related(
180 'company_id', 'postlogistics_license_less_1kg',
181 string='License less than 1kg', type='char'),
182@@ -117,15 +122,14 @@
183 company = self.pool.get('res.company'
184 ).browse(cr, uid, company_id, context=context)
185
186+ license_ids = [l.id for l in company.postlogistics_license_ids]
187 label_layout = company.postlogistics_default_label_layout.id or False
188 output_format = company.postlogistics_default_output_format.id or False
189 resolution = company.postlogistics_default_resolution.id or False
190 values = {
191 'username': company.postlogistics_username,
192 'password': company.postlogistics_password,
193- 'license_less_1kg': company.postlogistics_license_less_1kg,
194- 'license_more_1kg': company.postlogistics_license_more_1kg,
195- 'license_vinolog': company.postlogistics_license_vinolog,
196+ 'license_ids': license_ids,
197 'logo': company.postlogistics_logo,
198 'office': company.postlogistics_office,
199 'default_label_layout': label_layout,
200@@ -422,3 +426,65 @@
201 continue
202 self._update_service_groups(cr, uid, ids, web_service, company, context=ctx)
203 return True
204+
205+ def _get_allowed_service_group_codes(self, web_service, company,
206+ license, context=None):
207+ """ Get a list of allowed service group codes"""
208+ if context is None:
209+ context = {}
210+
211+ lang = context.get('lang', 'en')
212+ res = web_service.read_allowed_services_by_franking_license(
213+ license.number, company, lang)
214+ if 'errors' in res:
215+ errors = '\n'.join(res['errors'])
216+ error_message = (_('Could not retrieve allowed Postlogistics '
217+ 'service groups for the %s licence:\n%s')
218+ % (license.name, errors))
219+ raise orm.except_orm(_('Error'), error_message)
220+
221+ if not res['value']:
222+ return []
223+
224+ if hasattr(res['value'], 'Errors') and res['value'].Errors:
225+ for error in res['value'].Errors.Error:
226+ message = '[%s] %s' % (error.Code, error.Message)
227+ raise orm.except_orm('Error', message)
228+
229+ service_group_codes = []
230+ for group in res['value'].ServiceGroups:
231+ service_group_codes.append(group.ServiceGroup.ServiceGroupID)
232+
233+ return service_group_codes
234+
235+ def assign_licenses_to_service_groups(self, cr, uid, ids, context=None):
236+ """ Check all licenses to assign it to PostLogistics service groups """
237+
238+ if context is None:
239+ context = {}
240+
241+ user_obj = self.pool.get('res.users')
242+ service_group_obj = self.pool.get('postlogistics.service.group')
243+ for config in self.browse(cr, uid, ids, context=context):
244+ company = config.company_id
245+ web_service = PostlogisticsWebService(company)
246+
247+ relations = {}
248+ for license in company.postlogistics_license_ids:
249+ service_groups = self._get_allowed_service_group_codes(
250+ web_service, company, license, context=context)
251+ group_ids = service_group_obj.search(
252+ cr, uid, [('group_extid', 'in', service_groups)],
253+ context=context)
254+ for group_id in group_ids:
255+ if group_id in relations:
256+ relations[group_id].append(license.id)
257+ else:
258+ relations[group_id] = [license.id]
259+ for group_id, license_ids in relations.iteritems():
260+ vals = {'postlogistics_license_ids': [(6, 0, license_ids)]}
261+ service_group_obj.write(cr, uid, group_id, vals,
262+ context=context)
263+
264+
265+ return True
266
267=== modified file 'delivery_carrier_label_postlogistics/res_config_view.xml'
268--- delivery_carrier_label_postlogistics/res_config_view.xml 2013-12-03 17:18:48 +0000
269+++ delivery_carrier_label_postlogistics/res_config_view.xml 2014-01-23 10:39:04 +0000
270@@ -41,16 +41,13 @@
271 <group>
272 <div>
273 <div>
274- <label for="license_less_1kg"/>
275- <field name="license_less_1kg" class="oe_inline"/>
276- </div>
277- <div>
278- <label for="license_more_1kg"/>
279- <field name="license_more_1kg" class="oe_inline"/>
280- </div>
281- <div>
282- <label for="license_vinolog"/>
283- <field name="license_vinolog" class="oe_inline"/>
284+ <field name="license_ids" class="oe_inline">
285+ <tree editable="bottom">
286+ <field name="name"/>
287+ <field name="number"/>
288+ <field name="sequence" invisible="True"/>
289+ </tree>
290+ </field>
291 </div>
292 </div>
293 </group>
294@@ -88,6 +85,7 @@
295 <div>
296 <div>
297 <button string="Update PostLogistics Services" type="object" name="update_postlogistics_options" class="oe_highlight"/>
298+ <button string="Assign PostLogistics Licenses to service groups" type="object" name="assign_licenses_to_service_groups" class="oe_highlight"/>
299 </div>
300 </div>
301 </group>
302
303=== modified file 'delivery_carrier_label_postlogistics/security/ir.model.access.csv'
304--- delivery_carrier_label_postlogistics/security/ir.model.access.csv 2013-12-23 10:54:36 +0000
305+++ delivery_carrier_label_postlogistics/security/ir.model.access.csv 2014-01-23 10:39:04 +0000
306@@ -1,3 +1,5 @@
307 id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
308 access_postlogistics_service_group_salesman,postlogistics.service.group.salesman,model_postlogistics_service_group,base.group_sale_salesman,1,0,0,0
309 access_postlogistics_service_group_manager,postlogistics.service.group.manager,model_postlogistics_service_group,base.group_sale_manager,1,1,1,1
310+access_postlogistics_license_salesman,postlogistics.license.salesman,model_postlogistics_license,base.group_sale_salesman,1,0,0,0
311+access_postlogistics_license_manager,postlogistics.license.manager,model_postlogistics_license,base.group_sale_manager,1,1,1,1

Subscribers

People subscribed via source and target branches