[MERGE] merge with trunk addons

bzr revid: mra@mra-laptop-20100702071324-kcjq6m9s7hl29niw
bzr revid: mra@mra-laptop-20100702083333-ftyxwj0elwmb9cb3
bzr revid: mra@mra-laptop-20100702093820-i77e8r5o9nr2dowj
bzr revid: mra@mra-laptop-20100702103322-garklatxelh1dz4a
This commit is contained in:
Mustufa Rangwala
2010-07-02 16:03:22 +05:30
17 changed files with 143 additions and 86 deletions
-2
View File
@@ -2057,7 +2057,6 @@ class account_add_tmpl_wizard(osv.osv_memory):
def _get_def_cparent(self, cr, uid, context):
acc_obj=self.pool.get('account.account')
tmpl_obj=self.pool.get('account.account.template')
#print "Searching for ",context
tids=tmpl_obj.read(cr, uid, [context['tmpl_ids']], ['parent_id'])
if not tids or not tids[0]['parent_id']:
return False
@@ -2099,7 +2098,6 @@ class account_add_tmpl_wizard(osv.osv_memory):
# 'tax_ids': [(6,0,tax_ids)], todo!!
'company_id': company_id,
}
# print "Creating:", vals
new_account = acc_obj.create(cr, uid, vals)
return {'type':'state', 'state': 'end' }
+10 -8
View File
@@ -18,42 +18,42 @@
<field name="close_method">balance</field>
</record>
<record id="account_type_receivable" model="account.account.type">
<field name="name">Receivable</field>
<field name="name">Receivable</field>
<field name="code">receivable</field>
<field name="report_type">asset</field>
<field name="close_method">unreconciled</field>
</record>
<record id="account_type_liability" model="account.account.type">
<field name="name">Liability</field>
<field name="name">Liability</field>
<field name="code">liability</field>
<field name="report_type">liability</field>
<field name="close_method">balance</field>
</record>
<record id="account_type_payable" model="account.account.type">
<field name="name">Payable</field>
<field name="name">Payable</field>
<field name="code">payable</field>
<field name="report_type">liability</field>
<field name="close_method">unreconciled</field>
</record>
<record id="account_type_income" model="account.account.type">
<field name="name">Income</field>
<field name="name">Income</field>
<field name="code">income</field>
<field name="report_type">income</field>
<field name="close_method">none</field>
</record>
<record id="account_type_expense" model="account.account.type">
<field name="name">Expense</field>
<field name="name">Expense</field>
<field name="code">expense</field>
<field name="report_type">expense</field>
<field name="close_method">none</field>
</record>
<record id="account_type_cash_equity" model="account.account.type">
<field name="name">Equity</field>
<field name="name">Equity</field>
<field name="code">equity</field>
<field name="close_method">balance</field>
</record>
<record id="account_type_cash_moves" model="account.account.type">
<field name="name">Cash</field>
<field name="name">Cash</field>
<field name="code">cash</field>
<field name="report_type">asset</field>
<field name="close_method">balance</field>
@@ -179,6 +179,7 @@ your own chart of account.
<field name="type">sale</field>
<field name="view_id" ref="account_journal_view"/>
<field name="sequence_id" ref="sequence_sale_journal"/>
<field name="invoice_sequence_id" ref="seq_type_out_invoice"/>
<field model="account.account" name="default_credit_account_id" ref="a_sale"/>
<field model="account.account" name="default_debit_account_id" ref="a_sale"/>
<field name="user_id" ref="base.user_root"/>
@@ -201,6 +202,7 @@ your own chart of account.
<field name="type">purchase</field>
<field name="view_id" ref="account_journal_view"/>
<field name="sequence_id" ref="sequence_purchase_journal"/>
<field name="invoice_sequence_id" ref="seq_type_in_invoice"/>
<field model="account.account" name="default_debit_account_id" ref="a_expense"/>
<field model="account.account" name="default_credit_account_id" ref="a_expense"/>
<field name="user_id" ref="base.user_root"/>
@@ -241,7 +243,7 @@ your own chart of account.
<!--
Product income and expense accounts, default parameters
-->
<record id="property_account_expense_prd" model="ir.property">
<field name="name">property_account_expense</field>
<field name="fields_id" search="[('model','=','product.template'),('name','=','property_account_expense')]"/>
-7
View File
@@ -41,7 +41,6 @@ class rml_parse(report_sxw.rml_parse):
})
def comma_me(self,amount):
#print "#" + str(amount) + "#"
if not amount:
amount = 0.0
if type(amount) is float :
@@ -98,7 +97,6 @@ class rml_parse(report_sxw.rml_parse):
try:
Stringer = str.encode("utf-16")
except UnicodeDecodeError:
print "UTF_16 Error"
Stringer = str
else:
return Stringer
@@ -120,14 +118,12 @@ class rml_parse(report_sxw.rml_parse):
UnicodeAst = []
_previouslyfound = False
i = 0
#print str(ast)
while i < len(ast):
elem = ast[i]
try:
Stringer = elem.encode("utf-8")
except UnicodeDecodeError:
to_reencode = elem + ast[i+1]
print str(to_reencode)
Good_char = to_reencode.decode('utf-8')
UnicodeAst.append(Good_char)
i += i +2
@@ -139,14 +135,11 @@ class rml_parse(report_sxw.rml_parse):
return "".join(UnicodeAst)
def ReencodeAscii(self,str):
print sys.stdin.encoding
try:
Stringer = str.decode("ascii")
except UnicodeEncodeError:
print "REENCODING ERROR"
return str.encode("ascii")
except UnicodeDecodeError:
print "DECODING ERROR"
return str.encode("ascii")
else:
@@ -113,7 +113,6 @@ class accounting_report_indicator(report_sxw.rml_parse):
else:
temp_head = [str(x[0:3]) for x in self.header_name]
head_dict = dict(zip(temp_head,temp_head))
print "head_dict",head_dict
return [head_dict]
def getarray(self,data,object,array_header=''):
+6 -14
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -41,7 +41,6 @@ class rml_parse(report_sxw.rml_parse):
})
def comma_me(self,amount):
#print "#" + str(amount) + "#"
if not amount:
amount = 0.0
if type(amount) is float :
@@ -56,14 +55,14 @@ class rml_parse(report_sxw.rml_parse):
return new
else:
return self.comma_me(new)
def _ellipsis(self, string, maxlen=100, ellipsis = '...'):
ellipsis = ellipsis or ''
try:
return string[:maxlen - len(ellipsis) ] + (ellipsis, '')[len(string) < maxlen]
except Exception, e:
return False
def _strip_name(self, name, maxlen=50):
return self._ellipsis(name, maxlen, '...')
@@ -100,14 +99,13 @@ class rml_parse(report_sxw.rml_parse):
try:
Stringer = str.encode("utf-16")
except UnicodeDecodeError:
print "UTF_16 Error"
Stringer = str
else:
return Stringer
else:
return Stringer
return Stringer
def explode_this(self,chaine,length):
#chaine = self.repair_string(chaine)
chaine = rstrip(chaine)
@@ -118,20 +116,18 @@ class rml_parse(report_sxw.rml_parse):
i = i + length
chaine = str("".join(ast))
return chaine
def repair_string(self,chaine):
ast = list(chaine)
UnicodeAst = []
_previouslyfound = False
i = 0
#print str(ast)
while i < len(ast):
elem = ast[i]
try:
Stringer = elem.encode("utf-8")
except UnicodeDecodeError:
to_reencode = elem + ast[i+1]
print str(to_reencode)
Good_char = to_reencode.decode('utf-8')
UnicodeAst.append(Good_char)
i += i +2
@@ -141,17 +137,13 @@ class rml_parse(report_sxw.rml_parse):
return "".join(UnicodeAst)
def ReencodeAscii(self,str):
print sys.stdin.encoding
try:
Stringer = str.decode("ascii")
except UnicodeEncodeError:
print "REENCODING ERROR"
return str.encode("ascii")
except UnicodeDecodeError:
print "DECODING ERROR"
return str.encode("ascii")
else:
print Stringer
return Stringer
def _add_header(self, node, header=1):
+8 -9
View File
@@ -177,7 +177,7 @@ class Code128(MultiWidthBarcode):
Code 128 can also encode digits at double density (2 per byte)
and has a mandatory checksum. Code 128 is well supported and
commonly used -- for example, by UPS for tracking labels.
Because of these qualities, Code 128 is probably the best choice
for a linear symbology today (assuming you have a choice).
@@ -185,11 +185,11 @@ class Code128(MultiWidthBarcode):
value (int, or numeric string. required.):
The value to encode.
xdim (float, default .0075):
X-Dimension, or width of the smallest element
Minumum is .0075 inch (7.5 mils).
height (float, see default below):
Height of the symbol. Default is the height of the two
bearer bars (if they exist) plus the greater of .25 inch
@@ -197,14 +197,14 @@ class Code128(MultiWidthBarcode):
quiet (bool, default 1):
Wether to include quiet zones in the symbol.
lquiet (float, see default below):
Quiet zone size to left of code, if quiet is true.
Default is the greater of .25 inch, or 10 xdim
rquiet (float, defaults as above):
Quiet zone size to right left of code, if quiet is true.
Sources of Information on Code 128:
http://www.semiconductor.agilent.com/barcode/sg/Misc/code_128.html
@@ -223,7 +223,7 @@ class Code128(MultiWidthBarcode):
if type(value) is type(1):
value = str(value)
for (k, v) in args.items():
setattr(self, k, v)
@@ -288,12 +288,11 @@ class Code128(MultiWidthBarcode):
if l[1] in tos:
l[:2] = ['START_' + l[1][-1]]
# print `l`
# encode into numbers
start, set, shset = setmap[l[0]]
e = [start]
l = l[1:-1]
while l:
c = l[0]
-2
View File
@@ -34,8 +34,6 @@ def run():
story.append(Extended93("L@@K! Code 93 :-)")) #, xdim=0.005 * inch))
story.append(Paragraph('Code 128', styleN))
c=Code128("AB-12345678") #, xdim=0.005 * inch)
#print 'WIDTH =', (c.width / inch), 'XDIM =', (c.xdim / inch)
#print 'LQ =', (c.lquiet / inch), 'RQ =', (c.rquiet / inch)
story.append(c)
story.append(Paragraph('USPS FIM', styleN))
story.append(FIM("A"))
+2 -8
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -132,12 +132,6 @@ class report_custom(report_rml):
# file('/tmp/terp.xml','wb+').write(xml)
# end_time = time.clock()
# print "db:", mid_time-start_time
# print "addition:", mid_time2-mid_time
# print "buyer costs:", mid_time3-mid_time2
# print "seller costs:", mid_time4-mid_time3
# print "rest:", end_time-mid_time4
# print "total:", end_time-start_time
return self.post_process_xml_data(cr, uid, xml, context)
report_custom('report.auction.total', 'auction.lots', '', 'addons/auction/report/total.xsl')
+4 -4
View File
@@ -24,10 +24,10 @@
"version" : "1.0",
"depends" : ["base"],
'description': """Full featured calendar system that supports:
- Calendar of events
- Alerts (create requests)
- Recurring events (*)
- Invitations to others people""",
- Recurring events
- Invitations to people""",
"author" : "Tiny",
'category': 'Generic Modules/Others',
'website': 'http://www.openerp.com',
@@ -42,7 +42,7 @@
'wizard/base_calendar_set_exrule_view.xml',
'base_calendar_view.xml'
],
# "test" : ['test/base_calendar_test.yml'],
"test" : ['test/base_calendar_test.yml'],
"installable" : True,
"active" : False,
}
+55 -19
View File
@@ -375,7 +375,7 @@ property or property parameter."),
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
}
_defaults = {
'state': lambda *x: 'needs-action',
'state': 'needs-action',
}
def copy(self, cr, uid, id, default=None, context=None):
@@ -524,8 +524,7 @@ property or property parameter."),
@param *args: Get Tupple value
@param context: A standard dictionary for contextual values
"""
self.write(cr, uid, ids, {'state': 'tentative'}, context)
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
def do_accept(self, cr, uid, ids, context=None, *args):
"""
@@ -561,7 +560,7 @@ property or property parameter."),
@param *args: Get Tupple value
@param context: A standard dictionary for contextual values """
self.write(cr, uid, ids, {'state': 'declined'}, context)
return self.write(cr, uid, ids, {'state': 'declined'}, context)
def create(self, cr, uid, vals, context=None):
""" Overrides orm create method.
@@ -608,11 +607,11 @@ are both optional, but if one occurs, so MUST the other"""),
true, it will allow you to hide the event alarm information without removing it.")
}
_defaults = {
'trigger_interval': lambda *x: 'minutes',
'trigger_duration': lambda *x: 5,
'trigger_occurs': lambda *x: 'before',
'trigger_related': lambda *x: 'start',
'active': lambda *x: 1,
'trigger_interval': 'minutes',
'trigger_duration': 5,
'trigger_occurs': 'before',
'trigger_related': 'start',
'active': 1,
}
def do_alarm_create(self, cr, uid, ids, model, date, context=None):
@@ -753,8 +752,8 @@ class calendar_alarm(osv.osv):
}
_defaults = {
'action': lambda *x: 'email',
'state': lambda *x: 'run',
'action': 'email',
'state': 'run',
}
def create(self, cr, uid, vals, context=None):
@@ -1043,7 +1042,10 @@ class calendar_event(osv.osv):
'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
'Show as', states={'done': [('readonly', True)]}),
'base_calendar_url': fields.char('Caldav URL', size=264),
'base_calendar_url': fields.char('Caldav URL', size=264),
'state': fields.selection([('tentative', 'Tentative'),
('confirmed', 'Confirmed'),
('cancelled', 'Cancelled')], 'State', readonly=True),
'exdate': fields.text('Exception Date/Times', help="This property \
defines the list of date/time exceptions for arecurring calendar component."),
'exrule': fields.char('Exception Rule', size=352, help="defines a \
@@ -1101,13 +1103,14 @@ true, it will allow you to hide the event alarm information without removing it.
}
_defaults = {
'class': lambda *a: 'public',
'show_as': lambda *a: 'busy',
'freq': lambda *x: 'None',
'select1': lambda *x: 'date',
'interval': lambda *x: 1,
'active': lambda *x: 1,
}
'state': 'tentative',
'class': 'public',
'show_as': 'busy',
'freq': 'None',
'select1': 'date',
'interval': 1,
'active': 1,
}
def open_event(self, cr, uid, ids, context=None):
"""
@@ -1535,6 +1538,39 @@ true, it will allow you to hide the event alarm information without removing it.
alarm_obj = self.pool.get('res.alarm')
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
return res
def do_tentative(self, cr, uid, ids, context=None, *args):
""" Makes event invitation as Tentative
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of Event IDs
@param *args: Get Tupple value
@param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
def do_cancel(self, cr, uid, ids, context=None, *args):
""" Makes event invitation as Tentative
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of Event IDs
@param *args: Get Tupple value
@param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'cancelled'}, context)
def do_confirm(self, cr, uid, ids, context=None, *args):
""" Makes event invitation as Tentative
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of Event IDs
@param *args: Get Tupple value
@param context: A standard dictionary for contextual values
"""
return self.write(cr, uid, ids, {'state': 'confirmed'}, context)
calendar_event()
+27 -2
View File
@@ -206,7 +206,7 @@
<form string="Events">
<group col="6" colspan="4">
<field name="name" select="1" string="Summary"
colspan="4" />
colspan="4" required="1" />
<field name="allday" colspan="2" on_change="onchange_allday(allday)" />
<newline/>
<field name="date" string="Start Date" required="1" select="1"
@@ -289,7 +289,25 @@
</group>
<separator string="Description" colspan="4" />
<field name="description" nolabel="1" colspan="4" />
<separator colspan="4"/>
<separator colspan="4" string="" />
<group col="5" colspan="4">
<field name="state" select="2" />
<button name="do_tentative"
states="confirmed,cancelled"
string="Uncertain"
type="object"
icon="terp-crm" />
<button name="do_confirm"
string="Confirm"
states="tentative,cancelled"
type="object"
icon="gtk-apply" />
<button name="do_cancel"
string="Cancel"
states="tentative,confirmed"
type="object"
icon="gtk-cancel" />
</group>
</page>
<page string="Invitation Detail">
<button string="Invite People"
@@ -360,6 +378,7 @@
<field name="show_as" />
<field name="class" string="Privacy" />
<field name="user_id" invisible="1"/>
<field name="state" invisible="1"/>
</tree>
</field>
</record>
@@ -393,6 +412,10 @@
domain="[('user_id','=',uid)]"
help="My Events" />
<separator orientation="vertical"/>
<filter icon="terp-check" string="Confirmed"
domain="[('state','=','confirmed')]"
help="Confirmed Events" />
<separator orientation="vertical"/>
<field name="name" select="1" string="Summary"/>
<field name="location" select="1" string="Location"/>
<separator orientation="vertical"/>
@@ -403,6 +426,8 @@
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<filter string="Date" icon="terp-go-month"
domain="[]" context="{'group_by':'date'}" />
<filter string="Availability" icon="terp-camera_test"
@@ -3,3 +3,4 @@
"access_calendar_alarm","calendar.alarm","model_calendar_alarm","base.group_user",1,1,1,1
"access_res_alarm","res.alarm","model_res_alarm","base.group_user",1,1,1,1
"access_calendar_todo","calendar.todo","model_calendar_todo","base.group_user",1,1,1,1
"access_calendar_event","calendar.event.user","model_calendar_event","base.group_user",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
3 access_calendar_alarm calendar.alarm model_calendar_alarm base.group_user 1 1 1 1
4 access_res_alarm res.alarm model_res_alarm base.group_user 1 1 1 1
5 access_calendar_todo calendar.todo model_calendar_todo base.group_user 1 1 1 1
6 access_calendar_event calendar.event.user model_calendar_event base.group_user 1 1 1 1
+6
View File
@@ -176,6 +176,12 @@ class event_event(osv.osv):
'note': fields.text('Notes', help="Description or Summary of Event"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
"unit_price": fields.float('Cost'),
'partner_id': fields.many2one('res.partner','Teacher'),
'address_id': fields.many2one('res.partner.address','Location Room'),
'teacher_confirmed': fields.boolean('Teacher Confirmed'),
'country_id': fields.related('address_id', 'country_id',
type='many2one', relation='res.country', string='Country'),
}
+11 -1
View File
@@ -57,6 +57,11 @@
<page string="General">
<field name="unit_price"/>
<field name="currency_id"/>
<separator string="Teacher Information" colspan="4"/>
<field name="partner_id"/>
<field name="address_id"/>
<field name="teacher_confirmed"/>
<field name="country_id" />
<separator string="Event description" colspan="4"/>
<field name="parent_id" domain="[('parent_id','child_of','Event')]"/>
<field name="active"/>
@@ -97,6 +102,10 @@
<field name="register_current"/>
<field name="register_prospect"/>
</page>
<page string="Notes">
<separator string="Notes" colspan="4"/>
<field name="note" colspan="4" nolabel="1"/>
</page>
</notebook>
</form>
</field>
@@ -129,7 +138,8 @@
<field name="arch" type="xml">
<calendar color="user_id" date_start="date_begin" string="Event Organization">
<field name="name"/>
<field name="type"/>
<field name="partner_id"/>
<field name="type" widget="selection"/>
</calendar>
</field>
</record>
+7 -8
View File
@@ -310,7 +310,9 @@ class scrum_meeting(osv.osv):
meeting_id = self.browse(cr, uid, ids)[0]
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
if meeting_id and meeting_id.sprint_id.scrum_master_id.user_email:
self.email_send(cr, uid, ids, meeting_id.sprint_id.scrum_master_id.user_email)
res = self.email_send(cr, uid, ids, meeting_id.sprint_id.scrum_master_id.user_email)
if not res:
raise osv.except_osv(_('Error !'), _(' Email Not send to the scrum master %s!' % meeting_id.sprint_id.scrum_master_id.name))
else:
raise osv.except_osv(_('Error !'), _('Please provide email address for scrum master defined on sprint.'))
return True
@@ -321,7 +323,9 @@ class scrum_meeting(osv.osv):
context.update({'button_send_product_owner': True})
meeting_id = self.browse(cr, uid, ids)[0]
if meeting_id.sprint_id.product_owner_id.user_email:
self.email_send(cr,uid,ids,meeting_id.sprint_id.product_owner_id.user_email)
res = self.email_send(cr,uid,ids,meeting_id.sprint_id.product_owner_id.user_email)
if not res:
raise osv.except_osv(_('Error !'), _(' Email Not send to the product owner %s!' % meeting_id.sprint_id.product_owner_id.name))
else:
raise osv.except_osv(_('Error !'), _('Please provide email address for product owner defined on sprint.'))
return True
@@ -339,12 +343,7 @@ class scrum_meeting(osv.osv):
sub_name = meeting_id.name or 'Scrum Meeting of %s '%meeting_id.date
flag = tools.email_send(user_email , [email], sub_name, body, reply_to=None, openobject_id=str(meeting_id.id))
if not flag:
if context.get('button_send_product_owner', False):
raise osv.except_osv(_('Error !'), _(' Email Not send to the product owner %s!' % meeting_id.sprint_id.product_owner_id.name))
raise osv.except_osv(_('Error !'), _(' Email Not send to the scrum master %s!' % meeting_id.sprint_id.scrum_master_id.name))
if context.get('button_send_product_owner', False):
raise osv.except_osv(_('Information !'), _(' Email send successfully to product owner %s!' % meeting_id.sprint_id.product_owner_id.name))
raise osv.except_osv(_('Information!'), _(' Email send successfully to scrum master %s!'% meeting_id.sprint_id.scrum_master_id.name))
return False
return True
scrum_meeting()
+2 -1
View File
@@ -79,7 +79,8 @@ class subscription_subscription(osv.osv):
'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'State'),
'doc_source': fields.reference('Source Document', required=True, selection=_get_document_types, size=128),
'doc_lines': fields.one2many('subscription.subscription.history', 'subscription_id', 'Documents created', readonly=True),
'cron_id': fields.many2one('ir.cron', 'Cron Job')
'cron_id': fields.many2one('ir.cron', 'Cron Job'),
'note': fields.text('Notes', help="Description or Summary of Subscription"),
}
_defaults = {
'date_init': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
@@ -42,6 +42,10 @@
<page string="Documents created">
<field colspan="4" name="doc_lines" nolabel="1" widget="one2many_list"/>
</page>
<page string="Notes">
<separator string="Notes" colspan="4"/>
<field name="note" colspan="4" nolabel="1"/>
</page>
</notebook>
</form>
</field>