[IMP]: store temp file
[odoo/odoo.git] / openerp / addons / base / res / res_company.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 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 from osv import osv
23 from osv import fields
24 import os
25 import tools
26 from tools.translate import _
27 from tools.safe_eval import safe_eval as eval
28 from lxml import etree
29
30 import pooler
31 import netsvc
32 from report.interface import report_rml
33 from tools import to_xml
34 from report import report_sxw
35
36 class multi_company_default(osv.osv):
37     """
38     Manage multi company default value
39     """
40     _name = 'multi_company.default'
41     _description = 'Default multi company'
42     _order = 'company_id,sequence,id'
43
44     _columns = {
45         'sequence': fields.integer('Sequence'),
46         'name': fields.char('Name', size=256, required=True, help='Name it to easily find a record'),
47         'company_id': fields.many2one('res.company', 'Main Company', required=True,
48             help='Company where the user is connected'),
49         'company_dest_id': fields.many2one('res.company', 'Default Company', required=True,
50             help='Company to store the current record'),
51         'object_id': fields.many2one('ir.model', 'Object', required=True,
52             help='Object affected by this rule'),
53         'expression': fields.char('Expression', size=256, required=True,
54             help='Expression, must be True to match\nuse context.get or user (browse)'),
55         'field_id': fields.many2one('ir.model.fields', 'Field', help='Select field property'),
56     }
57
58     _defaults = {
59         'expression': lambda *a: 'True',
60         'sequence': lambda *a: 100,
61     }
62
63     def copy(self, cr, uid, id, default=None, context=None):
64         """
65         Add (copy) in the name when duplicate record
66         """
67         if not context:
68             context = {}
69         if not default:
70             default = {}
71         company = self.browse(cr, uid, id, context=context)
72         default = default.copy()
73         default['name'] = company.name + _(' (copy)')
74         return super(multi_company_default, self).copy(cr, uid, id, default, context=context)
75
76 multi_company_default()
77
78 class res_company(osv.osv):
79     _name = "res.company"
80     _description = 'Companies'
81     _order = 'name'
82     _columns = {
83         'name': fields.char('Company Name', size=64, required=True),
84         'parent_id': fields.many2one('res.company', 'Parent Company', select=True),
85         'child_ids': fields.one2many('res.company', 'parent_id', 'Child Companies'),
86         'partner_id': fields.many2one('res.partner', 'Partner', required=True),
87         'rml_header1': fields.char('Report Header', size=200),
88         'rml_footer1': fields.char('Report Footer 1', size=200),
89         'rml_footer2': fields.char('Report Footer 2', size=200),
90         'rml_header' : fields.text('RML Header', required=True),
91         'rml_header2' : fields.text('RML Internal Header', required=True),
92         'rml_header3' : fields.text('RML Internal Header', required=True),
93         'logo' : fields.binary('Logo'),
94         'currency_id': fields.many2one('res.currency', 'Currency', required=True),
95         'currency_ids': fields.one2many('res.currency', 'company_id', 'Currency'),
96         'user_ids': fields.many2many('res.users', 'res_company_users_rel', 'cid', 'user_id', 'Accepted Users'),
97         'account_no':fields.char('Account No.', size=64),
98     }
99
100     def _search(self, cr, uid, args, offset=0, limit=None, order=None,
101             context=None, count=False, access_rights_uid=None):
102
103         if context is None:
104             context = {}
105         user_preference = context.get('user_preference', False)
106         if user_preference:
107             # We browse as superuser. Otherwise, the user would be able to
108             # select only the currently visible companies (according to rules,
109             # which are probably to allow to see the child companies) even if
110             # she belongs to some other companies.
111             user = self.pool.get('res.users').browse(cr, 1, uid, context=context)
112             cmp_ids = list(set([user.company_id.id] + [cmp.id for cmp in user.company_ids]))
113             return cmp_ids
114         return super(res_company, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
115             context=context, count=count, access_rights_uid=access_rights_uid)
116
117     def _company_default_get(self, cr, uid, object=False, field=False, context=None):
118         """
119         Check if the object for this company have a default value
120         """
121         if not context:
122             context = {}
123         proxy = self.pool.get('multi_company.default')
124         args = [
125             ('object_id.model', '=', object),
126             ('field_id', '=', field),
127         ]
128
129         ids = proxy.search(cr, uid, args, context=context)
130         user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
131         for rule in proxy.browse(cr, uid, ids, context):
132             if eval(rule.expression, {'context': context, 'user': user}):
133                 return rule.company_dest_id.id
134         return user.company_id.id
135
136     def _get_child_ids(self, cr, uid, uid2, context={}):
137         company = self.pool.get('res.users').company_get(cr, uid, uid2)
138         ids = self._get_company_children(cr, uid, company)
139         return ids
140
141     @tools.cache()
142     def _get_company_children(self, cr, uid=None, company=None):
143         if not company:
144             return []
145         ids =  self.search(cr, uid, [('parent_id','child_of',[company])])
146         return ids
147
148 #  For Report
149
150     def createReport(cr, uid, report, ids, name=False):
151         files = []
152         for id in ids:
153             try:
154                 service = netsvc.LocalService(report)
155                 (result, format) = service.create(cr, uid, [id], {}, {})
156                 if not name:
157                     report_file = '/tmp/reports'+ str(id) + '.pdf'
158                 else:
159                     report_file = name
160                 fp = open(report_file,'wb+')
161                 fp.write(result);
162                 fp.close();
163                 files += [report_file]
164             except Exception,e:
165                 continue
166         return files
167
168     def _get_partner_hierarchy(self, cr, uid, company_id, context={}):
169         if company_id:
170             parent_id = self.browse(cr, uid, company_id)['parent_id']
171             if parent_id:
172                 return self._get_partner_hierarchy(cr, uid, parent_id.id, context)
173             else:
174                 return self._get_partner_descendance(cr, uid, company_id, [], context)
175         return []
176
177     def _get_partner_descendance(self, cr, uid, company_id, descendance, context={}):
178         descendance.append(self.browse(cr, uid, company_id).partner_id.id)
179         for child_id in self._get_company_children(cr, uid, company_id):
180             if child_id != company_id:
181                 descendance = self._get_partner_descendance(cr, uid, child_id, descendance)
182         return descendance
183
184     #
185     # This function restart the cache on the _get_company_children method
186     #
187     def cache_restart(self, cr):
188         self._get_company_children.clear_cache(cr.dbname)
189
190     def create(self, cr, uid, vals, context=None):
191         if not vals.get('name', False) or vals.get('partner_id', False):
192             self.cache_restart(cr)
193             return super(res_company, self).create(cr, uid, vals, context=context)
194         obj_partner = self.pool.get('res.partner')
195         partner_id = obj_partner.create(cr, uid, {'name': vals['name']}, context=context)
196         vals.update({'partner_id': partner_id})
197         self.cache_restart(cr)
198         company_id = super(res_company, self).create(cr, uid, vals, context=context)
199         obj_partner.write(cr, uid, partner_id, {'company_id': company_id}, context=context)
200         return company_id
201
202     def write(self, cr, *args, **argv):
203         self.cache_restart(cr)
204         return super(res_company, self).write(cr, *args, **argv)
205
206     def _get_euro(self, cr, uid, context={}):
207         try:
208             return self.pool.get('res.currency').search(cr, uid, [])[0]
209         except:
210             return False
211
212     def _get_logo(self, cr, uid, ids):
213         return open(os.path.join(
214             tools.config['root_path'], '..', 'pixmaps', 'openerp-header.png'),
215                     'rb') .read().encode('base64')
216
217     def _get_header3(self,cr,uid,ids):
218         return """
219 <header>
220 <pageTemplate>
221     <frame id="first" x1="28.0" y1="28.0" width="786" height="525"/>
222     <pageGraphics>
223         <fill color="black"/>
224         <stroke color="black"/>
225         <setFont name="DejaVu Sans" size="8"/>
226         <drawString x="25" y="555"> [[ formatLang(time.strftime("%Y-%m-%d"), date=True) ]]  [[ time.strftime("%H:%M") ]]</drawString>
227         <setFont name="DejaVu Sans Bold" size="10"/>
228         <drawString x="382" y="555">[[ company.partner_id.name ]]</drawString>
229         <stroke color="#000000"/>
230         <lines>25 550 818 550</lines>
231     </pageGraphics>
232     </pageTemplate>
233 </header>"""
234     def _get_header2(self,cr,uid,ids):
235         return """
236         <header>
237         <pageTemplate>
238         <frame id="first" x1="28.0" y1="28.0" width="539" height="772"/>
239         <pageGraphics>
240         <fill color="black"/>
241         <stroke color="black"/>
242         <setFont name="DejaVu Sans" size="8"/>
243         <drawString x="1.0cm" y="28.3cm"> [[ formatLang(time.strftime("%Y-%m-%d"), date=True) ]]  [[ time.strftime("%H:%M") ]]</drawString>
244         <setFont name="DejaVu Sans Bold" size="10"/>
245         <drawString x="9.3cm" y="28.3cm">[[ company.partner_id.name ]]</drawString>
246         <stroke color="#000000"/>
247         <lines>1.0cm 28.1cm 20.1cm 28.1cm</lines>
248         </pageGraphics>
249         </pageTemplate>
250 </header>"""
251     def _get_header(self,cr,uid,ids):
252         try :
253             header_file = tools.file_open(os.path.join('base', 'report', 'corporate_rml_header.rml'))
254             try:
255                 return header_file.read()
256             finally:
257                 header_file.close()
258         except:
259             return """
260     <header>
261     <pageTemplate>
262         <frame id="first" x1="1.3cm" y1="2.5cm" height="23.0cm" width="19cm"/>
263         <pageGraphics>
264             <!-- You Logo - Change X,Y,Width and Height -->
265             <image x="1.3cm" y="27.6cm" height="40.0" >[[ company.logo or removeParentNode('image') ]]</image>
266             <setFont name="DejaVu Sans" size="8"/>
267             <fill color="black"/>
268             <stroke color="black"/>
269             <lines>1.3cm 27.7cm 20cm 27.7cm</lines>
270
271             <drawRightString x="20cm" y="27.8cm">[[ company.rml_header1 ]]</drawRightString>
272
273
274             <drawString x="1.3cm" y="27.2cm">[[ company.partner_id.name ]]</drawString>
275             <drawString x="1.3cm" y="26.8cm">[[ company.partner_id.address and company.partner_id.address[0].street or  '' ]]</drawString>
276             <drawString x="1.3cm" y="26.4cm">[[ company.partner_id.address and company.partner_id.address[0].zip or '' ]] [[ company.partner_id.address and company.partner_id.address[0].city or '' ]] - [[ company.partner_id.address and company.partner_id.address[0].country_id and company.partner_id.address[0].country_id.name  or '']]</drawString>
277             <drawString x="1.3cm" y="26.0cm">Phone:</drawString>
278             <drawRightString x="7cm" y="26.0cm">[[ company.partner_id.address and company.partner_id.address[0].phone or '' ]]</drawRightString>
279             <drawString x="1.3cm" y="25.6cm">Mail:</drawString>
280             <drawRightString x="7cm" y="25.6cm">[[ company.partner_id.address and company.partner_id.address[0].email or '' ]]</drawRightString>
281             <lines>1.3cm 25.5cm 7cm 25.5cm</lines>
282
283             <!--page bottom-->
284
285             <lines>1.2cm 2.15cm 19.9cm 2.15cm</lines>
286
287             <drawCentredString x="10.5cm" y="1.7cm">[[ company.rml_footer1 ]]</drawCentredString>
288             <drawCentredString x="10.5cm" y="1.25cm">[[ company.rml_footer2 ]]</drawCentredString>
289             <drawCentredString x="10.5cm" y="0.8cm">Contact : [[ user.name ]] - Page: <pageNumber/></drawCentredString>
290         </pageGraphics>
291     </pageTemplate>
292 </header>"""
293     _defaults = {
294         'currency_id': _get_euro,
295         'rml_header':_get_header,
296         'rml_header2': _get_header2,
297         'rml_header3': _get_header3,
298         #'logo':_get_logo
299     }
300
301     _constraints = [
302         (osv.osv._check_recursion, 'Error! You can not create recursive companies.', ['parent_id'])
303     ]
304
305     def createReport(self, cr, uid, ids, context=None):
306         # Used new cursor as it was closed explicitly somewhere and because of this partner data was not printed
307         # Tocheck: its not closed
308         cr = pooler.get_db(cr.dbname).cursor()
309         company = self.browse(cr, uid, ids, context=context)[0]
310
311         class company_parser(report_sxw.rml_parse):
312             def __init__(self, cr, uid, name, context):
313                 super(company_parser, self).__init__(cr, uid, name, context=context)
314                 self.setCompany(company)
315         rml = etree.XML(company.rml_header)
316         rml = rml.getchildren()[0]
317         header_xml = """<document filename="Preview Report.pdf">
318         <template pageSize="(595.0,842.0)" title="Preview Report" author="OpenERP S.A.(sales@openerp.com)" allowSplitting="20">""" + etree.tostring(rml) +  """
319           </template>
320           </document>
321           """
322         tempfilename= '/tmp/previews.rml'
323         fp = open(tempfilename, 'wb+')
324         fp.write(header_xml)
325         fp.close()
326         if netsvc.Service._services.get('report.company.report'):
327             netsvc.Service._services.pop('report.company.report')
328         myreport = report_sxw.report_sxw('report.company.report', 'res.company', tempfilename, parser=company_parser)
329         return {
330                 'type': 'ir.actions.report.xml',
331                 'report_name': 'company.report',
332                 'datas': {'ids': ids, 'model': 'res.company'},
333                 'nodestroy': True
334             }
335
336 res_company()
337
338 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
339
340
341