root / zinnplugins / tryton / party.py @ a899390a2a8aca3b3b4617dd7cd96a19e64b489c

View | Annotate | Download (16 KB)

1 a899390a seb
 # -*- coding: utf-8 -*-
2 a67efaab seb
 # Copyright (c) 2009 Lost Oasis, IELO <info@ielo.net>
3 a67efaab seb
 #
4 a67efaab seb
 # This file is part of ZINN.
5 a67efaab seb
 #
6 a67efaab seb
 # SINN is free software: you can redistribute it and/or modify it under
7 a67efaab seb
 # the terms of the GNU General Public License as published by the Free
8 a67efaab seb
 # Software Foundation, either version 3 of the License, or (at your
9 a67efaab seb
 # option) any later version.
10 a67efaab seb
 #
11 a67efaab seb
 # SINN is distributed in the hope that it will be useful, but WITHOUT
12 a67efaab seb
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 a67efaab seb
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 a67efaab seb
 # for more details.
15 a67efaab seb
 #
16 a67efaab seb
 # You should have received a copy of the GNU General Public License
17 a67efaab seb
 # along with ZINN.  If not, see <http://www.gnu.org/licenses/>.
18 a67efaab seb
19 a67efaab seb
 import xmlrpclib
20 a899390a seb
21 a899390a seb
 from erp import Itransport
22 a67efaab seb
 from erp import Iparty
23 a899390a seb
 from erp import IpartyAddress
24 a899390a seb
 from erp import IpartyContactMechanism
25 a67efaab seb
26 a899390a seb
 from urlparse import urlparse
27 a67efaab seb
28 a899390a seb
 class TrytonTransport(Itransport.Itransport):
29 a899390a seb
     def __init__(self, dsn):
30 a899390a seb
         super(TrytonTransport, self).__init__(dsn)
31 a899390a seb
         port = ''
32 a899390a seb
         o = urlparse(dsn)
33 a899390a seb
         if o.port: port = ':'+str(o.port)
34 a899390a seb
         self.uri = o.scheme+'://'+o.hostname+port+o.path
35 a899390a seb
         self.user     = o.username
36 a899390a seb
         self.password = o.password
37 a67efaab seb
38 a899390a seb
         self.proxy = xmlrpclib.ServerProxy(self.uri)
39 a67efaab seb
         self.user_id, self.session = self.proxy.common.db.login(self.user,
40 a67efaab seb
                 self.password)
41 a67efaab seb
         self.context = self.proxy.model.res.user.get_preferences(self.user_id,
42 a67efaab seb
                 self.session, True, {})
43 a67efaab seb
44 a899390a seb
     def getProxy(self):
45 a899390a seb
         return self.proxy
46 a899390a seb
47 a899390a seb
     def getContext(self):
48 a899390a seb
         return self.context
49 a899390a seb
50 a899390a seb
     def getSession(self):
51 a899390a seb
         return self.session
52 a899390a seb
53 a899390a seb
     def getUserId(self):
54 a899390a seb
         return self.user_id
55 a899390a seb
56 a899390a seb
57 a899390a seb
 class CountrySubdivision():
58 a899390a seb
     def __init__(self, transport):
59 a899390a seb
         self.transport = transport
60 a899390a seb
         self.proxy     = self.transport.getProxy().model.country.subdivision
61 a899390a seb
62 a899390a seb
     def list(self, countryName, subdivisionName=None):
63 a899390a seb
         subdivision = self.byName(countryName, subdivisionName)
64 a899390a seb
         if not subdivision:
65 a899390a seb
             return subdivision
66 a899390a seb
         else:
67 a899390a seb
             return [s['name'] for s in subdivision]
68 a899390a seb
69 a899390a seb
     def byId(self, subdivisionId):
70 a899390a seb
         if not subdivisionId:
71 a899390a seb
             return False
72 a899390a seb
         where = [('id', '=', subdivisionId)]
73 a899390a seb
         args = [self.transport.getUserId(), self.transport.getSession(),
74 a899390a seb
                 where,                          # where
75 a899390a seb
                 0,                              # offset
76 a899390a seb
                 1,                              # limit
77 a899390a seb
                 [],                             # order
78 a899390a seb
                 self.transport.getContext(),    # context
79 a899390a seb
                 ['name']                        # fields
80 a899390a seb
                 ]
81 a899390a seb
         subdivision = self.proxy.search_read(*args)
82 a899390a seb
         return subdivision['name'] if len(subdivision) else False
83 a899390a seb
84 a899390a seb
85 a899390a seb
     def byName(self, countryName=None, subdivisionName=None):
86 a899390a seb
         c = PartyCountry(self.transport)
87 a899390a seb
         country = c.byName(countryName) if countryName else None
88 a899390a seb
         where = []
89 a899390a seb
         if country:
90 a899390a seb
             where.append(('country', '=', country[0]['id']))
91 a899390a seb
         if subdivisionName:
92 a899390a seb
             where.append(('name', '=', subdivisionName))
93 a899390a seb
         args = [self.transport.getUserId(), self.transport.getSession(),
94 a899390a seb
                 where,                          # where
95 a899390a seb
                 0,                              # offset
96 a899390a seb
                 10000000,                       # limit
97 a899390a seb
                 [],                             # order
98 a899390a seb
                 self.transport.getContext(),    # context
99 a899390a seb
                 ['id', 'name']                  # fields
100 a899390a seb
                 ]
101 a899390a seb
         subdivision = self.proxy.search_read(*args)
102 a899390a seb
         return subdivision if len(subdivision) else None
103 a899390a seb
104 a899390a seb
105 a899390a seb
 class PartyCountry():
106 a899390a seb
     def __init__(self, transport):
107 a899390a seb
         self.transport   = transport
108 a899390a seb
         self.subdivision = CountrySubdivision(self.transport)
109 a899390a seb
         self.proxy       = self.transport.getProxy().model.country.country
110 a899390a seb
111 a899390a seb
     def list(self, countryName=None):
112 a899390a seb
         country = self.byName(countryName)
113 a899390a seb
         if not country:
114 a899390a seb
             return country
115 a899390a seb
         else:
116 a899390a seb
             return [c['name'] for c in country]
117 a899390a seb
118 a899390a seb
     def byId(self, countryId):
119 a899390a seb
         if not countryId:
120 a899390a seb
             return False
121 a899390a seb
         where = [('id', '=', countryId)]
122 a899390a seb
         args = [self.transport.getUserId(), self.transport.getSession(),
123 a899390a seb
                 where,                          # where
124 a899390a seb
                 0,                              # offset
125 a899390a seb
                 1,                              # limit
126 a899390a seb
                 [],                             # order
127 a899390a seb
                 self.transport.getContext(),    # context
128 a899390a seb
                 ['id', 'name']                  # fields
129 a899390a seb
                 ]
130 a899390a seb
         country = self.proxy.search_read(*args)
131 a899390a seb
         return country if len(country) else False
132 a899390a seb
133 a899390a seb
     def byName(self, countryName=None):
134 a899390a seb
         where = [('name', '=', countryName)] if countryName else []
135 a899390a seb
         args = [self.transport.getUserId(), self.transport.getSession(),
136 a899390a seb
                 where,                          # where
137 a899390a seb
                 0,                              # offset
138 a899390a seb
                 1000000,                        # limit
139 a899390a seb
                 [],                             # order
140 a899390a seb
                 self.transport.getContext(),    # context
141 a899390a seb
                 ['id', 'name']                  # fields
142 a899390a seb
                 ]
143 a899390a seb
         country = self.proxy.search_read(*args)
144 a899390a seb
         return country if len(country) else None
145 a899390a seb
146 a899390a seb
 class PartyAddress(IpartyAddress.IpartyAddress):
147 a899390a seb
     def __init__(self, transport):
148 a899390a seb
         self.transport   = transport
149 a899390a seb
         self.country     = PartyCountry(self.transport)
150 a899390a seb
         self.subdivision = CountrySubdivision(self.transport)
151 a899390a seb
         self.proxy       = self.transport.getProxy().model.party.address
152 a899390a seb
153 a899390a seb
     def list(self, partyLabel, label=None):
154 a899390a seb
         fields = [] if label else ['name']
155 a899390a seb
         address = self.byLabel(partyLabel, label, fields)
156 a899390a seb
         if not address:
157 a899390a seb
             return address
158 a899390a seb
         if not label:
159 a899390a seb
             return [p['name'] for p in address]
160 a899390a seb
         else:
161 a899390a seb
             return self._decorate(address)
162 a899390a seb
163 a899390a seb
     def create(self, partyLabel, label, attributes):
164 a899390a seb
         address = self.byLabel(partyLabel, label)
165 a899390a seb
         if address:
166 a899390a seb
             return False
167 a899390a seb
         else:
168 a899390a seb
             p = Party(self.transport)
169 a899390a seb
             party = p.byLabel(partyLabel)
170 a899390a seb
             if not party:
171 a899390a seb
                 return False
172 a899390a seb
             else:
173 a899390a seb
                 default = {
174 a899390a seb
                         'name'  : label,
175 a899390a seb
                         'party' : party[0]['id'],
176 a899390a seb
                         }
177 a899390a seb
                 attr = self.AttributesFilter(attributes, default)
178 a899390a seb
                 attr = self.transformAttributesInRelationsId(attr)
179 a899390a seb
                 attr['name'] = str(attr['name']).strip(' \t\r\n')
180 a899390a seb
                 args = [self.transport.getUserId(), self.transport.getSession(),
181 a899390a seb
                         attr, self.transport.getContext()]
182 a899390a seb
                 return self.proxy.create(*args)
183 a899390a seb
184 a899390a seb
     def update(self, partyLabel, label, attributes):
185 a899390a seb
         address = self.byLabel(partyLabel, label)
186 a899390a seb
         if not address:
187 a899390a seb
             return False
188 a899390a seb
         else:
189 a899390a seb
             if not address[0]['party']:
190 a899390a seb
                 return False
191 a899390a seb
             else:
192 a899390a seb
                 attr = self.AttributesFilter(attributes)
193 a899390a seb
                 attr = self.transformAttributesInRelationsId(attr)
194 a899390a seb
                 args = [self.transport.getUserId(), self.transport.getSession(),
195 a899390a seb
                         address[0]['id'], attr, self.transport.getContext()]
196 a899390a seb
                 return self.proxy.write(*args)
197 a899390a seb
198 a899390a seb
     def delete(self, partyLabel, label):
199 a899390a seb
         address = self.byLabel(partyLabel, label)
200 a899390a seb
         if not address:
201 a899390a seb
             return False # already deleted
202 a899390a seb
         else:
203 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
204 a899390a seb
                     address[0]['id'], self.transport.getContext()]
205 a899390a seb
             return self.proxy.delete(*args)
206 a899390a seb
207 a899390a seb
     def attributes(self, onlyMutables=False):
208 a899390a seb
         return self.getAttributes(onlyMutables)
209 a899390a seb
210 a899390a seb
     def byLabel(self, partyLabel, label=None, fields=[]):
211 a899390a seb
         p = Party(self.transport)
212 a899390a seb
         party = p.byLabel(partyLabel)
213 a899390a seb
         if not party:
214 a899390a seb
             return None
215 a899390a seb
         where = ['AND', ('party', '=', party[0]['id'])]
216 a899390a seb
         if not label:
217 a899390a seb
             whereAnd = []
218 a899390a seb
         else:
219 a899390a seb
             if isinstance(label, list):
220 a899390a seb
                 whereAnd = ['OR']
221 a899390a seb
                 for l in label:
222 a899390a seb
                     whereAnd.append(('name', '=', l))
223 a899390a seb
             else:
224 a899390a seb
                 whereAnd = [('name', '=', label)]
225 a899390a seb
         where.append(whereAnd)
226 a899390a seb
227 a899390a seb
         args = [self.transport.getUserId(), self.transport.getSession(),
228 a899390a seb
                 where,                          # where
229 a899390a seb
                 0,                              # offset
230 a899390a seb
                 10000,                          # limit # FIXME
231 a899390a seb
                 [],                             # order
232 a899390a seb
                 self.transport.getContext(),    # context
233 a899390a seb
                 []                              # fields
234 a899390a seb
                 ]
235 a899390a seb
         address = self.proxy.search_read(*args)
236 a899390a seb
         return None if len(address) == 0 else address
237 a899390a seb
238 a899390a seb
     def transformAttributesInRelationsId(self, attributes):
239 a899390a seb
         attr = attributes
240 a899390a seb
         country_label = None
241 a899390a seb
         if attr.has_key('country') and attr['country']:
242 a899390a seb
             country = self.country.byName(attr['country'])
243 a899390a seb
             if country:
244 a899390a seb
                 country_label = attr['country']
245 a899390a seb
                 attr['country'] = country[0]['id']
246 a899390a seb
             else:
247 a899390a seb
                 del attr['country']
248 a899390a seb
249 a899390a seb
         if attr.has_key('subdivision') and attr['subdivision']:
250 a899390a seb
             subdivision = self.subdivision.byName(country_label,
251 a899390a seb
                     attr['subdivision'])
252 a899390a seb
             if subdivision:
253 a899390a seb
                 attr['subdivision'] = subdivision[0]['id']
254 a899390a seb
             else:
255 a899390a seb
                 del attr['subdivision']
256 a899390a seb
257 a899390a seb
         return attr
258 a899390a seb
259 a899390a seb
260 a899390a seb
 class PartyContactMechanism(IpartyContactMechanism.IpartyContactMechanism):
261 a899390a seb
     def __init__(self, transport):
262 a899390a seb
         self.transport = transport
263 a899390a seb
         self.proxy     = self.transport.getProxy().model.party.contact_mechanism
264 a899390a seb
265 a899390a seb
     def list(self, partyLabel, contactType=None):
266 a899390a seb
         fields = ['value', 'type']
267 a899390a seb
         contact_mechanism = self.byType(partyLabel, contactType, None, fields)
268 a899390a seb
         if not contact_mechanism:
269 a899390a seb
             return contact_mechanism
270 a899390a seb
         else:
271 a899390a seb
             return [{'type': cm['type'], 'value': cm['value']} for cm in
272 a899390a seb
                     contact_mechanism]
273 a899390a seb
274 a899390a seb
     def byType(self, partyLabel, contactType=None, contactValue=None, fields=[]):
275 a899390a seb
         p = Party(self.transport)
276 a899390a seb
         party = p.byLabel(partyLabel)
277 a899390a seb
         if not party:
278 a899390a seb
             return None
279 a899390a seb
         else:
280 a899390a seb
             where = [('party', '=', party[0]['id'])]
281 a899390a seb
             if contactType in self.types:
282 a899390a seb
                 where.append(('type', '=', contactType))
283 a899390a seb
             if contactValue:
284 a899390a seb
                 where.append(('value', '=', contactValue))
285 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
286 a899390a seb
                     where,                          # where
287 a899390a seb
                     0,                              # offset
288 a899390a seb
                     1000,                           # limit #FIXME
289 a899390a seb
                     [('type', 'ASC')],              # order
290 a899390a seb
                     self.transport.getContext(),    # context
291 a899390a seb
                     fields                          # fields
292 a899390a seb
                     ]
293 a899390a seb
             return self.proxy.search_read(*args)
294 a899390a seb
295 a899390a seb
     def create(self, partyLabel, attributes):
296 a899390a seb
         if not isinstance(attributes, dict):
297 a899390a seb
             return False
298 a899390a seb
         if not (attributes.has_key('type') and attributes['type'] in self.types):
299 a899390a seb
             return False
300 a899390a seb
         if not attributes.has_key('value'):
301 a899390a seb
             return False
302 a899390a seb
         attributes['value'] = str(attributes['value']).strip(' \n\t\r')
303 a899390a seb
         contact_mechanism = self.byType(partyLabel, attributes['type'], attributes['value'])
304 a899390a seb
         if contact_mechanism:
305 a899390a seb
             return False
306 a899390a seb
         p = Party(self.transport)
307 a899390a seb
         party = p.byLabel(partyLabel)
308 a899390a seb
         if not party:
309 a899390a seb
             return False
310 a899390a seb
         else:
311 a899390a seb
             default = {'party' : party[0]['id']}
312 a899390a seb
             attr = self.AttributesFilter(attributes, default)
313 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
314 a899390a seb
                             attr, self.transport.getContext()]
315 a899390a seb
             return self.proxy.create(*args)
316 a899390a seb
317 a899390a seb
     def delete(self, partyLabel, attributes):
318 a899390a seb
         if not isinstance(attributes, dict):
319 a899390a seb
             return False
320 a899390a seb
         if not (attributes.has_key('type') and attributes['type'] in self.types):
321 a899390a seb
             return False
322 a899390a seb
         if not attributes.has_key('value'):
323 a899390a seb
             return False
324 a899390a seb
         attributes['value'] = str(attributes['value']).strip(' \n\t\r')
325 a899390a seb
         contact_mechanism = self.byType(partyLabel, attributes['type'], attributes['value'])
326 a899390a seb
         if not contact_mechanism:
327 a899390a seb
             return False
328 a899390a seb
         else:
329 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
330 a899390a seb
                             contact_mechanism[0]['id'],
331 a899390a seb
                             self.transport.getContext()]
332 a899390a seb
             return self.proxy.delete(*args)
333 a899390a seb
334 a899390a seb
     def attributes(self, onlyMutables=False):
335 a899390a seb
         return self.getAttributes(onlyMutables)
336 a899390a seb
337 a899390a seb
338 a899390a seb
 class Party(Iparty.Iparty):
339 a899390a seb
     def __init__(self, transport):
340 a899390a seb
         super(Party, self).__init__(transport)
341 a899390a seb
         self.transport = transport
342 a899390a seb
         self.proxy   = self.transport.getProxy().model.party.party
343 a899390a seb
         self.country = PartyCountry(self.transport)
344 a899390a seb
         self.address = PartyAddress(self.transport)
345 a899390a seb
         self.contact_mechanism = PartyContactMechanism(self.transport)
346 a899390a seb
347 a899390a seb
     def list(self, label=None):
348 a899390a seb
         fields = [] if label else ['name']
349 a899390a seb
         party = self.byLabel(label, fields)
350 a899390a seb
         if not party:
351 a899390a seb
             return party
352 a899390a seb
         if not label:
353 a899390a seb
             return [p['name'] for p in party]
354 a899390a seb
         else:
355 a899390a seb
             return self._decorate(party)
356 a899390a seb
357 a899390a seb
     def create(self, label, attributes):
358 a899390a seb
         party = self.byLabel(label)
359 a899390a seb
         if party:
360 a899390a seb
             return False
361 a899390a seb
         else:
362 a899390a seb
             default = {
363 a899390a seb
                     'active'       : True,
364 a899390a seb
                     'name'         : label,
365 a899390a seb
                     'full_name'    : label,
366 a899390a seb
                     'vat_country'  : 'FR'
367 a899390a seb
                     }
368 a899390a seb
             attr = self.AttributesFilter(attributes, default)
369 a899390a seb
             attr['name'] = str(attr['name']).strip(' \t\r\n')
370 a899390a seb
             attr['full_name'] = str(attr['full_name']).strip(' \t\r\n')
371 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
372 a899390a seb
                     attr, self.transport.getContext()]
373 a899390a seb
             ret = self.proxy.create(*args)
374 a899390a seb
             return ret
375 a899390a seb
376 a899390a seb
     def update(self, label, attributes):
377 a899390a seb
         party = self.byLabel(label)
378 a899390a seb
         if party is None:
379 a899390a seb
             return False
380 a899390a seb
         else:
381 a899390a seb
             attr = self.AttributesFilter(attributes)
382 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
383 a899390a seb
                     party[0]['id'], attr, self.transport.getContext()]
384 a899390a seb
             return self.proxy.write(*args)
385 a899390a seb
386 a899390a seb
     def delete(self, label):
387 a899390a seb
         party = self.byLabel(label)
388 a899390a seb
         if party:
389 a899390a seb
             args = [self.transport.getUserId(), self.transport.getSession(),
390 a899390a seb
                     party[0]['id'], self.transport.getContext()]
391 a899390a seb
             return self.proxy.delete(*args)
392 a899390a seb
         else:
393 a899390a seb
             return False # already deleted
394 a899390a seb
395 a899390a seb
     def attributes(self, onlyMutables=False):
396 a899390a seb
         return self.getAttributes(onlyMutables)
397 a899390a seb
398 a899390a seb
     def byLabel(self, label=None, fields=[]):
399 a899390a seb
         if not label:
400 a899390a seb
             where = []
401 a899390a seb
         else:
402 a899390a seb
             if isinstance(label, list):
403 a899390a seb
                 where = ['OR']
404 a899390a seb
                 for l in label:
405 a899390a seb
                     where.append(('name', '=', l))
406 a899390a seb
             else:
407 a899390a seb
                 where = [('name', '=', label)]
408 a899390a seb
         ctx = self.transport.getContext()
409 a899390a seb
         ctx['active_test'] = False
410 a899390a seb
         args = [self.transport.getUserId(), self.transport.getSession(),
411 a899390a seb
                 where,                          # where
412 a899390a seb
                 0,                              # offset
413 a899390a seb
                 10000,                          # limit FIXME
414 a899390a seb
                 [],                             # order
415 a899390a seb
                 ctx,                            # context
416 a899390a seb
                 fields                          # fields
417 a899390a seb
                 ]
418 a899390a seb
         party = self.proxy.search_read(*args)
419 a899390a seb
         return None if len(party) == 0 else party