7f97ed0b615e2a29af3c122b8a75a74aa680fe5b
[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 : 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 + ": " + 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
109     
110 class map_val(mapper):
111     """
112         Use : map_val(external_field, val_mapping)
113         where val_mapping is a dictionary 
114         with external_val : openerp_val
115         
116         usefull for selection field like state
117         to map value 
118     """
119     def __init__(self, val, map, default='draft'):
120         self.val = value(val)
121         self.map = map
122         self.default = default
123         
124     def __call__(self, external_values):
125         return self.map.get(self.val(external_values), self.default)
126     
127 class ref(dbmapper):
128     """
129         Use : ref(table_name, external_id)
130         return the xml_id of the ressource
131         
132         to associate an already imported object with the current object
133     """
134     def __init__(self, table, field_name):
135         self.table = table
136         self.field_name = field_name
137         
138     def __call__(self, external_values):
139         return self.parent.xml_id_exist(self.table, external_values.get(self.field_name))
140   
141 class refbyname(dbmapper):  
142     """
143         Use : refbyname(table_name, external_name, res.model)
144         same as ref but use the name of the ressource to find it
145     """
146     def __init__(self, table, field_name, model):
147         self.table = table
148         self.field_name = field_name
149         self.model = model
150         
151     def __call__(self, external_values):
152         v = external_values.get(self.field_name, '')
153         return self.parent.name_exist(self.table, v , self.model)
154         
155 class call(mapper):
156     """
157         Use : call(function, arg1, arg2)
158         to call the function with external val follow by the arg specified 
159     """
160     def __init__(self, fun, *arg):
161         self.fun = fun
162         self.arg = arg
163     
164     def __call__(self, external_values):
165         args = []
166         for arg in self.arg:
167             if isinstance(arg, mapper):
168                 args.append(arg(external_values))
169             else:
170                 args.append(arg)
171         return self.fun(external_values, *args)
172     
173