if line.account_id.currency_id:
if line.account_id.currency_id.id != line.currency_id.id and (line.account_id.currency_id.id != line.account_id.company_id.currency_id.id or line.currency_id):
- raise osv.except_osv(_('Error'), _('Couldn\'t create move with currency different than the secondary currency of the account'))
+ raise osv.except_osv(_('Error'), _('Couldn\'t create move with currency different than the secondary currency of the account "%s - %s". Clear the secondary currency field of the account definition if you want to accept all currencies.' % (line.account_id.code, line.account_id.name)))
if abs(amount) < 0.0001:
if not len(line_draft_ids):
obj_journal = self.pool.get('account.journal')
obj_acc_template = self.pool.get('account.account.template')
- if obj_multi.code_digits<=5:
- raise osv.except_osv(_('User Error'), _('Account code should be of more than 5 digits.'))
-
# Creating Account
obj_acc_root = obj_multi.chart_template_id.account_root_id
tax_code_root_id = obj_multi.chart_template_id.tax_code_root_id.id
'name': (obj_acc_root.id == account_template.id) and obj_multi.company_id.name or account_template.name,
#'sign': account_template.sign,
'currency_id': account_template.currency_id and account_template.currency_id.id or False,
- 'code': code_acc[:dig],
+ 'code': code_acc,
'type': account_template.type,
'user_type': account_template.user_type and account_template.user_type.id or False,
'reconcile': account_template.reconcile,
from report.interface import report_int
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
-import reportlab.lib.colors as colors
-#from reportlab.graphics.widgetbase import Widget, TypedPropertyCollection
-#from reportlab.graphics.charts.textlabels import BarChartLabel
+import reportlab.lib.colors
#from reportlab.graphics import renderPM
-import tools
class accounting_report1(report_sxw.rml_parse):
self.localcontext.update({
'time': time,
'test': self.test1,
- 'lines':self.lines,
+# 'childs':self.process
})
- self.count=0
- self.list=[]
- def lines(self,data):
- res={}
- result=[]
- obj_inds=self.pool.get('account.report.report').browse(self.cr,self.uid,data['indicator_id'])
- def find_child(obj):
- self.list.append(obj)
- if obj.child_ids:
- for child in obj.child_ids:
- find_child(child)
- return True
- find_child(obj_inds)
-
- for obj_ind in self.list:
- res = {
- 'id':obj_ind.id,
- 'name':obj_ind.name,
- 'code':obj_ind.code,
- 'expression':obj_ind.expression,
- 'disp_graph':obj_ind.disp_graph,
- 'note':obj_ind.note,
- 'type':obj_ind.type
- }
- result.append(res)
- return result
-
- def test1(self,data,object):
- path=tools.config['root_path']+"/Temp_report/Image"
- obj_history=self.pool.get('account.report.history')
-
- if data['select_base']=='year':
- tuple_search=('fiscalyear_id','in',data['base_selection'][0][2])
- else:
- tuple_search=('period_id','in',data['base_selection'][0][2])
-
- history_ids=obj_history.search(self.cr,self.uid,[('name','=',object['id']),tuple_search])
- obj_his=obj_history.browse(self.cr,self.uid,history_ids)
-
- data_val=[]
- data_period=[]
- for item in obj_his:
- data_val.append(item.val)
- data_period.append(item.period_id.name)
- self.count +=1
- drawing = Drawing(400, 300)
+ def test1(self):
+ drawing = Drawing(400, 200)
data = [
- tuple(data_val),
+ (13, 5, 20, 22, 37, 45, 19, 4),
+ (11, 3, 10, 22, 30, 25, 29, 6),
]
- value_min=0.0
- vmin=min(data_val)
- vmax=max(data_val)
-
- val_min=((vmin < 0.00 and vmin-2.00) or 0.00)
- # calculating maximum
- val_max=(vmax/(pow(10,len(str(int(vmax)))-2))+1)*pow(10,len(str(int(vmax)))-2)
bc = VerticalBarChart()
bc.x = 50
bc.y = 50
- bc.height = 245
+ bc.height = 125
bc.width = 300
bc.data = data
- value_step=(abs(val_max)-abs(val_min))/5
-
- bc.strokeColor = colors.black
- bc.valueAxis.valueMin = val_min
- bc.valueAxis.valueMax = val_max
- bc.valueAxis.valueStep = value_step
-
+ bc.strokeColor = reportlab.lib.colors.black
+ bc.valueAxis.valueMin = 0
+ bc.valueAxis.valueMax = 50
+ bc.valueAxis.valueStep = 10
bc.categoryAxis.labels.boxAnchor = 'ne'
bc.categoryAxis.labels.dx = 8
-
bc.categoryAxis.labels.dy = -2
bc.categoryAxis.labels.angle = 30
- bc.categoryAxis.categoryNames = data_period
+ bc.categoryAxis.categoryNames = ['Jan-99','Feb-99','Mar-99',
+ 'Apr-99','May-99','Jun-99','Jul-99','Aug-99']
drawing.add(bc)
- drawing.save(formats=['png'],fnRoot=path+str(self.count),title="helo")
-# renderPM.drawToFile(drawing1, 'example1.jpg','jpg')
- return path+str(self.count)+'.png'
+# renderPM.drawToFile(drawing, 'example1.jpg','jpg')
+ return True
report_sxw.report_sxw('report.print.indicators', 'account.report.history',
<field name="active" select="1"/>
<field name="carrier_id" select="1"/>
<field name="sequence" select="1"/>
- <notebook>
+ <notebook colspan="4">
<page string="Grid definition">
<field colspan="4" name="line_ids" nolabel="1" select="1"/>
</page>
_description = "Packaging"
_rec_name = 'ean'
_columns = {
+ 'sequence': fields.integer('Sequence'),
'name' : fields.char('Description', size=64),
'qty' : fields.float('Quantity by Package',
help="The total number of products you can put by palet or box."),
_defaults = {
'rows' : lambda *a : 3,
+ 'sequence' : lambda *a : 1,
'ul' : _get_1st_ul,
}
<field colspan="4" name="packaging" nolabel="1">
<form string="Packaging">
<field name="ean" select="1"/>
+ <field name="sequence"/>
<newline/>
<field name="qty" select="1"/>
<field name="ul"/>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Packaging">
+ <field name="sequence"/>
<field name="ean"/>
<field name="qty"/>
<field name="ul"/>
<field name="arch" type="xml">
<form string="Packaging">
<field name="product_id" select="1"/>
+ <newline/>
<field name="ean" select="1"/>
+ <field name="sequence"/>
<newline/>
<field name="qty" select="1"/>
<field name="ul"/>
def test_state(self, cr, uid, ids, mode, *args):
assert mode in ('finished', 'canceled'), _("invalid mode for test_state")
finished = True
- canceled = False
+ canceled = False
+ notcanceled = False
write_done_ids = []
write_cancel_ids = []
for order in self.browse(cr, uid, ids, context={}):
finished = False
if line.procurement_id and line.procurement_id.state == 'cancel':
canceled = True
+ if line.procurement_id and line.procurement_id.state <> 'cancel':
+ notcanceled = True
# if a line is finished (ie its procuremnt is done or it has not procuremernt and it
# is not already marked as done, mark it as being so...
if ((not line.procurement_id) or line.procurement_id.state == 'done') and line.state != 'done':
if mode=='finished':
return finished
elif mode=='canceled':
+ if notcanceled:
+ return False
return canceled
def action_ship_create(self, cr, uid, ids, *args):
rml="sale/report/prepare_allot.rml"
auto="False"/>
-->
- <report auto="False" id="report_sale_order" model="sale.order" name="sale.order" rml="sale/report/order.rml" string="Print Order"/>
-
+ <report auto="False" id="report_sale_order" model="sale.order" name="sale.order" rml="sale/report/order.rml" string="Quotation / Order"/>
+
</data>
</openerp>
('tree', 'Tree'),
('form', 'Form'),
('graph', 'Graph'),
- ('calendar', 'Calendar')), string='Type of view', required=True),
+ ('calendar', 'Calendar'),
+ ('gantt', 'Gantt')), string='Type of view', required=True),
'act_window_id': fields.many2one('ir.actions.act_window', 'Action', ondelete='cascade'),
'multi': fields.boolean('On multiple doc.',
help="If set to true, the action will not be displayed on the right toolbar of a form views."),
('tree','Tree'),
('form','Form'),
('graph', 'Graph'),
- ('calendar', 'Calendar')), 'View Type', required=True),
+ ('calendar', 'Calendar'),
+ ('gantt', 'Gantt')), 'View Type', required=True),
'arch': fields.text('View Architecture', required=True),
'inherit_id': fields.many2one('ir.ui.view', 'Inherited View', ondelete='cascade'),
'field_parent': fields.char('Childs Field',size=64),
_columns = {
'wizard_id': fields.many2one('wizard.ir.model.menu.create','Wizard'),
'sequence': fields.integer('Sequence'),
- 'view_type': fields.selection([('tree','Tree'),('form','Form'),('graph','Graph'),('calendar','Calendar')],'View Type',required=True),
+ 'view_type': fields.selection([
+ ('tree','Tree'),
+ ('form','Form'),
+ ('graph','Graph'),
+ ('calendar','Calendar'),
+ ('gantt','Gantt')],'View Type',required=True),
'view_id': fields.many2one('ir.ui.view', 'View'),
}
_defaults = {
query = '(%s OR %s IS NULL)' % (query, left)
else:
params = []
- if right is False and operator == '=':
+ if (right == False or right is None) and operator == '=':
query = '%s IS NULL' % left
- elif right is False and operator in ['<>', '!=']:
+ elif (right == False or right is None) and operator in ['<>', '!=']:
query = '%s IS NOT NULL' % left
else:
if left == 'id':
units = [
(re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
- (re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
+ (re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
(re.compile('^(-?[0-9\.]+)\s*mm$'), reportlab.lib.units.mm),
(re.compile('^(-?[0-9\.]+)\s*$'), 1)
]
elif dict[key]=='int':
res[key] = int(node.getAttribute(key))
elif dict[key]=='unit':
- res[key] = unit_get(node.getAttribute(name))
+ res[key] = unit_get(node.getAttribute(key))
return res
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
--- /dev/null
+# -*- coding: iso8859-1 -*-
+##############################################################################
+#
+# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
+# Fabien Pinckaers <fp@tiny.Be>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+#-------------------------------------------------------------
+#ENGLISH
+#-------------------------------------------------------------
+
+ones = {
+ 0: '', 1:'One', 2:'Two', 3:'Three', 4:'Four', 5:'Five', 6:'Six', 7:'Seven', 8:'Eight', 9:'Nine',
+ 10:'Ten', 11:'Eleven', 12:'Twelve', 13:'Thirteen', 14:'Forteen', 15:'Fifteen', 16:'Sixteen', 17:"Seventeen",18:"Eighteen",19:"Nineteen",
+}
+
+tens = {
+ 1: 'Ten', 2: 'Twenty ', 3:'Thirty', 4:'Forty', 5:'Fifty', 6: 'Sixty', 7 : 'Seventy', 8:'Eighty' ,9: 'Ninety'}
+
+hundred = {
+ 0:'',1: 'One Hundred', 2: 'Two Hundred', 3: 'Three Hundred', 4 :'Four Hundred', 5: 'Five Hundred', 6: 'Six Hundred', 7 :'Seven Hundred', 8:' Eight Hundred ', 9:'Nine Hundred '
+}
+
+thousands ={
+ 0:'',1: 'One Thousand'
+}
+
+lacs = {
+ 0:'',1: 'Lac'
+}
+
+def _100_to_text(number):
+ if number in ones:
+ return ones[number]
+ else:
+ if number%10>0:
+ return tens[number / 10]+'-'+ones[number % 10]
+ else:
+ return tens[number / 10]
+
+def _1000_to_text(number):
+ d = _100_to_text(number % 100)
+ d2 = number/100
+ if d2>0 and d:
+ return hundred[d2]+' '+d
+ elif d2>1 and not(d):
+ return hundred[d2]+'s'
+ else:
+ return hundred[d2] or d
+
+def _10000_to_text(number):
+ if number==0:
+ return 'zero'
+ part1 = _1000_to_text(number % 1000)
+ part2 = thousands.get(number / 1000, _1000_to_text(number / 1000)+' Thousands')
+ if part2 and part1:
+ part1 = ' '+part1
+ return part2+part1
+
+def _1000000_to_text(number):
+ if number==0:
+ return 'zero'
+ part1 = _10000_to_text(number % 100000)
+ part2 = lacs.get(number / 100000, _10000_to_text(number / 100000)+' Lacs')
+ if part2 and part1:
+ part1 = ' '+part1
+ return part2+part1
+
+
+def amount_to_text(number, currency):
+ lacs_number = int(number)
+ units_name = currency
+ if lacs_number > 1:
+ units_name += 's'
+
+ lacs = _1000000_to_text(lacs_number)
+ lacs = lacs_number and '%s %s' % (lacs, units_name) or ''
+
+ units_number = int(number * 10000) % 10000
+ units = _10000_to_text(units_number)
+ units = units_number and '%s %s' % (units, units_name) or ''
+
+ cents_number = int(number * 100) % 100
+ cents_name = (cents_number > 1) and 'cents' or 'cent'
+ cents = _100_to_text(cents_number)
+ cents = cents_number and '%s %s' % (cents, cents_name) or ''
+ return lacs
+
+
+#-------------------------------------------------------------
+# Generic functions
+#-------------------------------------------------------------
+
+_translate_funcs = {'en' : amount_to_text}
+
+#TODO: we should use the country AND language (ex: septante VS soixante dix)
+#TODO: we should use en by default, but the translation func is yet to be implemented
+def amount_to_text(nbr, lang='en', currency='euro'):
+ """
+ Converts an integer to its textual representation, using the language set in the context if any.
+ Example:
+ 1654: thousands six cent cinquante-quatre.
+ """
+ if nbr > 10000000:
+#TODO: use logger
+ print "WARNING: number too large '%d', can't translate it!" % (nbr,)
+ return str(nbr)
+
+ if not _translate_funcs.has_key(lang):
+#TODO: use logger
+ print "WARNING: no translation function found for lang: '%s'" % (lang,)
+#TODO: (default should be en) same as above
+ lang = 'en'
+ return _translate_funcs[lang](nbr, currency)
+
+if __name__=='__main__':
+ from sys import argv
+
+ lang = 'nl'
+ if len(argv) < 2:
+ for i in range(1,200):
+ print i, ">>", int_to_text(i, lang)
+ for i in range(200,999999,139):
+ print i, ">>", int_to_text(i, lang)
+ else:
+ print int_to_text(int(argv[1]), lang)
+
options = {"py2exe": {
"compressed": 0,
"optimize": 2,
- "packages": ["decimal", "xml", "xml.dom", "xml.xpath", "encodings","mx.DateTime","wizard","pychart","PIL", "pyparsing", "pydot"],
+ "packages": ["lxml", "lxml.builder", "lxml._elementpath", "lxml.etree",
+ "lxml.objectify", "decimal", "xml", "xml.dom", "xml.xpath",
+ "encodings","mx.DateTime","wizard","pychart","PIL", "pyparsing",
+ "pydot"],
"excludes" : ["Tkconstants","Tkinter","tcl"],
}}
\r
\r
def StartTERP(self):\r
- # The server finds now its configuration automatically on Windows\r
- # We start the ERP Server as an independent process, but we keep its handle\r
- # The server's binary must be one directory above the service's binary (when py2exe'd the python libraries shouldn' mix)\r
- service_dir = os.path.dirname(sys.argv[0])\r
- server_dir = os.path.split(service_dir)[0]\r
- server_path = os.path.join(server_dir, 'openerp-server.exe')\r
- self.terpprocess = subprocess.Popen([server_path], \\r
- cwd=server_dir,\r
- creationflags=win32process.CREATE_NO_WINDOW)\r
+ # The server finds now its configuration automatically on Windows\r
+ # We start the ERP Server as an independent process, but we keep its handle\r
+ # The server's binary must be one directory above the service's binary (when py2exe'd the python libraries shouldn' mix)\r
+ service_dir = os.path.dirname(sys.argv[0])\r
+ server_dir = os.path.split(service_dir)[0]\r
+ server_path = os.path.join(server_dir, 'openerp-server.exe')\r
+ self.terpprocess = subprocess.Popen([server_path], cwd=server_dir, creationflags=win32process.CREATE_NO_WINDOW)\r
\r
\r
def StartControl(self,ws):\r
# Start OpenERP Server itself\r
self.StartTERP()\r
# start the loop waiting for the Service Manager's stop signal\r
- thread.start_new_thread(self.StartControl, (self.hWaitStop,))\r
- # Log a info message that the server is running\r
- servicemanager.LogInfoMsg("OpenERP Server up and running")\r
- # verification if the server is really running, else quit with an error\r
+ thread.start_new_thread(self.StartControl, (self.hWaitStop,))\r
+ # Log a info message that the server is running\r
+ servicemanager.LogInfoMsg("OpenERP Server up and running")\r
+ # verification if the server is really running, else quit with an error\r
self.terpprocess.wait()\r
if not self.stopping:\r
sys.exit("OpenERP Server check: server not running, check the logfile for more info")\r