4f34712f7ae8e5df9ad3919f76a418002fdc695c
[odoo/odoo.git] / addons / import_base / mapper.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22
23 class mapper(object):
24     """
25         super class for all mapper class
26         They are call before import data
27         to transform the mapping into real value that we
28         will import
29         
30         the call function receive a dictionary with external data
31             'external_field' : value
32     """
33     def __call__(self, external_values):
34         raise NotImplementedError()
35
36 class dbmapper(mapper):
37     """
38         Super class for mapper that need to access to 
39         data base or any function of the import_framework
40         
41         self.parent contains a reference to the instance of
42         the import framework
43     """
44     def set_parent(self, parent):
45         self.parent = parent
46         
47
48 class concat(mapper):
49     """
50         Use : contact('field_name1', 'field_name2', delimiter='_')
51         concat value of fields using the delimiter, delimiter is optional
52         and by default is a space
53         
54     """
55     def __init__(self, *arg, **delimiter):
56         self.arg = arg
57         self.delimiter = delimiter and delimiter.get('delimiter', ' ') or ' '
58         
59     def __call__(self, external_values):
60         return self.delimiter.join(map(lambda x : str(external_values.get(x,'')), self.arg))
61     
62 class ppconcat(mapper):
63     """
64         Use : contact('field_name1', 'field_name2', delimiter='_')
65         concat external field name and value of fields using the delimiter, 
66         delimiter is optional and by default is a two line feeds
67         
68     """
69     def __init__(self, *arg, **delimiter):
70         self.arg = arg
71         self.delimiter = delimiter and delimiter.get('delimiter', ' ') or '\n\n'
72         
73     def __call__(self, external_values):
74         return self.delimiter.join(map(lambda x : x + ": " + str(external_values.get(x,'')), self.arg))
75     
76 class const(mapper):
77     """
78         Use : const(arg)
79         return always arg
80     """
81     def __init__(self, val):
82         self.val = val
83         
84     def __call__(self, external_values):
85         return self.val 
86     
87 class value(mapper):
88     """
89         Use : value(external_field_name)
90         Return the value of the external field name
91         this is equivalent to the a single string
92         
93         usefull for call if you want your call get the value
94         and don't care about the name of the field
95         call(self.method, value('field1'))
96     """
97     def __init__(self, val, default='', fallback=False):
98         self.val = val
99         self.default = default
100         self.fallback = fallback
101         
102     def __call__(self, external_values):
103         val = external_values.get(self.val, self.default) 
104         if self.fallback and (not val or val == self.default):
105             val = external_values.get(self.fallback, self.default)
106         return val 
107     
108 class map_val(mapper):
109     """
110         Use : map_val(external_field, val_mapping)
111         where val_mapping is a dictionary 
112         with external_val : openerp_val
113         
114         usefull for selection field like state
115         to map value 
116     """
117     def __init__(self, val, map, default='draft'):
118         self.val = value(val)
119         self.map = map
120         self.default = default
121         
122     def __call__(self, external_values):
123         return self.map.get(self.val(external_values), self.default)
124     
125 class ref(dbmapper):
126     """
127         Use : ref(table_name, external_id)
128         return the xml_id of the ressource
129         
130         to associate an already imported object with the current object
131     """
132     def __init__(self, table, field_name):
133         self.table = table
134         self.field_name = field_name
135         
136     def __call__(self, external_values):
137         return self.parent.xml_id_exist(self.table, external_values.get(self.field_name))
138   
139 class refbyname(dbmapper):  
140     """
141         Use : refbyname(table_name, external_name, res.model)
142         same as ref but use the name of the ressource to find it
143     """
144     def __init__(self, table, field_name, model):
145         self.table = table
146         self.field_name = field_name
147         self.model = model
148         
149     def __call__(self, external_values):
150         v = external_values.get(self.field_name, '')
151         return self.parent.name_exist(self.table, v , self.model)
152         
153 class call(mapper):
154     """
155         Use : call(function, arg1, arg2)
156         to call the function with external val follow by the arg specified 
157     """
158     def __init__(self, fun, *arg):
159         self.fun = fun
160         self.arg = arg
161     
162     def __call__(self, external_values):
163         args = []
164         for arg in self.arg:
165             if isinstance(arg, mapper):
166                 args.append(arg(external_values))
167             else:
168                 args.append(arg)
169         return self.fun(external_values, *args)