Merge lp:~anybox/aeroo/fix-upgrade into lp:aeroo

Proposed by Georges Racinet
Status: Superseded
Proposed branch: lp:~anybox/aeroo/fix-upgrade
Merge into: lp:aeroo
Diff against target: 11765 lines (+11131/-0) (has conflicts)
114 files modified
report_aeroo/ExtraFunctions.py (+664/-0)
report_aeroo/__init__.py (+52/-0)
report_aeroo/__openerp__.py (+82/-0)
report_aeroo/barcode/EANBarCode.py (+159/-0)
report_aeroo/barcode/__init__.py (+34/-0)
report_aeroo/barcode/barcode.py (+63/-0)
report_aeroo/barcode/code128.py (+189/-0)
report_aeroo/barcode/code39.py (+166/-0)
report_aeroo/check_deps.py (+52/-0)
report_aeroo/ctt_languages/__init__.py (+3/-0)
report_aeroo/ctt_languages/en_US/__init__.py (+91/-0)
report_aeroo/ctt_languages/en_US/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/en_US/currencies/eur.py (+19/-0)
report_aeroo/ctt_languages/en_US/currencies/ltl.py (+19/-0)
report_aeroo/ctt_languages/en_US/currencies/lvl.py (+19/-0)
report_aeroo/ctt_languages/en_US/currencies/mxn.py (+19/-0)
report_aeroo/ctt_languages/en_US/currencies/trl.py (+19/-0)
report_aeroo/ctt_languages/en_US/currencies/usd.py (+19/-0)
report_aeroo/ctt_languages/es_ES/__init__.py (+102/-0)
report_aeroo/ctt_languages/es_ES/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/es_ES/currencies/eur.py (+19/-0)
report_aeroo/ctt_languages/es_ES/currencies/mxn.py (+19/-0)
report_aeroo/ctt_languages/es_ES/currencies/usd.py (+19/-0)
report_aeroo/ctt_languages/lt_LT/__init__.py (+107/-0)
report_aeroo/ctt_languages/lt_LT/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/lt_LT/currencies/eur.py (+25/-0)
report_aeroo/ctt_languages/lt_LT/currencies/ltl.py (+25/-0)
report_aeroo/ctt_languages/lt_LT/currencies/lvl.py (+25/-0)
report_aeroo/ctt_languages/lt_LT/currencies/uah.py (+25/-0)
report_aeroo/ctt_languages/lt_LT/currencies/usd.py (+25/-0)
report_aeroo/ctt_languages/lv_LV/__init__.py (+101/-0)
report_aeroo/ctt_languages/lv_LV/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/lv_LV/currencies/eur.py (+22/-0)
report_aeroo/ctt_languages/lv_LV/currencies/ltl.py (+25/-0)
report_aeroo/ctt_languages/lv_LV/currencies/lvl.py (+25/-0)
report_aeroo/ctt_languages/lv_LV/currencies/mxn.py (+22/-0)
report_aeroo/ctt_languages/lv_LV/currencies/rub.py (+25/-0)
report_aeroo/ctt_languages/lv_LV/currencies/trl.py (+25/-0)
report_aeroo/ctt_languages/lv_LV/currencies/uah.py (+24/-0)
report_aeroo/ctt_languages/lv_LV/currencies/usd.py (+25/-0)
report_aeroo/ctt_languages/ru_RU/__init__.py (+110/-0)
report_aeroo/ctt_languages/ru_RU/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/ru_RU/currencies/eur.py (+22/-0)
report_aeroo/ctt_languages/ru_RU/currencies/ltl.py (+23/-0)
report_aeroo/ctt_languages/ru_RU/currencies/lvl.py (+23/-0)
report_aeroo/ctt_languages/ru_RU/currencies/rub.py (+23/-0)
report_aeroo/ctt_languages/ru_RU/currencies/uah.py (+23/-0)
report_aeroo/ctt_languages/ru_RU/currencies/usd.py (+23/-0)
report_aeroo/ctt_languages/tr_TR/__init__.py (+93/-0)
report_aeroo/ctt_languages/tr_TR/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/tr_TR/currencies/eur.py (+21/-0)
report_aeroo/ctt_languages/tr_TR/currencies/lvl.py (+21/-0)
report_aeroo/ctt_languages/tr_TR/currencies/trl.py (+21/-0)
report_aeroo/ctt_languages/tr_TR/currencies/usd.py (+21/-0)
report_aeroo/ctt_languages/uk_UA/__init__.py (+112/-0)
report_aeroo/ctt_languages/uk_UA/currencies/__init__.py (+3/-0)
report_aeroo/ctt_languages/uk_UA/currencies/eur.py (+21/-0)
report_aeroo/ctt_languages/uk_UA/currencies/ltl.py (+23/-0)
report_aeroo/ctt_languages/uk_UA/currencies/lvl.py (+23/-0)
report_aeroo/ctt_languages/uk_UA/currencies/rub.py (+23/-0)
report_aeroo/ctt_languages/uk_UA/currencies/uah.py (+23/-0)
report_aeroo/ctt_languages/uk_UA/currencies/usd.py (+23/-0)
report_aeroo/ctt_objects.py (+161/-0)
report_aeroo/currency_to_text.py (+491/-0)
report_aeroo/data/report_aeroo_data.xml (+25/-0)
report_aeroo/domain_parser.py (+49/-0)
report_aeroo/installer.py (+79/-0)
report_aeroo/installer.xml (+56/-0)
report_aeroo/report_aeroo.py (+859/-0)
report_aeroo/report_view.xml (+322/-0)
report_aeroo/report_xml.py (+680/-0)
report_aeroo/security/ir.model.access.csv (+5/-0)
report_aeroo/translate.py (+352/-0)
report_aeroo/wizard/__init__.py (+38/-0)
report_aeroo/wizard/add_print_button.py (+111/-0)
report_aeroo/wizard/add_print_button_view.xml (+40/-0)
report_aeroo/wizard/remove_print_button.py (+97/-0)
report_aeroo/wizard/remove_print_button_view.xml (+37/-0)
report_aeroo/wizard/report_actions.py (+149/-0)
report_aeroo/wizard/report_import_wizard.py (+152/-0)
report_aeroo/wizard/report_print_actions.py (+183/-0)
report_aeroo/wizard/report_print_by_action.py (+63/-0)
report_aeroo_direct_print/__init__.py (+40/-0)
report_aeroo_direct_print/__openerp__.py (+76/-0)
report_aeroo_direct_print/check_deps.py (+51/-0)
report_aeroo_direct_print/data/report_aeroo_direct_data.xml (+17/-0)
report_aeroo_direct_print/installer.py (+152/-0)
report_aeroo_direct_print/installer.xml (+62/-0)
report_aeroo_direct_print/report_aeroo_direct_print.py (+299/-0)
report_aeroo_direct_print/report_aeroo_direct_print_view.xml (+158/-0)
report_aeroo_direct_print/security/ir.model.access.csv (+2/-0)
report_aeroo_direct_print/security/security_rules.xml (+14/-0)
report_aeroo_ooo/DocumentConverter.py (+221/-0)
report_aeroo_ooo/__init__.py (+80/-0)
report_aeroo_ooo/__openerp__.py (+64/-0)
report_aeroo_ooo/check_deps.py (+52/-0)
report_aeroo_ooo/data/report_aeroo_data.xml (+47/-0)
report_aeroo_ooo/installer.py (+165/-0)
report_aeroo_ooo/installer.xml (+72/-0)
report_aeroo_ooo/report.py (+95/-0)
report_aeroo_ooo/report_view.xml (+31/-0)
report_aeroo_ooo/tests/__init__.py (+4/-0)
report_aeroo_ooo/tests/test_service.py (+34/-0)
report_aeroo_printscreen/__init__.py (+32/-0)
report_aeroo_printscreen/__openerp__.py (+52/-0)
report_aeroo_printscreen/data/report_aeroo_printscreen_data.xml (+21/-0)
report_aeroo_printscreen/parser.py (+77/-0)
report_aeroo_printscreen/static/src/js/report_aeroo_printscreen.js (+41/-0)
report_aeroo_sample/__init__.py (+33/-0)
report_aeroo_sample/__openerp__.py (+48/-0)
report_aeroo_sample/report/__init__.py (+34/-0)
report_aeroo_sample/report/lorem.py (+1982/-0)
report_aeroo_sample/report/parser.py (+49/-0)
report_aeroo_sample/report/report_sample.xml (+30/-0)
Conflict adding file report_aeroo.  Moved existing file to report_aeroo.moved.
Conflict adding file report_aeroo_direct_print.  Moved existing file to report_aeroo_direct_print.moved.
Conflict adding file report_aeroo_ooo.  Moved existing file to report_aeroo_ooo.moved.
Conflict adding file report_aeroo_printscreen.  Moved existing file to report_aeroo_printscreen.moved.
Conflict adding file report_aeroo_sample.  Moved existing file to report_aeroo_sample.moved.
To merge this branch: bzr merge lp:~anybox/aeroo/fix-upgrade
Reviewer Review Type Date Requested Status
Christophe Combelles thorough ! Pending
Review via email: mp+214388@code.launchpad.net

This proposal has been superseded by a proposal from 2014-04-05.

Description of the change

To test, take any customer project using an earlier version of aeroo (no restart_ooo_cmd column in oo_config table), and perform an upgrade with the upgrade script provided by the recipe.

A quicker test is to check if the server starts *without -u report_aeroo_ooo*

Note that I am also tempted by fixing the bare excepts once the fix itself is more mature.

I'm asking ccomb, but any comments are welcome, and especially further tests by the Anybox team on customer projects.

To post a comment you must log in.
lp:~anybox/aeroo/fix-upgrade updated
38. By Georges Racinet <email address hidden>

Removed some bare excepts

This did not change the behaviour for me. But exception treatment is so
messy in aeroo that I could not see the warning in the except: block

I could see parts of the module that systematically wrap and reraise everything
as Exception

39. By Pierre Verkest

use exception message

40. By Pierre Verkest

[FIX]use Message instead message from uno exception

41. By Georges Racinet

[FIX] (temp) graceful instantiation of OOo service depended on bare except

put a big comment in check_deps indicating how a proper fix of this terrible
entanglement should look

Unmerged revisions

41. By Georges Racinet

[FIX] (temp) graceful instantiation of OOo service depended on bare except

put a big comment in check_deps indicating how a proper fix of this terrible
entanglement should look

40. By Pierre Verkest

[FIX]use Message instead message from uno exception

39. By Pierre Verkest

use exception message

38. By Georges Racinet <email address hidden>

Removed some bare excepts

This did not change the behaviour for me. But exception treatment is so
messy in aeroo that I could not see the warning in the except: block

I could see parts of the module that systematically wrap and reraise everything
as Exception

37. By Georges Racinet <email address hidden>

[FIX] made startup sequence more robust in upgrade situations

See explanations in OpenOffice_service docstring
This fixes in particular upgrades done with anybox.recipe.openerp's
standard upgrade scripts, which will act only after the database has been
loaded.

36. By fjouatte <email address hidden>

[FIX] Fix report visualization from openerp ui

35. By Mathieu Vatel - Julius Network Solutions

[FIX] - remove a cr.rollback() which leads to not computing parent_left parent_right in ir_ui_menu when OpenOfficeService is not working

34. By Mathieu Vatel - Julius Network Solutions

[IMP] simple code cleaning

33. By Mathieu Vatel - Julius Network Solutions

[FIX] - error on loading

32. By Mathieu Vatel - Julius Network Solutions

[IMP] - improve the last commit to get the last version of lp:aeroo

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'report_aeroo'
2=== renamed directory 'report_aeroo' => 'report_aeroo.moved'
3=== added file 'report_aeroo/ExtraFunctions.py'
4--- report_aeroo/ExtraFunctions.py 1970-01-01 00:00:00 +0000
5+++ report_aeroo/ExtraFunctions.py 2014-04-05 13:18:49 +0000
6@@ -0,0 +1,664 @@
7+# -*- coding: utf-8 -*-
8+##############################################################################
9+#
10+# Copyright (c) 2009-2013 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
11+# General contacts <info@alistek.com>
12+#
13+# WARNING: This program as such is intended to be used by professional
14+# programmers who take the whole responsability of assessing all potential
15+# consequences resulting from its eventual inadequacies and bugs
16+# End users who are looking for a ready-to-use solution with commercial
17+# garantees and support are strongly adviced to contract a Free Software
18+# Service Company
19+#
20+# This program is Free Software; you can redistribute it and/or
21+# modify it under the terms of the GNU General Public License
22+# as published by the Free Software Foundation; either version 3
23+# of the License, or (at your option) any later version.
24+#
25+# This module is GPLv3 or newer and incompatible
26+# with OpenERP SA "AGPL + Private Use License"!
27+#
28+# This program is distributed in the hope that it will be useful,
29+# but WITHOUT ANY WARRANTY; without even the implied warranty of
30+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31+# GNU General Public License for more details.
32+#
33+# You should have received a copy of the GNU General Public License
34+# along with this program; if not, write to the Free Software
35+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36+#
37+##############################################################################
38+
39+from .barcode import barcode
40+from openerp.tools import translate
41+#from .currency_to_text import currency_to_text
42+from .ctt_objects import supported_language
43+import logging
44+_logger = logging.getLogger(__name__)
45+import base64
46+import StringIO
47+try:
48+ from PIL import Image
49+except:
50+ _logger.warning("ERROR IMPORTING PIL, if not installed, please install it:"
51+ " get it here: https://pypi.python.org/pypi/PIL")
52+from openerp import pooler
53+import time
54+from openerp.osv import orm
55+from openerp.report import report_sxw
56+from openerp.tools.translate import _
57+from openerp import netsvc
58+from openerp.tools.safe_eval import safe_eval as eval
59+from aeroolib.plugins.opendocument import _filter
60+
61+try:
62+ from docutils.examples import html_parts # use python-docutils library
63+except ImportError, e:
64+ _logger.warning("ERROR IMPORTING docutils, if not installed, please install it:"
65+ " e.g.: apt-get install python-docutils")
66+ rest_ok = False
67+else:
68+ rest_ok = True
69+
70+try:
71+ import nltk
72+except:
73+ _logger.warning("ERROR IMPORTING nltk, if not installed, please install it:"
74+ " e.g.: apt-get install python-nltk")
75+
76+try:
77+ import markdown
78+ from markdown import Markdown # use python-markdown library
79+ from markdown.inlinepatterns import AutomailPattern
80+
81+ class AutomailPattern_mod (AutomailPattern, object):
82+ def __init__(self, *args, **kwargs):
83+ super(AutomailPattern_mod, self).__init__(*args, **kwargs)
84+
85+ def handleMatch(self, m):
86+ el = super(AutomailPattern_mod, self).handleMatch(m)
87+ href = ''.join([chr(int(a.replace(markdown.AMP_SUBSTITUTE+'#', ''))) for a in el.get('href').split(';') if a])
88+ el.set('href', href)
89+ return el
90+
91+ markdown.inlinepatterns.AutomailPattern = AutomailPattern_mod # easy hack for correct displaying in Joomla
92+
93+except ImportError, e:
94+ markdown_ok = False
95+ _logger.warning("ERROR IMPORTING markdown, if not installed, please install it:"
96+ " e.g.: apt-get install python-markdown")
97+else:
98+ markdown_ok = True
99+
100+try:
101+ from mediawiki import wiki2html # use python-mediawiki library
102+except ImportError, e:
103+ wikitext_ok = False
104+else:
105+ wikitext_ok = True
106+
107+from .domain_parser import domain2statement
108+
109+class ExtraFunctions(object):
110+ """ This class contains some extra functions which
111+ can be called from the report's template.
112+ """
113+ def __init__(self, cr, uid, report_id, context):
114+ self.cr = cr
115+ self.uid = uid
116+ self.pool = pooler.get_pool(self.cr.dbname)
117+ self.report_id = report_id
118+ self.context = context
119+ self.functions = {
120+ 'report_context': self.context,
121+ 'asarray':self._asarray,
122+ 'asimage':self._asimage,
123+ 'html_embed_image':self._embed_image,
124+ 'get_attachments':self._get_attachments,
125+ 'get_name':self._get_name,
126+ 'get_label':self._get_label,
127+ 'getLang':self._get_lang,
128+ 'get_selection_item':self._get_selection_items('item'),
129+ 'safe':self._get_safe,
130+ 'countif':self._countif,
131+ 'count':self._count,
132+ 'sumif':self._sumif,
133+ 'sum_field':self._sum,
134+ 'max_field':self._max,
135+ 'min_field':self._min,
136+ 'average':self._average,
137+ 'large':self._large,
138+ 'small':self._small,
139+ 'count_blank':self._count_blank,
140+ '_':self._translate_text,
141+ 'gettext':self._translate_text,
142+ 'currency_to_text':self._currency2text(context['company'].currency_id.name), #self._currency2text(context['company'].currency_id.code),
143+ 'barcode':barcode.make_barcode,
144+ 'debugit':self.debugit,
145+ 'dec_to_time':self._dec2time,
146+ 'chunks':self._chunks,
147+ 'browse':self._browse,
148+ 'search':self._search,
149+ 'search_ids':self._search_ids,
150+ 'field_size':self._field_size,
151+ 'field_accuracy':self._field_accuracy,
152+ 'bool_as_icon':self._bool_as_icon,
153+ 'time':time,
154+ 'report_xml': self._get_report_xml(),
155+ 'get_log': self._perm_read(self.cr, self.uid),
156+ 'get_selection_items': self._get_selection_items(),
157+ 'itemize': self._itemize,
158+ 'html_escape': self._html_escape,
159+ 'html_remove': self._html_remove,
160+ 'http_prettyuri': self._http_prettyuri,
161+ 'http_builduri': self._http_builduri,
162+ 'text_markdown': markdown_ok and self._text_markdown or \
163+ self._text_plain('"markdown" format is not supported! Need to be installed "python-markdown" package.'),
164+ 'text_restruct': rest_ok and self._text_restruct or \
165+ self._text_plain('"reStructuredText" format is not supported! Need to be installed "python-docutils" package.'),
166+ 'text_wiki': wikitext_ok and self._text_wiki or \
167+ self._text_plain('"wikimarkup" format is not supported! Need to be installed "python-mediawiki" package.'),
168+ 'text_markup': self._text_markup,
169+ '__filter': self.__filter, # Don't use in the report template!
170+ 'specific_lang': self._specific_lang,
171+ 'sort_by':self._sort_by,
172+ 'group_by':self._group_by,
173+ 'invoice_lines': self._invoice_lines,
174+ 'location_name': self._location,
175+ }
176+
177+ def __filter(self, val):
178+ if isinstance(val, orm.browse_null):
179+ return ''
180+ elif isinstance(val, orm.browse_record):
181+ return val.name_get({'lang':self._get_lang()})[0][1]
182+ return _filter(val)
183+
184+ def _perm_read(self, cr, uid):
185+ def get_log(obj, field=None):
186+ if field:
187+ return obj.perm_read(self.uid, [obj.id])[0][field]
188+ else:
189+ return obj.perm_read(self.uid, [obj.id])[0]
190+ return get_log
191+
192+ def _get_report_xml(self):
193+ return self.pool.get('ir.actions.report.xml').browse(self.cr, self.uid, self.report_id)
194+
195+ def _get_lang(self, source='current'):
196+ if source=='current':
197+ return self.context['lang'] or self.context['user_lang']
198+ elif source=='company':
199+ return self.context['user'].company_id.partner_id.lang
200+ elif source=='user':
201+ return self.context['user_lang']
202+
203+ def _bool_as_icon(self, val, kind=0):
204+ if isinstance(kind, (list, tuple)):
205+ if val==True:
206+ return kind [0]
207+ elif val==False:
208+ return kind[1]
209+ else:
210+ return kind[2]
211+ bool_kind = {0:{True:self._translate_text('True'), False:self._translate_text('False'), None:""},
212+ 1:{True:self._translate_text('T'), False:self._translate_text('F'), None:""},
213+ 2:{True:self._translate_text('Yes'), False:self._translate_text('No'), None:""},
214+ 3:{True:self._translate_text('Y'), False:self._translate_text('N'), None:""},
215+ 4:{True:'+', False:'-', None:""},
216+ 5:{True:'[ + ]', False:'[ - ]', None:"[ ]"},
217+ 6:{True:'[ x ]', False:'[ ]', None:"[ ]"},
218+ 7:{True:'x', False:'', None:""},
219+ }
220+ return bool_kind.get(kind, {}).get(val, val)
221+
222+ def _dec2time(self, dec, h_format, min_format):
223+ if dec==0.0:
224+ return None
225+ elif int(dec)==0:
226+ return min_format.replace('%M', str(int(round((dec-int(dec))*60))))
227+ elif dec-int(dec)==0.0:
228+ return h_format.replace('%H', str(int(dec)))
229+ else:
230+ return h_format.replace('%H', str(int(dec)))+min_format.replace('%M', str(int(round((dec-int(dec))*60))))
231+
232+ def _currency2text(self, currency):
233+ def c_to_text(sum, currency=currency, language=None):
234+ return unicode(supported_language.get(language or self._get_lang()).currency_to_text(sum, currency), "UTF-8")
235+ return c_to_text
236+
237+ def _translate_text(self, source):
238+ trans_obj = self.pool.get('ir.translation')
239+ trans = trans_obj.search(self.cr,self.uid,[('res_id','=',self.report_id),('type','=','report'),('src','=',source),('lang','=',self.context['lang'] or self.context['user_lang'])])
240+ if not trans:
241+ #trans_obj.create(self.cr, self.uid, {'src':source,'type':'report','lang':self._get_lang(),'res_id':self.report_id,'name':('ir.actions.report.xml,%s' % source)[:128]})
242+ trans_obj.create(self.cr, self.uid, {'src':source,'type':'report','lang':self._get_lang(),'res_id':self.report_id,'name':'ir.actions.report.xml'})
243+ return translate(self.cr, 'ir.actions.report.xml', 'report', self._get_lang(), source) or source
244+
245+ def _countif(self, attr, domain):
246+ statement = domain2statement(domain)
247+ expr = "for o in objects:\n\tif%s:\n\t\tcount+=1" % statement
248+ localspace = {'objects':attr, 'count':0}
249+ exec expr in localspace
250+ return localspace['count']
251+
252+ def _count_blank(self, attr, field):
253+ expr = "for o in objects:\n\tif not o.%s:\n\t\tcount+=1" % field
254+ localspace = {'objects':attr, 'count':0}
255+ exec expr in localspace
256+ return localspace['count']
257+
258+ def _count(self, attr):
259+ return len(attr)
260+
261+ def _sumif(self, attr, sum_field, domain):
262+ statement = domain2statement(domain)
263+ expr = "for o in objects:\n\tif%s:\n\t\tsumm+=float(o.%s)" % (statement, sum_field)
264+ localspace = {'objects':attr, 'summ':0}
265+ exec expr in localspace
266+ return localspace['summ']
267+
268+ def _sum(self, attr, sum_field):
269+ expr = "for o in objects:\n\tsumm+=float(o.%s)" % sum_field
270+ localspace = {'objects':attr, 'summ':0}
271+ exec expr in localspace
272+ return localspace['summ']
273+
274+ def _max(self, attr, field):
275+ expr = "for o in objects:\n\tvalue_list.append(o.%s)" % field
276+ localspace = {'objects':attr, 'value_list':[]}
277+ exec expr in localspace
278+ return max(localspace['value_list'])
279+
280+ def _min(self, attr, field):
281+ expr = "for o in objects:\n\tvalue_list.append(o.%s)" % field
282+ localspace = {'objects':attr, 'value_list':[]}
283+ exec expr in localspace
284+ return min(localspace['value_list'])
285+
286+ def _average(self, attr, field):
287+ expr = "for o in objects:\n\tvalue_list.append(o.%s)" % field
288+ localspace = {'objects':attr, 'value_list':[]}
289+ exec expr in localspace
290+ return float(sum(localspace['value_list']))/float(len(localspace['value_list']))
291+
292+ def _asarray(self, attr, field):
293+ expr = "for o in objects:\n\tvalue_list.append(o.%s)" % field
294+ localspace = {'objects':attr, 'value_list':[]}
295+ exec expr in localspace
296+ return localspace['value_list']
297+
298+ def _get_name(self, obj):
299+ if obj.__class__== orm.browse_record:
300+ return self.pool.get(obj._table_name).name_get(self.cr, self.uid, [obj.id], {'lang':self._get_lang()})[0][1]
301+ elif type(obj)==str: # only for fields in root record
302+ model = self.context['model']
303+ field, rec_id = obj.split(',')
304+ rec_id = int(rec_id)
305+ if rec_id:
306+ field_data = self.pool.get(model).fields_get(self.cr, self.uid, [field], context=self.context)
307+ return self.pool.get(field_data[field]['relation']).name_get(self.cr, self.uid, [rec_id], {'lang':self._get_lang()})[0][1]
308+ else:
309+ return ''
310+ return ''
311+
312+ def _get_label(self, obj, field):
313+ if not obj:
314+ return ''
315+ try:
316+ if isinstance(obj, report_sxw.browse_record_list):
317+ obj = obj[0]
318+ if isinstance(obj, (str,unicode)):
319+ model = obj
320+ else:
321+ model = obj._table_name
322+ if isinstance(obj, (str,unicode)) or hasattr(obj, field):
323+ labels = self.pool.get(model).fields_get(self.cr, self.uid, allfields=[field], context=self.context)
324+ return labels[field]['string']
325+ except Exception, e:
326+ return ''
327+
328+ def _field_size(self, obj, field):
329+ try:
330+ if isinstance(obj, report_sxw.browse_record_list):
331+ obj = obj[0]
332+ if isinstance(obj, (str,unicode)):
333+ model = obj
334+ else:
335+ model = obj._table_name
336+ if isinstance(obj, (str,unicode)) or hasattr(obj, field):
337+ size = self.pool.get(model)._columns[field].size
338+ return size
339+ except Exception, e:
340+ return ''
341+
342+ def _field_accuracy(self, obj, field):
343+ try:
344+ if isinstance(obj, report_sxw.browse_record_list):
345+ obj = obj[0]
346+ if isinstance(obj, (str,unicode)):
347+ model = obj
348+ else:
349+ model = obj._table_name
350+ if isinstance(obj, (str,unicode)) or hasattr(obj, field):
351+ digits = self.pool.get(model)._columns[field].digits
352+ return digits or [16,2]
353+ except Exception:
354+ return []
355+
356+ def _get_selection_items(self, kind='items'):
357+ def get_selection_item(obj, field, value=None):
358+ try:
359+ if isinstance(obj, report_sxw.browse_record_list):
360+ obj = obj[0]
361+ if isinstance(obj, (str,unicode)):
362+ model = obj
363+ field_val = value
364+ else:
365+ model = obj._table_name
366+ field_val = getattr(obj, field)
367+ if kind=='item':
368+ if field_val:
369+ return dict(self.pool.get(model).fields_get(self.cr, self.uid, allfields=[field], context=self.context)[field]['selection'])[field_val]
370+ elif kind=='items':
371+ return self.pool.get(model).fields_get(self.cr, self.uid, allfields=[field], context=self.context)[field]['selection']
372+ return ''
373+ except Exception:
374+ return ''
375+ return get_selection_item
376+
377+ def _get_attachments(self, o, index=None, raw=False):
378+ attach_obj = self.pool.get('ir.attachment')
379+ srch_param = [('res_model','=',o._name),('res_id','=',o.id)]
380+ if type(index)==str:
381+ srch_param.append(('name','=',index))
382+ attachments = attach_obj.search(self.cr,self.uid,srch_param)
383+ res = [x['datas'] for x in attach_obj.read(self.cr,self.uid,attachments,['datas']) if x['datas']]
384+ convert = raw and base64.decodestring or (lambda a: a)
385+ if type(index)==int:
386+ return convert(res[index])
387+ return convert(len(res)==1 and res[0] or res)
388+
389+ def _asimage(self, field_value, rotate=None, size_x=None, size_y=None, uom='px', hold_ratio=False):
390+ def size_by_uom(val, uom, dpi):
391+ if uom=='px':
392+ result=str(val/dpi)+'in'
393+ elif uom=='cm':
394+ result=str(val/2.54)+'in'
395+ elif uom=='in':
396+ result=str(val)+'in'
397+ return result
398+ ##############################################
399+ if not field_value:
400+ return StringIO.StringIO(), 'image/png'
401+ field_value = base64.decodestring(field_value)
402+ tf = StringIO.StringIO(field_value)
403+ tf.seek(0)
404+ try:
405+ im=Image.open(tf)
406+ format = im.format.lower()
407+ dpi_x, dpi_y = map(float, im.info.get('dpi', (96, 96)))
408+ except Exception, e:
409+ raise orm.except_orm('Error', e)
410+ try:
411+ if rotate!=None:
412+ im=im.rotate(int(rotate))
413+ tf.seek(0)
414+ im.save(tf, format)
415+ except Exception, e:
416+ raise orm.except_orm('Error', e)
417+
418+ if hold_ratio:
419+ img_ratio = im.size[0] / float(im.size[1]) # width / height
420+ if size_x and not size_y:
421+ size_y = size_x / img_ratio
422+ elif not size_x and size_y:
423+ size_x = size_y * img_ratio
424+ elif size_x and size_y:
425+ size_y2 = size_x / img_ratio
426+ size_x2 = size_y * img_ratio
427+ if size_y2 > size_y:
428+ size_x = size_x2
429+ elif size_x2 > size_x:
430+ size_y = size_y2
431+
432+ size_x = size_x and size_by_uom(size_x, uom, dpi_x) or str(im.size[0]/dpi_x)+'in'
433+ size_y = size_y and size_by_uom(size_y, uom, dpi_y) or str(im.size[1]/dpi_y)+'in'
434+ return tf, 'image/%s' % format, size_x, size_y
435+
436+ def _embed_image(self, extention, img, width=0, height=0, raw=False):
437+ "Transform a DB image into an embeded HTML image"
438+ if not img:
439+ return ''
440+ try:
441+ if width :
442+ width = ' width="%spx"'%(width)
443+ else :
444+ width = ''
445+ if height :
446+ height = 'height="%spx" '%(height)
447+ else :
448+ height = ''
449+ if raw:
450+ toreturn = 'data:image/%s;base64,%s' % (extention, ''.join(str(img).splitlines()))
451+ else:
452+ toreturn = '<img%s %ssrc="data:image/%s;base64,%s">' % (width, height, extention, str(img))
453+ return toreturn
454+ except Exception, exp:
455+ return 'No image'
456+
457+ def _large(self, attr, field, n):
458+ array=self._asarray(attr, field)
459+ try:
460+ n-=1
461+ while(n):
462+ array.remove(max(array))
463+ n-=1
464+ return max(array)
465+ except ValueError, e:
466+ return None
467+
468+ def _small(self, attr, field, n):
469+ array=self._asarray(attr, field)
470+ try:
471+ n-=1
472+ while(n):
473+ array.remove(min(array))
474+ n-=1
475+ return min(array)
476+ except ValueError, e:
477+ return None
478+
479+ def _chunks(self, l, n):
480+ """ Yield successive n-sized chunks from l.
481+ """
482+ for i in xrange(0, len(l), n):
483+ yield l[i:i+n]
484+
485+ def _search_ids(self, model, domain):
486+ obj = self.pool.get(model)
487+ return obj.search(self.cr, self.uid, domain)
488+
489+ def _search(self, model, domain, context=None):
490+ obj = self.pool.get(model)
491+ ids = obj.search(self.cr, self.uid, domain)
492+ if context is None:
493+ context = {}
494+ context['lang'] = self._get_lang()
495+ return obj.browse(self.cr, self.uid, ids, context=context)
496+
497+ def _browse(self, *args):
498+ if not args or (args and not args[0]):
499+ return None
500+ if len(args)==1:
501+ model, id = args[0].split(',')
502+ id = int(id)
503+ elif len(args)==2:
504+ model, id = args
505+ else:
506+ raise None
507+ return self.pool.get(model).browse(self.cr, self.uid, id)
508+
509+ def _get_safe(self, expression, obj):
510+ try:
511+ return eval(expression, {'o':obj})
512+ except Exception, e:
513+ return None
514+
515+ def debugit(self, object):
516+ """ Run the server from command line and
517+ call 'debugit' from the template to inspect variables.
518+ """
519+ import pdb;pdb.set_trace()
520+ return
521+
522+ def _itemize(self, array, purefalse = False, base_num = 1):
523+ it = iter(array)
524+ falseval = purefalse and False or ''
525+ e = it.next()
526+ lind = 0
527+ while True:
528+ lind += 1
529+ is_even = lind%2 == 0 or falseval
530+ is_odd = not is_even or falseval
531+ is_first = lind == 1 or falseval
532+ try:
533+ nxt = it.next()
534+ yield (lind-1, lind+base_num-1, e, is_even, is_odd, is_first, falseval)
535+ e = nxt
536+ except StopIteration:
537+ yield (lind-1, lind+base_num-1, e, is_even, is_odd, is_first, True)
538+ break
539+
540+ def _html_escape(self, s):
541+ toesc={ '<': '&lt;',
542+ '>': '&gt;',
543+ '&': '&amp;',
544+ '"': '&quot;',
545+ "'": '&apos;' }
546+
547+ if type(s) is str:
548+ s.decode()
549+ try:
550+ return ''.join(map(lambda a: toesc.get(a, a), s))
551+ except TypeError:
552+ return s
553+
554+ def _html_remove(self, s):
555+ def replace_specifics(s):
556+ list_to_change = {
557+ '&lt;': '<',
558+ '&gt;': '>',
559+ '&amp;': '&' ,
560+ '&quot;': '"',
561+ '&apos;': "'"
562+ }
563+ for key1 in list_to_change.keys():
564+ s = s.replace(key1, list_to_change[key1])
565+ return s
566+ try:
567+ return replace_specifics(nltk.clean_html(s))
568+ except Exception, e:
569+ raise orm.except_orm('Error', e)
570+
571+ def _http_prettyuri(self, s):
572+ def do_filter(c):
573+ # filter out reserved and "unsafe" characters
574+ pos = '''<>$&+,/\:;=?@'"#%{}|^~[]()`'''.find(c)
575+ if pos >= 0: return False
576+
577+ # filter out ASCII Control characters and unhandled Non-ASCII characters
578+ ordc = ord(c)
579+ if (ordc >= 0 and ordc <= 31) or (ordc >= 127 and ordc <= 255): return False
580+ return c
581+
582+ if type(s) is str: s.decode()
583+ # tranlate specific latvian characters into latin and whitespace into dash
584+ tt = dict(zip(map(ord, 'āčēģīķļņōŗšūžĀČĒĢĪĶĻŅŌŖŠŪŽ '.decode()), 'acegiklnorsuzACEGIKLNORSUZ-'.decode()))
585+ try:
586+ s = s.translate(tt)
587+ return (filter(do_filter, s)).lower()
588+ except TypeError:
589+ return s
590+
591+ def _http_builduri(self, *dicts):
592+ d = {}
593+ for ind in dicts:
594+ d.update(ind)
595+ result = ''
596+ for pair in d.iteritems():
597+ result += '&%s=%s' % pair
598+ return result
599+
600+ def _text_restruct(self, text):
601+ output = html_parts(unicode(text), doctitle=False)
602+ return output['body']
603+
604+ def _text_markdown(self, text):
605+ md = Markdown()
606+ return md.convert(text)
607+
608+ def _text_wiki(self, text):
609+ return wiki2html(text, True)
610+
611+ def _text_plain(self, msg):
612+ def text_plain(text):
613+ _logger.info(msg)
614+ return text
615+ return text_plain
616+
617+ def _text_markup(self, text):
618+ lines = text.splitlines()
619+ first_line = lines.pop(0)
620+ if first_line=='text/x-markdown':
621+ return self._text_markdown('\n'.join(lines))
622+ elif first_line=='text/x-wiki':
623+ return self._text_wiki('\n'.join(lines))
624+ elif first_line=='text/x-rst':
625+ return self._text_rest('\n'.join(lines))
626+ return text
627+
628+ def _specific_lang(self, model, id, lang=False):
629+ context = self.context
630+ context['lang'] = lang or self._get_lang()
631+ obj = self.pool.get(model)
632+ return obj.browse(self.cr, self.uid, id, context=context)
633+
634+ def _invoice_lines(self, lines):
635+ result = []
636+ res = {}
637+ for entry in lines:
638+ flag = False
639+ for res in result:
640+ if entry.product_id == res.product_id and entry.price_unit == res.price_unit \
641+ and entry.invoice_line_tax_id == res.invoice_line_tax_id and entry.discount == res.discount:
642+ res.quantity += entry.quantity
643+ res.price_subtotal += entry.price_subtotal
644+ flag = True
645+ if flag == False:
646+ result.append(entry)
647+ return result
648+
649+ def _location(self):
650+ if self.context is None:
651+ self.context = {}
652+ location_name = ''
653+ if self.context.get('location'):
654+ location_name = self.pool.get('stock.location').read(self.cr, self.uid,
655+ self.context.get('location'), ['name'], context = self.context)['name']
656+ return location_name
657+
658+ def _sort_by(self, attr, field):
659+ expr = "for o in objects:\n\tdict_vals[o] = o.%s or ''" % field
660+ localspace = {'objects':attr, 'dict_vals':{}}
661+ exec expr in localspace
662+ return [o for o, val in sorted(localspace['dict_vals'].items(), key=lambda x: x[1])]
663+
664+ def _group_by(self, attr, field):
665+ expr = "for o in objects:\n\tdict_vals.setdefault(o.%s or '', [])\n\tdict_vals[o.%s or ''].append(o)" % (field, field)
666+ localspace = {'objects':attr, 'dict_vals':{}}
667+ exec expr in localspace
668+ return sorted(localspace['dict_vals'].items(), key=lambda x: x[0])
669+
670+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
671
672=== added file 'report_aeroo/__init__.py'
673--- report_aeroo/__init__.py 1970-01-01 00:00:00 +0000
674+++ report_aeroo/__init__.py 2014-04-05 13:18:49 +0000
675@@ -0,0 +1,52 @@
676+# -*- coding: utf-8 -*-
677+##############################################################################
678+#
679+# Copyright (c) 2009-2012 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
680+# General contacts <info@alistek.com>
681+#
682+# WARNING: This program as such is intended to be used by professional
683+# programmers who take the whole responsability of assessing all potential
684+# consequences resulting from its eventual inadequacies and bugs
685+# End users who are looking for a ready-to-use solution with commercial
686+# garantees and support are strongly adviced to contract a Free Software
687+# Service Company
688+#
689+# This program is Free Software; you can redistribute it and/or
690+# modify it under the terms of the GNU General Public License
691+# as published by the Free Software Foundation; either version 3
692+# of the License, or (at your option) any later version.
693+#
694+# This module is GPLv3 or newer and incompatible
695+# with OpenERP SA "AGPL + Private Use License"!
696+#
697+# This program is distributed in the hope that it will be useful,
698+# but WITHOUT ANY WARRANTY; without even the implied warranty of
699+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
700+# GNU General Public License for more details.
701+#
702+# You should have received a copy of the GNU General Public License
703+# along with this program; if not, write to the Free Software
704+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
705+#
706+##############################################################################
707+
708+import aeroolib
709+from genshi.template import NewTextTemplate
710+
711+check_list = [
712+ 'import aeroolib',
713+ 'import genshi',
714+ 'from genshi.template import NewTextTemplate',
715+ 'from xml.dom import minidom',
716+]
717+
718+from check_deps import check_deps
719+check_deps(check_list)
720+
721+import installer
722+import translate
723+import report_xml
724+import report_aeroo
725+import wizard
726+
727+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
728
729=== added file 'report_aeroo/__openerp__.py'
730--- report_aeroo/__openerp__.py 1970-01-01 00:00:00 +0000
731+++ report_aeroo/__openerp__.py 2014-04-05 13:18:49 +0000
732@@ -0,0 +1,82 @@
733+# -*- coding: utf-8 -*-
734+########################################################################
735+#
736+# Copyright (C) 2009 Domsense s.r.l.
737+# @authors: Simone Orsi
738+# Copyright (C) 2009-2013 Alistek Ltd
739+#
740+#This program is free software: you can redistribute it and/or modify
741+#it under the terms of the GNU General Public License as published by
742+#the Free Software Foundation, either version 3 of the License, or
743+#(at your option) any later version.
744+#
745+# This module is GPLv3 or newer and incompatible
746+# with OpenERP SA "AGPL + Private Use License"!
747+#
748+#This program is distributed in the hope that it will be useful,
749+#but WITHOUT ANY WARRANTY; without even the implied warranty of
750+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
751+#GNU General Public License for more details.
752+#
753+#You should have received a copy of the GNU General Public License
754+#along with this program. If not, see <http://www.gnu.org/licenses/>.
755+########################################################################
756+
757+{
758+ 'name': 'Aeroo Reports',
759+ 'version': '1.2',
760+ 'category': 'Generic Modules/Aeroo Reporting',
761+ 'description': """
762+Aeroo Reports for OpenERP is a comprehensive reporting engine based on Aeroo Library.
763+
764+Report templates can be created directly in of following formats:
765+=================================================================
766+* Open Document Format (ODF) - .odt, .ods;
767+* Other ASCII based formats, like HTML, CSV, etc.
768+
769+Output formats:
770+=================================================================
771+* Open Document Format (ODF) - .odt, .ods;
772+* Other ASCII based formats, like HTML, CSV, etc.
773+* with report_aeroo_ooo [1] module - PDF, DOC, XLS, CSV.
774+
775+Reporting engine features:
776+=================================================================
777+* Add reports from UI "on the fly";
778+* Install reports from module;
779+* Dynamic template load/unload;
780+* Extra Functions - set of functions for rapid template development;
781+* Use templates stored on filesystem, database or elsewhere;
782+* Same button - different templates;
783+* Powerful stylesheet system for ODF templates;
784+* Global or local stylesheets;
785+* Template preloading for performance concerns;
786+* User defined parsers;
787+* Report deactivation;
788+* Tunable format fallback;
789+* Add/Remove print button wizards;
790+* Test report on particular object ID, directly from Report form;
791+* Translatable reports;
792+* Translation export;
793+* Number of copies;
794+* Universal Report wizard;
795+* Override report file extension (for direct printing, etc);
796+* Separate input/output format selections;
797+
798+[1] For more information on available template -> output pairs and other features, see description of report_aeroo_ooo module.
799+
800+=> You need to install python-nltk on your machine
801+""",
802+ 'author': 'Alistek Ltd, Simone Orsi - Domsense',
803+ 'website': 'http://www.alistek.com',
804+ 'complexity': "easy",
805+ 'depends': ['base'],
806+ "init_xml" : [],
807+ 'update_xml': ["installer.xml", "report_view.xml", "data/report_aeroo_data.xml", "wizard/add_print_button_view.xml", "wizard/remove_print_button_view.xml", "security/ir.model.access.csv"],
808+ "license" : "GPL-3 or any later version",
809+ 'installable': True,
810+ 'active': False,
811+ 'application': True,
812+}
813+
814+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
815
816=== added directory 'report_aeroo/barcode'
817=== added file 'report_aeroo/barcode/EANBarCode.py'
818--- report_aeroo/barcode/EANBarCode.py 1970-01-01 00:00:00 +0000
819+++ report_aeroo/barcode/EANBarCode.py 2014-04-05 13:18:49 +0000
820@@ -0,0 +1,159 @@
821+# Copyright (c) 2009-2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
822+# General contacts <info@alistek.com>
823+
824+from openerp.tools import config, ustr
825+fontsize = 15
826+
827+"""
828+This class generate EAN bar code, it required PIL (python imaging library)
829+installed.
830+
831+If the code has not checksum (12 digits), it added automatically.
832+
833+Create bar code sample :
834+ from EANBarCode import EanBarCode
835+ bar = EanBarCode()
836+ bar.getImage("9782212110708",50,"gif")
837+
838+"""
839+
840+class EanBarCode:
841+ """ Compute the EAN bar code """
842+ def __init__(self):
843+ A = {0 : "0001101", 1 : "0011001", 2 : "0010011", 3 : "0111101", 4 : "0100011",
844+ 5 : "0110001", 6 : "0101111", 7 : "0111011", 8 : "0110111", 9 : "0001011"}
845+ B = {0 : "0100111", 1 : "0110011", 2 : "0011011", 3 : "0100001", 4 : "0011101",
846+ 5 : "0111001", 6 : "0000101", 7 : "0010001", 8 : "0001001", 9 : "0010111"}
847+ C = {0 : "1110010", 1 : "1100110", 2 : "1101100", 3 : "1000010", 4 : "1011100",
848+ 5 : "1001110", 6 : "1010000", 7 : "1000100", 8 : "1001000", 9 : "1110100"}
849+ self.groupC = C
850+
851+ self.family = {0 : (A,A,A,A,A,A), 1 : (A,A,B,A,B,B), 2 : (A,A,B,B,A,B), 3 : (A,A,B,B,B,A), 4 : (A,B,A,A,B,B),
852+ 5 : (A,B,B,A,A,B), 6 : (A,B,B,B,A,A), 7 : (A,B,A,B,A,B), 8 : (A,B,A,B,B,A), 9 : (A,B,B,A,B,A)}
853+
854+
855+ def makeCode(self, code):
856+ """ Create the binary code
857+ return a string which contains "0" for white bar, "1" for black bar, "L" for long bar """
858+
859+ # Convert code string in integer list
860+ self.EAN13 = []
861+ for digit in code:
862+ self.EAN13.append(int(digit))
863+
864+ # If the code has already a checksum
865+ if len(self.EAN13) == 13:
866+ # Verify checksum
867+ self.verifyChecksum(self.EAN13)
868+ # If the code has not yet checksum
869+ elif len(self.EAN13) == 12:
870+ # Add checksum value
871+ self.EAN13.append(self.computeChecksum(self.EAN13))
872+
873+ # Get the left codage class
874+ left = self.family[self.EAN13[0]]
875+
876+ # Add start separator
877+ strCode = 'L0L'
878+
879+ # Compute the left part of bar code
880+ for i in range(0,6):
881+ strCode += left[i][self.EAN13[i+1]]
882+
883+ # Add middle separator
884+ strCode += '0L0L0'
885+
886+ # Compute the right codage class
887+ for i in range (7,13):
888+ strCode += self.groupC[self.EAN13[i]]
889+
890+ # Add stop separator
891+ strCode += 'L0L'
892+
893+ return strCode
894+
895+
896+ def computeChecksum(self, arg):
897+ """ Compute the checksum of bar code """
898+ # UPCA/EAN13
899+ weight=[1,3]*6
900+ magic=10
901+ sum = 0
902+
903+ for i in range(12): # checksum based on first 12 digits.
904+ sum = sum + int(arg[i]) * weight[i]
905+ z = ( magic - (sum % magic) ) % magic
906+ if z < 0 or z >= magic:
907+ return None
908+ return z
909+
910+
911+ def verifyChecksum(self, bits):
912+ """ Verify the checksum """
913+ computedChecksum = self.computeChecksum(bits[:12])
914+ codeBarChecksum = bits[12]
915+
916+ if codeBarChecksum != computedChecksum:
917+ raise Exception ("Bad checksum is %s and should be %s"%(codeBarChecksum, computedChecksum))
918+
919+
920+ def getImage(self, value, height = 50, xw=1, rotate=None, extension = "PNG"):
921+ """ Get an image with PIL library
922+ value code barre value
923+ height height in pixel of the bar code
924+ extension image file extension"""
925+ from PIL import Image, ImageFont, ImageDraw
926+ import os
927+ from string import lower, upper
928+
929+ # Get the bar code list
930+ bits = self.makeCode(value)
931+
932+ # Get thee bar code with the checksum added
933+ code = ""
934+ for digit in self.EAN13:
935+ code += "%d"%digit
936+
937+ # Create a new image
938+ position = 8
939+ im = Image.new("1",(len(bits)+position,height))
940+
941+ # Load font
942+ ad = os.path.abspath(os.path.join(ustr(config['root_path']), u'addons'))
943+ mod_path_list = map(lambda m: os.path.abspath(ustr(m.strip())), config['addons_path'].split(','))
944+ mod_path_list.append(ad)
945+
946+ for mod_path in mod_path_list:
947+ font_file = mod_path+os.path.sep+ \
948+ "report_aeroo"+os.path.sep+"barcode"+os.path.sep+"FreeMonoBold.ttf"
949+ if os.path.lexists(font_file):
950+ font = ImageFont.truetype(font_file, fontsize)
951+
952+ # Create drawer
953+ draw = ImageDraw.Draw(im)
954+
955+ # Erase image
956+ draw.rectangle(((0,0),(im.size[0],im.size[1])),fill=256)
957+
958+ # Draw first part of number
959+ draw.text((0, height-9), code[0], font=font, fill=0)
960+
961+ # Draw first part of number
962+ draw.text((position+7, height-9), code[1:7], font=font, fill=0)
963+
964+ # Draw second part of number
965+ draw.text((len(bits)/2+6+position, height-9), code[7:], font=font, fill=0)
966+
967+ # Draw the bar codes
968+ for bit in range(len(bits)):
969+ # Draw normal bar
970+ if bits[bit] == '1':
971+ draw.rectangle(((bit+position,0),(bit+position,height-10)),fill=0)
972+ # Draw long bar
973+ elif bits[bit] == 'L':
974+ draw.rectangle(((bit+position,0),(bit+position,height-3)),fill=0)
975+
976+ # Save the result image
977+ return im
978+
979+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
980
981=== added file 'report_aeroo/barcode/FreeMonoBold.ttf'
982Binary files report_aeroo/barcode/FreeMonoBold.ttf 1970-01-01 00:00:00 +0000 and report_aeroo/barcode/FreeMonoBold.ttf 2014-04-05 13:18:49 +0000 differ
983=== added file 'report_aeroo/barcode/__init__.py'
984--- report_aeroo/barcode/__init__.py 1970-01-01 00:00:00 +0000
985+++ report_aeroo/barcode/__init__.py 2014-04-05 13:18:49 +0000
986@@ -0,0 +1,34 @@
987+##############################################################################
988+#
989+# Copyright (c) 2008-2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
990+# General contacts <info@alistek.com>
991+#
992+# WARNING: This program as such is intended to be used by professional
993+# programmers who take the whole responsability of assessing all potential
994+# consequences resulting from its eventual inadequacies and bugs
995+# End users who are looking for a ready-to-use solution with commercial
996+# garantees and support are strongly adviced to contract a Free Software
997+# Service Company
998+#
999+# This program is Free Software; you can redistribute it and/or
1000+# modify it under the terms of the GNU General Public License
1001+# as published by the Free Software Foundation; either version 3
1002+# of the License, or (at your option) any later version.
1003+#
1004+# This module is GPLv3 or newer and incompatible
1005+# with OpenERP SA "AGPL + Private Use License"!
1006+#
1007+# This program is distributed in the hope that it will be useful,
1008+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1009+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1010+# GNU General Public License for more details.
1011+#
1012+# You should have received a copy of the GNU General Public License
1013+# along with this program; if not, write to the Free Software
1014+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1015+#
1016+##############################################################################
1017+
1018+import barcode
1019+
1020+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1021
1022=== added file 'report_aeroo/barcode/barcode.py'
1023--- report_aeroo/barcode/barcode.py 1970-01-01 00:00:00 +0000
1024+++ report_aeroo/barcode/barcode.py 2014-04-05 13:18:49 +0000
1025@@ -0,0 +1,63 @@
1026+##############################################################################
1027+#
1028+# Copyright (c) 2008-2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
1029+# General contacts <info@alistek.com>
1030+#
1031+# WARNING: This program as such is intended to be used by professional
1032+# programmers who take the whole responsability of assessing all potential
1033+# consequences resulting from its eventual inadequacies and bugs
1034+# End users who are looking for a ready-to-use solution with commercial
1035+# garantees and support are strongly adviced to contract a Free Software
1036+# Service Company
1037+#
1038+# This program is Free Software; you can redistribute it and/or
1039+# modify it under the terms of the GNU General Public License
1040+# as published by the Free Software Foundation; either version 3
1041+# of the License, or (at your option) any later version.
1042+#
1043+# This module is GPLv3 or newer and incompatible
1044+# with OpenERP SA "AGPL + Private Use License"!
1045+#
1046+# This program is distributed in the hope that it will be useful,
1047+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1048+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1049+# GNU General Public License for more details.
1050+#
1051+# You should have received a copy of the GNU General Public License
1052+# along with this program; if not, write to the Free Software
1053+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1054+#
1055+##############################################################################
1056+
1057+from .code128 import get_code
1058+from .code39 import create_c39
1059+from .EANBarCode import EanBarCode
1060+try:
1061+ from cStringIO import StringIO
1062+except ImportError:
1063+ from StringIO import StringIO
1064+
1065+def make_barcode(code, code_type='ean13', rotate=None, height=50, xw=1):
1066+ if code:
1067+ if code_type.lower()=='ean13':
1068+ bar=EanBarCode()
1069+ im = bar.getImage(code,height)
1070+ elif code_type.lower()=='code128':
1071+ im = get_code(code, xw, height)
1072+ elif code_type.lower()=='code39':
1073+ im = create_c39(height, xw, code)
1074+ else:
1075+ return StringIO(), 'image/png'
1076+
1077+ tf = StringIO()
1078+ try:
1079+ if rotate!=None:
1080+ im=im.rotate(int(rotate))
1081+ except Exception, e:
1082+ pass
1083+ im.save(tf, 'png')
1084+ size_x = str(im.size[0]/96.0)+'in'
1085+ size_y = str(im.size[1]/96.0)+'in'
1086+ return tf, 'image/png', size_x, size_y
1087+
1088+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1089
1090=== added file 'report_aeroo/barcode/code128.py'
1091--- report_aeroo/barcode/code128.py 1970-01-01 00:00:00 +0000
1092+++ report_aeroo/barcode/code128.py 2014-04-05 13:18:49 +0000
1093@@ -0,0 +1,189 @@
1094+# Copyright (c) 2009-2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
1095+# General contacts <info@alistek.com>
1096+# This list was cut'n'pasted verbatim from the "Code 128 Specification Page"
1097+# at http://www.adams1.com/pub/russadam/128code.html
1098+
1099+codelist="""0 SP SP 00 2 1 2 2 2 2
1100+1 ! ! 01 2 2 2 1 2 2
1101+2 " " 02 2 2 2 2 2 1
1102+3 # # 03 1 2 1 2 2 3
1103+4 $ $ 04 1 2 1 3 2 2
1104+5 % % 05 1 3 1 2 2 2
1105+6 & & 06 1 2 2 2 1 3
1106+7 ' ' 07 1 2 2 3 1 2
1107+8 ( ( 08 1 3 2 2 1 2
1108+9 ) ) 09 2 2 1 2 1 3
1109+10 * * 10 2 2 1 3 1 2
1110+11 + + 11 2 3 1 2 1 2
1111+12 , , 12 1 1 2 2 3 2
1112+13 - - 13 1 2 2 1 3 2
1113+14 . . 14 1 2 2 2 3 1
1114+15 / / 15 1 1 3 2 2 2
1115+16 0 0 16 1 2 3 1 2 2
1116+17 1 1 17 1 2 3 2 2 1
1117+18 2 2 18 2 2 3 2 1 1
1118+19 3 3 19 2 2 1 1 3 2
1119+20 4 4 20 2 2 1 2 3 1
1120+21 5 5 21 2 1 3 2 1 2
1121+22 6 6 22 2 2 3 1 1 2
1122+23 7 7 23 3 1 2 1 3 1
1123+24 8 8 24 3 1 1 2 2 2
1124+25 9 9 25 3 2 1 1 2 2
1125+26 : : 26 3 2 1 2 2 1
1126+27 ; ; 27 3 1 2 2 1 2
1127+28 < < 28 3 2 2 1 1 2
1128+29 = = 29 3 2 2 2 1 1
1129+30 > > 30 2 1 2 1 2 3
1130+31 ? ? 31 2 1 2 3 2 1
1131+32 @ @ 32 2 3 2 1 2 1
1132+33 A A 33 1 1 1 3 2 3
1133+34 B B 34 1 3 1 1 2 3
1134+35 C C 35 1 3 1 3 2 1
1135+36 D D 36 1 1 2 3 1 3
1136+37 E E 37 1 3 2 1 1 3
1137+38 F F 38 1 3 2 3 1 1
1138+39 G G 39 2 1 1 3 1 3
1139+40 H H 40 2 3 1 1 1 3
1140+41 I I 41 2 3 1 3 1 1
1141+42 J J 42 1 1 2 1 3 3
1142+43 K K 43 1 1 2 3 3 1
1143+44 L L 44 1 3 2 1 3 1
1144+45 M M 45 1 1 3 1 2 3
1145+46 N N 46 1 1 3 3 2 1
1146+47 O O 47 1 3 3 1 2 1
1147+48 P P 48 3 1 3 1 2 1
1148+49 Q Q 49 2 1 1 3 3 1
1149+50 R R 50 2 3 1 1 3 1
1150+51 S S 51 2 1 3 1 1 3
1151+52 T T 52 2 1 3 3 1 1
1152+53 U U 53 2 1 3 1 3 1
1153+54 V V 54 3 1 1 1 2 3
1154+55 W W 55 3 1 1 3 2 1
1155+56 X X 56 3 3 1 1 2 1
1156+57 Y Y 57 3 1 2 1 1 3
1157+58 Z Z 58 3 1 2 3 1 1
1158+59 [ [ 59 3 3 2 1 1 1
1159+60 \\ \\ 60 3 1 4 1 1 1
1160+61 ] ] 61 2 2 1 4 1 1
1161+62 ^ ^ 62 4 3 1 1 1 1
1162+63 _ _ 63 1 1 1 2 2 4
1163+64 NUL ' 64 1 1 1 4 2 2
1164+65 SOH a 65 1 2 1 1 2 4
1165+66 STX b 66 1 2 1 4 2 1
1166+67 ETX c 67 1 4 1 1 2 2
1167+68 EOT d 68 1 4 1 2 2 1
1168+69 ENQ e 69 1 1 2 2 1 4
1169+70 ACK f 70 1 1 2 4 1 2
1170+71 BEL g 61 1 2 2 1 1 4
1171+72 BS h 72 1 2 2 4 1 1
1172+73 HT i 73 1 4 2 1 1 2
1173+74 LF j 74 1 4 2 2 1 1
1174+75 VT k 75 2 4 1 2 1 1
1175+76 FF l 76 2 2 1 1 1 4
1176+77 CR m 77 4 1 3 1 1 1
1177+78 SO n 78 2 4 1 1 1 2
1178+79 SI o 79 1 3 4 1 1 1
1179+80 DLE p 80 1 1 1 2 4 2
1180+81 DC1 q 81 1 2 1 1 4 2
1181+82 DC2 r 82 1 2 1 2 4 1
1182+83 DC3 s 83 1 1 4 2 1 2
1183+84 DC4 t 84 1 2 4 1 1 2
1184+85 NAK u 85 1 2 4 2 1 1
1185+86 SYN v 86 4 1 1 2 1 2
1186+87 ETB w 87 4 2 1 1 1 2
1187+88 CAN x 88 4 2 1 2 1 1
1188+89 EM y 89 2 1 2 1 4 1
1189+90 SUB z 90 2 1 4 1 2 1
1190+91 ESC { 91 4 1 2 1 2 1
1191+92 FS | 92 1 1 1 1 4 3
1192+93 GS } 93 1 1 1 3 4 1
1193+94 RS ~ 94 1 3 1 1 4 1
1194+95 (Hex 7F) US DEL 95 1 1 4 1 1 3
1195+96 (Hex 80) FNC 3 FNC 3 96 1 1 4 3 1 1
1196+97 (Hex 81) FNC 2 FNC 2 97 4 1 1 1 1 3
1197+98 (Hex 82) SHIFT SHIFT 98 4 1 1 3 1 1
1198+99 (Hex 83) CODE C CODE C 99 1 1 3 1 4 1
1199+100 (Hex 84) CODE B FNC 4 CODE B 1 1 4 1 3 1
1200+101 (Hex 85) FNC 4 CODE A CODE A 3 1 1 1 4 1
1201+102 (Hex 86) FNC 1 FNC 1 FNC 1 4 1 1 1 3 1"""
1202+
1203+
1204+
1205+
1206+other="""103 (Hex 87) START (Code A) 2 1 1 4 1 2
1207+104 (Hex 88) START (Code B) 2 1 1 2 1 4
1208+105 (Hex 89) START (Code C) 2 1 1 2 3 2
1209+106 STOP 2 3 3 1 1 1 2"""
1210+
1211+
1212+codes={}
1213+values={}
1214+for l in codelist.split('\n'):
1215+ l.strip()
1216+ num,a1,b1,c1,code=l.split('\t')
1217+ num=int(num.split(' ')[0])
1218+ values[num]=[int(x) for x in code.split()]
1219+ codes[b1.strip()]=num
1220+
1221+codes[' ']=codes['SP']
1222+
1223+for l in other.split('\n'):
1224+ l.strip()
1225+ num,name,code=l.split('\t')
1226+ num=int(num.split(' ')[0])
1227+ values[num]=[int(x) for x in code.split()]
1228+ codes[name.strip()]=num
1229+
1230+def encode_message(msg):
1231+ startnum=codes['START (Code B)']
1232+ message=values[startnum][:]
1233+ chksum=startnum
1234+ mult=1
1235+ for c in msg:
1236+ if not codes.has_key(c):
1237+ raise "No code for "+c
1238+ chksum=chksum+mult*codes[c]
1239+ mult=mult+1
1240+ message=message+values[codes[c]]
1241+
1242+ chksum=chksum%103
1243+
1244+ message=message+values[chksum]
1245+ message=message+values[codes['STOP']]
1246+
1247+ return message
1248+
1249+
1250+import os
1251+try:
1252+ from PIL import Image
1253+except:
1254+ _logger.warning("ERROR IMPORTING PIL, if not installed, please install it:"
1255+ " get it here: https://pypi.python.org/pypi/PIL")
1256+def get_code(message,xw=1,h=100,rotate=None):
1257+ """ message is message to code.
1258+ xw is horizontal multiplier (in pixels width of narrowest bar)
1259+ h is height in pixels.
1260+
1261+ Returns a Python Imaging Library object."""
1262+
1263+ widths=[xw*20]+encode_message(message)+[xw*20]
1264+
1265+ bits=[]
1266+ i=1
1267+ for w in widths:
1268+ bits=bits+[i]*w*xw
1269+ i=1-i
1270+
1271+ #print len(bits)
1272+ #print bits
1273+
1274+ i=Image.new('1',(len(bits),h),1)
1275+
1276+ for b in range(len(bits)):
1277+ for y in range(h):
1278+ i.putpixel((b,y),255*bits[b])
1279+
1280+ return i
1281+
1282+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1283
1284=== added file 'report_aeroo/barcode/code39.py'
1285--- report_aeroo/barcode/code39.py 1970-01-01 00:00:00 +0000
1286+++ report_aeroo/barcode/code39.py 2014-04-05 13:18:49 +0000
1287@@ -0,0 +1,166 @@
1288+# Copyright (c) 2008 marscel.wordpress.com
1289+#
1290+# Copyright (c) 2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
1291+# General contacts <info@alistek.com>
1292+
1293+# Code39.py v1
1294+# Requires Python and Python Imaging Library (PIL),
1295+# has been tested with Python v2.6 and PIL v1.1.6
1296+
1297+# Usage example:
1298+# code39.py 100 2 "Hello World" barcode.png
1299+#
1300+# This creates a PNG image "barcode.png" containing a barcode of the height of 100px
1301+# a min line width of 2px with "Hello World" encoded as "*HELLO WORLD*" in Code 39
1302+try:
1303+ from PIL import Image, ImageDraw, ImageFont
1304+except:
1305+ _logger.warning("ERROR IMPORTING PIL, if not installed, please install it:"
1306+ " get it here: https://pypi.python.org/pypi/PIL")
1307+from openerp.tools import config, ustr
1308+import os, sys
1309+
1310+marginx = 10
1311+marginy = 10
1312+fontsize = 15
1313+
1314+charmap = {
1315+'*':[0,3,0,1,2,1,2,1,0],
1316+'-':[0,3,0,1,0,1,2,1,2],
1317+'$':[0,3,0,3,0,3,0,1,0],
1318+'%':[0,1,0,3,0,3,0,3,0],
1319+' ':[0,3,2,1,0,1,2,1,0],
1320+'.':[2,3,0,1,0,1,2,1,0],
1321+'/':[0,3,0,3,0,1,0,3,0],
1322+'+':[0,3,0,1,0,3,0,3,0],
1323+'0':[0,1,0,3,2,1,2,1,0],
1324+'1':[2,1,0,3,0,1,0,1,2],
1325+'2':[0,1,2,3,0,1,0,1,2],
1326+'3':[2,1,2,3,0,1,0,1,0],
1327+'4':[0,1,0,3,2,1,0,1,2],
1328+'5':[2,1,0,3,2,1,0,1,0],
1329+'6':[0,1,2,3,2,1,0,1,0],
1330+'7':[0,1,0,3,0,1,2,1,2],
1331+'8':[2,1,0,3,0,1,2,1,0],
1332+'9':[0,1,2,3,0,1,2,1,0],
1333+'A':[2,1,0,1,0,3,0,1,2],
1334+'B':[0,1,2,1,0,3,0,1,2],
1335+'C':[2,1,2,1,0,3,0,1,0],
1336+'D':[0,1,0,1,2,3,0,1,2],
1337+'E':[2,1,0,1,2,3,0,1,0],
1338+'F':[0,1,2,1,2,3,0,1,0],
1339+'G':[0,1,0,1,0,3,2,1,2],
1340+'H':[2,1,0,1,0,3,2,1,0],
1341+'I':[0,1,2,1,0,3,2,1,0],
1342+'J':[0,1,0,1,2,3,2,1,0],
1343+'K':[2,1,0,1,0,1,0,3,2],
1344+'L':[0,1,2,1,0,1,0,3,2],
1345+'M':[2,1,2,1,0,1,0,3,0],
1346+'N':[0,1,0,1,2,1,0,3,2],
1347+'O':[2,1,0,1,2,1,0,3,0],
1348+'P':[0,1,2,1,2,1,0,3,0],
1349+'Q':[0,1,0,1,0,1,2,3,2],
1350+'R':[2,1,0,1,0,1,2,3,0],
1351+'S':[0,1,2,1,0,1,2,3,0],
1352+'T':[0,1,0,1,2,1,2,3,0],
1353+'U':[2,3,0,1,0,1,0,1,2],
1354+'V':[0,3,2,1,0,1,0,1,2],
1355+'W':[2,3,2,1,0,1,0,1,0],
1356+'X':[0,3,0,1,2,1,0,1,2],
1357+'Y':[2,3,0,1,2,1,0,1,0],
1358+'Z':[0,3,2,1,2,1,0,1,0]
1359+}
1360+
1361+def create_c39(height, smallest, text):
1362+ pixel_length = 0
1363+ i = 0
1364+ newtext = ""
1365+ machinetext = "*" + text + "*"
1366+ seglist = []
1367+ while i < len(machinetext):
1368+ char = machinetext[i].capitalize()
1369+ i = i + 1
1370+ try:
1371+ cmap = charmap[char]
1372+ if len(cmap) != 9:
1373+ continue
1374+
1375+ j = 0
1376+ while j < 9:
1377+ seg = int(cmap[j])
1378+
1379+ if seg == 0 or seg == 1:
1380+ pixel_length = pixel_length + smallest
1381+ seglist.append(seg)
1382+ elif seg == 2 or seg == 3:
1383+ pixel_length = pixel_length + smallest * 3
1384+ seglist.append(seg)
1385+
1386+ j = j + 1
1387+
1388+ newtext += char
1389+ except:
1390+ continue
1391+
1392+ pixel_length = pixel_length + 2*marginx + len(newtext) * smallest
1393+ pixel_height = height + 2*marginy + fontsize
1394+
1395+ barcode_img = Image.new('RGB', [pixel_length, pixel_height], "white")
1396+
1397+ if len(seglist) == 0:
1398+ return barcode_img
1399+
1400+ i = 0
1401+ draw = ImageDraw.Draw(barcode_img)
1402+ current_x = marginx
1403+
1404+ while i < len(seglist):
1405+ seg = seglist[i]
1406+ color = (255, 255, 255)
1407+ wdth = smallest
1408+
1409+ if seg == 0 or seg == 2:
1410+ color = 0
1411+ if seg == 0:
1412+ wdth = smallest
1413+ else:
1414+ wdth = smallest * 3
1415+ elif seg == 1 or seg == 3:
1416+ color = (255, 255, 255)
1417+ if seg == 1:
1418+ wdth = smallest
1419+ else:
1420+ wdth = smallest * 3
1421+
1422+ j = 1
1423+
1424+ while j <= wdth:
1425+ draw.line((current_x, marginy, current_x, marginy+height), fill=color)
1426+ current_x = current_x + 1
1427+ j = j + 1
1428+
1429+ if ((i+1) % 9) == 0:
1430+ j = 1
1431+ while j <= smallest:
1432+ draw.line((current_x, marginy, current_x, marginy+height), fill=(255,255,255))
1433+ current_x = current_x + 1
1434+ j = j + 1
1435+ i = i + 1
1436+
1437+ ad = os.path.abspath(os.path.join(ustr(config['root_path']), u'addons'))
1438+ mod_path_list = map(lambda m: os.path.abspath(ustr(m.strip())), config['addons_path'].split(','))
1439+ mod_path_list.append(ad)
1440+
1441+ for mod_path in mod_path_list:
1442+ font_file = mod_path+os.path.sep+ \
1443+ "report_aeroo"+os.path.sep+"barcode"+os.path.sep+"FreeMonoBold.ttf"
1444+ if os.path.lexists(font_file):
1445+ font = ImageFont.truetype(font_file, fontsize)
1446+
1447+ draw.text((pixel_length/2 - len(newtext)*(fontsize/2)/2-len(newtext), height+fontsize), newtext, font=font, fill=0)
1448+
1449+ del draw
1450+
1451+ return barcode_img
1452+
1453+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1454
1455=== added file 'report_aeroo/barcode/courB08.pbm'
1456Binary files report_aeroo/barcode/courB08.pbm 1970-01-01 00:00:00 +0000 and report_aeroo/barcode/courB08.pbm 2014-04-05 13:18:49 +0000 differ
1457=== added file 'report_aeroo/barcode/courB08.pil'
1458Binary files report_aeroo/barcode/courB08.pil 1970-01-01 00:00:00 +0000 and report_aeroo/barcode/courB08.pil 2014-04-05 13:18:49 +0000 differ
1459=== added file 'report_aeroo/check_deps.py'
1460--- report_aeroo/check_deps.py 1970-01-01 00:00:00 +0000
1461+++ report_aeroo/check_deps.py 2014-04-05 13:18:49 +0000
1462@@ -0,0 +1,52 @@
1463+# -*- encoding: utf-8 -*-
1464+##############################################################################
1465+#
1466+# Copyright (c) 2009-2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
1467+# General contacts <info@alistek.com>
1468+#
1469+# WARNING: This program as such is intended to be used by professional
1470+# programmers who take the whole responsability of assessing all potential
1471+# consequences resulting from its eventual inadequacies and bugs
1472+# End users who are looking for a ready-to-use solution with commercial
1473+# garantees and support are strongly adviced to contract a Free Software
1474+# Service Company
1475+#
1476+# This program is Free Software; you can redistribute it and/or
1477+# modify it under the terms of the GNU General Public License
1478+# as published by the Free Software Foundation; either version 3
1479+# of the License, or (at your option) any later version.
1480+#
1481+# This module is GPLv3 or newer and incompatible
1482+# with OpenERP SA "AGPL + Private Use License"!
1483+#
1484+# This program is distributed in the hope that it will be useful,
1485+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1486+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1487+# GNU General Public License for more details.
1488+#
1489+# You should have received a copy of the GNU General Public License
1490+# along with this program; if not, write to the Free Software
1491+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1492+#
1493+##############################################################################
1494+
1495+from openerp.osv import orm
1496+from openerp.tools.translate import _
1497+
1498+__all__ = [
1499+ 'check_deps',
1500+]
1501+
1502+def check_deps(check_list):
1503+ error = False
1504+ import_errors = []
1505+ for imp in check_list:
1506+ try:
1507+ exec imp in {}
1508+ except ImportError,e:
1509+ error = True
1510+ import_errors.append(str(e))
1511+ if error:
1512+ raise orm.except_orm(_('Warning!')+' '+_('Unmet python dependencies!'), '\n'.join(import_errors))
1513+
1514+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1515
1516=== added directory 'report_aeroo/config_pixmaps'
1517=== added file 'report_aeroo/config_pixmaps/module_banner.png'
1518Binary files report_aeroo/config_pixmaps/module_banner.png 1970-01-01 00:00:00 +0000 and report_aeroo/config_pixmaps/module_banner.png 2014-04-05 13:18:49 +0000 differ
1519=== added directory 'report_aeroo/ctt_languages'
1520=== added file 'report_aeroo/ctt_languages/__init__.py'
1521--- report_aeroo/ctt_languages/__init__.py 1970-01-01 00:00:00 +0000
1522+++ report_aeroo/ctt_languages/__init__.py 2014-04-05 13:18:49 +0000
1523@@ -0,0 +1,3 @@
1524+#!/usr/bin/python
1525+# -*- coding: utf8 -*-
1526+# Please do not edit this file!
1527
1528=== added directory 'report_aeroo/ctt_languages/en_US'
1529=== added file 'report_aeroo/ctt_languages/en_US/__init__.py'
1530--- report_aeroo/ctt_languages/en_US/__init__.py 1970-01-01 00:00:00 +0000
1531+++ report_aeroo/ctt_languages/en_US/__init__.py 2014-04-05 13:18:49 +0000
1532@@ -0,0 +1,91 @@
1533+#!/usr/bin/python
1534+# -*- coding: utf8 -*-
1535+# en_US
1536+
1537+from report_aeroo.ctt_objects import ctt_language
1538+
1539+class en_US(ctt_language):
1540+ def _init_lang(self):
1541+ # language name
1542+ self.name = 'en_US'
1543+ # digits - masculine, singular
1544+ self.digits_sng_msc = [u'zero', u'one', u'two', u'three', u'four',
1545+ u'five', u'six', u'seven', u'eight', u'nine']
1546+ # tens - masculine, singular
1547+ self.tens_sng_msc = [u'', u'one', u'twen', u'thir', u'four', u'fif',
1548+ u'six', u'seven', u'eigh', u'nine']
1549+ # teens - masculine
1550+ self.teens = [u'ten', u'eleven', u'twelve', u'thirteen', u'fourteen',
1551+ u'fifteen', u'sixteen', u'seventeen', u'eighteen',
1552+ u'nineteen']
1553+ # multiplier - masculine, singular
1554+ self.multi_sng_msc = [u' hundred', u' thousand', u' million',
1555+ u' billion']
1556+ # multiplier - masculine, plural
1557+ self.multi_plr_msc = [u' hundreds', u' thousands', u' millions',
1558+ u' billions']
1559+
1560+ # next line is needed for correct loading of currencies
1561+ import currencies
1562+ return currencies
1563+
1564+
1565+ def wordify(self, chunk, chunknr, gender):
1566+ if gender == 'm':
1567+ number = self.digits_sng_msc
1568+ elif gender == 'f':
1569+ number = self.digits_sng_fem
1570+ elif gender == 'n':
1571+ number = self.digits_sng_neu
1572+ words = u''
1573+ digit1 = u''
1574+ digit2 = u''
1575+ digit3 = u''
1576+ chunklength = len(chunk)
1577+ # placing digits in right places
1578+ if chunklength == 1:
1579+ digit3 = chunk[0 : 1]
1580+ if chunklength == 2:
1581+ digit2 = chunk[0 : 1]
1582+ digit3 = chunk[1 : 2]
1583+ if chunklength == 3:
1584+ digit1 = chunk[0 : 1]
1585+ digit2 = chunk[1 : 2]
1586+ digit3 = chunk[-1]
1587+ # processing zero
1588+ if chunklength == 1 and digit3 == '0' :
1589+ return number[0]
1590+ # processing hundreds
1591+ if chunklength == 3 :
1592+ if digit1 == '1' :
1593+ words += self.digits_sng_msc[int(digit1)] + self.multi_sng_msc[0]
1594+ else :
1595+ if int(digit1) >= 1 : words += self.digits_sng_msc[int(digit1)] + self.multi_plr_msc[0]
1596+ # processing tens
1597+ if chunklength > 1:
1598+ spacer = ''
1599+ if len(words) > 0 : spacer = u' '
1600+ if digit2 == '1':
1601+ words += spacer + self.teens[int(digit3)]
1602+ else:
1603+ if int(digit2) > 1 and int(digit2) > 0:
1604+ words += spacer + self.tens_sng_msc[int(digit2)] + u'ty'
1605+
1606+ # processing ones
1607+ if chunklength > 0 and digit2 != '1' :
1608+ spacer = ''
1609+ if len(words) > 0: spacer = u' '
1610+ if int(digit3) > 0:
1611+ words += spacer + number[int(digit3)]
1612+ # end processing
1613+ if len(words) > 0 :
1614+ if digit3 == '1' and chunknr > 0:
1615+ return words + self.multi_sng_msc[chunknr]
1616+ elif digit3 != '1' and chunknr > 0:
1617+ return words + self.multi_sng_msc[chunknr]
1618+ else:
1619+ return words
1620+ else:
1621+ return ''
1622+
1623+en_US()
1624
1625=== added directory 'report_aeroo/ctt_languages/en_US/currencies'
1626=== added file 'report_aeroo/ctt_languages/en_US/currencies/__init__.py'
1627--- report_aeroo/ctt_languages/en_US/currencies/__init__.py 1970-01-01 00:00:00 +0000
1628+++ report_aeroo/ctt_languages/en_US/currencies/__init__.py 2014-04-05 13:18:49 +0000
1629@@ -0,0 +1,3 @@
1630+#!/usr/bin/python
1631+# -*- coding: utf8 -*-
1632+# Please do not edit this file!
1633
1634=== added file 'report_aeroo/ctt_languages/en_US/currencies/eur.py'
1635--- report_aeroo/ctt_languages/en_US/currencies/eur.py 1970-01-01 00:00:00 +0000
1636+++ report_aeroo/ctt_languages/en_US/currencies/eur.py 2014-04-05 13:18:49 +0000
1637@@ -0,0 +1,19 @@
1638+#!/usr/bin/python
1639+# -*- coding: utf8 -*-
1640+
1641+from report_aeroo.ctt_objects import ctt_currency
1642+
1643+class eur(ctt_currency):
1644+ def _init_currency(self):
1645+ self.language = u'en_US'
1646+ self.code = u'EUR'
1647+ self.fractions = 100
1648+ self.cur_singular = u' euro'
1649+ self.cur_plural = u' euro'
1650+ self.frc_singular = u' cent'
1651+ self.frc_plural = u' cents'
1652+ # grammatical genders: f - feminine, m - masculine, n -neuter
1653+ self.cur_gram_gender = 'm'
1654+ self.frc_gram_gender = 'm'
1655+
1656+eur()
1657
1658=== added file 'report_aeroo/ctt_languages/en_US/currencies/ltl.py'
1659--- report_aeroo/ctt_languages/en_US/currencies/ltl.py 1970-01-01 00:00:00 +0000
1660+++ report_aeroo/ctt_languages/en_US/currencies/ltl.py 2014-04-05 13:18:49 +0000
1661@@ -0,0 +1,19 @@
1662+#!/usr/bin/python
1663+# -*- coding: utf8 -*-
1664+
1665+from report_aeroo.ctt_objects import ctt_currency
1666+
1667+class ltl(ctt_currency):
1668+ def _init_currency(self):
1669+ self.language = u'en_US'
1670+ self.code = u'LTL'
1671+ self.fractions = 100
1672+ self.cur_singular = u' Lithuanian litas'
1673+ self.cur_plural = u' Lithuanian litas'
1674+ self.frc_singular = u' cent'
1675+ self.frc_plural = u' cents'
1676+ # grammatical genders: f - feminine, m - masculine, n -neuter
1677+ self.cur_gram_gender = 'm'
1678+ self.frc_gram_gender = 'm'
1679+
1680+ltl()
1681
1682=== added file 'report_aeroo/ctt_languages/en_US/currencies/lvl.py'
1683--- report_aeroo/ctt_languages/en_US/currencies/lvl.py 1970-01-01 00:00:00 +0000
1684+++ report_aeroo/ctt_languages/en_US/currencies/lvl.py 2014-04-05 13:18:49 +0000
1685@@ -0,0 +1,19 @@
1686+#!/usr/bin/python
1687+# -*- coding: utf8 -*-
1688+
1689+from report_aeroo.ctt_objects import ctt_currency
1690+
1691+class lvl(ctt_currency):
1692+ def _init_currency(self):
1693+ self.language = u'en_US'
1694+ self.code = u'LVL'
1695+ self.fractions = 100
1696+ self.cur_singular = u' lat'
1697+ self.cur_plural = u' lats'
1698+ self.frc_singular = u' santim'
1699+ self.frc_plural = u' santims'
1700+ # grammatical genders: f - feminine, m - masculine, n -neuter
1701+ self.cur_gram_gender = 'm'
1702+ self.frc_gram_gender = 'm'
1703+
1704+lvl()
1705
1706=== added file 'report_aeroo/ctt_languages/en_US/currencies/mxn.py'
1707--- report_aeroo/ctt_languages/en_US/currencies/mxn.py 1970-01-01 00:00:00 +0000
1708+++ report_aeroo/ctt_languages/en_US/currencies/mxn.py 2014-04-05 13:18:49 +0000
1709@@ -0,0 +1,19 @@
1710+#!/usr/bin/python
1711+# -*- coding: utf8 -*-
1712+
1713+from report_aeroo.ctt_objects import ctt_currency
1714+
1715+class mxn(ctt_currency):
1716+ def _init_currency(self):
1717+ self.language = u'en_US'
1718+ self.code = u'MXN'
1719+ self.fractions = 100
1720+ self.cur_singular = u' Mexican peso'
1721+ self.cur_plural = u' Mexican pesos'
1722+ self.frc_singular = u' cent'
1723+ self.frc_plural = u' cents'
1724+ # grammatical genders: f - feminine, m - masculine, n -neuter
1725+ self.cur_gram_gender = 'm'
1726+ self.frc_gram_gender = 'm'
1727+
1728+mxn()
1729
1730=== added file 'report_aeroo/ctt_languages/en_US/currencies/trl.py'
1731--- report_aeroo/ctt_languages/en_US/currencies/trl.py 1970-01-01 00:00:00 +0000
1732+++ report_aeroo/ctt_languages/en_US/currencies/trl.py 2014-04-05 13:18:49 +0000
1733@@ -0,0 +1,19 @@
1734+#!/usr/bin/python
1735+# -*- coding: utf8 -*-
1736+
1737+from report_aeroo.ctt_objects import ctt_currency
1738+
1739+class trl(ctt_currency):
1740+ def _init_currency(self):
1741+ self.language = u'en_US'
1742+ self.code = u'TRL'
1743+ self.fractions = 100
1744+ self.cur_singular = u' Turkish lira'
1745+ self.cur_plural = u' Turkish Liras'
1746+ self.frc_singular = u' kurus'
1747+ self.frc_plural = u' kuruss'
1748+ # grammatical genders: f - feminine, m - masculine, n -neuter
1749+ self.cur_gram_gender = 'm'
1750+ self.frc_gram_gender = 'm'
1751+
1752+trl()
1753
1754=== added file 'report_aeroo/ctt_languages/en_US/currencies/usd.py'
1755--- report_aeroo/ctt_languages/en_US/currencies/usd.py 1970-01-01 00:00:00 +0000
1756+++ report_aeroo/ctt_languages/en_US/currencies/usd.py 2014-04-05 13:18:49 +0000
1757@@ -0,0 +1,19 @@
1758+#!/usr/bin/python
1759+# -*- coding: utf8 -*-
1760+
1761+from report_aeroo.ctt_objects import ctt_currency
1762+
1763+class usd(ctt_currency):
1764+ def _init_currency(self):
1765+ self.language = u'en_US'
1766+ self.code = u'USD'
1767+ self.fractions = 100
1768+ self.cur_singular = u' US dollar'
1769+ self.cur_plural = u' US dollars'
1770+ self.frc_singular = u' cent'
1771+ self.frc_plural = u' cents'
1772+ # grammatical genders: f - feminine, m - masculine, n -neuter
1773+ self.cur_gram_gender = 'm'
1774+ self.frc_gram_gender = 'm'
1775+
1776+usd()
1777
1778=== added directory 'report_aeroo/ctt_languages/es_ES'
1779=== added file 'report_aeroo/ctt_languages/es_ES/__init__.py'
1780--- report_aeroo/ctt_languages/es_ES/__init__.py 1970-01-01 00:00:00 +0000
1781+++ report_aeroo/ctt_languages/es_ES/__init__.py 2014-04-05 13:18:49 +0000
1782@@ -0,0 +1,102 @@
1783+#!/usr/bin/python
1784+# -*- coding: utf8 -*-
1785+# es_ES
1786+################################################################################
1787+# Spanish language support assembled from contributions provided by:
1788+# * mechiscogo
1789+# * Christopher Ormaza - Ecuadorenlinea.net <chris.ormaza@gmail.com>, 2011
1790+################################################################################
1791+
1792+from report_aeroo.ctt_objects import ctt_language
1793+
1794+class es_ES(ctt_language):
1795+ def _init_lang(self):
1796+ # language name
1797+ self.name = 'es_ES'
1798+ # digits - masculine, singular
1799+ self.digits_sng_msc = [u'cero', u'uno', u'dos', u'tres', u'cuatro',
1800+ u'cinco', u'seis', u'siete', u'ocho', u'nueve']
1801+
1802+ # tens - masculine, singular
1803+ self.tens_sng_msc = [u'', u'', u'veint', u'treinta', u'cuarenta',
1804+ u'cincuenta', u'sesenta', u'setenta', u'ochenta',
1805+ u'noventa ']
1806+
1807+ # teens - masculine
1808+ self.teens = [u'diez', u'once', u'doce', u'trece', u'catorce',
1809+ u'quince', u'dieciséis', u'diecisiete', u'dieciocho',
1810+ u'diecinueve']
1811+
1812+ # multiplier - masculine, singular
1813+ self.multi_sng_msc = [u'cien', u' mil', u' millón', u' billón']
1814+
1815+ # multiplier - masculine, plural
1816+ self.multi_plr_msc = [u'cientos', u' mil', u' millones', u' billones']
1817+
1818+ # next line is needed for correct loading of currencies
1819+ import currencies
1820+ return currencies
1821+
1822+
1823+ def wordify(self, chunk, chunknr, gender):
1824+ if gender == 'm':
1825+ number = self.digits_sng_msc
1826+ elif gender == 'f':
1827+ number = self.digits_sng_fem
1828+ elif gender == 'n':
1829+ number = self.digits_sng_neu
1830+ words = u''
1831+ digit1 = u''
1832+ digit2 = u''
1833+ digit3 = u''
1834+ chunklength = len(chunk)
1835+ # placing digits in right places
1836+ if chunklength == 1:
1837+ digit3 = chunk[0 : 1]
1838+ if chunklength == 2:
1839+ digit2 = chunk[0 : 1]
1840+ digit3 = chunk[1 : 2]
1841+ if chunklength == 3:
1842+ digit1 = chunk[0 : 1]
1843+ digit2 = chunk[1 : 2]
1844+ digit3 = chunk[-1]
1845+ # processing zero
1846+ if chunklength == 1 and digit3 == '0' :
1847+ return number[0]
1848+ # processing hundreds
1849+ if chunklength == 3 :
1850+ if digit1 == '1' :
1851+ words += self.multi_sng_msc[0]
1852+ else :
1853+ if int(digit1) >= 1 : words += self.digits_sng_msc[int(digit1)]\
1854+ + self.multi_plr_msc[0]
1855+ # processing tens
1856+ if chunklength > 1:
1857+ spacer = ''
1858+ if len(words) > 0 : spacer = u' '
1859+ if digit2 == '1':
1860+ words += spacer + self.teens[int(digit3)]
1861+ else:
1862+ if int(digit2) > 1 and int(digit2) > 0:
1863+ words += spacer + self.tens_sng_msc[int(digit2)]
1864+ if int(digit3) > 0:
1865+ words += u' y'
1866+
1867+ # processing ones
1868+ if chunklength > 0 and digit2 != '1' :
1869+ spacer = ''
1870+ if len(words) > 0: spacer = u' '
1871+ if int(digit3) > 0:
1872+ words += spacer + number[int(digit3)]
1873+ # end processing
1874+ if len(words) > 0 :
1875+ if digit3 == '1' and chunknr > 0:
1876+ return words + self.multi_sng_msc[chunknr]
1877+ elif digit3 != '1' and chunknr > 0:
1878+ return words + self.multi_plr_msc[chunknr]
1879+ else:
1880+ return words
1881+ else:
1882+ return ''
1883+
1884+es_ES()
1885
1886=== added directory 'report_aeroo/ctt_languages/es_ES/currencies'
1887=== added file 'report_aeroo/ctt_languages/es_ES/currencies/__init__.py'
1888--- report_aeroo/ctt_languages/es_ES/currencies/__init__.py 1970-01-01 00:00:00 +0000
1889+++ report_aeroo/ctt_languages/es_ES/currencies/__init__.py 2014-04-05 13:18:49 +0000
1890@@ -0,0 +1,3 @@
1891+#!/usr/bin/python
1892+# -*- coding: utf8 -*-
1893+# Please do not edit this file!
1894
1895=== added file 'report_aeroo/ctt_languages/es_ES/currencies/eur.py'
1896--- report_aeroo/ctt_languages/es_ES/currencies/eur.py 1970-01-01 00:00:00 +0000
1897+++ report_aeroo/ctt_languages/es_ES/currencies/eur.py 2014-04-05 13:18:49 +0000
1898@@ -0,0 +1,19 @@
1899+#!/usr/bin/python
1900+# -*- coding: utf8 -*-
1901+
1902+from report_aeroo.ctt_objects import ctt_currency
1903+
1904+class eur(ctt_currency):
1905+ def _init_currency(self):
1906+ self.language = u'es_ES'
1907+ self.code = u'EUR'
1908+ self.fractions = 100
1909+ self.cur_singular = u' euro'
1910+ self.cur_plural = u' euros'
1911+ self.frc_singular = u' centavo'
1912+ self.frc_plural = u' centavos'
1913+ # grammatical genders: f - feminine, m - masculine, n -neuter
1914+ self.cur_gram_gender = 'm'
1915+ self.frc_gram_gender = 'm'
1916+
1917+eur()
1918
1919=== added file 'report_aeroo/ctt_languages/es_ES/currencies/mxn.py'
1920--- report_aeroo/ctt_languages/es_ES/currencies/mxn.py 1970-01-01 00:00:00 +0000
1921+++ report_aeroo/ctt_languages/es_ES/currencies/mxn.py 2014-04-05 13:18:49 +0000
1922@@ -0,0 +1,19 @@
1923+#!/usr/bin/python
1924+# -*- coding: utf8 -*-
1925+
1926+from report_aeroo.ctt_objects import ctt_currency
1927+
1928+class mxn(ctt_currency):
1929+ def _init_currency(self):
1930+ self.language = u'es_ES'
1931+ self.code = u'MXN'
1932+ self.fractions = 100
1933+ self.cur_singular = u' peso'
1934+ self.cur_plural = u' pesos'
1935+ self.frc_singular = u' centavo'
1936+ self.frc_plural = u' centavos'
1937+ # grammatical genders: f - feminine, m - masculine, n -neuter
1938+ self.cur_gram_gender = 'm'
1939+ self.frc_gram_gender = 'm'
1940+
1941+mxn()
1942
1943=== added file 'report_aeroo/ctt_languages/es_ES/currencies/usd.py'
1944--- report_aeroo/ctt_languages/es_ES/currencies/usd.py 1970-01-01 00:00:00 +0000
1945+++ report_aeroo/ctt_languages/es_ES/currencies/usd.py 2014-04-05 13:18:49 +0000
1946@@ -0,0 +1,19 @@
1947+#!/usr/bin/python
1948+# -*- coding: utf8 -*-
1949+
1950+from report_aeroo.ctt_objects import ctt_currency
1951+
1952+class usd(ctt_currency):
1953+ def _init_currency(self):
1954+ self.language = u'es_ES'
1955+ self.code = u'USD'
1956+ self.fractions = 100
1957+ self.cur_singular = u' dólar Américano'
1958+ self.cur_plural = u' dólares Américanos'
1959+ self.frc_singular = u' centavo'
1960+ self.frc_plural = u' centavos'
1961+ # grammatical genders: f - feminine, m - masculine, n -neuter
1962+ self.cur_gram_gender = 'm'
1963+ self.frc_gram_gender = 'm'
1964+
1965+usd()
1966
1967=== added directory 'report_aeroo/ctt_languages/lt_LT'
1968=== added file 'report_aeroo/ctt_languages/lt_LT/__init__.py'
1969--- report_aeroo/ctt_languages/lt_LT/__init__.py 1970-01-01 00:00:00 +0000
1970+++ report_aeroo/ctt_languages/lt_LT/__init__.py 2014-04-05 13:18:49 +0000
1971@@ -0,0 +1,107 @@
1972+#!/usr/bin/python
1973+# -*- coding: utf8 -*-
1974+# lt_LT
1975+################################################################################
1976+#
1977+# Lithuanian language support assembled from contributions provided by:
1978+# Paulius Sladkevičius
1979+#
1980+################################################################################
1981+
1982+from report_aeroo.ctt_objects import ctt_language
1983+
1984+class lt_LT(ctt_language):
1985+ def _init_lang(self):
1986+ self.name = 'lt_LT'
1987+ # digits - masculine, singular
1988+ self.number_sng_msc = [u'nulis', u'vienas', u'du', u'trys', u'keturi',
1989+ u'penkti', u'šeši', u'septyni', u'aštuoni',
1990+ u'devyni']
1991+ # tens - masculine, singular
1992+ self.tens_sng_msc = [u'nulis', u'vienas', u'dvi', u'tris',
1993+ u'keturias', u'penkias', u'šešias', u'septynias',
1994+ u'aštuonias', u'devynias']
1995+ # teens - masculine
1996+ self.teens = [u'dešimt', u'vienuolika', u'dvylika', u'trylika',
1997+ u'keturiolika', u'penkiolika', u'šešiolika',
1998+ u'septyniolika', u'aštuonolika', u'devyniolika']
1999+ # multiplier - masculine, singular
2000+ self.multi_sng_msc = [u' šimtas', u' tūkstantis', u' milijonas',
2001+ u' milijardas']
2002+ # multiplier - masculine, plural
2003+ self.multi_plr_msc = [u' šimtai', u' tūkstančiai', u' milijonai',
2004+ u' milijardai']
2005+ # multiplier - masculine, plural (other form)
2006+ self.multi_plr_msc_2 = [u' šimtų', u' tūkstančių', u' milijonų',
2007+ u' milijardų']
2008+
2009+ # next line is needed for correct loading of currencies
2010+ import currencies
2011+ return currencies
2012+
2013+
2014+ def wordify(self, chunk, chunknr, gender):
2015+ if gender == 'm':
2016+ number = self.number_sng_msc
2017+ elif gender == 'f':
2018+ number = self.number_sng_fem
2019+ elif gender == 'n':
2020+ number = self.number_sng_neu
2021+ words = u''
2022+ digit1 = u''
2023+ digit2 = u''
2024+ digit3 = u''
2025+ chunklength = len(chunk)
2026+ # placing digits in right places
2027+ if chunklength == 1:
2028+ digit3 = chunk[0 : 1]
2029+ if chunklength == 2:
2030+ digit2 = chunk[0 : 1]
2031+ digit3 = chunk[1 : 2]
2032+ if chunklength == 3:
2033+ digit1 = chunk[0 : 1]
2034+ digit2 = chunk[1 : 2]
2035+ digit3 = chunk[-1]
2036+ # processing zero
2037+ if chunklength == 1 and digit3 == '0' :
2038+ return number[0]
2039+ # processing hundreds
2040+ if chunklength == 3 :
2041+ if digit1 == '1' :
2042+ words += self.multi_sng_msc[0]
2043+ else :
2044+ if int(digit1) > 1 : words += number[int(digit1)] + \
2045+ self.multi_plr_msc[0]
2046+ # processing tens
2047+ if chunklength > 1:
2048+ spacer = ''
2049+ if len(words) > 0 : spacer = ' '
2050+ if digit2 == '1':
2051+ words += spacer + self.number_teens[int(digit3)]
2052+ else:
2053+ if int(digit2) > 1 and int(digit2) > 0:
2054+ words += spacer + self.tens_sng_msc[int(digit2)] + u'dešimt'
2055+
2056+ # processing ones
2057+ if chunklength > 0 and digit2 != '1' :
2058+ spacer = ''
2059+ if len(words) > 0: spacer = u' '
2060+ if int(digit3) > 0:
2061+ words += spacer + number[int(digit3)]
2062+ # end processing
2063+ if len(words) > 0 :
2064+ if digit3 == '1' and chunknr > 0:
2065+ return words + self.multi_sng_msc[chunknr]
2066+ elif digit3 != '1' and chunknr > 0:
2067+ if chunklength >= 2 and ((int(chunk) % 10) == 0 or (digit2 == \
2068+ '1' and int(digit3) > 0)):
2069+ return words + multi_plr_msc_2[chunknr]
2070+ else:
2071+ return words + multi_plr_msc[chunknr]
2072+
2073+ else:
2074+ return words
2075+ else:
2076+ return ''
2077+
2078+lt_LT()
2079
2080=== added directory 'report_aeroo/ctt_languages/lt_LT/currencies'
2081=== added file 'report_aeroo/ctt_languages/lt_LT/currencies/__init__.py'
2082--- report_aeroo/ctt_languages/lt_LT/currencies/__init__.py 1970-01-01 00:00:00 +0000
2083+++ report_aeroo/ctt_languages/lt_LT/currencies/__init__.py 2014-04-05 13:18:49 +0000
2084@@ -0,0 +1,3 @@
2085+#!/usr/bin/python
2086+# -*- coding: utf8 -*-
2087+# Please do not edit this file!
2088
2089=== added file 'report_aeroo/ctt_languages/lt_LT/currencies/eur.py'
2090--- report_aeroo/ctt_languages/lt_LT/currencies/eur.py 1970-01-01 00:00:00 +0000
2091+++ report_aeroo/ctt_languages/lt_LT/currencies/eur.py 2014-04-05 13:18:49 +0000
2092@@ -0,0 +1,25 @@
2093+#!/usr/bin/python
2094+# -*- coding: utf8 -*-
2095+
2096+from report_aeroo.ctt_objects import ctt_currency
2097+
2098+class eur(ctt_currency):
2099+ def _init_currency(self):
2100+ self.language = u'lt_LT'
2101+ self.code = u'EUR'
2102+ self.fractions = 100
2103+ self.cur_singular = u' euras'
2104+ # default plural form for currency
2105+ self.cur_plural = u' eurų'
2106+ # betwean 1 and 10 yields different plural form, if defined
2107+ self.cur_plural_2to10 = u' eurai'
2108+ self.frc_singular = u' centas'
2109+ # default plural form for fractions
2110+ self.frc_plural = u' centų'
2111+ # betwean 1 and 10 yields different plural form, if defined
2112+ self.frc_plural_2to10 = u' centai'
2113+ # grammatical genders: f - feminine, m - masculine, n -neuter
2114+ self.cur_gram_gender = 'm'
2115+ self.frc_gram_gender = 'm'
2116+
2117+eur()
2118
2119=== added file 'report_aeroo/ctt_languages/lt_LT/currencies/ltl.py'
2120--- report_aeroo/ctt_languages/lt_LT/currencies/ltl.py 1970-01-01 00:00:00 +0000
2121+++ report_aeroo/ctt_languages/lt_LT/currencies/ltl.py 2014-04-05 13:18:49 +0000
2122@@ -0,0 +1,25 @@
2123+#!/usr/bin/python
2124+# -*- coding: utf8 -*-
2125+
2126+from report_aeroo.ctt_objects import ctt_currency
2127+
2128+class ltl(ctt_currency):
2129+ def _init_currency(self):
2130+ self.language = u'lt_LT'
2131+ self.code = u'LTL'
2132+ self.fractions = 100
2133+ self.cur_singular = u' litas'
2134+ # default plural form for currency
2135+ self.cur_plural = u' litų'
2136+ # betwean 1 and 10 yields different plural form, if defined
2137+ self.cur_plural_2to10 = u' litai'
2138+ self.frc_singular = u' centas'
2139+ # default plural form for fractions
2140+ self.frc_plural = u' centų'
2141+ # betwean 1 and 10 yields different plural form, if defined
2142+ self.frc_plural_2to10 = u' centai'
2143+ # grammatical genders: f - feminine, m - masculine, n -neuter
2144+ self.cur_gram_gender = 'm'
2145+ self.frc_gram_gender = 'm'
2146+
2147+ltl()
2148
2149=== added file 'report_aeroo/ctt_languages/lt_LT/currencies/lvl.py'
2150--- report_aeroo/ctt_languages/lt_LT/currencies/lvl.py 1970-01-01 00:00:00 +0000
2151+++ report_aeroo/ctt_languages/lt_LT/currencies/lvl.py 2014-04-05 13:18:49 +0000
2152@@ -0,0 +1,25 @@
2153+#!/usr/bin/python
2154+# -*- coding: utf8 -*-
2155+
2156+from report_aeroo.ctt_objects import ctt_currency
2157+
2158+class lvl(ctt_currency):
2159+ def _init_currency(self):
2160+ self.language = u'lt_LT'
2161+ self.code = u'LVL'
2162+ self.fractions = 100
2163+ self.cur_singular = u' latas'
2164+ # default plural form for currency
2165+ self.cur_plural = u' latų'
2166+ # betwean 1 and 10 yields different plural form, if defined
2167+ self.cur_plural_2to10 = u' latai'
2168+ self.frc_singular = u' santimas'
2169+ # default plural form for fractions
2170+ self.frc_plural = u' santimų'
2171+ # betwean 1 and 10 yields different plural form, if defined
2172+ self.frc_plural_2to10 = u' santimai'
2173+ # grammatical genders: f - feminine, m - masculine, n -neuter
2174+ self.cur_gram_gender = 'm'
2175+ self.frc_gram_gender = 'm'
2176+
2177+lvl()
2178
2179=== added file 'report_aeroo/ctt_languages/lt_LT/currencies/uah.py'
2180--- report_aeroo/ctt_languages/lt_LT/currencies/uah.py 1970-01-01 00:00:00 +0000
2181+++ report_aeroo/ctt_languages/lt_LT/currencies/uah.py 2014-04-05 13:18:49 +0000
2182@@ -0,0 +1,25 @@
2183+#!/usr/bin/python
2184+# -*- coding: utf8 -*-
2185+
2186+from report_aeroo.ctt_objects import ctt_currency
2187+
2188+class uah(ctt_currency):
2189+ def _init_currency(self):
2190+ self.language = u'lt_LT'
2191+ self.code = u'UAH'
2192+ self.fractions = 100
2193+ self.cur_singular = u' grivna'
2194+ # default plural form for currency
2195+ self.cur_plural = u' grivnų'
2196+ # betwean 1 and 10 yields different plural form, if defined
2197+ self.cur_plural_2to10 = u' grivnai'
2198+ self.frc_singular = u' kapeika'
2199+ # default plural form for fractions
2200+ self.frc_plural = u' kapeikų'
2201+ # betwean 1 and 10 yields different plural form, if defined
2202+ self.frc_plural_2to10 = u' kapeikos'
2203+ # grammatical genders: f - feminine, m - masculine, n -neuter
2204+ self.cur_gram_gender = 'm'
2205+ self.frc_gram_gender = 'm'
2206+
2207+uah()
2208
2209=== added file 'report_aeroo/ctt_languages/lt_LT/currencies/usd.py'
2210--- report_aeroo/ctt_languages/lt_LT/currencies/usd.py 1970-01-01 00:00:00 +0000
2211+++ report_aeroo/ctt_languages/lt_LT/currencies/usd.py 2014-04-05 13:18:49 +0000
2212@@ -0,0 +1,25 @@
2213+#!/usr/bin/python
2214+# -*- coding: utf8 -*-
2215+
2216+from report_aeroo.ctt_objects import ctt_currency
2217+
2218+class usd(ctt_currency):
2219+ def _init_currency(self):
2220+ self.language = u'lt_LT'
2221+ self.code = u'USD'
2222+ self.fractions = 100
2223+ self.cur_singular = u' doleris'
2224+ # default plural form for currency
2225+ self.cur_plural = u' dolerių'
2226+ # betwean 1 and 10 yields different plural form, if defined
2227+ self.cur_plural_2to10 = u' doleriai'
2228+ self.frc_singular = u' centas'
2229+ # default plural form for fractions
2230+ self.frc_plural = u' centų'
2231+ # betwean 1 and 10 yields different plural form, if defined
2232+ self.frc_plural_2to10 = u' centai'
2233+ # grammatical genders: f - feminine, m - masculine, n -neuter
2234+ self.cur_gram_gender = 'm'
2235+ self.frc_gram_gender = 'm'
2236+
2237+usd()
2238
2239=== added directory 'report_aeroo/ctt_languages/lv_LV'
2240=== added file 'report_aeroo/ctt_languages/lv_LV/__init__.py'
2241--- report_aeroo/ctt_languages/lv_LV/__init__.py 1970-01-01 00:00:00 +0000
2242+++ report_aeroo/ctt_languages/lv_LV/__init__.py 2014-04-05 13:18:49 +0000
2243@@ -0,0 +1,101 @@
2244+#!/usr/bin/python
2245+# -*- coding: utf8 -*-
2246+# lv_LV
2247+
2248+from report_aeroo.ctt_objects import ctt_language
2249+
2250+class lv_LV(ctt_language):
2251+ def _init_lang(self):
2252+ self.name = 'lv_LV'
2253+ # digits - masculine, singular
2254+ self.number_sng_msc = [u'nulle', u'viens', u'divi',
2255+ u'trīs', u'četri', u'pieci',
2256+ u'seši', u'septiņi', u'astoņi',
2257+ u'deviņi']
2258+ # digits - feminine, singular
2259+ self.number_sng_fem = [u'nulle', u'viena', u'divas',
2260+ u'trīs', u'četras', u'piecas',
2261+ u'sešas', u'septiņas', u'astoņas',
2262+ u'deviņas']
2263+ # tens - masculine, singular
2264+ self.tens_sng_msc = [u'nulle', u'vien', u'div',
2265+ u'trīs', u'četr', u'piec',
2266+ u'seš', u'septiņ', u'astoņ',
2267+ u'deviņ']
2268+ # teens - masculine
2269+ self.teens = [u'desmit', u'vienpadsmit', u'divpadsmit',
2270+ u'trīspadsmit', u'četrpadsmit', u'piecpadsmit',
2271+ u'sešpadsmit', u'septiņpadsmit', u'astoņpadsmit',
2272+ u'deviņpadsmit']
2273+ # multiplier - masculine, singular
2274+ self.multi_sng_msc = [u'simts', u' tūkstotis', u' miljons',
2275+ u' miljards']
2276+ # multiplier - masculine, plural
2277+ self.multi_plr_msc = [u' simti', u' tūkstoši', u' miljoni',
2278+ u' miljardi']
2279+
2280+ # next line is needed for correct loading of currencies
2281+ import currencies
2282+ return currencies
2283+
2284+
2285+ def wordify(self, chunk, chunknr, gender):
2286+ if gender == 'm':
2287+ number = self.number_sng_msc
2288+ elif gender == 'f':
2289+ number = self.number_sng_fem
2290+ elif gender == 'n':
2291+ number = self.number_sng_neu
2292+ words = u''
2293+ digit1 = u''
2294+ digit2 = u''
2295+ digit3 = u''
2296+ chunklength = len(chunk)
2297+ # placing digits in right places
2298+ if chunklength == 1:
2299+ digit3 = chunk[0 : 1]
2300+ if chunklength == 2:
2301+ digit2 = chunk[0 : 1]
2302+ digit3 = chunk[1 : 2]
2303+ if chunklength == 3:
2304+ digit1 = chunk[0 : 1]
2305+ digit2 = chunk[1 : 2]
2306+ digit3 = chunk[-1]
2307+ # processing zero
2308+ if chunklength == 1 and digit3 == '0' :
2309+ return number[0]
2310+ # processing hundreds
2311+ if chunklength == 3 :
2312+ if digit1 == '1' :
2313+ words += self.multi_sng_msc[0]
2314+ else :
2315+ if int(digit1) > 1 : words += number[int(digit1)] + \
2316+ self.multi_plr_msc[0]
2317+ # processing tens
2318+ if chunklength > 1:
2319+ spacer = ''
2320+ if len(words) > 0 : spacer = ' '
2321+ if digit2 == '1':
2322+ words += spacer + self.teens[int(digit3)]
2323+ else:
2324+ if int(digit2) > 1 and int(digit2) > 0:
2325+ words += spacer + self.tens_sng_msc[int(digit2)] + u'desmit'
2326+
2327+ # processing ones
2328+ if chunklength > 0 and digit2 != '1' :
2329+ spacer = ''
2330+ if len(words) > 0: spacer = u' '
2331+ if int(digit3) > 0:
2332+ words += spacer + number[int(digit3)]
2333+ # end processing
2334+ if len(words) > 0 :
2335+ if digit3 == '1' and chunknr > 0:
2336+ return words + self.multi_sng_msc[chunknr]
2337+ elif digit3 != '1' and chunknr > 0:
2338+ return words + self.multi_plr_msc[chunknr]
2339+ else:
2340+ return words
2341+ else:
2342+ return ''
2343+
2344+lv_LV()
2345
2346=== added directory 'report_aeroo/ctt_languages/lv_LV/currencies'
2347=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/__init__.py'
2348--- report_aeroo/ctt_languages/lv_LV/currencies/__init__.py 1970-01-01 00:00:00 +0000
2349+++ report_aeroo/ctt_languages/lv_LV/currencies/__init__.py 2014-04-05 13:18:49 +0000
2350@@ -0,0 +1,3 @@
2351+#!/usr/bin/python
2352+# -*- coding: utf8 -*-
2353+# Please do not edit this file!
2354
2355=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/eur.py'
2356--- report_aeroo/ctt_languages/lv_LV/currencies/eur.py 1970-01-01 00:00:00 +0000
2357+++ report_aeroo/ctt_languages/lv_LV/currencies/eur.py 2014-04-05 13:18:49 +0000
2358@@ -0,0 +1,22 @@
2359+#!/usr/bin/python
2360+# -*- coding: utf8 -*-
2361+
2362+from report_aeroo.ctt_objects import ctt_currency
2363+
2364+class eur(ctt_currency):
2365+ def _init_currency(self):
2366+ self.language = u'lv_LV'
2367+ self.code = u'EUR'
2368+ self.fractions = 100
2369+ self.cur_singular = u' eiro'
2370+ self.cur_plural = u' eiro'
2371+ self.frc_singular = u' cents'
2372+ # default plural form for fractions
2373+ self.frc_plural = u' centu'
2374+ # betwean 1 and 10 yields different plural form, if defined
2375+ self.frc_plural_2to10 = u' centi'
2376+ # grammatical genders: f - feminine, m - masculine, n -neuter
2377+ self.cur_gram_gender = 'm'
2378+ self.frc_gram_gender = 'm'
2379+
2380+eur()
2381
2382=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/ltl.py'
2383--- report_aeroo/ctt_languages/lv_LV/currencies/ltl.py 1970-01-01 00:00:00 +0000
2384+++ report_aeroo/ctt_languages/lv_LV/currencies/ltl.py 2014-04-05 13:18:49 +0000
2385@@ -0,0 +1,25 @@
2386+#!/usr/bin/python
2387+# -*- coding: utf8 -*-
2388+
2389+from report_aeroo.ctt_objects import ctt_currency
2390+
2391+class ltl(ctt_currency):
2392+ def _init_currency(self):
2393+ self.language = u'lv_LV'
2394+ self.code = u'LTL'
2395+ self.fractions = 100
2396+ self.cur_singular = u' lits'
2397+ # default plural form for currency
2398+ self.cur_plural = u' litu'
2399+ # betwean 1 and 10 yields different plural form, if defined
2400+ self.cur_plural_2to10 = u' liti'
2401+ self.frc_singular = u' cents'
2402+ # default plural form for fractions
2403+ self.frc_plural = u' centu'
2404+ # betwean 1 and 10 yields different plural form, if defined
2405+ self.frc_plural_2to10 = u' centi'
2406+ # grammatical genders: f - feminine, m - masculine, n -neuter
2407+ self.cur_gram_gender = 'm'
2408+ self.frc_gram_gender = 'm'
2409+
2410+ltl()
2411
2412=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/lvl.py'
2413--- report_aeroo/ctt_languages/lv_LV/currencies/lvl.py 1970-01-01 00:00:00 +0000
2414+++ report_aeroo/ctt_languages/lv_LV/currencies/lvl.py 2014-04-05 13:18:49 +0000
2415@@ -0,0 +1,25 @@
2416+#!/usr/bin/python
2417+# -*- coding: utf8 -*-
2418+
2419+from report_aeroo.ctt_objects import ctt_currency
2420+
2421+class lvl(ctt_currency):
2422+ def _init_currency(self):
2423+ self.language = u'lv_LV'
2424+ self.code = u'LVL'
2425+ self.fractions = 100
2426+ self.cur_singular = u' lats'
2427+ # default plural form for currency
2428+ self.cur_plural = u' latu'
2429+ # betwean 1 and 10 yields different plural form, if defined
2430+ self.cur_plural_2to10 = u' lati'
2431+ self.frc_singular = u' santīms'
2432+ # default plural form for fractions
2433+ self.frc_plural = u' santīmi'
2434+ # betwean 1 and 10 yields different plural form, if defined
2435+ self.frc_plural_2to10 = u' santīmu'
2436+ # grammatical genders: f - feminine, m - masculine, n -neuter
2437+ self.cur_gram_gender = 'm'
2438+ self.frc_gram_gender = 'm'
2439+
2440+lvl()
2441
2442=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/mxn.py'
2443--- report_aeroo/ctt_languages/lv_LV/currencies/mxn.py 1970-01-01 00:00:00 +0000
2444+++ report_aeroo/ctt_languages/lv_LV/currencies/mxn.py 2014-04-05 13:18:49 +0000
2445@@ -0,0 +1,22 @@
2446+#!/usr/bin/python
2447+# -*- coding: utf8 -*-
2448+
2449+from report_aeroo.ctt_objects import ctt_currency
2450+
2451+class mxn(ctt_currency):
2452+ def _init_currency(self):
2453+ self.language = u'lv_LV'
2454+ self.code = u'MXN'
2455+ self.fractions = 100
2456+ self.cur_singular = u' Meksikas peso'
2457+ self.cur_plural = self.cur_singular
2458+ self.frc_singular = u' cents'
2459+ # default plural form for fractions
2460+ self.frc_plural = u' centu'
2461+ # betwean 1 and 10 yields different plural form, if defined
2462+ self.frc_plural_2to10 = u' centi'
2463+ # grammatical genders: f - feminine, m - masculine, n -neuter
2464+ self.cur_gram_gender = 'm'
2465+ self.frc_gram_gender = 'm'
2466+
2467+mxn()
2468
2469=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/rub.py'
2470--- report_aeroo/ctt_languages/lv_LV/currencies/rub.py 1970-01-01 00:00:00 +0000
2471+++ report_aeroo/ctt_languages/lv_LV/currencies/rub.py 2014-04-05 13:18:49 +0000
2472@@ -0,0 +1,25 @@
2473+#!/usr/bin/python
2474+# -*- coding: utf8 -*-
2475+
2476+from report_aeroo.ctt_objects import ctt_currency
2477+
2478+class rub(ctt_currency):
2479+ def _init_currency(self):
2480+ self.language = u'lv_LV'
2481+ self.code = u'RUB'
2482+ self.fractions = 100
2483+ self.cur_singular = u' rublis'
2484+ # default plural form for currency
2485+ self.cur_plural = u' rubļu'
2486+ # betwean 1 and 10 yields different plural form, if defined
2487+ self.cur_plural_2to10 = u' rubļi'
2488+ self.frc_singular = u' kapeika'
2489+ # default plural form for fractions
2490+ self.frc_plural = u' kapeiku'
2491+ # betwean 1 and 10 yields different plural form, if defined
2492+ self.frc_plural_2to10 = u' kapeikas'
2493+ # grammatical genders: f - feminine, m - masculine, n -neuter
2494+ self.cur_gram_gender = 'm'
2495+ self.frc_gram_gender = 'f'
2496+
2497+rub()
2498
2499=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/trl.py'
2500--- report_aeroo/ctt_languages/lv_LV/currencies/trl.py 1970-01-01 00:00:00 +0000
2501+++ report_aeroo/ctt_languages/lv_LV/currencies/trl.py 2014-04-05 13:18:49 +0000
2502@@ -0,0 +1,25 @@
2503+#!/usr/bin/python
2504+# -*- coding: utf8 -*-
2505+
2506+from report_aeroo.ctt_objects import ctt_currency
2507+
2508+class trl(ctt_currency):
2509+ def _init_currency(self):
2510+ self.language = u'lv_LV'
2511+ self.code = u'TRL'
2512+ self.fractions = 100
2513+ self.cur_singular = u' Turku lira'
2514+ # default plural form for currency
2515+ self.cur_plural = u' Turku liru'
2516+ # betwean 1 and 10 yields different plural form, if defined
2517+ self.cur_plural_2to10 = u' Turku liras'
2518+ self.frc_singular = u' kurušs'
2519+ # default plural form for fractions
2520+ self.frc_plural = u' kurušu'
2521+ # betwean 1 and 10 yields different plural form, if defined
2522+ self.frc_plural_2to10 = u' kuruši'
2523+ # grammatical genders: f - feminine, m - masculine, n -neuter
2524+ self.cur_gram_gender = 'f'
2525+ self.frc_gram_gender = 'm'
2526+
2527+trl()
2528
2529=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/uah.py'
2530--- report_aeroo/ctt_languages/lv_LV/currencies/uah.py 1970-01-01 00:00:00 +0000
2531+++ report_aeroo/ctt_languages/lv_LV/currencies/uah.py 2014-04-05 13:18:49 +0000
2532@@ -0,0 +1,24 @@
2533+#!/usr/bin/python
2534+# -*- coding: utf8 -*-
2535+
2536+from report_aeroo.ctt_objects import ctt_currency
2537+
2538+class uah(ctt_currency):
2539+ def _init_currency(self):
2540+ self.language = u'lv_LV'
2541+ self.code = u'UAH'
2542+ self.fractions = 100
2543+ self.cur_singular = u' grivna'
2544+ # default plural form for currency
2545+ self.cur_plural = u' grivnu'
2546+ # betwean 1 and 10 yields different plural form, if defined
2547+ self.cur_plural_2to10 = u' grivnas'
2548+ self.frc_singular = u' kapeika'
2549+ # default plural form for fractions
2550+ self.frc_plural = u' kapeiku'
2551+ # betwean 1 and 10 yields different plural form, if defined
2552+ self.frc_plural_2to10 = u' kapeikas'
2553+ # grammatical genders: f - feminine, m - masculine, n -neuter
2554+ self.cur_gram_gender = 'f'
2555+ self.frc_gram_gender = 'f'
2556+uah()
2557
2558=== added file 'report_aeroo/ctt_languages/lv_LV/currencies/usd.py'
2559--- report_aeroo/ctt_languages/lv_LV/currencies/usd.py 1970-01-01 00:00:00 +0000
2560+++ report_aeroo/ctt_languages/lv_LV/currencies/usd.py 2014-04-05 13:18:49 +0000
2561@@ -0,0 +1,25 @@
2562+#!/usr/bin/python
2563+# -*- coding: utf8 -*-
2564+
2565+from report_aeroo.ctt_objects import ctt_currency
2566+
2567+class usd(ctt_currency):
2568+ def _init_currency(self):
2569+ self.language = u'lv_LV'
2570+ self.code = u'USD'
2571+ self.fractions = 100
2572+ self.cur_singular = u' ASV dolārs'
2573+ # default plural form for currency
2574+ self.cur_plural = u' ASV dolāru'
2575+ # betwean 1 and 10 yields different plural form, if defined
2576+ self.cur_plural_2to10 = u' ASV dolāri'
2577+ self.frc_singular = u' cents'
2578+ # default plural form for fractions
2579+ self.frc_plural = u' centu'
2580+ # betwean 1 and 10 yields different plural form, if defined
2581+ self.frc_plural_2to10 = u' centi'
2582+ # grammatical genders: f - feminine, m - masculine, n -neuter
2583+ self.cur_gram_gender = 'm'
2584+ self.frc_gram_gender = 'm'
2585+
2586+usd()
2587
2588=== added directory 'report_aeroo/ctt_languages/ru_RU'
2589=== added file 'report_aeroo/ctt_languages/ru_RU/__init__.py'
2590--- report_aeroo/ctt_languages/ru_RU/__init__.py 1970-01-01 00:00:00 +0000
2591+++ report_aeroo/ctt_languages/ru_RU/__init__.py 2014-04-05 13:18:49 +0000
2592@@ -0,0 +1,110 @@
2593+#!/usr/bin/python
2594+# -*- coding: utf8 -*-
2595+# ru_RU
2596+
2597+from report_aeroo.ctt_objects import ctt_language
2598+
2599+class ru_RU(ctt_language):
2600+ def _init_lang(self):
2601+ # language name
2602+ self.name = 'ru_RU'
2603+ # digits - masculine, singular
2604+ self.number_sng_msc = [u'ноль', u'один', u'два', u'три', u'четыре',
2605+ u'пять', u'шесть', u'семь', u'восемь', u'девять']
2606+ # tens - masculine, singular
2607+ self.number_sng_fem = [u'ноль', u'одна', u'две', u'три', u'четыре',
2608+ u'пять', u'шесть', u'семь', u'восемь', u'девять']
2609+ # tens - masculine, plural
2610+ self.number_plr_msc = [u'', u'один', u'двa', u'три', u'четыре', u'пять',
2611+ u'шесть', u'семь', u'восемь', u'девять']
2612+ # teens - masculine
2613+ self.number_teens = [u'десять', u'одиннадцать', u'двенадцать',
2614+ u'тринадцать', u'четырнадцать', u'пятнадцать',
2615+ u'шестнадцать', u'семнадцать', u'восемнадцать',
2616+ u'девятнадцать']
2617+ # multiplier - masculine, singular
2618+ self.multi_sng_msc = [u'стo', u' тысяча', u' миллион', u' миллиард']
2619+ # multiplier - masculine, plural
2620+ self.multi_plr_msc = [u'сoт', u' тысяч', u' миллионов', u' миллиардов']
2621+
2622+ # next line is needed for correct loading of currencies
2623+ import currencies
2624+ return currencies
2625+
2626+
2627+ def wordify(self, chunk, chunknr, gender):
2628+ if gender == 'm':
2629+ number = self.number_sng_msc
2630+ elif gender == 'f':
2631+ number = self.number_sng_fem
2632+ elif gender == 'n':
2633+ number = self.number_sng_neu
2634+ words = u''
2635+ digit1 = u''
2636+ digit2 = u''
2637+ digit3 = u''
2638+ chunklength = len(chunk)
2639+ # placing digits in right places
2640+ if chunklength == 1:
2641+ digit3 = chunk[0 : 1]
2642+ if chunklength == 2:
2643+ digit2 = chunk[0 : 1]
2644+ digit3 = chunk[1 : 2]
2645+ if chunklength == 3:
2646+ digit1 = chunk[0 : 1]
2647+ digit2 = chunk[1 : 2]
2648+ digit3 = chunk[-1]
2649+ # processing zero
2650+ if chunklength == 1 and digit3 == '0' :
2651+ return number[0]
2652+ # processing hundreds
2653+ if chunklength == 3 :
2654+ if int(digit1) == 1 :
2655+ words += self.multi_sng_msc[0]
2656+ elif int(digit1) == 2 :
2657+ words += u'двести'
2658+ elif int(digit1) == 3 :
2659+ words += u'триста'
2660+ elif int(digit1) == 4 :
2661+ words += u'четыреста'
2662+ elif int(digit1) >= 5 :
2663+ words += self.number_sng_msc[int(digit1)] + self.multi_plr_msc[0]
2664+ # processing tens
2665+ if chunklength > 1:
2666+ spacer = ''
2667+ if len(words) > 0 : spacer = ' '
2668+ if digit2 == '1':
2669+ words += spacer + self.number_teens[int(digit3)]
2670+ else:
2671+ if int(digit2) > 1 and int(digit2) < 4:
2672+ words += spacer + self.number_plr_msc[int(digit2)] + u'дцать'
2673+ elif digit2 == '4':
2674+ words += spacer + u'сорок'
2675+ elif int(digit2) >= 5 and int(digit2) != 9:
2676+ words += spacer + self.number_plr_msc[int(digit2)] + u'десят'
2677+ elif digit2 == '9':
2678+ words += spacer + u'девяносто'
2679+
2680+ # processing ones
2681+ if chunklength > 0 and digit2 != '1' :
2682+ spacer = ''
2683+ if len(words) > 0: spacer = u' '
2684+ if chunknr == 1:
2685+ if int(digit3) == 1 or int(digit3) == 2:
2686+ words += spacer + self.number_sng_fem[int(digit3)]
2687+ elif int(digit3) >= 3 and int(digit3) != 0:
2688+ words += spacer + self.number_sng_msc[int(digit3)]
2689+ else:
2690+ if int(digit3) > 0: words += spacer + self.number_sng_msc[int(digit3)]
2691+ # end processing
2692+ if len(words) > 0 :
2693+ if digit3 == '1' and chunknr > 0:
2694+ return words + self.multi_sng_msc[chunknr]
2695+ elif digit3 != '1' and chunknr > 0:
2696+ return words + self.multi_plr_msc[chunknr]
2697+ else:
2698+ return words
2699+ else:
2700+ return ''
2701+
2702+ru_RU()
2703
2704=== added directory 'report_aeroo/ctt_languages/ru_RU/currencies'
2705=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/__init__.py'
2706--- report_aeroo/ctt_languages/ru_RU/currencies/__init__.py 1970-01-01 00:00:00 +0000
2707+++ report_aeroo/ctt_languages/ru_RU/currencies/__init__.py 2014-04-05 13:18:49 +0000
2708@@ -0,0 +1,3 @@
2709+#!/usr/bin/python
2710+# -*- coding: utf8 -*-
2711+# Please do not edit this file!
2712
2713=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/eur.py'
2714--- report_aeroo/ctt_languages/ru_RU/currencies/eur.py 1970-01-01 00:00:00 +0000
2715+++ report_aeroo/ctt_languages/ru_RU/currencies/eur.py 2014-04-05 13:18:49 +0000
2716@@ -0,0 +1,22 @@
2717+#!/usr/bin/python
2718+# -*- coding: utf8 -*-
2719+
2720+from report_aeroo.ctt_objects import ctt_currency
2721+
2722+class eur(ctt_currency):
2723+ def _init_currency(self):
2724+ self.language = u'ru_RU'
2725+ self.code = u'EUR'
2726+ self.fractions = 100
2727+ self.cur_singular = u' евро'
2728+ self.cur_plural = u' евро'
2729+ self.frc_singular = u' цент'
2730+ # default plural form for fractions
2731+ self.frc_plural = u' центов'
2732+ self.frc_plural_2_to4 = u' цента'
2733+
2734+ # grammatical genders: f - feminine, m - masculine, n -neuter
2735+ self.cur_gram_gender = 'm'
2736+ self.frc_gram_gender = 'm'
2737+
2738+eur()
2739
2740=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/ltl.py'
2741--- report_aeroo/ctt_languages/ru_RU/currencies/ltl.py 1970-01-01 00:00:00 +0000
2742+++ report_aeroo/ctt_languages/ru_RU/currencies/ltl.py 2014-04-05 13:18:49 +0000
2743@@ -0,0 +1,23 @@
2744+#!/usr/bin/python
2745+# -*- coding: utf8 -*-
2746+
2747+from report_aeroo.ctt_objects import ctt_currency
2748+
2749+class ltl(ctt_currency):
2750+ def _init_currency(self):
2751+ self.language = u'ru_RU'
2752+ self.code = u'LTL'
2753+ self.fractions = 100
2754+ self.cur_singular = u' лит'
2755+ # default plural form for currency
2756+ self.cur_plural = u' литов'
2757+ self.cur_plural_2to4 = u' лита'
2758+ self.frc_singular = u' цент'
2759+ # default plural form for fractions
2760+ self.frc_plural = u' центов'
2761+ self.frc_plural_2to4 = u' цента'
2762+ # grammatical genders: f - feminine, m - masculine, n -neuter
2763+ self.cur_gram_gender = 'm'
2764+ self.frc_gram_gender = 'm'
2765+
2766+ltl()
2767
2768=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/lvl.py'
2769--- report_aeroo/ctt_languages/ru_RU/currencies/lvl.py 1970-01-01 00:00:00 +0000
2770+++ report_aeroo/ctt_languages/ru_RU/currencies/lvl.py 2014-04-05 13:18:49 +0000
2771@@ -0,0 +1,23 @@
2772+#!/usr/bin/python
2773+# -*- coding: utf8 -*-
2774+
2775+from report_aeroo.ctt_objects import ctt_currency
2776+
2777+class lvl(ctt_currency):
2778+ def _init_currency(self):
2779+ self.language = u'ru_RU'
2780+ self.code = u'LVL'
2781+ self.fractions = 100
2782+ self.cur_singular = u' лат'
2783+ # default plural form for currency
2784+ self.cur_plural = u' латов'
2785+ self.cur_plural_2to4 = u' лата'
2786+ self.frc_singular = u' сантим'
2787+ # default plural form for fractions
2788+ self.frc_plural = u' сантимов'
2789+ self.frc_plural_2to4 = u' сантима'
2790+ # grammatical genders: f - feminine, m - masculine, n -neuter
2791+ self.cur_gram_gender = 'm'
2792+ self.frc_gram_gender = 'm'
2793+
2794+lvl()
2795
2796=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/rub.py'
2797--- report_aeroo/ctt_languages/ru_RU/currencies/rub.py 1970-01-01 00:00:00 +0000
2798+++ report_aeroo/ctt_languages/ru_RU/currencies/rub.py 2014-04-05 13:18:49 +0000
2799@@ -0,0 +1,23 @@
2800+#!/usr/bin/python
2801+# -*- coding: utf8 -*-
2802+
2803+from report_aeroo.ctt_objects import ctt_currency
2804+
2805+class rub(ctt_currency):
2806+ def _init_currency(self):
2807+ self.language = u'ru_RU'
2808+ self.code = u'RUB'
2809+ self.fractions = 100
2810+ self.cur_singular = u' рубль'
2811+ # default plural form for currency
2812+ self.cur_plural = u' рублей'
2813+ self.cur_plural_2to4 = u' рубля'
2814+ self.frc_singular = u' копейка'
2815+ # default plural form for fractions
2816+ self.frc_plural = u' копеек'
2817+ self.frc_plural_2to4 = u' копейки'
2818+ # grammatical genders: f - feminine, m - masculine, n -neuter
2819+ self.cur_gram_gender = 'm'
2820+ self.frc_gram_gender = 'f'
2821+
2822+rub()
2823
2824=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/uah.py'
2825--- report_aeroo/ctt_languages/ru_RU/currencies/uah.py 1970-01-01 00:00:00 +0000
2826+++ report_aeroo/ctt_languages/ru_RU/currencies/uah.py 2014-04-05 13:18:49 +0000
2827@@ -0,0 +1,23 @@
2828+#!/usr/bin/python
2829+# -*- coding: utf8 -*-
2830+
2831+from report_aeroo.ctt_objects import ctt_currency
2832+
2833+class uah(ctt_currency):
2834+ def _init_currency(self):
2835+ self.language = u'ru_RU'
2836+ self.code = u'UAH'
2837+ self.fractions = 100
2838+ self.cur_singular = u' гривна'
2839+ # default plural form for currency
2840+ self.cur_plural = u' гривен'
2841+ self.cur_plural_2to4 = u' гривны'
2842+ self.frc_singular = u' копeйка'
2843+ # default plural form for fractions
2844+ self.frc_plural = u' копeек'
2845+ self.frc_plural_2to4 = u' копeйки'
2846+ # grammatical genders: f - feminine, m - masculine, n -neuter
2847+ self.cur_gram_gender = 'f'
2848+ self.frc_gram_gender = 'f'
2849+
2850+uah()
2851
2852=== added file 'report_aeroo/ctt_languages/ru_RU/currencies/usd.py'
2853--- report_aeroo/ctt_languages/ru_RU/currencies/usd.py 1970-01-01 00:00:00 +0000
2854+++ report_aeroo/ctt_languages/ru_RU/currencies/usd.py 2014-04-05 13:18:49 +0000
2855@@ -0,0 +1,23 @@
2856+#!/usr/bin/python
2857+# -*- coding: utf8 -*-
2858+
2859+from report_aeroo.ctt_objects import ctt_currency
2860+
2861+class usd(ctt_currency):
2862+ def _init_currency(self):
2863+ self.language = u'ru_RU'
2864+ self.code = u'USD'
2865+ self.fractions = 100
2866+ self.cur_singular = u' доллара США'
2867+ # default plural form for currency
2868+ self.cur_plural = u' долларов США'
2869+ self.cur_frc_plural_2to4 = u' доллара США'
2870+ self.frc_singular = u' цент'
2871+ # default plural form for fractions
2872+ self.frc_plural = u' центов'
2873+ self.frc_plural_2to4 = u' цента'
2874+ # grammatical genders: f - feminine, m - masculine, n -neuter
2875+ self.cur_gram_gender = 'm'
2876+ self.frc_gram_gender = 'm'
2877+
2878+usd()
2879
2880=== added directory 'report_aeroo/ctt_languages/tr_TR'
2881=== added file 'report_aeroo/ctt_languages/tr_TR/__init__.py'
2882--- report_aeroo/ctt_languages/tr_TR/__init__.py 1970-01-01 00:00:00 +0000
2883+++ report_aeroo/ctt_languages/tr_TR/__init__.py 2014-04-05 13:18:49 +0000
2884@@ -0,0 +1,93 @@
2885+#!/usr/bin/python
2886+# -*- coding: utf8 -*-
2887+# tr_TR
2888+################################################################################
2889+#
2890+# Turkish language support assembled from contributions provided by:
2891+# Ahmet Altınışık
2892+#
2893+################################################################################
2894+from report_aeroo.ctt_objects import ctt_language
2895+
2896+class tr_TR(ctt_language):
2897+ def _init_lang(self):
2898+ self.name = 'tr_TR'
2899+ # digits - masculine, singular
2900+ self.number_sng_msc = [u'', u'bir', u'iki', u'üç', u'dört', u'beş',
2901+ u'alti', u'yedi', u'sekiz', u'dokuz']
2902+ # tens - masculine, singular
2903+ self.tens_sng_msc = [u'on', u'on bir', u'on iki', u'on üç', u'on dört',
2904+ u'on beş', u'on alti', u'on yedi', u'on sekiz',
2905+ u'on dokuz']
2906+ # teens - masculine
2907+ self.teens = [u'on', u'on bir', u'on iki', u'on üç', u'on dört',
2908+ u'on beş', u'on alti', u'on yedi', u'on sekiz',
2909+ u'on dokuz']
2910+ # multiplier - masculine, singular
2911+ self.multi_sng_msc = [u'yüz', u' bin', u' milyon', u' milyar']
2912+
2913+ # next line is needed for correct loading of currencies
2914+ import currencies
2915+ return currencies
2916+
2917+
2918+ def wordify(self, chunk, chunknr, gender):
2919+ if gender == 'm':
2920+ number = self.number_sng_msc
2921+ elif gender == 'f':
2922+ number = self.number_sng_fem
2923+ elif gender == 'n':
2924+ number = self.number_sng_neu
2925+ words = u''
2926+ digit1 = u''
2927+ digit2 = u''
2928+ digit3 = u''
2929+ chunklength = len(chunk)
2930+ # placing digits in right places
2931+ if chunklength == 1:
2932+ digit3 = chunk[0 : 1]
2933+ if chunklength == 2:
2934+ digit2 = chunk[0 : 1]
2935+ digit3 = chunk[1 : 2]
2936+ if chunklength == 3:
2937+ digit1 = chunk[0 : 1]
2938+ digit2 = chunk[1 : 2]
2939+ digit3 = chunk[-1]
2940+ # processing zero
2941+ if chunklength == 1 and digit3 == '0' :
2942+ return number[0]
2943+ # processing hundreds
2944+ if chunklength == 3 :
2945+ if digit1 == '1' :
2946+ words += self.multi_sng_msc[0]
2947+ else :
2948+ if int(digit1) > 1 : words += number[int(digit1)] + \
2949+ self.multi_plr_msc[0]
2950+ # processing tens
2951+ if chunklength > 1:
2952+ spacer = ''
2953+ if len(words) > 0 : spacer = ' '
2954+ if digit2 == '1':
2955+ words += spacer + self.teens[int(digit3)]
2956+ else:
2957+ if int(digit2) > 1 and int(digit2) > 0:
2958+ words += spacer + self.tens_sng_msc[int(digit2)]
2959+
2960+ # processing ones
2961+ if chunklength > 0 and digit2 != '1' :
2962+ spacer = ''
2963+ if len(words) > 0: spacer = u' '
2964+ if int(digit3) > 0:
2965+ words += spacer + number[int(digit3)]
2966+ # end processing
2967+ if len(words) > 0 :
2968+ if digit3 == '1' and chunknr > 0:
2969+ return words + self.multi_sng_msc[chunknr]
2970+ elif digit3 != '1' and chunknr > 0:
2971+ return words + self.multi_plr_msc[chunknr]
2972+ else:
2973+ return words
2974+ else:
2975+ return ''
2976+
2977+tr_TR()
2978
2979=== added directory 'report_aeroo/ctt_languages/tr_TR/currencies'
2980=== added file 'report_aeroo/ctt_languages/tr_TR/currencies/__init__.py'
2981--- report_aeroo/ctt_languages/tr_TR/currencies/__init__.py 1970-01-01 00:00:00 +0000
2982+++ report_aeroo/ctt_languages/tr_TR/currencies/__init__.py 2014-04-05 13:18:49 +0000
2983@@ -0,0 +1,3 @@
2984+#!/usr/bin/python
2985+# -*- coding: utf8 -*-
2986+# Please do not edit this file!
2987
2988=== added file 'report_aeroo/ctt_languages/tr_TR/currencies/eur.py'
2989--- report_aeroo/ctt_languages/tr_TR/currencies/eur.py 1970-01-01 00:00:00 +0000
2990+++ report_aeroo/ctt_languages/tr_TR/currencies/eur.py 2014-04-05 13:18:49 +0000
2991@@ -0,0 +1,21 @@
2992+#!/usr/bin/python
2993+# -*- coding: utf8 -*-
2994+
2995+from report_aeroo.ctt_objects import ctt_currency
2996+
2997+class eur(ctt_currency):
2998+ def _init_currency(self):
2999+ self.language = u'tr_TR'
3000+ self.code = u'EUR'
3001+ self.fractions = 100
3002+ self.cur_singular = u' Euro'
3003+ # default plural form for currency
3004+ self.cur_plural = u' Euro'
3005+ self.frc_singular = u' sent'
3006+ # default plural form for fractions
3007+ self.frc_plural = u' sent'
3008+ # grammatical genders: f - feminine, m - masculine, n -neuter
3009+ self.cur_gram_gender = 'm'
3010+ self.frc_gram_gender = 'm'
3011+
3012+eur()
3013
3014=== added file 'report_aeroo/ctt_languages/tr_TR/currencies/lvl.py'
3015--- report_aeroo/ctt_languages/tr_TR/currencies/lvl.py 1970-01-01 00:00:00 +0000
3016+++ report_aeroo/ctt_languages/tr_TR/currencies/lvl.py 2014-04-05 13:18:49 +0000
3017@@ -0,0 +1,21 @@
3018+#!/usr/bin/python
3019+# -*- coding: utf8 -*-
3020+
3021+from report_aeroo.ctt_objects import ctt_currency
3022+
3023+class lvl(ctt_currency):
3024+ def _init_currency(self):
3025+ self.language = u'tr_TR'
3026+ self.code = u'LVL'
3027+ self.fractions = 100
3028+ self.cur_singular = u' Litvanya Liatası'
3029+ # default plural form for currency
3030+ self.cur_plural = u' Litvanya Liatası'
3031+ self.frc_singular = u' santim'
3032+ # default plural form for fractions
3033+ self.frc_plural = u' santims'
3034+ # grammatical genders: f - feminine, m - masculine, n -neuter
3035+ self.cur_gram_gender = 'm'
3036+ self.frc_gram_gender = 'm'
3037+
3038+lvl()
3039
3040=== added file 'report_aeroo/ctt_languages/tr_TR/currencies/trl.py'
3041--- report_aeroo/ctt_languages/tr_TR/currencies/trl.py 1970-01-01 00:00:00 +0000
3042+++ report_aeroo/ctt_languages/tr_TR/currencies/trl.py 2014-04-05 13:18:49 +0000
3043@@ -0,0 +1,21 @@
3044+#!/usr/bin/python
3045+# -*- coding: utf8 -*-
3046+
3047+from report_aeroo.ctt_objects import ctt_currency
3048+
3049+class trl(ctt_currency):
3050+ def _init_currency(self):
3051+ self.language = u'tr_TR'
3052+ self.code = u'TRL'
3053+ self.fractions = 100
3054+ self.cur_singular = u' Lira'
3055+ # default plural form for currency
3056+ self.cur_plural = u' Lira'
3057+ self.frc_singular = u' kuruş'
3058+ # default plural form for fractions
3059+ self.frc_plural = u' kuruş'
3060+ # grammatical genders: f - feminine, m - masculine, n -neuter
3061+ self.cur_gram_gender = 'm'
3062+ self.frc_gram_gender = 'm'
3063+
3064+trl()
3065
3066=== added file 'report_aeroo/ctt_languages/tr_TR/currencies/usd.py'
3067--- report_aeroo/ctt_languages/tr_TR/currencies/usd.py 1970-01-01 00:00:00 +0000
3068+++ report_aeroo/ctt_languages/tr_TR/currencies/usd.py 2014-04-05 13:18:49 +0000
3069@@ -0,0 +1,21 @@
3070+#!/usr/bin/python
3071+# -*- coding: utf8 -*-
3072+
3073+from report_aeroo.ctt_objects import ctt_currency
3074+
3075+class usd(ctt_currency):
3076+ def _init_currency(self):
3077+ self.language = u'tr_TR'
3078+ self.code = u'USD'
3079+ self.fractions = 100
3080+ self.cur_singular = u' USD'
3081+ # default plural form for currency
3082+ self.cur_plural = u' USD'
3083+ self.frc_singular = u' sent'
3084+ # default plural form for fractions
3085+ self.frc_plural = u' sent'
3086+ # grammatical genders: f - feminine, m - masculine, n -neuter
3087+ self.cur_gram_gender = 'm'
3088+ self.frc_gram_gender = 'm'
3089+
3090+usd()
3091
3092=== added directory 'report_aeroo/ctt_languages/uk_UA'
3093=== added file 'report_aeroo/ctt_languages/uk_UA/__init__.py'
3094--- report_aeroo/ctt_languages/uk_UA/__init__.py 1970-01-01 00:00:00 +0000
3095+++ report_aeroo/ctt_languages/uk_UA/__init__.py 2014-04-05 13:18:49 +0000
3096@@ -0,0 +1,112 @@
3097+#!/usr/bin/python
3098+# -*- coding: utf8 -*-
3099+# uk_UA
3100+
3101+from report_aeroo.ctt_objects import ctt_language
3102+
3103+class uk_UA(ctt_language):
3104+ def _init_lang(self):
3105+ # language name
3106+ self.name = 'uk_UA'
3107+ # digits - masculine, singular
3108+ self.number_sng_msc = [u'ноль', u'один', u'два', u'три', u'чотири',
3109+ u'п\'ять', u'шість', u'сім', u'вісім',
3110+ u'дев\'ять']
3111+ # tens - masculine, singular
3112+ self.number_sng_fem = [u'ноль', u'одна', u'дві', u'три', u'чотири',
3113+ u'п\'ять', u'шість', u'сім', u'вісім',
3114+ u'дев\'ять']
3115+ # tens - masculine, plural
3116+ self.number_plr_msc = [u'', u'один', u'двa', u'три', u'четыре', u'пять',
3117+ u'шесть', u'семь', u'восемь', u'девять']
3118+ # teens - masculine
3119+ self.number_teens = [u'десять', u'одинадцять', u'дванадцять',
3120+ u'тринадцять', u'чотирнадцять', u'п\'ятнадцять',
3121+ u'шістнадцять', u'сімнадцять', u'вісімнадцять',
3122+ u'дев\'ятнадцять']
3123+ # multiplier - masculine, singular
3124+ self.multi_sng_msc = [u'стo', u' тисяча', u' мiллiон', u' мiллiард']
3125+ # multiplier - masculine, plural
3126+ self.multi_plr_msc = [u'сoт', u' тисяч', u' мiллiонiв', u' мiллiардов']
3127+
3128+ # next line is needed for correct loading of currencies
3129+ import currencies
3130+ return currencies
3131+
3132+
3133+ def wordify(self, chunk, chunknr, gender):
3134+ if gender == 'm':
3135+ number = self.number_sng_msc
3136+ elif gender == 'f':
3137+ number = self.number_sng_fem
3138+ elif gender == 'n':
3139+ number = self.number_sng_neu
3140+ words = u''
3141+ digit1 = u''
3142+ digit2 = u''
3143+ digit3 = u''
3144+ chunklength = len(chunk)
3145+ # placing digits in right places
3146+ if chunklength == 1:
3147+ digit3 = chunk[0 : 1]
3148+ if chunklength == 2:
3149+ digit2 = chunk[0 : 1]
3150+ digit3 = chunk[1 : 2]
3151+ if chunklength == 3:
3152+ digit1 = chunk[0 : 1]
3153+ digit2 = chunk[1 : 2]
3154+ digit3 = chunk[-1]
3155+ # processing zero
3156+ if chunklength == 1 and digit3 == '0' :
3157+ return number[0]
3158+ # processing hundreds
3159+ if chunklength == 3 :
3160+ if int(digit1) == 1 :
3161+ words += self.multi_sng_msc[0]
3162+ elif int(digit1) == 2 :
3163+ words += u'двісті'
3164+ elif int(digit1) == 3 :
3165+ words += u'триста'
3166+ elif int(digit1) == 4 :
3167+ words += u'чотириста'
3168+ elif int(digit1) >= 5 :
3169+ words += self.number_sng_msc[int(digit1)] + self.multi_plr_msc[0]
3170+ # processing tens
3171+ if chunklength > 1:
3172+ spacer = ''
3173+ if len(words) > 0 : spacer = ' '
3174+ if digit2 == '1':
3175+ words += spacer + self.number_teens[int(digit3)]
3176+ else:
3177+ if int(digit2) > 1 and int(digit2) < 4:
3178+ words += spacer + skaitlix[int(digit2)] + u'дцять'
3179+ elif digit2 == '4':
3180+ words += spacer + u'сорок'
3181+ elif int(digit2) >= 5 and int(digit2) != 9:
3182+ words += spacer + skaitlix[int(digit2)] + u'десят'
3183+ elif digit2 == '9':
3184+ words += spacer + u'дев\'яносто'
3185+
3186+ # processing ones
3187+ if chunklength > 0 and digit2 != '1' :
3188+ spacer = ''
3189+ if len(words) > 0: spacer = u' '
3190+ if chunknr == 1:
3191+ if int(digit3) == 1 or int(digit3) == 2:
3192+ words += spacer + self.number_sng_fem[int(digit3)]
3193+ elif int(digit3) >= 3 and int(digit3) != 0:
3194+ words += spacer + self.number_sng_msc[int(digit3)]
3195+ else:
3196+ if int(digit3) > 0: words += spacer + self.number_sng_msc[int(digit3)]
3197+ # end processing
3198+ if len(words) > 0 :
3199+ if digit3 == '1' and chunknr > 0:
3200+ return words + self.multi_sng_msc[chunknr]
3201+ elif digit3 != '1' and chunknr > 0:
3202+ return words + self.multi_plr_msc[chunknr]
3203+ else:
3204+ return words
3205+ else:
3206+ return ''
3207+
3208+uk_UA()
3209
3210=== added directory 'report_aeroo/ctt_languages/uk_UA/currencies'
3211=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/__init__.py'
3212--- report_aeroo/ctt_languages/uk_UA/currencies/__init__.py 1970-01-01 00:00:00 +0000
3213+++ report_aeroo/ctt_languages/uk_UA/currencies/__init__.py 2014-04-05 13:18:49 +0000
3214@@ -0,0 +1,3 @@
3215+#!/usr/bin/python
3216+# -*- coding: utf8 -*-
3217+# Please do not edit this file!
3218
3219=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/eur.py'
3220--- report_aeroo/ctt_languages/uk_UA/currencies/eur.py 1970-01-01 00:00:00 +0000
3221+++ report_aeroo/ctt_languages/uk_UA/currencies/eur.py 2014-04-05 13:18:49 +0000
3222@@ -0,0 +1,21 @@
3223+#!/usr/bin/python
3224+# -*- coding: utf8 -*-
3225+
3226+from report_aeroo.ctt_objects import ctt_currency
3227+
3228+class eur(ctt_currency):
3229+ def _init_currency(self):
3230+ self.language = u'uk_UA'
3231+ self.code = u'EUR'
3232+ self.fractions = 100
3233+ self.cur_singular = u' евро'
3234+ self.cur_plural = u' евро'
3235+ self.frc_singular = u' цент'
3236+ # default plural form for fractions
3237+ self.frc_plural = u' центов'
3238+ self.frc_plural_2to4 = u' цента'
3239+ # grammatical genders: f - feminine, m - masculine, n -neuter
3240+ self.cur_gram_gender = 'm'
3241+ self.frc_gram_gender = 'm'
3242+
3243+eur()
3244
3245=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/ltl.py'
3246--- report_aeroo/ctt_languages/uk_UA/currencies/ltl.py 1970-01-01 00:00:00 +0000
3247+++ report_aeroo/ctt_languages/uk_UA/currencies/ltl.py 2014-04-05 13:18:49 +0000
3248@@ -0,0 +1,23 @@
3249+#!/usr/bin/python
3250+# -*- coding: utf8 -*-
3251+
3252+from report_aeroo.ctt_objects import ctt_currency
3253+
3254+class ltl(ctt_currency):
3255+ def _init_currency(self):
3256+ self.language = u'uk_UA'
3257+ self.code = u'LTL'
3258+ self.fractions = 100
3259+ self.cur_singular = u' лит'
3260+ # default plural form for currency
3261+ self.cur_plural = u' литов'
3262+ self.cur_plural_2to4 = u' лита'
3263+ self.frc_singular = u' цент'
3264+ # default plural form for fractions
3265+ self.frc_plural = u' центов'
3266+ self.frc_plural_2to4 = u' цента'
3267+ # grammatical genders: f - feminine, m - masculine, n -neuter
3268+ self.cur_gram_gender = 'm'
3269+ self.frc_gram_gender = 'm'
3270+
3271+ltl()
3272
3273=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/lvl.py'
3274--- report_aeroo/ctt_languages/uk_UA/currencies/lvl.py 1970-01-01 00:00:00 +0000
3275+++ report_aeroo/ctt_languages/uk_UA/currencies/lvl.py 2014-04-05 13:18:49 +0000
3276@@ -0,0 +1,23 @@
3277+#!/usr/bin/python
3278+# -*- coding: utf8 -*-
3279+
3280+from report_aeroo.ctt_objects import ctt_currency
3281+
3282+class lvl(ctt_currency):
3283+ def _init_currency(self):
3284+ self.language = u'uk_UA'
3285+ self.code = u'LVL'
3286+ self.fractions = 100
3287+ self.cur_singular = u' лат'
3288+ # default plural form for currency
3289+ self.cur_plural = u' латов'
3290+ self.cur_plural_2to3 = u' лата'
3291+ self.frc_singular = u' сантим'
3292+ # default plural form for fractions
3293+ self.frc_plural = u' сантимов'
3294+ self.frc_plural_2to3 = u' сантима'
3295+ # grammatical genders: f - feminine, m - masculine, n -neuter
3296+ self.cur_gram_gender = 'm'
3297+ self.frc_gram_gender = 'm'
3298+
3299+lvl()
3300
3301=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/rub.py'
3302--- report_aeroo/ctt_languages/uk_UA/currencies/rub.py 1970-01-01 00:00:00 +0000
3303+++ report_aeroo/ctt_languages/uk_UA/currencies/rub.py 2014-04-05 13:18:49 +0000
3304@@ -0,0 +1,23 @@
3305+#!/usr/bin/python
3306+# -*- coding: utf8 -*-
3307+
3308+from report_aeroo.ctt_objects import ctt_currency
3309+
3310+class rub(ctt_currency):
3311+ def _init_currency(self):
3312+ self.language = u'uk_UA'
3313+ self.code = u'RUB'
3314+ self.fractions = 100
3315+ self.cur_singular = u' рубль'
3316+ # default plural form for currency
3317+ self.cur_plural = u' рублiв'
3318+ self.cur_plural_2to4 = u' рубля'
3319+ self.frc_singular = u' копійка'
3320+ # default plural form for fractions
3321+ self.frc_plural = u' копійок'
3322+ self.frc_plural_2to4 = u' копійки'
3323+ # grammatical genders: f - feminine, m - masculine, n -neuter
3324+ self.cur_gram_gender = 'm'
3325+ self.frc_gram_gender = 'f'
3326+
3327+rub()
3328
3329=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/uah.py'
3330--- report_aeroo/ctt_languages/uk_UA/currencies/uah.py 1970-01-01 00:00:00 +0000
3331+++ report_aeroo/ctt_languages/uk_UA/currencies/uah.py 2014-04-05 13:18:49 +0000
3332@@ -0,0 +1,23 @@
3333+#!/usr/bin/python
3334+# -*- coding: utf8 -*-
3335+
3336+from report_aeroo.ctt_objects import ctt_currency
3337+
3338+class uah(ctt_currency):
3339+ def _init_currency(self):
3340+ self.language = u'uk_UA'
3341+ self.code = u'UAH'
3342+ self.fractions = 100
3343+ self.cur_singular = u' гривня'
3344+ # default plural form for currency
3345+ self.cur_plural = u' гривень'
3346+ self.cur_plural_2to4 = u' гривні'
3347+ self.frc_singular = u' копійка'
3348+ # default plural form for fractions
3349+ self.frc_plural = u' копійок'
3350+ self.frc_plural_2to4 = u' копійки'
3351+ # grammatical genders: f - feminine, m - masculine, n -neuter
3352+ self.cur_gram_gender = 'f'
3353+ self.frc_gram_gender = 'f'
3354+
3355+uah()
3356
3357=== added file 'report_aeroo/ctt_languages/uk_UA/currencies/usd.py'
3358--- report_aeroo/ctt_languages/uk_UA/currencies/usd.py 1970-01-01 00:00:00 +0000
3359+++ report_aeroo/ctt_languages/uk_UA/currencies/usd.py 2014-04-05 13:18:49 +0000
3360@@ -0,0 +1,23 @@
3361+#!/usr/bin/python
3362+# -*- coding: utf8 -*-
3363+
3364+from report_aeroo.ctt_objects import ctt_currency
3365+
3366+class usd(ctt_currency):
3367+ def _init_currency(self):
3368+ self.language = u'uk_UA'
3369+ self.code = u'USD'
3370+ self.fractions = 100
3371+ self.cur_singular = u' доллара США'
3372+ # default plural form for currency
3373+ self.cur_plural = u' долларов США'
3374+ self.cur_plural_2to4 = u' доллара США'
3375+ self.frc_singular = u' цент'
3376+ # default plural form for fractions
3377+ self.frc_plural = u' центов'
3378+ self.frc_plural_2to4 = u' цента'
3379+ # grammatical genders: f - feminine, m - masculine, n -neuter
3380+ self.cur_gram_gender = 'm'
3381+ self.frc_gram_gender = 'm'
3382+
3383+usd()
3384
3385=== added file 'report_aeroo/ctt_objects.py'
3386--- report_aeroo/ctt_objects.py 1970-01-01 00:00:00 +0000
3387+++ report_aeroo/ctt_objects.py 2014-04-05 13:18:49 +0000
3388@@ -0,0 +1,161 @@
3389+#!/usr/bin/python
3390+# -*- coding: utf8 -*-
3391+################################################################################
3392+# Developed by Kaspars Vilkens - Alistek Ltd (c) 2011
3393+#
3394+# Supported sum: 0 ... 999999999999.99
3395+# Supported languages: for more reference see languages forlder
3396+# Supported currencies: see particular language for reference
3397+################################################################################
3398+
3399+import os
3400+supported_language = {}
3401+
3402+if __name__ == '__main__':
3403+ from sys import exit
3404+ error = '''This code is part of Report Aeroo package!
3405+ Not to be used separately...'''
3406+ exit(error)
3407+
3408+def currency_to_text(sum, currency_code, language_code):
3409+ if language_code not in supported_language:
3410+ raise Exception('Not supported or no language: %s' % language_code)
3411+ else:
3412+ suppl = supported_language[language_code]
3413+ return suppl.currency_to_text(sum, currency_code)
3414+
3415+class ctt_language(object):
3416+ def _init_lang(self):
3417+ pass
3418+
3419+ def __repr__(self):
3420+ return self.name
3421+
3422+ def __init__(self):
3423+ self.supported_currency = {}
3424+ self.minbound = 0
3425+ self.maxbound = 999999999999.99
3426+ currencies = self._init_lang()
3427+ supported_language.update({self.name : self})
3428+ import_submodules('currency', currencies, 0)
3429+
3430+ def check_sum(self):
3431+ if sum < self.minbound or sum > self.maxbound :
3432+ raise Exception(\
3433+ """Sum out of bounds: must be from %s to %s""" % \
3434+ (str(self.minbound), str(self.maxbound)))
3435+
3436+ def check_currency(self):
3437+ if currency not in supported_currency:
3438+ raise Exception(\
3439+ """Unsupported or no currency: must be one of (%s)""" % \
3440+ ', '.join(self.supported_currency))
3441+
3442+ def dtowords(self, sum_integers, gender):
3443+ diginwords = u''
3444+ if sum_integers == 0:
3445+ return self.wordify('0', 0, gender)
3446+ elif sum_integers > 0:
3447+ lengthx = len(str(sum_integers))
3448+ nrchunks = (lengthx / 3)
3449+ if nrchunks < (float(lengthx) / 3) :
3450+ nrchunks+=1
3451+ inc = 1
3452+ while inc <= nrchunks:
3453+ startpos = (lengthx - inc * 3)
3454+ chunklength = 3
3455+ if startpos < 0:
3456+ chunklength += startpos
3457+ startpos = 0
3458+ chunk = str(sum_integers)[startpos : startpos + chunklength]
3459+ #print str(startpos)+' '+str(chunklength)+' '+ chunk
3460+ if inc == 1:
3461+ wordified = self.wordify(chunk, inc-1, gender)
3462+ else:
3463+ wordified = self.wordify(chunk, inc-1, 'm')
3464+ inc += 1
3465+ spacer = ''
3466+ if len(diginwords) > 0 and wordified:
3467+ spacer = ' '
3468+ diginwords = wordified + spacer + diginwords
3469+ return diginwords
3470+
3471+
3472+ def currency_to_text(self, sum, currency):
3473+ #--------------for currencies with 100 fractions
3474+ sum = float(sum)
3475+ sum = round(sum, 2)
3476+ # find out digits before floating point - currency
3477+ sum_cur = int(sum)
3478+ # find out digits after floating point - fractions
3479+ sum_frc = int(round((sum - sum_cur) * 100,0))
3480+ curr = self.supported_currency.get(currency)
3481+ cur_in_words = self.dtowords(sum_cur, curr.cur_gram_gender)
3482+ frc_in_words = self.dtowords(sum_frc, curr.frc_gram_gender)
3483+ #------------------------------------
3484+
3485+ return (cur_in_words + curr.cur_to_text(sum_cur) + ' ' + frc_in_words +\
3486+ curr.frc_to_text(sum_frc)).strip().encode('utf-8')
3487+
3488+
3489+class ctt_currency(object):
3490+ def _init_currency(self):
3491+ pass
3492+
3493+ def __repr__(self):
3494+ return self.code
3495+
3496+ def __init__(self):
3497+ self._init_currency()
3498+ suppl = supported_language.get(self.language)
3499+ suppl.supported_currency.update({self.code : self})
3500+
3501+ def cur_to_text(self, sum_cur):
3502+ # is the currency sum one
3503+ if sum_cur == 1 or (str(sum_cur)[-1] == '1' and str(sum_cur)[-2] !='1'):
3504+ return self.cur_singular
3505+ # 2,3 and 4 yields different plural form, if defined
3506+ elif ((sum_cur in [2, 3, 4]) or (str(sum_cur)[-1] in ['2', '3', '4'] \
3507+ and str(sum_cur)[-2] != '1')) and hasattr(self, 'cur_plural_2to4'):
3508+ return self.cur_plural_2to4
3509+ # betwean 1 and 10 yields different plural form, if defined
3510+ elif (sum_cur > 1 and sum_cur < 10 or (int(str(sum_cur)[-1]) > 1 \
3511+ and str(sum_cur)[-2] != '1')) and hasattr(self, 'cur_plural_2to10'):
3512+ return self.cur_plural_2to10
3513+ # starting from 10 yields uses default plural form
3514+ else:
3515+ return self.cur_plural
3516+
3517+ def frc_to_text(self, sum_frc):
3518+ # is the fraction sum one
3519+ if sum_frc == 1 or (str(sum_frc)[-1] == '1' and str(sum_frc)[-2] !='1'):
3520+ return self.frc_singular
3521+ # 2,3 and 4 yields different plural form, if defined
3522+ elif ((sum_frc in [2, 3, 4]) or (str(sum_frc)[-1] in ['2', '3', '4'] \
3523+ and str(sum_frc)[-2] != '1')) and hasattr(self, 'frc_plural_2to4'):
3524+ return self.frc_plural_2to4
3525+ # betwean 1 and 10 yields different plural form, if defined
3526+ elif (sum_frc > 1 and sum_frc < 10 or (int(str(sum_frc)[-1]) > 1 \
3527+ and str(sum_frc)[-2] != '1')) and hasattr(self, 'frc_plural_2to10'):
3528+ return self.frc_plural_2to10
3529+ # starting from 10 yields uses default plural form
3530+ else:
3531+ return self.frc_plural
3532+
3533+def __filter_names(to_import, package):
3534+ folder = os.path.split(package.__file__)[0]
3535+ for name in os.listdir(folder):
3536+ if to_import == 'currency':
3537+ if name.endswith(".py") and not name.startswith("__"):
3538+ yield name[:-3]
3539+ if to_import == 'language':
3540+ if len(name) == 5 and not name.startswith("__"):
3541+ yield name
3542+
3543+def import_submodules(to_import, package, level=-1):
3544+ names = list(__filter_names(to_import, package))
3545+ m = __import__(package.__name__, globals(), locals(), names, level)
3546+ return dict((name, getattr(m, name)) for name in names)
3547+
3548+import ctt_languages
3549+import_submodules('language', ctt_languages, 0)
3550
3551=== added file 'report_aeroo/currency_to_text.py'
3552--- report_aeroo/currency_to_text.py 1970-01-01 00:00:00 +0000
3553+++ report_aeroo/currency_to_text.py 2014-04-05 13:18:49 +0000
3554@@ -0,0 +1,491 @@
3555+#!/usr/bin/python
3556+# -*- coding: utf8 -*-
3557+
3558+###########################################################
3559+# Developed by Kaspars Vilkens - Alistek Ltd (c) 2011
3560+# pep-8, unicode and doctests by Paul Stevens, paul@nfg.nl, 2010
3561+#
3562+# Supported currencies: LVL, EUR, USD, UAH
3563+# Supported sum: 0 ... 999999999999.99
3564+# Supported languages: lv_LV, en_US, ru_RU, uk_UA
3565+###########################################################
3566+import string
3567+
3568+supported_currency = ['LVL','EUR','USD', 'UAH']
3569+supported_language = ['lv_LV','en_US','ru_RU', 'uk_UA']
3570+
3571+def currency_to_text(sum, currency, language):
3572+ """
3573+
3574+ first some simple tests
3575+
3576+ >>> currency_to_text(123, 'EUR', 'en_US')
3577+ 'one hundred twenty three euros zero cents'
3578+
3579+ >>> currency_to_text(1.11, 'EUR', 'en_US')
3580+ 'one euro eleven cents'
3581+
3582+ >>> currency_to_text(1.10, 'USD', 'en_US')
3583+ 'one US dollar ten cents'
3584+
3585+ >>> currency_to_text(1.01, 'USD', 'en_US')
3586+ 'one US dollar one cent'
3587+
3588+ >>> currency_to_text(1.01, 'LVL', 'lv_LV') == 'viens lats viens santīms'
3589+ True
3590+
3591+ >>> currency_to_text(123.12, 'LVL', 'ru_RU') == 'стo двaдцать три лата двенадцать сантимов'
3592+ True
3593+
3594+ >>> currency_to_text(123.12, 'USD', 'ru_RU') == 'стo двaдцать три доллара США двенадцать центов'
3595+ True
3596+
3597+
3598+ """
3599+ if sum < 0 or sum > 999999999999.99 :
3600+ raise Exception('Sum out of bounds: must be from 0 to 999999999999.99')
3601+ if currency not in supported_currency:
3602+ raise Exception("""Unsupported or no currency: must be one of (%s)""" % \
3603+ string.join(supported_currency,','))
3604+ if language not in supported_language:
3605+ raise Exception("""Unsupported or no language: must be one of (%s)""" % \
3606+ string.join(supported_language,','))
3607+#--------------for currencies with 100 fractions
3608+ sum = float(sum)
3609+ sum = round(sum, 2)
3610+ # find out digits before floating point - currency
3611+ sum_cur = int(sum)
3612+ # find out digits after floating point - fractions
3613+ sum_frc = int(round((sum - sum_cur) * 100,0))
3614+ cur_in_words = dtowords(sum_cur, language)
3615+ #print cur_in_words
3616+ frc_in_words = dtowords(sum_frc, language)
3617+ #print frc_in_words
3618+ #------------------------------------
3619+ if language == 'lv_LV' :
3620+ if sum_cur == 1 or (str(sum_cur)[-1] == '1' and str(sum_cur)[-2] != '1'): # is the currency sum one
3621+ if currency == 'LVL':
3622+ cur_in_words += u' lats'
3623+ elif currency == 'EUR':
3624+ cur_in_words += u' eiro'
3625+ elif currency == 'USD':
3626+ cur_in_words += u' dolārs'
3627+ elif currency == 'UAH':
3628+ cur_in_words += u' grivna'
3629+ else:
3630+ if currency == 'LVL':
3631+ cur_in_words += u' lati'
3632+ elif currency == 'EUR':
3633+ cur_in_words += u' eiro'
3634+ elif currency == 'USD':
3635+ cur_in_words += u' dolāri'
3636+ elif currency == 'UAH':
3637+ cur_in_words += u' grivnas'
3638+
3639+ if sum_frc == 1 or (str(sum_frc)[-1] == '1' and str(sum_frc)[-2] != '1'): # is the fraction sum one
3640+ if currency == 'LVL':
3641+ frc_in_words += u' santīms'
3642+ elif currency == 'EUR' or currency == 'USD' :
3643+ frc_in_words += u' cents'
3644+ elif currency == 'UAH':
3645+ frc_in_words += u' kapeika'
3646+ else:
3647+ if currency == 'LVL':
3648+ frc_in_words += u' santīmi'
3649+ elif currency == 'EUR' or currency == 'USD':
3650+ frc_in_words += u' centi'
3651+ elif currency == 'UAH':
3652+ frc_in_words += u' kapeikas'
3653+ #------------------------------------
3654+ if language == 'en_US' :
3655+ if sum_cur == 1 or (str(sum_cur)[-1] == '1' and str(sum_cur)[-2] != '1'): # is the currency sum one
3656+ if currency == 'LVL':
3657+ cur_in_words += u' Latvian lats'
3658+ elif currency == 'EUR':
3659+ cur_in_words += u' euro'
3660+ elif currency == 'USD':
3661+ cur_in_words += u' US dollar'
3662+ else:
3663+ if currency == 'LVL':
3664+ cur_in_words += u' Latvian lats'
3665+ elif currency == 'EUR':
3666+ cur_in_words += u' euros'
3667+ elif currency == 'USD':
3668+ cur_in_words += u' dollars'
3669+ if sum_frc == 1 or (str(sum_frc)[-1] == '1' and str(sum_frc)[-2] != '1'): # is the fraction sum one
3670+ if currency == 'LVL':
3671+ frc_in_words += u' santim'
3672+ elif currency == 'EUR' or currency == 'USD':
3673+ frc_in_words += u' cent'
3674+ else:
3675+ if currency == 'LVL':
3676+ frc_in_words += u' santims'
3677+ elif currency == 'EUR' or currency == 'USD' :
3678+ frc_in_words += u' cents'
3679+ #------------------------------------
3680+ if language == 'ru_RU' :
3681+ if sum_cur == 1 or (str(sum_cur)[-1] == '1' and str(sum_cur)[-2] != '1'): # is the currency sum one
3682+ if currency == 'LVL':
3683+ cur_in_words += u' лат'
3684+ elif currency == 'EUR':
3685+ cur_in_words += u' евро'
3686+ elif currency == 'USD':
3687+ cur_in_words += u' доллар США'
3688+ elif (sum_cur in [2, 3, 4]) or (str(sum_cur)[-1] in ['2', '3', '4'] and str(sum_cur)[-2] != '1'):
3689+ if currency == 'LVL':
3690+ cur_in_words += u' лата'
3691+ elif currency == 'EUR' :
3692+ cur_in_words += u' евро'
3693+ elif currency == 'USD' :
3694+ cur_in_words += u' доллара США'
3695+ elif (sum_cur >= 5 and sum_cur <= 20) or str(sum_cur)[-1] not in [2, 3, 4]:
3696+ if currency == 'LVL' :
3697+ cur_in_words += u' латов'
3698+ elif currency == 'EUR' :
3699+ cur_in_words += u' евро'
3700+ elif currency == 'USD' :
3701+ cur_in_words += u' долларов США'
3702+
3703+ if sum_frc == 1 or (str(sum_frc)[-1] == '1' and str(sum_frc)[-2] != '1') : # is the fraction one
3704+ if currency == 'LVL' :
3705+ frc_in_words += u' сантим'
3706+ elif currency == 'EUR' or currency == 'USD' :
3707+ frc_in_words += u' цент'
3708+ elif (sum_frc in [2, 3, 4]) or (str(sum_frc)[-1] in ['2', '3', '4'] and str(sum_frc)[-2] != '1') :
3709+ if currency == 'LVL' :
3710+ frc_in_words += u' сантима'
3711+ elif currency == 'EUR' or currency == 'USD' :
3712+ frc_in_words += u' цента'
3713+ elif (sum_frc >= 5 and sum_frc <= 20) or str(sum_frc)[-1] not in [2, 3, 4] :
3714+ if currency == 'LVL' :
3715+ frc_in_words += u' сантимов'
3716+ elif currency == 'EUR' or currency == 'USD' :
3717+ frc_in_words += u' центов'
3718+ #------------------------------------
3719+ if language == 'uk_UA' :
3720+ if sum_cur == 1 or (str(sum_cur)[-1] == '1' and str(sum_cur)[-2] != '1') : # is the currency sum one
3721+ if currency == 'LVL' :
3722+ cur_in_words += u' лат'
3723+ elif currency == 'EUR' :
3724+ cur_in_words += u' евро'
3725+ elif currency == 'USD' :
3726+ cur_in_words += u' доллар США'
3727+ elif currency == 'UAH' :
3728+ cur_in_words += u' гривня'
3729+ elif (sum_cur in [2, 3, 4]) or (str(sum_cur)[-1] in ['2', '3', '4'] and str(sum_cur)[-2] != '1') :
3730+ if currency == 'LVL' :
3731+ cur_in_words += u' лата'
3732+ elif currency == 'EUR' :
3733+ cur_in_words += u' евро'
3734+ elif currency == 'USD' :
3735+ cur_in_words += u' доллара США'
3736+ elif currency == 'UAH' :
3737+ cur_in_words += u' гривні'
3738+ elif (sum_cur >= 5 and sum_cur <= 20) or str(sum_cur)[-1] not in [2, 3, 4] :
3739+ if currency == 'LVL' :
3740+ cur_in_words += u' латов'
3741+ elif currency == 'EUR' :
3742+ cur_in_words += u' евро'
3743+ elif currency == 'USD' :
3744+ cur_in_words += u' долларов США'
3745+ elif currency == 'UAH' :
3746+ cur_in_words += u' гривень'
3747+
3748+ if sum_frc == 1 or (str(sum_frc)[-1] == '1' and str(sum_frc)[-2] != '1') : # is the fraction one
3749+ if currency == 'LVL' :
3750+ frc_in_words += u' сантим'
3751+ elif currency == 'EUR' or currency == 'USD' :
3752+ frc_in_words += u' цент'
3753+ elif currency == 'UAH' :
3754+ frc_in_words += u' копійка'
3755+ elif (sum_frc in [2, 3, 4]) or (str(sum_frc)[-1] in ['2', '3', '4'] and str(sum_frc)[-2] != '1') :
3756+ if currency == 'LVL' :
3757+ frc_in_words += u' сантима'
3758+ elif currency == 'EUR' or currency == 'USD' :
3759+ frc_in_words += u' цента'
3760+ elif currency == 'UAH' :
3761+ frc_in_words += u' копійки'
3762+ elif (sum_frc >= 5 and sum_frc <= 20) or str(sum_frc)[-1] not in [2, 3, 4] :
3763+ if currency == 'LVL' :
3764+ frc_in_words += u' сантимов'
3765+ elif currency == 'EUR' or currency == 'USD' :
3766+ frc_in_words += u' центов'
3767+ elif currency == 'UAH' :
3768+ frc_in_words += u' копійок'
3769+ frc_in_words = str(sum_frc) + u' коп.'
3770+
3771+ return (cur_in_words + ' ' + frc_in_words).strip().encode('utf-8')
3772+
3773+
3774+def dtowords(sum_integers, language):
3775+ """
3776+ >>> dtowords(0, 'en_US')
3777+ u'zero'
3778+
3779+ >>> dtowords(1, 'en_US')
3780+ u'one'
3781+
3782+ >>> dtowords(11, 'en_US')
3783+ u'eleven'
3784+
3785+ >>> dtowords(169, 'en_US')
3786+ u'one hundred sixty nine'
3787+
3788+ >>> dtowords(12345, 'en_US')
3789+ u'twelve thousand three hundred fourty five'
3790+
3791+ >>> dtowords(123456, 'en_US')
3792+ u'one hundred twenty three thousand four hundred fifty six'
3793+
3794+ >>> dtowords(0, 'lv_LV')
3795+ u'nulle'
3796+
3797+ >>> dtowords(1, 'lv_LV')
3798+ u'viens'
3799+
3800+ >>> dtowords(11, 'lv_LV')
3801+ u'vienpadsmit'
3802+
3803+ >>> dtowords(169, 'lv_LV').encode('utf-8') == 'simts sešdesmit deviņi'
3804+ True
3805+
3806+ >>> dtowords(12345, 'lv_LV').encode('utf-8') == 'divpadsmit tūkstoši trīs simti četrdesmit pieci'
3807+ True
3808+
3809+ >>> dtowords(123456, 'lv_LV').encode('utf-8') == 'simts divdesmit trīs tūkstoši četri simti piecdesmit seši'
3810+ True
3811+
3812+ >>> dtowords(0, 'ru_RU').encode('utf-8') == 'ноль'
3813+ True
3814+
3815+ >>> dtowords(1, 'ru_RU').encode('utf-8') == 'один'
3816+ True
3817+
3818+ >>> dtowords(11, 'ru_RU').encode('utf-8') == 'одиннадцать'
3819+ True
3820+
3821+ >>> dtowords(169, 'ru_RU').encode('utf-8') == 'стo шестьдесят девять'
3822+ True
3823+
3824+ >>> dtowords(12345, 'ru_RU').encode('utf-8') == 'двенадцать тысяч триста сорок пять'
3825+ True
3826+
3827+ >>> dtowords(123456, 'ru_RU').encode('utf-8') == 'стo двaдцать три тысячи четыреста пятьдесят шесть'
3828+ True
3829+
3830+
3831+ """
3832+ diginwords = u''
3833+ if sum_integers == 0:
3834+ return wordify('0', 0, language)
3835+ elif sum_integers > 0:
3836+ lengthx = len(str(sum_integers))
3837+ nrchunks = (lengthx / 3)
3838+ if nrchunks < (float(lengthx) / 3) :
3839+ nrchunks+=1
3840+ inc = 1
3841+ while inc <= nrchunks:
3842+ startpos = (lengthx - inc * 3)
3843+ chunklength = 3
3844+ if startpos < 0:
3845+ chunklength += startpos
3846+ startpos = 0
3847+ chunk = str(sum_integers)[startpos : startpos + chunklength]
3848+ #print str(startpos)+' '+str(chunklength)+' '+ chunk
3849+ wordified = wordify(chunk, inc-1, language)
3850+ inc += 1
3851+ spacer = ''
3852+ if len(diginwords) > 0 :
3853+ spacer = ' '
3854+ diginwords = wordified + spacer + diginwords
3855+ return diginwords
3856+
3857+def wordify(chunk, chunknr, language):
3858+ #print 'chunk '+str(chunk)
3859+ #print 'cunknr '+str(chunknr)
3860+ words = u''
3861+
3862+ if language == 'lv_LV':
3863+ skaitli = [u'nulle', u'viens', u'divi', u'trīs', u'četri', u'pieci',
3864+ u'seši', u'septiņi', u'astoņi', u'deviņi']
3865+ skaitlix = [u'nulle', u'vien', u'div', u'trīs', u'četr', u'piec', u'seš',
3866+ u'septiņ', u'astoņ', u'deviņ']
3867+ skaitli_teens = [u'desmit', u'vienpadsmit', u'divpadsmit', u'trīspadsmit',
3868+ u'četrpadsmit', u'piecpadsmit', u'sešpadsmit',
3869+ u'septiņpadsmit', u'astoņpadsmit', u'deviņpadsmit']
3870+ daudzums = [u'simts', u' tūkstotis', u' miljons', u' miljards']
3871+ daudzumsx = [u' simti', u' tūkstoši', u' miljoni', u' miljardi']
3872+
3873+ elif language == 'en_US':
3874+ skaitli = [u'zero', u'one', u'two', u'three', u'four', u'five', u'six',
3875+ u'seven', u'eight', u'nine']
3876+ skaitlix = [u'zero', u'one', u'twen', u'thir', u'four', u'fif', u'six',
3877+ u'seven', u'eigh', u'nine']
3878+ skaitli_teens = [u'ten', u'eleven', u'twelve', u'thirteen', u'fourteen',
3879+ u'fifteen', u'sixteen', u'seventeen', u'eighteen', u'nineteen']
3880+ daudzums = [u' hundred', u' thousand', u' million', u' billion']
3881+ daudzumsx = daudzums
3882+
3883+ elif language == 'ru_RU':
3884+ skaitli = [u'ноль', u'один', u'два', u'три', u'четыре', u'пять', u'шесть',
3885+ u'семь', u'восемь', u'девять']
3886+ skaitlix = [u'', u'один', u'двa', u'три', u'четыре', u'пять', u'шесть',
3887+ u'семь', u'восемь', u'девять']
3888+ skaitli_teens = [u'десять', u'одиннадцать', u'двенадцать', u'тринадцать',
3889+ u'четырнадцать', u'пятнадцать', u'шестнадцать', u'семнадцать',
3890+ u'восемнадцать', u'девятнадцать']
3891+ daudzums = [u'стo', u' тысяча', u' миллион', u' миллиард']
3892+ daudzumsx = [u'сoт', u' тысяч', u' миллионов', u' миллиардов']
3893+
3894+ elif language == 'uk_UA' :
3895+ skaitli = [u'ноль', u'один', u'два', u'три', u'чотири', u'п\'ять', u'шість',
3896+ u'сім', u'вісім', u'дев\'ять']
3897+ skaitlix = [u'', u'один', u'двa', u'три', u'чотири', u'п\'ять', u'шість',
3898+ u'сім', u'вісім', u'дев\'ять']
3899+ skaitli_teens = [u'десять', u'одинадцять', u'дванадцять', u'тринадцять',
3900+ u'чотирнадцять', u'п\'ятнадцять', u'шістнадцять', u'сімнадцять',
3901+ u'вісімнадцять', u'дев\'ятнадцять']
3902+ daudzums = [u'стo', u' тисяча', u' мiллiон', u' мiллiард']
3903+ daudzumsx = [u'сoт', u' тисяч', u' мiллiонiв', u' мiллiардов']
3904+ digit1 = u''
3905+ digit2 = u''
3906+ digit3 = u''
3907+ chunklength = len(chunk)
3908+ # placing digits in right places
3909+ if chunklength == 1:
3910+ digit3 = chunk[0 : 1]
3911+ if chunklength == 2:
3912+ digit2 = chunk[0 : 1]
3913+ digit3 = chunk[1 : 2]
3914+ if chunklength == 3:
3915+ digit1 = chunk[0 : 1]
3916+ digit2 = chunk[1 : 2]
3917+ digit3 = chunk[-1]
3918+ # processing zero
3919+ if chunklength == 1 and digit3 == '0' :
3920+ return skaitli[0]
3921+ # processing hundreds
3922+ if chunklength == 3 :
3923+ if digit1 == '1' :
3924+ if language == 'lv_LV' or language == 'ru_RU' or language == 'uk_UA':
3925+ words += daudzums[0]
3926+ elif language == 'en_US' :
3927+ words += skaitli[int(digit1)] + daudzumsx[0]
3928+ else :
3929+ if language == 'lv_LV' :
3930+ if int(digit1) > 1 : words += skaitli[int(digit1)] + daudzumsx[0]
3931+ elif language == 'en_US' :
3932+ if int(digit1) > 1 : words += skaitli[int(digit1)] + daudzumsx[0]
3933+ elif language == 'ru_RU' :
3934+ if int(digit1) == 2 :
3935+ words += u'двести'
3936+ elif int(digit1) == 3 :
3937+ words += u'триста'
3938+ elif int(digit1) == 4 :
3939+ words += u'четыреста'
3940+ elif int(digit1) >= 5 :
3941+ words += skaitli[int(digit1)] + daudzumsx[0]
3942+ elif language == 'uk_UA' :
3943+ if int(digit1) == 2 :
3944+ words += u'двісті'
3945+ elif int(digit1) == 3 :
3946+ words += u'триста'
3947+ elif int(digit1) == 4 :
3948+ words += u'чотириста'
3949+ elif int(digit1) >= 5 :
3950+ words += skaitli[int(digit1)] + daudzumsx[0]
3951+ # processing tens
3952+ if chunklength > 1:
3953+ spacer = ''
3954+ if len(words) > 0 : spacer = ' '
3955+ if digit2 == '1':
3956+ if language == 'lv_LV' or language == 'en_US' or language == 'ru_RU' or language == 'uk_UA':
3957+ words += spacer + skaitli_teens[int(digit3)]
3958+ else:
3959+ if language == 'lv_LV':
3960+ if int(digit2) > 1 and int(digit2) > 0:
3961+ words += spacer + skaitlix[int(digit2)] + u'desmit'
3962+ elif language == 'en_US':
3963+ if int(digit2) > 1 and int(digit2) > 0:
3964+ words += spacer + skaitlix[int(digit2)] + u'ty'
3965+ elif language == 'ru_RU':
3966+ if int(digit2) > 1 and int(digit2) < 4:
3967+ words += spacer + skaitlix[int(digit2)] + u'дцать'
3968+ elif digit2 == '4':
3969+ words += spacer + u'сорок'
3970+ elif int(digit2) >= 5 and int(digit2) != 9:
3971+ words += spacer + skaitlix[int(digit2)] + u'десят'
3972+ elif digit2 == '9':
3973+ words += spacer + u'девяносто'
3974+ elif language == 'uk_UA' :
3975+ if int(digit2) > 1 and int(digit2) < 4:
3976+ words += spacer + skaitlix[int(digit2)] + u'дцять'
3977+ elif digit2 == '4':
3978+ words += spacer + u'сорок'
3979+ elif int(digit2) >= 5 and int(digit2) != 9:
3980+ words += spacer + skaitlix[int(digit2)] + u'десят'
3981+ elif digit2 == '9':
3982+ words += spacer + u'дев\'яносто'
3983+ # processing ones
3984+ if chunklength > 0 and digit2 != '1' :
3985+ spacer = ''
3986+ if len(words) > 0: spacer = u' '
3987+ if language == 'lv_LV' or language == 'en_US':
3988+ if int(digit3) > 0:
3989+ words += spacer + skaitli[int(digit3)]
3990+ elif language == 'ru_RU':
3991+ if chunknr == 1:
3992+ if int(digit3) == 1:
3993+ words += spacer + u'одна'
3994+ elif int(digit3) == 2:
3995+ words += spacer + u'две'
3996+ elif int(digit3) >= 3 and int(digit3) != 0:
3997+ words += spacer + skaitli[int(digit3)]
3998+ else:
3999+ if int(digit3) > 0: words += spacer + skaitli[int(digit3)]
4000+ elif language == 'uk_UA' :
4001+ if chunknr == 1 :
4002+ if int(digit3) == 1 : words += spacer + u'одна'
4003+ elif int(digit3) == 2 : words += spacer + u'дві'
4004+ elif int(digit3) >= 3 and int(digit3) != 0: words += spacer + skaitli[int(digit3)]
4005+ else:
4006+ if int(digit3) > 0 : words += spacer + skaitli[int(digit3)]
4007+ # end processing
4008+ if len(words) > 0 :
4009+
4010+ if digit3 == '1' and chunknr > 0:
4011+ return words + daudzums[chunknr]
4012+ elif digit3 != '1' and chunknr > 0:
4013+ if language == 'lv_LV' or language == 'en_US' :
4014+ return words + daudzumsx[chunknr]
4015+ elif language == 'ru_RU' :
4016+ if (int(digit3) == 2 or int(digit3) == 3 or int(digit3) == 4) and digit2 != '1' :
4017+ if chunknr == 1 :
4018+ return words + u' тысячи'
4019+ elif chunknr == 2 :
4020+ return words + u' миллионa'
4021+ elif chunknr == 3 :
4022+ return words + u' миллиардa'
4023+ else:
4024+ return words + daudzumsx[chunknr]
4025+ elif language == 'uk_UA' :
4026+ if (int(digit3) == 2 or int(digit3) == 3 or int(digit3) == 4) and digit2 != '1' :
4027+ if chunknr == 1 :
4028+ return words + u' тисячі'
4029+ elif chunknr == 2 :
4030+ return words + u' мілліонa'
4031+ elif chunknr == 3 :
4032+ return words + u' мілліардa'
4033+ else:
4034+ return words + daudzumsx[chunknr]
4035+ else:
4036+ return words
4037+ else:
4038+ return ''
4039+
4040+
4041+if __name__ == '__main__':
4042+ import doctest
4043+ doctest.testmod()
4044+
4045+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4046
4047=== added directory 'report_aeroo/data'
4048=== added file 'report_aeroo/data/report_aeroo_data.xml'
4049--- report_aeroo/data/report_aeroo_data.xml 1970-01-01 00:00:00 +0000
4050+++ report_aeroo/data/report_aeroo_data.xml 2014-04-05 13:18:49 +0000
4051@@ -0,0 +1,25 @@
4052+<?xml version="1.0"?>
4053+<openerp>
4054+ <data noupdate="1">
4055+
4056+ <record model="report.mimetypes" id="report_mimetypes_odt_odt" >
4057+ <field name="name">ODF Text Document (.odt)</field>
4058+ <field name="code">oo-odt</field>
4059+ <field name="compatible_types">oo-odt</field>
4060+ </record>
4061+
4062+ <record model="report.mimetypes" id="report_mimetypes_ods_ods" >
4063+ <field name="name">ODF Spreadsheet (.ods)</field>
4064+ <field name="code">oo-ods</field>
4065+ <field name="compatible_types">oo-ods</field>
4066+ </record>
4067+
4068+ <record model="report.mimetypes" id="report_mimetypes_raw" >
4069+ <field name="name">Generic</field>
4070+ <field name="code">genshi-raw</field>
4071+ <field name="compatible_types">genshi-raw</field>
4072+ </record>
4073+
4074+ </data>
4075+</openerp>
4076+
4077
4078=== added file 'report_aeroo/domain_parser.py'
4079--- report_aeroo/domain_parser.py 1970-01-01 00:00:00 +0000
4080+++ report_aeroo/domain_parser.py 2014-04-05 13:18:49 +0000
4081@@ -0,0 +1,49 @@
4082+##############################################################################
4083+#
4084+# Copyright (c) 2009-2011 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
4085+# General contacts <info@alistek.com>
4086+#
4087+# WARNING: This program as such is intended to be used by professional
4088+# programmers who take the whole responsability of assessing all potential
4089+# consequences resulting from its eventual inadequacies and bugs
4090+# End users who are looking for a ready-to-use solution with commercial
4091+# garantees and support are strongly adviced to contract a Free Software
4092+# Service Company
4093+#
4094+# This program is Free Software; you can redistribute it and/or
4095+# modify it under the terms of the GNU General Public License
4096+# as published by the Free Software Foundation; either version 3
4097+# of the License, or (at your option) any later version.
4098+#
4099+# This module is GPLv3 or newer and incompatible
4100+# with OpenERP SA "AGPL + Private Use License"!
4101+#
4102+# This program is distributed in the hope that it will be useful,
4103+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4104+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4105+# GNU General Public License for more details.
4106+#
4107+# You should have received a copy of the GNU General Public License
4108+# along with this program; if not, write to the Free Software
4109+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4110+#
4111+##############################################################################
4112+
4113+def domain2statement(domain):
4114+ statement=''
4115+ operator=False
4116+ for d in domain:
4117+ if not operator:
4118+ if type(d)==str:
4119+ if d=='|':
4120+ operator=' or'
4121+ continue
4122+ else:
4123+ operator=False
4124+ statement+=' o.'+str(d[0])+' '+(d[1]=='=' and '==' or d[1])+' '+(isinstance(d[2], str) and '\''+d[2]+'\'' or str(d[2]))
4125+ if d!=domain[-1]:
4126+ statement+=operator or ' and'
4127+ operator=False
4128+ return statement
4129+
4130+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4131
4132=== added file 'report_aeroo/installer.py'
4133--- report_aeroo/installer.py 1970-01-01 00:00:00 +0000
4134+++ report_aeroo/installer.py 2014-04-05 13:18:49 +0000
4135@@ -0,0 +1,79 @@
4136+# -*- coding: utf-8 -*-
4137+##############################################################################
4138+#
4139+# Copyright (c) 2008-2013 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
4140+# General contacts <info@alistek.com>
4141+#
4142+# WARNING: This program as such is intended to be used by professional
4143+# programmers who take the whole responsability of assessing all potential
4144+# consequences resulting from its eventual inadequacies and bugs
4145+# End users who are looking for a ready-to-use solution with commercial
4146+# garantees and support are strongly adviced to contract a Free Software
4147+# Service Company
4148+#
4149+# This program is Free Software; you can redistribute it and/or
4150+# modify it under the terms of the GNU General Public License
4151+# as published by the Free Software Foundation; either version 3
4152+# of the License, or (at your option) any later version.
4153+#
4154+# This module is GPLv3 or newer and incompatible
4155+# with OpenERP SA "AGPL + Private Use License"!
4156+#
4157+# This program is distributed in the hope that it will be useful,
4158+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4159+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4160+# GNU General Public License for more details.
4161+#
4162+# You should have received a copy of the GNU General Public License
4163+# along with this program; if not, write to the Free Software
4164+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4165+#
4166+##############################################################################
4167+from openerp.osv import orm, fields
4168+from openerp import netsvc
4169+from openerp import tools
4170+import os, base64
4171+import urllib2
4172+
4173+_url = 'http://www.alistek.com/aeroo_banner/v7_0_report_aeroo.png'
4174+
4175+class report_aeroo_installer(orm.TransientModel):
4176+ _name = 'report.aeroo.installer'
4177+ _inherit = 'res.config.installer'
4178+ _logo_image = None
4179+
4180+ def _get_image(self, cr, uid, context=None):
4181+ if self._logo_image:
4182+ return self._logo_image
4183+ try:
4184+ im = urllib2.urlopen(_url.encode("UTF-8"))
4185+ if im.headers.maintype!='image':
4186+ raise TypeError(im.headers.maintype)
4187+ except Exception, e:
4188+ path = os.path.join('report_aeroo','config_pixmaps','module_banner.png')
4189+ image_file = file_data = tools.file_open(path,'rb')
4190+ try:
4191+ file_data = image_file.read()
4192+ self._logo_image = base64.encodestring(file_data)
4193+ return self._logo_image
4194+ finally:
4195+ image_file.close()
4196+ else:
4197+ self._logo_image = base64.encodestring(im.read())
4198+ return self._logo_image
4199+
4200+ def _get_image_fn(self, cr, uid, ids, name, args, context=None):
4201+ image = self._get_image(cr, uid, context)
4202+ return dict.fromkeys(ids, image) # ok to use .fromkeys() as the image is same for all
4203+
4204+ _columns = {
4205+ 'link':fields.char('Original developer', size=128, readonly=True),
4206+ 'config_logo': fields.function(_get_image_fn, string='Image', type='binary', method=True),
4207+ }
4208+
4209+ _defaults = {
4210+ 'config_logo': _get_image,
4211+ 'link':'http://www.alistek.com',
4212+ }
4213+
4214+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4215
4216=== added file 'report_aeroo/installer.xml'
4217--- report_aeroo/installer.xml 1970-01-01 00:00:00 +0000
4218+++ report_aeroo/installer.xml 2014-04-05 13:18:49 +0000
4219@@ -0,0 +1,56 @@
4220+<openerp>
4221+ <data>
4222+
4223+ <record id="view_report_aeroo_installer" model="ir.ui.view">
4224+ <field name="name">report.aeroo.installer.view</field>
4225+ <field name="model">report.aeroo.installer</field>
4226+ <field name="type">form</field>
4227+ <field name="inherit_id" ref="base.res_config_installer"/>
4228+ <field name="arch" type="xml">
4229+ <data>
4230+ <form position="attributes" version="7.0">
4231+ <attribute name="string">Aeroo Reports Installation</attribute>
4232+ </form>
4233+ <footer position="replace">
4234+ <footer>
4235+ <button name="action_next" type="object" string="Continue" invisible="context.get('menu',False)" class="oe_highlight"/>
4236+ or
4237+ <button special="cancel" string="Close" class="oe_link"/>
4238+ </footer>
4239+ </footer>
4240+ <separator string="title" position="replace">
4241+ <p class="oe_grey">
4242+ Aeroo Reports for OpenERP is a comprehensive reporting engine based on Aeroo Library.
4243+ </p>
4244+ <group>
4245+ <group width="25%%">
4246+ <field name="config_logo" widget="image" nolabel="1" colspan="2"/>
4247+ </group>
4248+ <group width="75%%">
4249+ <field name="link" widget="url"/>
4250+ </group>
4251+ </group>
4252+ </separator>
4253+ </data>
4254+ </field>
4255+ </record>
4256+
4257+ <record id="action_report_aeroo_installer" model="ir.actions.act_window">
4258+ <field name="name">Aeroo Reports Installation</field>
4259+ <field name="type">ir.actions.act_window</field>
4260+ <field name="res_model">report.aeroo.installer</field>
4261+ <field name="view_id" ref="view_report_aeroo_installer"/>
4262+ <field name="view_type">form</field>
4263+ <field name="view_mode">form</field>
4264+ <field name="target">new</field>
4265+ </record>
4266+
4267+ <record id="report_aeroo_installer_todo" model="ir.actions.todo">
4268+ <field name="action_id" ref="action_report_aeroo_installer"/>
4269+ <field name="restart">always</field>
4270+ <field name="sequence">3</field>
4271+ <field name="type">automatic</field>
4272+ </record>
4273+
4274+ </data>
4275+</openerp>
4276
4277=== added file 'report_aeroo/report_aeroo.py'
4278--- report_aeroo/report_aeroo.py 1970-01-01 00:00:00 +0000
4279+++ report_aeroo/report_aeroo.py 2014-04-05 13:18:49 +0000
4280@@ -0,0 +1,859 @@
4281+# -*- coding: utf-8 -*-
4282+##############################################################################
4283+#
4284+# Copyright (c) 2009-2013 Alistek Ltd (http://www.alistek.com) All Rights Reserved.
4285+# General contacts <info@alistek.com>
4286+# Copyright (C) 2009 Domsense s.r.l.
4287+#
4288+# WARNING: This program as such is intended to be used by professional
4289+# programmers who take the whole responsability of assessing all potential
4290+# consequences resulting from its eventual inadequacies and bugs
4291+# End users who are looking for a ready-to-use solution with commercial
4292+# garantees and support are strongly adviced to contract a Free Software
4293+# Service Company
4294+#
4295+# This program is Free Software; you can redistribute it and/or
4296+# modify it under the terms of the GNU General Public License
4297+# as published by the Free Software Foundation; either version 3
4298+# of the License, or (at your option) any later version.
4299+#
4300+# This module is GPLv3 or newer and incompatible
4301+# with OpenERP SA "AGPL + Private Use License"!
4302+#
4303+# This program is distributed in the hope that it will be useful,
4304+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4305+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4306+# GNU General Public License for more details.
4307+#
4308+# You should have received a copy of the GNU General Public License
4309+# along with this program; if not, write to the Free Software
4310+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4311+#
4312+##############################################################################
4313+
4314+import os, sys, traceback
4315+from tempfile import NamedTemporaryFile
4316+from openerp import report
4317+from report.report_sxw import report_sxw, report_rml, browse_record_list, _fields_process
4318+from report.pyPdf import PdfFileWriter, PdfFileReader
4319+#import zipfile
4320+try:
4321+ from cStringIO import StringIO
4322+except ImportError:
4323+ from StringIO import StringIO
4324+from xml.dom import minidom
4325+import base64
4326+from openerp.osv import orm
4327+from openerp import tools
4328+from tools.translate import _
4329+import time
4330+import re
4331+import copy
4332+import threading
4333+from random import randint
4334+try:
4335+ from addons import load_information_from_description_file # for OpenERP 6.0.x
4336+except ImportError:
4337+ from openerp.modules import load_information_from_description_file # for OpenERP 6.1 or 7.0
4338+from openerp import release
4339+
4340+import aeroolib
4341+from aeroolib.plugins.opendocument import Template, OOSerializer
4342+from genshi.template import NewTextTemplate
4343+from genshi import __version__ as genshi_version
4344+from openerp import pooler
4345+from openerp import netsvc
4346+from lxml import etree
4347+import logging
4348+
4349+logger = logging.getLogger(__name__)
4350+
4351+from .ExtraFunctions import ExtraFunctions
4352+
4353+try:
4354+ aeroo_lock = threading.Lock()
4355+ msg = "Aeroo lock instantiated."
4356+ logger.log(logging.INFO, msg)
4357+except Exception:
4358+ err_msg = "Could not instantiate Aeroo lock!!!"
4359+ logger.log(logging.CRITICAL, err_msg)
4360+
4361+from openerp import SUPERUSER_ID
4362+
4363+def _aeroo_ooo_test(cr):
4364+ '''
4365+ Detect report_aeroo_ooo module
4366+ '''
4367+ aeroo_ooo = False
4368+ cr.execute("SELECT id, state FROM ir_module_module WHERE name='report_aeroo_ooo'")
4369+ helper_module = cr.dictfetchone()
4370+ if helper_module and helper_module['state'] in ('installed', 'to upgrade'):
4371+ aeroo_ooo = True
4372+ return aeroo_ooo
4373+
4374+class Counter(object):
4375+ def __init__(self, name, start=0, interval=1):
4376+ self.name = name
4377+ self._number = start
4378+ self._interval = interval
4379+
4380+ def next(self, increment=True):
4381+ if increment:
4382+ self._number += self._interval
4383+ return self._number
4384+ else:
4385+ return self._number + self._interval
4386+
4387+ def get_inc(self):
4388+ return self._number
4389+
4390+ def prev(self, decrement=True):
4391+ if decrement:
4392+ self._number -= self._interval
4393+ return self._number
4394+ else:
4395+ return self._number-self._interval
4396+
4397+class AerooPrint(object):
4398+ print_ids = [] # static property
4399+ def __init__(self):
4400+ print_id = False
4401+ while(not print_id or print_id in self.print_ids):
4402+ print_id = randint(1, 99999)
4403+ self.print_ids.append(print_id)
4404+ self.id = print_id
4405+ self.subreports = []
4406+ self.epl_images = []
4407+ self.counters = {}
4408+ self.start_time = 0
4409+ self.start_total_time = 0
4410+
4411+class Aeroo_report(report_sxw):
4412+
4413+ _logger = logging.getLogger(__name__)
4414+
4415+ def __init__(self, cr, name, table, rml=False, parser=False, header=True, store=False):
4416+ super(Aeroo_report, self).__init__(name, table, rml, parser, header, store)
4417+ self._logger.info("registering %s (%s)" % (name, table))
4418+ self.active_prints = {}
4419+ self.oo_subreports = []
4420+ self.epl_images = []
4421+ self.counters = {}
4422+ self.start_time = 0
4423+
4424+ pool = pooler.get_pool(cr.dbname)
4425+ ir_obj = pool.get('ir.actions.report.xml')
4426+ name = name.startswith('report.') and name[7:] or name
4427+ try:
4428+ report_xml_ids = ir_obj.search(cr, SUPERUSER_ID, [('report_name', '=', name)])
4429+ if report_xml_ids:
4430+ report_xml = ir_obj.browse(cr, SUPERUSER_ID, report_xml_ids[0])
4431+ else:
4432+ report_xml = False
4433+
4434+ if report_xml and report_xml.preload_mode == 'preload':
4435+ file_data = report_xml.report_sxw_content
4436+ if not file_data:
4437+ self._logger.warning("template is not defined in %s (%s) !" % (name, table))
4438+ template_io = None
4439+ else:
4440+ template_io = StringIO()
4441+ template_io.write(base64.decodestring(file_data))
4442+ style_io=self.get_styles_file(cr, SUPERUSER_ID, report_xml)
4443+ if template_io:
4444+ self.serializer = OOSerializer(template_io, oo_styles=style_io)
4445+ except Exception, e:
4446+ print e
4447+
4448+ def getObjects_mod(self, cr, uid, ids, rep_type, context):
4449+ table_obj = pooler.get_pool(cr.dbname).get(self.table)
4450+ if rep_type=='aeroo':
4451+ return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context)
4452+ return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context)
4453+
4454+ ##### Counter functions #####
4455+ def _def_inc(self, aeroo_print):
4456+ def def_inc(name, start=0, interval=1):
4457+ aeroo_print.counters[name] = Counter(name, start, interval)
4458+ return def_inc
4459+
4460+ def _get_inc(self, aeroo_print):
4461+ def get_inc(name):
4462+ return aeroo_print.counters[name].get_inc()
4463+ return get_inc
4464+
4465+ def _prev(self, aeroo_print):
4466+ def prev(name):
4467+ return aeroo_print.counters[name].prev()
4468+ return prev
4469+
4470+ def _next(self, aeroo_print):
4471+ def next(name):
4472+ return aeroo_print.counters[name].next()
4473+ return next
4474+ #############################
4475+
4476+ def _epl_asimage(self, data, aeroo_print):
4477+ from PIL import Image
4478+ from math import ceil
4479+ if not data:
4480+ return ''
4481+ img = Image.open(StringIO(base64.decodestring(data)))
4482+ if img.format!='BMP':
4483+ return ''
4484+ data = base64.decodestring(data)[62:]
4485+ line_len = int(ceil(img.size[0]/32.0)*4)
4486+ temp_data = ''
4487+ for n in range(img.size[1]):
4488+ curr_pos = n*line_len
4489+ temp_data = data[curr_pos:curr_pos+line_len][:int(img.size[0]/8)] + temp_data
4490+
4491+ new_data = ''
4492+ for d in temp_data:
4493+ new_data += chr(ord(d)^255)
4494+ aeroo_print.epl_images.append(new_data)
4495+ return img.size
4496+
4497+ def _epl2_gw(self, aeroo_print):
4498+ def epl2_gw(start_x, start_y, data):
4499+ if not data:
4500+ return None
4501+ size_x, size_y = self._epl_asimage(data, aeroo_print)
4502+ return 'GW'+str(start_x)+','+str(start_y)+','+str(int(size_x/8))+','+str(size_y)+',<binary_data>'
4503+ return epl2_gw
4504+
4505+ def _include_document(self, print_id, aeroo_ooo=False):
4506+ def include_document(data, silent=False):
4507+ if not aeroo_ooo:
4508+ return _("Error! Include document not available!")
4509+ import binascii, urllib2
4510+ temp_file = NamedTemporaryFile(suffix='.odt', prefix='aeroo-report-', delete=False)
4511+ if os.path.isfile(data):
4512+ fd = file(data, 'rb')
4513+ data = fd.read()
4514+ else:
4515+ error = False
4516+ try:
4517+ url_file = urllib2.urlopen(data)
4518+ data = url_file.read()
4519+ except urllib2.HTTPError, e:
4520+ os.unlink(temp_file.name)
4521+ error = _('HTTP Error %s! File not found:') % e.getcode() + ' %s' % data
4522+ except urllib2.URLError, e:
4523+ os.unlink(temp_file.name)
4524+ error = _('Error!')+' %s' % e
4525+ except IOError, e:
4526+ os.unlink(temp_file.name)
4527+ error = _('Error!')+' %s' % e
4528+ except Exception, e:
4529+ try:
4530+ data = base64.decodestring(data)
4531+ except binascii.Error:
4532+ os.unlink(temp_file.name)
4533+ error = _('Error! File not found:')+' %s' % data
4534+ if error:
4535+ if not silent:
4536+ return error
4537+ else:
4538+ return None
4539+ try:
4540+ temp_file.write(data)
4541+ finally:
4542+ temp_file.close()
4543+ #self.oo_subreports[print_id].append(temp_file.name)
4544+ self.active_prints[print_id].subreports.append(temp_file.name)
4545+ return "<insert_doc('%s')>" % temp_file.name
4546+ return include_document
4547+
4548+ def _subreport(self, cr, uid, aeroo_print, output='odt', aeroo_ooo=False, context={}):
4549+ pool = pooler.get_pool(cr.dbname)
4550+ ir_obj = pool.get('ir.actions.report.xml')
4551+ #### for odt documents ####
4552+ def odt_subreport(name=None, obj=None):
4553+ if not aeroo_ooo:
4554+ return _("Error! Subreports not available!")
4555+ report_xml_ids = ir_obj.search(cr, uid, [('report_name', '=', name)], context=context)
4556+ if report_xml_ids:
4557+ service = netsvc.Service._services['report.%s' % name]
4558+ report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context)
4559+ data = {'model': obj._table_name, 'id': obj.id, 'report_type': 'aeroo', 'in_format': 'oo-odt'}
4560+ ### Get new printing object ###
4561+ sub_aeroo_print = AerooPrint()
4562+ service.active_prints[sub_aeroo_print.id] = sub_aeroo_print
4563+ context['print_id'] = sub_aeroo_print.id
4564+ ###############################
4565+ sub_aeroo_print.start_time = time.time()
4566+ report, output = service.create_aeroo_report(cr, uid, \
4567+ [obj.id], data, report_xml, context=context, output='odt') # change for OpenERP 6.0 - Service class usage
4568+
4569+ ### Delete printing object ###
4570+ AerooPrint.print_ids.remove(sub_aeroo_print.id)
4571+ del service.active_prints[sub_aeroo_print.id]
4572+ ##############################
4573+ with NamedTemporaryFile(suffix='.odt', prefix='aeroo-report-', delete=False) as temp_file:
4574+ temp_file.write(report)
4575+
4576+ #self.oo_subreports[print_id].append(temp_file.name)
4577+ aeroo_print.subreports.append(temp_file.name)
4578+
4579+ return "<insert_doc('%s')>" % temp_file.name
4580+ return None
4581+ #### for text documents ####
4582+ def raw_subreport(name=None, obj=None):
4583+ report_xml_ids = ir_obj.search(cr, uid, [('report_name', '=', name)], context=context)
4584+ if report_xml_ids:
4585+ report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context)
4586+ data = {'model': obj._table_name, 'id': obj.id, 'report_type': 'aeroo', 'in_format': 'genshi-raw'}
4587+ report, output = netsvc.Service._services['report.%s' % name].create_genshi_raw_report(cr, uid, \
4588+ [obj.id], data, report_xml, context=context, output=output) # change for OpenERP 6.0 - Service class usage
4589+ return report
4590+ return None
4591+
4592+ if output=='odt':
4593+ return odt_subreport
4594+ elif output=='raw':
4595+ return raw_subreport
4596+
4597+ def set_xml_data_fields(self, objects, parser):
4598+ xml_data_fields = parser.localcontext.get('xml_data_fields', False)
4599+ if xml_data_fields:
4600+ for field in xml_data_fields:
4601+ for o in objects:
4602+ if getattr(o, field):
4603+ xml_data = base64.decodestring(getattr(o, field))
4604+ xmldoc = minidom.parseString(xml_data)
4605+ setattr(o, field, xmldoc.firstChild)
4606+ return objects
4607+
4608+ def get_other_template(self, cr, uid, data, parser):
4609+ if hasattr(parser, 'get_template'):
4610+ pool = pooler.get_pool(cr.dbname)
4611+ record = pool.get(data['model']).browse(cr, uid, data['id'], {})
4612+ template = parser.get_template(cr, uid, record)
4613+ return template
4614+ else:
4615+ return False
4616+
4617+ def get_styles_file(self, cr, uid, report_xml, company=None, context=None):
4618+ pool = pooler.get_pool(cr.dbname)
4619+ style_io=None
4620+ if report_xml.styles_mode!='default':
4621+ if report_xml.styles_mode=='global':
4622+ company_id = company or pool.get('res.users')._get_company(cr, uid, context=context)
4623+ style_content = pool.get('res.company').browse(cr, uid, company_id, context=context).stylesheet_id
4624+ style_content = style_content and style_content.report_styles or False
4625+ elif report_xml.styles_mode=='specified':
4626+ style_content = report_xml.stylesheet_id
4627+ style_content = style_content and style_content.report_styles or False
4628+ if style_content:
4629+ style_io = StringIO()
4630+ style_io.write(base64.decodestring(style_content))
4631+ return style_io
4632+
4633+ def create_genshi_raw_report(self, cr, uid, ids, data, report_xml, context=None, output='raw', tmpl=False):
4634+ def preprocess(data, aeroo_print):
4635+ aeroo_print.epl_images.reverse()
4636+ while aeroo_print.epl_images:
4637+ img = aeroo_print.epl_images.pop()
4638+ data = data.replace('<binary_data>', img, 1)
4639+ return data.replace('\n', '\r\n')
4640+
4641+ print_id = context.get('print_id', False)
4642+ aeroo_print = self.active_prints[print_id] # Aeroo print object
4643+ if not aeroo_print.start_time:
4644+ aeroo_print.start_time = time.time()
4645+ if not context:
4646+ context={}
4647+ context = context.copy()
4648+ objects = self.getObjects_mod(cr, uid, ids, report_xml.report_type, context)
4649+ oo_parser = self.parser(cr, uid, self.name2, context=context)
4650+ oo_parser.localcontext.update(context)
4651+ oo_parser.set_context(objects, data, ids, report_xml.report_type)
4652+ self.set_xml_data_fields(oo_parser.objects, oo_parser) # Get/Set XML
4653+ oo_parser.localcontext['data'] = data
4654+ oo_parser.localcontext['user_lang'] = context.get('lang', False)
4655+ if len(objects)>0:
4656+ oo_parser.localcontext['o'] = objects[0]
4657+ xfunc = ExtraFunctions(cr, uid, report_xml.id, oo_parser.localcontext)
4658+ oo_parser.localcontext.update(xfunc.functions)
4659+ file_data = tmpl or self.get_other_template(cr, uid, data, oo_parser) or report_xml.report_sxw_content # Get other Tamplate
4660+ if not file_data or file_data=='False':
4661+ raise orm.except_orm(_('Error!'), _('No template found!'))
4662+ ################################################
4663+ if not file_data:
4664+ self._logger.info("End process %s (%s), elapsed time: %s" % (self.name, self.table, time.time() - aeroo_print.start_time)) # debug mode
4665+ return False, output
4666+
4667+ print_id = context.get('print_id', False)
4668+ aeroo_print = self.active_prints[print_id]
4669+
4670+ oo_parser.localcontext['include_subreport'] = self._subreport(cr, uid, aeroo_print, output='raw', aeroo_ooo=False, context=context)
4671+ oo_parser.localcontext['epl2_gw'] = self._epl2_gw(aeroo_print)
4672+ deferred = context.get('deferred_process')
4673+ oo_parser.localcontext['progress_update'] = deferred and deferred.progress_update or (lambda:True)
4674+
4675+ aeroo_print.epl_images = []
4676+ basic = NewTextTemplate(source=base64.decodestring(file_data))
4677+ if genshi_version<='0.6':
4678+ data = preprocess(basic.generate(**oo_parser.localcontext).render().decode('utf8').encode(report_xml.charset), aeroo_print)
4679+ else:
4680+ data = preprocess(basic.generate(**oo_parser.localcontext).render().encode(report_xml.charset), aeroo_print)
4681+
4682+ if report_xml.content_fname:
4683+ output = report_xml.content_fname
4684+ self._logger.info("End process %s (%s), elapsed time: %s" % (self.name, self.table, time.time() - aeroo_print.start_time)) # debug mode
4685+ return data, output
4686+
4687+ def _generate_doc(self, DC, data, report_xml, print_id):
4688+ with aeroo_lock:
4689+ DC.putDocument(data)
4690+ #subreports = self.oo_subreports.get(print_id)
4691+ aeroo_print = self.active_prints.get(print_id, False)
4692+ if aeroo_print:
4693+ DC.insertSubreports(aeroo_print.subreports)
4694+ #self.oo_subreports = []
4695+ #del self.oo_subreports[print_id]
4696+ if report_xml.out_format.code=='oo-dbf':
4697+ data = DC.saveByStream(report_xml.out_format.filter_name, "78")
4698+ else:
4699+ data = DC.saveByStream(report_xml.out_format.filter_name)
4700+ DC.closeDocument()
4701+ return data
4702+
4703+ def _raise_exception(self, e, print_id):
4704+ tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
4705+ self._logger.error(_("Report generation error!")+'\n'+tb_s)
4706+ #subreports = self.oo_subreports.get(print_id, [])
4707+ aeroo_print = self.active_prints.get(print_id, [])
4708+ if aeroo_print:
4709+ for sub_report in aeroo_print.subreports:
4710+ if os.path.isfile(sub_report):
4711+ os.unlink(sub_report)
4712+ raise Exception(_("Aeroo Reports: Error while generating the report."), e, str(e), _("For more reference inspect error logs."))
4713+
4714+ def create_aeroo_report(self, cr, uid, ids, data, report_xml, context=None, output='odt'):
4715+ """ Returns an aeroo report generated with aeroolib
4716+ """
4717+ pool = pooler.get_pool(cr.dbname)
4718+ if not context:
4719+ context={}
4720+ context = context.copy()
4721+ if self.name=='report.printscreen.list':
4722+ context['model'] = data['model']
4723+ context['ids'] = ids
4724+
4725+ print_id = context.get('print_id', False)
4726+ aeroo_print = self.active_prints[print_id] # Aeroo print object
4727+ aeroo_print.subreports = []
4728+ #self.oo_subreports[print_id] = []
4729+ objects = self.getObjects_mod(cr, uid, ids, report_xml.report_type, context) or []
4730+ oo_parser = self.parser(cr, uid, self.name2, context=context)
4731+ oo_parser.localcontext.update(context)
4732+ oo_parser.set_context(objects, data, ids, report_xml.report_type)
4733+ self.set_xml_data_fields(objects, oo_parser) # Get/Set XML
4734+
4735+ oo_parser.localcontext['data'] = data
4736+ oo_parser.localcontext['user_lang'] = context.get('lang', False)
4737+ if len(objects)>0:
4738+ oo_parser.localcontext['o'] = objects[0]
4739+ xfunc = ExtraFunctions(cr, uid, report_xml.id, oo_parser.localcontext)
4740+ oo_parser.localcontext.update(xfunc.functions)
4741+
4742+ #company_id = objects and 'company_id' in objects[0]._table._columns.keys() and \
4743+ # objects[0].company_id and objects[0].company_id.id or False # for object company usage
4744+ company_id = False
4745+ style_io=self.get_styles_file(cr, uid, report_xml, company=company_id, context=context)
4746+
4747+ if report_xml.tml_source in ('file', 'database'):
4748+ if not report_xml.report_sxw_content or report_xml.report_sxw_content=='False':
4749+ raise orm.except_orm(_('Error!'), _('No template found!'))
4750+ file_data = base64.decodestring(report_xml.report_sxw_content)
4751+ else:
4752+ file_data = self.get_other_template(cr, uid, data, oo_parser)
4753+ if not file_data and not report_xml.report_sxw_content:
4754+ self._logger.info("End process %s (%s), elapsed time: %s" % (self.name, self.table, time.time() - aeroo_print.start_time)) # debug mode
4755+ return False, output
4756+ #elif file_data:
4757+ # template_io = StringIO()
4758+ # template_io.write(file_data or report_xml.report_sxw_content)
4759+ # basic = Template(source=template_io, styles=style_io)
4760+ else:
4761+ if report_xml.preload_mode == 'preload' and hasattr(self, 'serializer'):
4762+ serializer = copy.copy(self.serializer)
4763+ serializer.apply_style(style_io)
4764+ template_io = serializer.template
4765+ else:
4766+ template_io = StringIO()
4767+ template_io.write(file_data or base64.decodestring(report_xml.report_sxw_content) )
4768+ serializer = OOSerializer(template_io, oo_styles=style_io)
4769+ try:
4770+ basic = Template(source=template_io, serializer=serializer)
4771+ except Exception, e:
4772+ self._raise_exception(e, print_id)
4773+
4774+ #if not file_data:
4775+ # return False, output
4776+
4777+ #basic = Template(source=template_io, serializer=serializer)
4778+
4779+ aeroo_ooo = context.get('aeroo_ooo', False)
4780+ oo_parser.localcontext['include_subreport'] = self._subreport(cr, uid, aeroo_print, output='odt', aeroo_ooo=aeroo_ooo, context=context)
4781+ oo_parser.localcontext['include_document'] = self._include_document(aeroo_ooo, print_id)
4782+ deferred = context.get('deferred_process')
4783+ oo_parser.localcontext['progress_update'] = deferred and deferred.progress_update or (lambda:True)
4784+ ####### Add counter functons to localcontext #######
4785+ oo_parser.localcontext.update({'def_inc':self._def_inc(aeroo_print),
4786+ 'get_inc':self._get_inc(aeroo_print),
4787+ 'prev':self._prev(aeroo_print),
4788+ 'next':self._next(aeroo_print)})
4789+
4790+ user_name = pool.get('res.users').browse(cr, uid, uid, {}).name
4791+ model_id = pool.get('ir.model').search(cr, uid, [('model','=',context.get('active_model', data['model']) or data['model'])])[0]
4792+ model_name = pool.get('ir.model').browse(cr, uid, model_id).name
4793+
4794+ #basic = Template(source=None, filepath=odt_path)
4795+
4796+ basic.Serializer.add_title(model_name)
4797+ basic.Serializer.add_creation_user(user_name)
4798+ module_info = load_information_from_description_file('report_aeroo')
4799+ version = module_info['version']
4800+ basic.Serializer.add_generator_info('Aeroo Lib/%s Aeroo Reports/%s' % (aeroolib.__version__, version))
4801+ basic.Serializer.add_custom_property('Aeroo Reports %s' % version, 'Generator')
4802+ basic.Serializer.add_custom_property('OpenERP %s' % release.version, 'Software')
4803+ basic.Serializer.add_custom_property(module_info['website'], 'URL')
4804+ basic.Serializer.add_creation_date(time.strftime('%Y-%m-%dT%H:%M:%S'))
4805+
4806+ try:
4807+ data = basic.generate(**oo_parser.localcontext).render().getvalue()
4808+ except orm.except_orm, e:
4809+ raise
4810+ except Exception, e:
4811+ self._raise_exception(e, print_id)
4812+
4813+ ######### OpenOffice extras #########
4814+ DC = netsvc.Service._services.get('openoffice')
4815+ if output!=report_xml.in_format[3:] or aeroo_print.subreports:
4816+ if aeroo_ooo and DC:
4817+ try:
4818+ data = self._generate_doc(DC, data, report_xml, print_id)
4819+ except Exception, e:
4820+ self._logger.error(_("OpenOffice.org related error!")+'\n'+str(e))
4821+ if DC._restart_ooo():
4822+ # We try again
4823+ try:
4824+ data = self._generate_doc(DC, data, report_xml, print_id)
4825+ except Exception, e:
4826+ self._logger.error(_("OpenOffice.org related error!")+'\n'+str(e))
4827+ if not report_xml.fallback_false:
4828+ output=report_xml.in_format[3:]
4829+ elif not report_xml.fallback_false:
4830+ output=report_xml.in_format[3:]
4831+ aeroo_print.subreports = []
4832+ else:
4833+ if report_xml.fallback_false:
4834+ if not aeroo_ooo:
4835+ raise orm.except_orm(_('OpenOffice.org related error!'), _('Module "report_aeroo_ooo" not installed.'))
4836+ elif not DC:
4837+ raise orm.except_orm(_('OpenOffice.org related error!'), _('Can not connect to OpenOffice.org.'))
4838+ else:
4839+ self._logger.warning("PDF generator temporarily offline, please wait a minute")
4840+ output=report_xml.in_format[3:]
4841+ elif output in ('pdf', 'doc', 'xls'):
4842+ output=report_xml.in_format[3:]
4843+ #####################################
4844+
4845+ if report_xml.content_fname:
4846+ output = report_xml.content_fname
4847+ self._logger.info("End process %s (%s), elapsed time: %s" % (self.name, self.table, time.time() - aeroo_print.start_time))
4848+ return data, output
4849+
4850+ # override needed to keep the attachments' storing procedure
4851+ def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None):
4852+ if not context:
4853+ context={}
4854+ if report_xml.report_type == 'aeroo':
4855+ if report_xml.out_format.code.startswith('oo-'):
4856+ output = report_xml.out_format.code[3:]
4857+ return self.create_aeroo_report(cr, uid, ids, data, report_xml, context=context, output=output)
4858+ elif report_xml.out_format.code =='genshi-raw':
4859+ return self.create_genshi_raw_report(cr, uid, ids, data, report_xml, context=context, output='raw')
4860+ logo = None
4861+ context = context.copy()
4862+ title = report_xml.name
4863+ rml = report_xml.report_rml_content
4864+ oo_parser = self.parser(cr, uid, self.name2, context=context)
4865+ objs = self.getObjects_mod(cr, uid, ids, report_xml.report_type, context)
4866+ oo_parser.set_context(objs, data, ids, report_xml.report_type)
4867+ processed_rml = self.preprocess_rml(etree.XML(rml),report_xml.report_type)
4868+ if report_xml.header:
4869+ oo_parser._add_header(processed_rml)
4870+ if oo_parser.logo:
4871+ logo = base64.decodestring(oo_parser.logo)
4872+ create_doc = self.generators[report_xml.report_type]
4873+ pdf = create_doc(etree.tostring(processed_rml),oo_parser.localcontext,logo,title.encode('utf8'))
4874+ return (pdf, report_xml.report_type)
4875+
4876+ def _get_attachment_create_vals(self, cr, uid, report_xml, vals, context=None):
4877+ if context is None:
4878+ context = {}
4879+ pool = pooler.get_pool(cr.dbname)
4880+ report_obj = pool.get('ir.actions.report.xml')
4881+ vals = report_obj._get_attachment_create_vals(cr, uid, report_xml, vals, context=context)
4882+ return vals
4883+
4884+ def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None):
4885+ if not context:
4886+ context={}
4887+ pool = pooler.get_pool(cr.dbname)
4888+ attach = report_xml.attachment
4889+ aeroo_ooo = _aeroo_ooo_test(cr) # Detect report_aeroo_ooo module
4890+ context['aeroo_ooo'] = aeroo_ooo
4891+ print_id = context.get('print_id', False)
4892+ aeroo_print = self.active_prints[print_id] # Aeroo print object
4893+ if attach or aeroo_ooo and report_xml.process_sep:
4894+ objs = self.getObjects_mod(cr, uid, ids, report_xml.report_type, context)
4895+ deferred = context.get('deferred_process')
4896+ results = []
4897+ for obj in objs:
4898+ aeroo_print.start_time = time.time()
4899+ if deferred:
4900+ deferred.progress_update()
4901+ aname = attach and eval(attach, {'object':obj, 'time':time}) or False
4902+ result = False
4903+ if report_xml.attachment_use and aname and context.get('attachment_use', True):
4904+ #aids = pool.get('ir.attachment').search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)])
4905+ #if aids:
4906+ # brow_rec = pool.get('ir.attachment').browse(cr, uid, aids[0])
4907+ # if not brow_rec.datas:
4908+ # continue
4909+ # d = base64.decodestring(brow_rec.datas)
4910+ # results.append((d,'pdf'))
4911+ # continue
4912+ cr.execute("SELECT id, datas_fname FROM ir_attachment WHERE datas_fname ilike %s and res_model=%s and res_id=%s LIMIT 1", (aname+'.%',self.table,obj.id))
4913+ search_res = cr.dictfetchone()
4914+ if search_res:
4915+ brow_rec = pool.get('ir.attachment').browse(cr, uid, search_res['id'])
4916+ if not brow_rec.datas:
4917+ continue
4918+ d = base64.decodestring(brow_rec.datas)
4919+ extension = search_res['datas_fname'].split('.')[1]
4920+ results.append((d,extension))
4921+ continue
4922+ result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context)
4923+ if not result:
4924+ return False
4925+ try:
4926+ if attach and aname:
4927+ name = aname+'.'+result[1]
4928+ datas = base64.encodestring(result[0])
4929+ ctx = dict(context)
4930+ ctx.pop('default_type', None)
4931+ vals = {
4932+ 'name': aname,
4933+ 'datas': datas,
4934+ 'file_size': len(datas),
4935+ 'datas_fname': name,
4936+ 'res_model': self.table,
4937+ 'res_id': obj.id,
4938+ 'type': 'binary',
4939+ }
4940+ attachment_vals = self._get_attachment_create_vals(
4941+ cr, uid, report_xml, vals, context=ctx)
4942+ pool.get('ir.attachment').create(cr, uid, attachment_vals, context=ctx)
4943+ cr.commit()
4944+ except Exception,e:
4945+ tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
4946+ self._logger.error(str(e))
4947+ results.append(result)
4948+ if results and len(results)==1:
4949+ return results[0]
4950+ if results:
4951+ not_pdf = filter(lambda r: r[1]!='pdf', results)
4952+ if not_pdf:
4953+ raise orm.except_orm(_('Error!'), _('Unsupported combination of formats!'))
4954+ #if results[0][1]=='pdf':
4955+ output = PdfFileWriter()
4956+ for r in results:
4957+ reader = PdfFileReader(StringIO(r[0]))
4958+ for page in range(reader.getNumPages()):
4959+ output.addPage(reader.getPage(page))
4960+ s = StringIO()
4961+ output.write(s)
4962+ return s.getvalue(), results[0][1]
4963+ return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
4964+
4965+ def create_source_odt(self, cr, uid, ids, data, report_xml, context=None):
4966+ if not context:
4967+ context={}
4968+ pool = pooler.get_pool(cr.dbname)
4969+ results = []
4970+ attach = report_xml.attachment
4971+ aeroo_ooo = _aeroo_ooo_test(cr) # Detect report_aeroo_ooo module
4972+ context['aeroo_ooo'] = aeroo_ooo
4973+ print_id = context.get('print_id', False)
4974+ aeroo_print = self.active_prints[print_id] # Aeroo print object
4975+ if attach or aeroo_ooo and report_xml.process_sep:
4976+ objs = self.getObjects_mod(cr, uid, ids, report_xml.report_type, context)
4977+ deferred = context.get('deferred_process')
4978+ for obj in objs:
4979+ aeroo_print.start_time = time.time()
4980+ if deferred:
4981+ deferred.progress_update()
4982+ aname = attach and eval(attach, {'object':obj, 'time':time}) or False
4983+ result = False
4984+ if report_xml.attachment_use and aname and context.get('attachment_use', True):
4985+ #aids = pool.get('ir.attachment').search(cr, uid, [('datas_fname','=',aname+'.odt'),('res_model','=',self.table),('res_id','=',obj.id)])
4986+ #if aids:
4987+ # brow_rec = pool.get('ir.attachment').browse(cr, uid, aids[0])
4988+ # if not brow_rec.datas:
4989+ # continue
4990+ # d = base64.decodestring(brow_rec.datas)
4991+ # results.append((d,'odt'))
4992+ # continue
4993+ cr.execute("SELECT id, datas_fname FROM ir_attachment WHERE datas_fname ilike %s and res_model=%s and res_id=%s LIMIT 1", (aname+'.%',self.table,obj.id))
4994+ search_res = cr.dictfetchone()
4995+ if search_res:
4996+ brow_rec = pool.get('ir.attachment').browse(cr, uid, search_res['id'])
4997+ if not brow_rec.datas:
4998+ continue
4999+ d = base64.decodestring(brow_rec.datas)
5000+ extension = search_res['datas_fname'].split('.')[1]
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches