[MERGE] latest trunk

bzr revid: abo@openerp.com-20120727092135-6vsw4et9khbph9io
This commit is contained in:
Antonin Bourguignon 2012-07-27 11:21:35 +02:00
commit f14850b63d
42 changed files with 5554 additions and 233 deletions

View File

@ -315,8 +315,8 @@ class account_account(osv.osv):
cr.execute(request, params) cr.execute(request, params)
_logger.debug('Status: %s',(cr.statusmessage)) _logger.debug('Status: %s',(cr.statusmessage))
for res in cr.dictfetchall(): for row in cr.dictfetchall():
accounts[res['id']] = res accounts[row['id']] = row
# consolidate accounts with direct children # consolidate accounts with direct children
children_and_consolidated.reverse() children_and_consolidated.reverse()

View File

@ -455,7 +455,6 @@ class account_analytic_account(osv.osv):
'invoice_on_timesheets' : fields.boolean("Invoice On Timesheets"), 'invoice_on_timesheets' : fields.boolean("Invoice On Timesheets"),
'month_ids': fields.function(_analysis_all, multi='analytic_analysis', type='many2many', relation='account_analytic_analysis.summary.month', string='Month'), 'month_ids': fields.function(_analysis_all, multi='analytic_analysis', type='many2many', relation='account_analytic_analysis.summary.month', string='Month'),
'user_ids': fields.function(_analysis_all, multi='analytic_analysis', type="many2many", relation='account_analytic_analysis.summary.user', string='User'), 'user_ids': fields.function(_analysis_all, multi='analytic_analysis', type="many2many", relation='account_analytic_analysis.summary.user', string='User'),
'template_id': fields.many2one('account.analytic.account', 'Template of Contract'),
'hours_qtt_est': fields.float('Estimation of Hours to Invoice'), 'hours_qtt_est': fields.float('Estimation of Hours to Invoice'),
'est_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total Estimation"), 'est_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total Estimation"),
'invoiced_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total Invoiced"), 'invoiced_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total Invoiced"),
@ -483,18 +482,15 @@ class account_analytic_account(osv.osv):
def on_change_template(self, cr, uid, ids, template_id, context=None): def on_change_template(self, cr, uid, ids, template_id, context=None):
if not template_id: if not template_id:
return {} return {}
res = {'value':{}} res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
template = self.browse(cr, uid, template_id, context=context) if template_id and 'value' in res:
res['value']['date_start'] = template.date_start template = self.browse(cr, uid, template_id, context=context)
res['value']['date'] = template.date res['value']['fix_price_invoices'] = template.fix_price_invoices
res['value']['fix_price_invoices'] = template.fix_price_invoices res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets
res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets res['value']['hours_qtt_est'] = template.hours_qtt_est
res['value']['quantity_max'] = template.quantity_max res['value']['amount_max'] = template.amount_max
res['value']['hours_qtt_est'] = template.hours_qtt_est res['value']['to_invoice'] = template.to_invoice.id
res['value']['amount_max'] = template.amount_max res['value']['pricelist_id'] = template.pricelist_id.id
res['value']['to_invoice'] = template.to_invoice.id
res['value']['pricelist_id'] = template.pricelist_id.id
res['value']['description'] = template.description
return res return res
account_analytic_account() account_analytic_account()
@ -532,40 +528,25 @@ class account_analytic_account_summary_user(osv.osv):
def init(self, cr): def init(self, cr):
tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_user') tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_user')
cr.execute('CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS (' \ cr.execute('''CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS (
'SELECT ' \ with mu as
'(u.account_id * u.max_user) + u."user" AS id, ' \ (select max(id) as max_user from res_users)
'u.account_id AS account_id, ' \ , lu AS
'u."user" AS "user", ' \ (SELECT
'COALESCE(SUM(l.unit_amount), 0.0) AS unit_amount ' \ l.account_id AS account_id,
'FROM ' \ coalesce(l.user_id, 0) AS user_id,
'(SELECT ' \ SUM(l.unit_amount) AS unit_amount
'a.id AS account_id, ' \ FROM account_analytic_line AS l,
'u1.id AS "user", ' \ account_analytic_journal AS j
'MAX(u2.id) AS max_user ' \ WHERE (j.type = 'general' ) and (j.id=l.journal_id)
'FROM ' \ GROUP BY l.account_id, l.user_id
'res_users AS u1, ' \ )
'res_users AS u2, ' \ select (lu.account_id * mu.max_user) + lu.user_id as id,
'account_analytic_account AS a ' \ lu.account_id as account_id,
'GROUP BY u1.id, a.id ' \ lu.user_id as "user",
') AS u ' \ unit_amount
'LEFT JOIN ' \ from lu, mu)''')
'(SELECT ' \
'l.account_id AS account_id, ' \
'l.user_id AS "user", ' \
'SUM(l.unit_amount) AS unit_amount ' \
'FROM account_analytic_line AS l, ' \
'account_analytic_journal AS j ' \
'WHERE (j.type = \'general\') and (j.id=l.journal_id) ' \
'GROUP BY l.account_id, l.user_id ' \
') AS l '
'ON (' \
'u.account_id = l.account_id ' \
'AND u."user" = l."user"' \
') ' \
'GROUP BY u."user", u.account_id, u.max_user' \
')')
account_analytic_account_summary_user() account_analytic_account_summary_user()
class account_analytic_account_summary_month(osv.osv): class account_analytic_account_summary_month(osv.osv):

View File

@ -20,9 +20,6 @@
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/> <field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field eval="40" name="priority"/> <field eval="40" name="priority"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr='//field[@name="type"]' position='after'>
<field name="template_id" on_change="on_change_template(template_id,context)" domain="[('type','=','template')]" attrs="{'invisible': [('type','in',['view', 'normal','template'])]}" context="{'default_type' : 'template'}"/>
</xpath>
<xpath expr='//div[@name="duration"]' position="after" version="7.0"> <xpath expr='//div[@name="duration"]' position="after" version="7.0">
<label for="quantity_max"/> <label for="quantity_max"/>
<div> <div>

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,7 @@ class account_analytic_account(osv.osv):
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\ "The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
"If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\ "If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\
"The special type 'Template of Project' allows you to define a template with default data that you can reuse easily."), "The special type 'Template of Project' allows you to define a template with default data that you can reuse easily."),
'template_id': fields.many2one('account.analytic.account', 'Template of Contract'),
'description': fields.text('Description'), 'description': fields.text('Description'),
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2), 'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),
'child_ids': fields.one2many('account.analytic.account', 'parent_id', 'Child Accounts'), 'child_ids': fields.one2many('account.analytic.account', 'parent_id', 'Child Accounts'),
@ -184,6 +185,17 @@ class account_analytic_account(osv.osv):
}, string='Currency', type='many2one', relation='res.currency'), }, string='Currency', type='many2one', relation='res.currency'),
} }
def on_change_template(self, cr, uid, ids, template_id, context=None):
if not template_id:
return {}
res = {'value':{}}
template = self.browse(cr, uid, template_id, context=context)
res['value']['date_start'] = template.date_start
res['value']['date'] = template.date
res['value']['quantity_max'] = template.quantity_max
res['value']['description'] = template.description
return res
def on_change_partner_id(self, cr, uid, ids,partner_id, name, context={}): def on_change_partner_id(self, cr, uid, ids,partner_id, name, context={}):
res={} res={}
if partner_id: if partner_id:

View File

@ -18,6 +18,7 @@
<field name="partner_id" on_change="on_change_partner_id(partner_id, name)" attrs="{'required':[('type','=','contract')]}"/> <field name="partner_id" on_change="on_change_partner_id(partner_id, name)" attrs="{'required':[('type','=','contract')]}"/>
<field name="parent_id" on_change="on_change_parent(parent_id)" attrs="{'invisible': [('type','in',['contract','template'])]}"/> <field name="parent_id" on_change="on_change_parent(parent_id)" attrs="{'invisible': [('type','in',['contract','template'])]}"/>
<field name="type"/> <field name="type"/>
<field name="template_id" on_change="on_change_template(template_id,context)" domain="[('type','=','template')]" attrs="{'invisible': [('type','in',['view', 'normal','template'])]}" context="{'default_type' : 'template'}"/>
</group> </group>
<group> <group>
<field name="code"/> <field name="code"/>

View File

@ -1,29 +1,20 @@
openerp.anonymous = function(instance) { openerp.anonymous = function(instance) {
instance.web.client_actions.add("login", "instance.web.Login"); instance.web.Login.include({
start: function() {
instance.web.WebClient.include({ var self = this;
show_login: function() { return $.when(this._super()).pipe(function() {
var self = this, _super = this._super; var dblist = self._db_list;
this.login.load_db_list().then(function() {
var dblist = self.login._db_list;
if (dblist && dblist.length === 1) { if (dblist && dblist.length === 1) {
self.login.remember_credentials = false; self.remember_credentials = false;
// XXX get login/pass from server (via a rpc call) ? // XXX get login/pass from server (via a rpc call) ?
self.login.do_login(dblist[0], 'anonymous', 'anonymous').fail(function() { return self.do_login(dblist[0], 'anonymous', 'anonymous')
_super.apply(self, []);
});
} else {
_super.apply(self, []);
} }
}); });
}, },
restart: function() {
return this.start();
}
}); });
instance.web.UserMenu.include({ instance.web.UserMenu.include({
init: function(parent) { init: function(parent) {
this._super(parent); this._super(parent);
@ -39,8 +30,8 @@ openerp.anonymous = function(instance) {
var p = self.getParent(); var p = self.getParent();
var am = p.action_manager; var am = p.action_manager;
p.$element.find('.oe_leftbar').hide(); p.$element.find('.oe_leftbar').hide();
am.do_action({type:'ir.actions.client', tag:'login'}); am.do_action({type:'ir.actions.client', tag:'login', target: 'new'});
am.inner_widget.on('login', p, p.restart); am.dialog_widget.on('login', p, p.restart);
}); });
} }
}); });

View File

@ -4,10 +4,12 @@
<templates id="template" xml:space="preserve"> <templates id="template" xml:space="preserve">
<t t-name="UserMenu.anonymous"> <t t-name="UserMenu.anonymous">
<div>
<a href="#" class="oe_user_menu oe_topbar_item oe_topbar_anonymous_login"> <a href="#" class="oe_user_menu oe_topbar_item oe_topbar_anonymous_login">
<img class="oe_topbar_avatar" t-att-src="_s + '/web/static/src/img/icons/gtk-dialog-authentication.png'"/> <img class="oe_topbar_avatar" t-att-src="_s + '/web/static/src/img/icons/gtk-dialog-authentication.png'"/>
Login Login
</a> </a>
</div>
</t> </t>
</templates> </templates>

View File

@ -0,0 +1,113 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-07-25 09:59+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-07-26 04:39+0000\n"
"X-Generator: Launchpad (build 15679)\n"
#. #-#-#-#-# auth_openid.pot (OpenERP Server 6.1rc1) #-#-#-#-#
#. module: auth_openid
#. #-#-#-#-# auth_openid.pot.web (PROJECT VERSION) #-#-#-#-#
#. openerp-web
#: view:res.users:0
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:12
msgid "OpenID"
msgstr "ÅpenID"
#. #-#-#-#-# auth_openid.pot (OpenERP Server 6.1rc1) #-#-#-#-#
#. module: auth_openid
#. #-#-#-#-# auth_openid.pot.web (PROJECT VERSION) #-#-#-#-#
#. openerp-web
#: field:res.users,openid_url:0
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:47
msgid "OpenID URL"
msgstr ""
#. module: auth_openid
#: help:res.users,openid_email:0
msgid "Used for disambiguation in case of a shared OpenID URL"
msgstr ""
#. module: auth_openid
#: sql_constraint:res.users:0
msgid "You can not have two users with the same login !"
msgstr "Du kan ikke ha to brukere med samme login !"
#. module: auth_openid
#: field:res.users,openid_email:0
msgid "OpenID Email"
msgstr "OpenID epost"
#. module: auth_openid
#: constraint:res.users:0
msgid "The chosen company is not in the allowed companies for this user"
msgstr ""
"Det valgte firmaet er ikke i listen over tillatte firmaer for denne brukeren"
#. module: auth_openid
#: field:res.users,openid_key:0
msgid "OpenID Key"
msgstr ""
#. module: auth_openid
#: model:ir.model,name:auth_openid.model_res_users
msgid "res.users"
msgstr "res.users"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:8
msgid "Password"
msgstr "Passord"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:9
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:10
msgid "Google"
msgstr "Google"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:10
msgid "Google Apps"
msgstr "Google Apps"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:11
msgid "Launchpad"
msgstr "Launchpad"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:20
msgid "Google Apps Domain:"
msgstr "Google Apps domene:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:24
msgid "Username:"
msgstr "Brukernavn:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:28
msgid "OpenID URL:"
msgstr "OpenID URL:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:35
msgid "Google Apps Domain"
msgstr "Google Apps domene"
#. openerp-web
#: /home/odo/repositories/addons/trunk/auth_openid/static/src/xml/auth_openid.xml:41
msgid "Username"
msgstr "Brukernavn"

View File

@ -73,7 +73,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Meetings" version="7.0"> <form string="Meetings" version="7.0">
<header> <header>
<button name="case_open" string="Confirm" type="object" class="oe_highlight" <button name="case_open" string="Confirm" type="object"
states="draft"/> states="draft"/>
<button name="case_close" string="Done" type="object" <button name="case_close" string="Done" type="object"
states="open"/> states="open"/>

View File

@ -0,0 +1,47 @@
# Dutch (Belgium) translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-07-26 17:52+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-07-27 05:23+0000\n"
"X-Generator: Launchpad (build 15694)\n"
#. module: base_crypt
#: model:ir.model,name:base_crypt.model_res_users
msgid "res.users"
msgstr "res.users"
#. module: base_crypt
#: sql_constraint:res.users:0
msgid "You can not have two users with the same login !"
msgstr "U kunt geen twee gebruikers met dezelfde login maken."
#. module: base_crypt
#: constraint:res.users:0
msgid "The chosen company is not in the allowed companies for this user"
msgstr ""
"De gekozen firma behoort niet tot de toegelaten bedrijven voor deze "
"gebruiker."
#. module: base_crypt
#: code:addons/base_crypt/crypt.py:140
#, python-format
msgid "Please specify the password !"
msgstr "Gelieve een wachtwoord op te geven"
#. module: base_crypt
#: code:addons/base_crypt/crypt.py:140
#, python-format
msgid "Error"
msgstr "Fout"

View File

@ -208,7 +208,6 @@ class crm_lead(base_stage, osv.osv):
'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel (mail, direct, phone, ...)"), 'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel (mail, direct, phone, ...)"),
'contact_name': fields.char('Contact Name', size=64), 'contact_name': fields.char('Contact Name', size=64),
'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner company that will be created while converting the lead into opportunity', select=1), 'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner company that will be created while converting the lead into opportunity', select=1),
'opt_in': fields.boolean('Opt-In', oldname='optin', help="If opt-in is checked, this contact has accepted to receive emails."),
'opt_out': fields.boolean('Opt-Out', oldname='optout', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."), 'opt_out': fields.boolean('Opt-Out', oldname='optout', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."),
'type':fields.selection([ ('lead','Lead'), ('opportunity','Opportunity'), ],'Type', help="Type is used to separate Leads and Opportunities"), 'type':fields.selection([ ('lead','Lead'), ('opportunity','Opportunity'), ],'Type', help="Type is used to separate Leads and Opportunities"),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority', select=True), 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority', select=True),
@ -279,12 +278,6 @@ class crm_lead(base_stage, osv.osv):
self.create_send_note(cr, uid, [obj_id], context=context) self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id return obj_id
def on_change_opt_in(self, cr, uid, ids, opt_in):
return {'value':{'opt_in':opt_in,'opt_out':False}}
def on_change_opt_out(self, cr, uid, ids, opt_out):
return {'value':{'opt_out':opt_out,'opt_in':False}}
def onchange_stage_id(self, cr, uid, ids, stage_id, context={}): def onchange_stage_id(self, cr, uid, ids, stage_id, context={}):
if not stage_id: if not stage_id:
return {'value':{}} return {'value':{}}
@ -772,6 +765,7 @@ class crm_lead(base_stage, osv.osv):
res['context'] = { res['context'] = {
'default_opportunity_id': opportunity.id, 'default_opportunity_id': opportunity.id,
'default_partner_id': opportunity.partner_id and opportunity.partner_id.id or False, 'default_partner_id': opportunity.partner_id and opportunity.partner_id.id or False,
'default_partner_ids' : opportunity.partner_id and [opportunity.partner_id.id] or False,
'default_user_id': uid, 'default_user_id': uid,
'default_section_id': opportunity.section_id and opportunity.section_id.id or False, 'default_section_id': opportunity.section_id and opportunity.section_id.id or False,
'default_email_from': opportunity.email_from, 'default_email_from': opportunity.email_from,

View File

@ -204,8 +204,7 @@
<field name="state" groups="base.group_no_one"/> <field name="state" groups="base.group_no_one"/>
</group> </group>
<group string="Mailings"> <group string="Mailings">
<field name="opt_in" on_change="on_change_opt_in(opt_in)"/> <field name="opt_out" />
<field name="opt_out" on_change="on_change_opt_out(opt_out)"/>
</group> </group>
</group> </group>
</page> </page>
@ -543,8 +542,7 @@
<field name="channel_id" widget="selection"/> <field name="channel_id" widget="selection"/>
</group> </group>
<group string="Mailings"> <group string="Mailings">
<field name="opt_in" on_change="on_change_opt_in(opt_in)"/> <field name="opt_out" />
<field name="opt_out" on_change="on_change_opt_out(opt_out)"/>
</group> </group>
<group string="Misc"> <group string="Misc">
<field name="active"/> <field name="active"/>

View File

@ -129,7 +129,7 @@
<button type="action" <button type="action"
string="Schedule a Meeting" string="Schedule a Meeting"
name="%(base_calendar.action_crm_meeting)d" name="%(base_calendar.action_crm_meeting)d"
context="{'search_default_partner_ids': active_id}"/> context="{'search_default_partner_ids': active_id, 'default_partner_ids' : [active_id]}"/>
<button type="action" string="Schedule a Call" <button type="action" string="Schedule a Call"
name="%(crm.crm_case_categ_phone_create_partner)d" name="%(crm.crm_case_categ_phone_create_partner)d"
context="{'search_default_partner_id': active_id, 'default_duration': 1.0}" /> context="{'search_default_partner_id': active_id, 'default_duration': 1.0}" />

View File

@ -7,7 +7,6 @@
type: opportunity type: opportunity
stage_id: crm.stage_lead1 stage_id: crm.stage_lead1
state: draft state: draft
opt_in: True
- -
I create lead record to call Mailing opt-out onchange method. I create lead record to call Mailing opt-out onchange method.
- -

View File

@ -226,7 +226,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="company_id" position="before"> <field name="company_id" position="before">
<field name="weight"/> <field name="weight"/>
<field name="weight_net"/> <field name="weight_net" groups="base.group_no_one"/>
</field> </field>
</field> </field>
</record> </record>
@ -251,7 +251,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="/form/sheet/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after"> <xpath expr="/form/sheet/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
<field name="weight"/> <field name="weight"/>
<field name="weight_net"/> <field name="weight_net" groups="base.group_no_one"/>
</xpath> </xpath>
</field> </field>
</record> </record>
@ -264,7 +264,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//group[@name='main_grp']" position="inside"> <xpath expr="//group[@name='main_grp']" position="inside">
<field name="weight"/> <field name="weight"/>
<field name="weight_net"/> <field name="weight_net" groups="base.group_no_one"/>
</xpath> </xpath>
</field> </field>
</record> </record>
@ -299,7 +299,7 @@
<field name="model">stock.picking</field> <field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/> <field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="/form/header//button[@string='Create Invoice']" position="after"> <xpath expr="/form/header//button[@string='Create Invoice/Refund']" position="after">
<button name="%(report_shipping)d" string="Delivery Order" states="done" type="action" icon="gtk-print"/> <button name="%(report_shipping)d" string="Delivery Order" states="done" type="action" icon="gtk-print"/>
</xpath> </xpath>
</field> </field>

View File

@ -60,7 +60,7 @@ Openlabs was kept.
'wizard/email_template_preview_view.xml', 'wizard/email_template_preview_view.xml',
'email_template_view.xml', 'email_template_view.xml',
'res_partner_view.xml', 'res_partner_view.xml',
'wizard/email_compose_message_view.xml', 'wizard/mail_compose_message_view.xml',
'security/ir.model.access.csv' 'security/ir.model.access.csv'
], ],
"demo": [ "demo": [

View File

@ -41,10 +41,10 @@
on_change="on_change_template(use_template, template_id, False, False, context)"/> on_change="on_change_template(use_template, template_id, False, False, context)"/>
</xpath> </xpath>
<xpath expr="//a[@class='oe_mail_compose_message_checklist']" position="before"> <xpath expr="//a[@class='oe_mail_compose_message_checklist']" position="before">
<button icon="../../../../../email_template/static/src/img/email_template" <button icon="/email_template/static/src/img/email_template.png"
type="object" name="template_toggle" string="" type="object" name="template_toggle" string=""
help="Use a message template"/> help="Use a message template"/>
<button icon="../../../../../email_template/static/src/img/email_template_save" <button icon="/email_template/static/src/img/email_template_save.png"
type="object" name="save_as_template" string="" type="object" name="save_as_template" string=""
help="Save as a new template"/> help="Save as a new template"/>
</xpath> </xpath>

1264
addons/event/i18n/nb.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,3 +5,4 @@ access_hr_holidays_employee,hr.holidays.employee,model_hr_holidays,base.group_us
access_hr_holydays_status_employee,hr.holidays.status employee,model_hr_holidays_status,base.group_user,1,0,0,0 access_hr_holydays_status_employee,hr.holidays.status employee,model_hr_holidays_status,base.group_user,1,0,0,0
access_hr_holidays_remain_user,hr.holidays.ramain.user,model_hr_holidays_remaining_leaves_user,base.group_hr_user,1,1,1,1 access_hr_holidays_remain_user,hr.holidays.ramain.user,model_hr_holidays_remaining_leaves_user,base.group_hr_user,1,1,1,1
access_resource_calendar_leaves_manager,resource_calendar_leaves_manager,resource.model_resource_calendar_leaves,base.group_hr_manager,1,1,1,1 access_resource_calendar_leaves_manager,resource_calendar_leaves_manager,resource.model_resource_calendar_leaves,base.group_hr_manager,1,1,1,1
access_crm_meeting_type_manager,crm.meeting.type.manager,base_calendar.model_crm_meeting_type,base.group_hr_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
5 access_hr_holydays_status_employee hr.holidays.status employee model_hr_holidays_status base.group_user 1 0 0 0
6 access_hr_holidays_remain_user hr.holidays.ramain.user model_hr_holidays_remaining_leaves_user base.group_hr_user 1 1 1 1
7 access_resource_calendar_leaves_manager resource_calendar_leaves_manager resource.model_resource_calendar_leaves base.group_hr_manager 1 1 1 1
8 access_crm_meeting_type_manager crm.meeting.type.manager base_calendar.model_crm_meeting_type base.group_hr_manager 1 1 1 1

View File

@ -198,6 +198,13 @@ class account_analytic_account(osv.osv):
_columns = { _columns = {
'use_timesheets': fields.boolean('Timesheets', help="Check this field if this project manages timesheets"), 'use_timesheets': fields.boolean('Timesheets', help="Check this field if this project manages timesheets"),
} }
def on_change_template(self, cr, uid, ids, template_id, context=None):
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
if template_id and 'value' in res:
template = self.browse(cr, uid, template_id, context=context)
res['value']['use_timesheets'] = template.use_timesheets
return res
account_analytic_account() account_analytic_account()

View File

@ -90,32 +90,28 @@ class account_analytic_line(osv.osv):
context2 = context.copy() context2 = context.copy()
context2['lang'] = partner.lang context2['lang'] = partner.lang
cr.execute("SELECT product_id, to_invoice, sum(unit_amount), product_uom_id " \ cr.execute("SELECT product_id, to_invoice, sum(unit_amount), product_uom_id, name " \
"FROM account_analytic_line as line " \ "FROM account_analytic_line as line " \
"WHERE account_id = %s " \ "WHERE account_id = %s " \
"AND id IN %s AND to_invoice IS NOT NULL " \ "AND id IN %s AND to_invoice IS NOT NULL " \
"GROUP BY product_id,to_invoice,product_uom_id", (account.id, tuple(ids),)) "GROUP BY product_id, to_invoice, product_uom_id, name", (account.id, tuple(ids),))
for product_id, factor_id, qty, uom in cr.fetchall(): for product_id, factor_id, qty, uom, line_name in cr.fetchall():
product = product_obj.browse(cr, uid, product_id, context2) if data.get('product'):
product_id = data['product'][0]
product = product_obj.browse(cr, uid, product_id, context=context2)
if not product: if not product:
raise osv.except_osv(_('Error'), _('At least one line has no product !')) raise osv.except_osv(_('Error'), _('There is no product defined for the line %s. Please select one or force the product through the wizard.') % (line_name))
factor_name = '' factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
factor = invoice_factor_obj.browse(cr, uid, factor_id, context2) factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
if not data.get('product', False): if factor.customer_name:
if factor.customer_name: factor_name += ' - ' + factor.customer_name
factor_name = product.name+' - '+factor.customer_name
else:
factor_name = product.name
else:
data['product'] = data['product'][0]
factor_name = product_obj.name_get(cr, uid, [data['product']], context=context)[0][1]
ctx = context.copy() ctx = context.copy()
ctx.update({'uom':uom}) ctx.update({'uom':uom})
if account.pricelist_id: if account.pricelist_id:
pl = account.pricelist_id.id pl = account.pricelist_id.id
price = pro_price_obj.price_get(cr,uid,[pl], data.get('product', False) or product_id, qty or 1.0, account.partner_id.id, context=ctx)[pl] price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=ctx)[pl]
else: else:
price = 0.0 price = 0.0
@ -131,7 +127,7 @@ class account_analytic_line(osv.osv):
'invoice_line_tax_id': [(6,0,tax )], 'invoice_line_tax_id': [(6,0,tax )],
'invoice_id': last_invoice, 'invoice_id': last_invoice,
'name': factor_name, 'name': factor_name,
'product_id': data.get('product',product_id), 'product_id': product_id,
'invoice_line_tax_id': [(6,0,tax)], 'invoice_line_tax_id': [(6,0,tax)],
'uos_id': uom, 'uos_id': uom,
'account_id': account_id, 'account_id': account_id,
@ -179,7 +175,7 @@ class hr_timesheet_invoice_create(osv.osv_memory):
'time': fields.boolean('Time spent', help='The time of each work done will be displayed on the invoice'), 'time': fields.boolean('Time spent', help='The time of each work done will be displayed on the invoice'),
'name': fields.boolean('Description', help='The detail of each work done will be displayed on the invoice'), 'name': fields.boolean('Description', help='The detail of each work done will be displayed on the invoice'),
'price': fields.boolean('Cost', help='The cost of each work done will be displayed on the invoice. You probably don\'t want to check this'), 'price': fields.boolean('Cost', help='The cost of each work done will be displayed on the invoice. You probably don\'t want to check this'),
'product': fields.many2one('product.product', 'Product', help='Fill this field only if you want to force to use a specific product. Keep empty to use the real product that comes from the cost.'), 'product': fields.many2one('product.product', 'Force Product', help='Fill this field only if you want to force to use a specific product. Keep empty to use the real product that comes from the cost.'),
} }
_defaults = { _defaults = {

View File

@ -20,22 +20,31 @@
############################################################################## ##############################################################################
import time import time
from report import report_sxw
from report_webkit import webkit_report
from report_webkit import report_helper
from osv import osv
from tools import mod10r
import sys import sys
import os import os
import re import re
from mako.template import Template
from mako.lookup import TemplateLookup
from mako import exceptions
from report import report_sxw
from report_webkit import webkit_report
from report_webkit import report_helper
from osv import osv
from osv.osv import except_osv
from tools import mod10r
from tools.translate import _
from tools.config import config
import wizard import wizard
import addons import addons
import pooler import pooler
from tools.config import config
from mako.template import Template
from mako import exceptions
from tools.translate import _
from osv.osv import except_osv
class l10n_ch_report_webkit_html(report_sxw.rml_parse): class l10n_ch_report_webkit_html(report_sxw.rml_parse):
@ -143,53 +152,26 @@ class l10n_ch_report_webkit_html(report_sxw.rml_parse):
'digits!\nPlease check your company ' 'digits!\nPlease check your company '
'information for the invoice:\n%s') %(invoice_name))) 'information for the invoice:\n%s') %(invoice_name)))
return '' return ''
def mako_template(text):
"""Build a Mako template.
This template uses UTF-8 encoding
"""
tmp_lookup = TemplateLookup() #we need it in order to allow inclusion and inheritance
return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup)
class BVRWebKitParser(webkit_report.WebKitParser): class BVRWebKitParser(webkit_report.WebKitParser):
def setLang(self, lang):
if not lang:
lang = 'en_US'
self.localcontext['lang'] = lang
def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False):
"""format using the know cursor, language from localcontext"""
if digits is None:
digits = self.parser_instance.get_digits(value)
if isinstance(value, (str, unicode)) and not value:
return ''
pool_lang = self.pool.get('res.lang')
lang = self.localcontext['lang']
lang_ids = pool_lang.search(self.parser_instance.cr, self.parser_instance.uid, [('code','=',lang)])[0]
lang_obj = pool_lang.browse(self.parser_instance.cr, self.parser_instance.uid, lang_ids)
if date or date_time:
if not str(value):
return ''
date_format = lang_obj.date_format
parse_format = '%Y-%m-%d'
if date_time:
value=value.split('.')[0]
date_format = date_format + " " + lang_obj.time_format
parse_format = '%Y-%m-%d %H:%M:%S'
if not isinstance(value, time.struct_time):
return time.strftime(date_format, time.strptime(value, parse_format))
else:
date = datetime(*value.timetuple()[:6])
return date.strftime(date_format)
return lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None): def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
"""generate the PDF""" """generate the PDF"""
self.parser_instance = self.parser( context = context or {}
cursor, if report_xml.report_type != 'webkit':
return super(WebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context)
self.parser_instance = self.parser(cursor,
uid, uid,
self.name2, self.name2,
context=context context=context)
)
self.pool = pooler.get_pool(cursor.dbname) self.pool = pooler.get_pool(cursor.dbname)
objs = self.getObjects(cursor, uid, ids, context) objs = self.getObjects(cursor, uid, ids, context)
self.parser_instance.set_context(objs, data, ids, report_xml.report_type) self.parser_instance.set_context(objs, data, ids, report_xml.report_type)
@ -201,7 +183,7 @@ class BVRWebKitParser(webkit_report.WebKitParser):
if not template and report_xml.report_webkit_data : if not template and report_xml.report_webkit_data :
template = report_xml.report_webkit_data template = report_xml.report_webkit_data
if not template : if not template :
raise except_osv(_('Webkit Report template not found !'), _('')) raise except_osv(_('Error'),_('Webkit Report template not found !'))
header = report_xml.webkit_header.html header = report_xml.webkit_header.html
footer = report_xml.webkit_header.footer_html footer = report_xml.webkit_header.footer_html
if not header and report_xml.header: if not header and report_xml.header:
@ -210,43 +192,19 @@ class BVRWebKitParser(webkit_report.WebKitParser):
_('Please set a header in company settings') _('Please set a header in company settings')
) )
if not report_xml.header : if not report_xml.header :
#I know it could be cleaner ... header = ''
header = u""" default_head = addons.get_module_resource('report_webkit', 'default_header.html')
<html> with open(default_head,'r') as f:
<head> header = f.read()
<style type="text/css">
${css}
</style>
<script>
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for(var i in x) {
var y = document.getElementsByClassName(x[i]);
for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script>
</head>
<body style="border:0; margin: 0;" onload="subst()">
</body>
</html>"""
self.parser_instance.localcontext.update({'setLang':self.setLang})
self.parser_instance.localcontext.update({'formatLang':self.formatLang})
css = report_xml.webkit_header.css css = report_xml.webkit_header.css
if not css : if not css :
css = '' css = ''
user = self.pool.get('res.users').browse(cursor, uid, uid) user = self.pool.get('res.users').browse(cursor, uid, uid)
company = user.company_id company = user.company_id
parse_template = template body_mako_tpl = mako_template(template)
#default_filters=['unicode', 'entity'] can be used to set global filter
body_mako_tpl = Template(parse_template ,input_encoding='utf-8', output_encoding='utf-8')
#BVR specific #BVR specific
bvr_path = addons.get_module_resource(os.path.join('l10n_ch','report','bvr.mako')) bvr_path = addons.get_module_resource(os.path.join('l10n_ch','report','bvr.mako'))
body_bvr_tpl = Template(file(bvr_path).read(), input_encoding='utf-8', output_encoding='utf-8') body_bvr_tpl = mako_template(file(bvr_path).read())
helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context) helper = report_helper.WebKitHelper(cursor, uid, report_xml.id, context)
##BVR Specific ##BVR Specific
htmls = [] htmls = []
@ -254,58 +212,48 @@ class BVRWebKitParser(webkit_report.WebKitParser):
self.parser_instance.localcontext['objects'] = [obj] self.parser_instance.localcontext['objects'] = [obj]
if not company.bvr_only: if not company.bvr_only:
try: try:
html = body_mako_tpl.render( html = body_mako_tpl.render(helper=helper,
helper=helper,
css=css, css=css,
_=self.translate_call, _=self.translate_call,
**self.parser_instance.localcontext **self.parser_instance.localcontext)
)
except Exception, e: except Exception, e:
raise Exception(exceptions.text_error_template().render()) raise Exception(exceptions.text_error_template().render())
htmls.append(html) htmls.append(html)
if not company.invoice_only: if not company.invoice_only:
try: try:
bvr = body_bvr_tpl.render( bvr = body_bvr_tpl.render(helper=helper,
helper=helper, css=css,
css=css, _=self.translate_call,
_=self.translate_call, **self.parser_instance.localcontext)
**self.parser_instance.localcontext
)
except Exception, e: except Exception, e:
raise Exception(exceptions.text_error_template().render()) raise Exception(exceptions.text_error_template().render())
htmls.append(bvr) htmls.append(bvr)
head_mako_tpl = Template(header, input_encoding='utf-8', output_encoding='utf-8') head_mako_tpl = Template(header, input_encoding='utf-8', output_encoding='utf-8')
try: try:
head = head_mako_tpl.render( head = head_mako_tpl.render(helper=helper,
helper=helper,
css=css, css=css,
_debug=False, _debug=False,
_=self.translate_call, _=self.translate_call,
**self.parser_instance.localcontext **self.parser_instance.localcontext)
)
except Exception, e: except Exception, e:
raise Exception(exceptions.text_error_template().render()) raise Exception(exceptions.text_error_template().render())
foot = False foot = False
if footer and company.invoice_only : if footer and company.invoice_only :
foot_mako_tpl = Template(footer, input_encoding='utf-8', output_encoding='utf-8') foot_mako_tpl = Template(footer, input_encoding='utf-8', output_encoding='utf-8')
try: try:
foot = foot_mako_tpl.render( foot = foot_mako_tpl.render(helper=helper,
helper=helper,
css=css, css=css,
_=self.translate_call, _=self.translate_call,
**self.parser_instance.localcontext **self.parser_instance.localcontext)
)
except Exception, e: except Exception, e:
raise Exception(exceptions.text_error_template().render()) raise Exception(exceptions.text_error_template().render())
if report_xml.webkit_debug : if report_xml.webkit_debug :
try: try:
deb = head_mako_tpl.render( deb = head_mako_tpl.render(helper=helper,
helper=helper,
css=css, css=css,
_debug=html, _debug=html,
_=self.translate_call, _=self.translate_call,
**self.parser_instance.localcontext **self.parser_instance.localcontext)
)
except Exception, e: except Exception, e:
raise Exception(exceptions.text_error_template().render()) raise Exception(exceptions.text_error_template().render())
return (deb, 'html') return (deb, 'html')

View File

@ -81,8 +81,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Messages Search"> <search string="Messages Search">
<field name="user_id"/> <field name="user_id"/>
<field name="body"/> <field name="subject" string="Content" filter_domain="['|', ('subject', 'ilike', self), ('body', 'ilike', self)]" />
<field name="subject" filter_domain="['|', ('subject', 'ilike', self), ('record_name', 'ilike', self)]" />
<field name="type"/> <field name="type"/>
<filter icon="terp-personal+" string="My Feeds" <filter icon="terp-personal+" string="My Feeds"
name="my_feeds" help="My Feeds" name="my_feeds" help="My Feeds"

View File

@ -843,10 +843,15 @@ openerp.mail = function(session) {
this.ds = new session.web.DataSet(this, this.view.model); this.ds = new session.web.DataSet(this, this.view.model);
this.ds_users = new session.web.DataSet(this, 'res.users'); this.ds_users = new session.web.DataSet(this, 'res.users');
}, },
start: function() { start: function() {
var self = this; var self = this;
this._super.apply(this, arguments);
// NB: all the widget should be modified to check the actual_mode property on view, not use
// any other method to know if the view is in create mode anymore
this.view.on("change:actual_mode", this, this._check_visibility);
this._check_visibility();
mail.ChatterUtils.bind_events(this); mail.ChatterUtils.bind_events(this);
this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); }); this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); });
if (! this.params.see_subscribers_options) { if (! this.params.see_subscribers_options) {
@ -859,7 +864,11 @@ openerp.mail = function(session) {
.mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); }); .mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
this.reinit(); this.reinit();
}, },
_check_visibility: function() {
this.$element.toggle(this.view.get("actual_mode") !== "create");
},
destroy: function () { destroy: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
}, },

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n" "Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n" "Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:37+0000\n" "POT-Creation-Date: 2012-02-08 00:37+0000\n"
"PO-Revision-Date: 2012-05-10 17:23+0000\n" "PO-Revision-Date: 2012-07-26 16:28+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n" "Last-Translator: Michael Otcheskih <otma@mail.ru>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-07-14 06:01+0000\n" "X-Launchpad-Export-Date: 2012-07-27 05:22+0000\n"
"X-Generator: Launchpad (build 15614)\n" "X-Generator: Launchpad (build 15694)\n"
#. module: product #. module: product
#: model:product.template,name:product.product_product_ram512_product_template #: model:product.template,name:product.product_product_ram512_product_template
@ -891,7 +891,7 @@ msgstr "В разработке"
#: code:addons/product/product.py:363 #: code:addons/product/product.py:363
#, python-format #, python-format
msgid "UoM categories Mismatch!" msgid "UoM categories Mismatch!"
msgstr "" msgstr "Несоответствие категорий единиц измерения!"
#. module: product #. module: product
#: model:product.template,name:product.product_product_shelfofcm1_product_template #: model:product.template,name:product.product_product_shelfofcm1_product_template

View File

@ -1227,6 +1227,13 @@ class account_analytic_account(osv.osv):
'use_tasks': fields.boolean('Tasks Mgmt.',help="If check,this contract will be available in the project menu and you will be able to manage tasks or track issues"), 'use_tasks': fields.boolean('Tasks Mgmt.',help="If check,this contract will be available in the project menu and you will be able to manage tasks or track issues"),
'company_uom_id': fields.related('company_id', 'project_time_mode_id', type='many2one', relation='product.uom'), 'company_uom_id': fields.related('company_id', 'project_time_mode_id', type='many2one', relation='product.uom'),
} }
def on_change_template(self, cr, uid, ids, template_id, context=None):
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
if template_id and 'value' in res:
template = self.browse(cr, uid, template_id, context=context)
res['value']['use_tasks'] = template.use_tasks
return res
def _trigger_project_creation(self, cr, uid, vals, context=None): def _trigger_project_creation(self, cr, uid, vals, context=None):
''' '''

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp> <openerp>
<data noupdate="1"> <data noupdate="1">
<!-- This will set the unit of measure used in projects and tasks.-->
<record id="base.main_company" model="res.company">
<field name="project_time_mode_id" ref="product.uom_hour"></field>
</record>
<!-- Requests Links --> <!-- Requests Links -->
<record id="req_link_project" model="res.request.link"> <record id="req_link_project" model="res.request.link">

View File

@ -2,7 +2,7 @@
<openerp> <openerp>
<data noupdate="1"> <data noupdate="1">
<!-- Users --> <!-- Users -->
<record id="base.user_demo" model="res.users"> <record id="base.user_demo" model="res.users">
<field name="groups_id" eval="[(4, ref('base.group_sale_salesman')),(4, ref('group_project_user'))]"/> <field name="groups_id" eval="[(4, ref('base.group_sale_salesman')),(4, ref('group_project_user'))]"/>
</record> </record>
@ -281,10 +281,8 @@
<field name="stage_id" ref="project_tt_specification"/> <field name="stage_id" ref="project_tt_specification"/>
</record> </record>
<!-- Resource: project.project-->
<!-- Projects --> <!-- Projects -->
<record id="base.main_company" model="res.company">
<field name="project_time_mode_id" ref="product.uom_hour"></field>
</record>
<record id="project_project_9" model="project.project"> <record id="project_project_9" model="project.project">
<field name="name">OpenERP Integration</field> <field name="name">OpenERP Integration</field>

View File

@ -575,6 +575,13 @@ class account_analytic_account(osv.osv):
'use_issues' : fields.boolean('Issues Tracking', help="Check this field if this project manages issues"), 'use_issues' : fields.boolean('Issues Tracking', help="Check this field if this project manages issues"),
} }
def on_change_template(self, cr, uid, ids, template_id, context=None):
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
if template_id and 'value' in res:
template = self.browse(cr, uid, template_id, context=context)
res['value']['use_issues'] = template.use_issues
return res
def _trigger_project_creation(self, cr, uid, vals, context=None): def _trigger_project_creation(self, cr, uid, vals, context=None):
res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context) res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)
return res or vals.get('use_issues') return res or vals.get('use_issues')

View File

@ -275,6 +275,13 @@ class account_analytic_account(osv.osv):
_columns = { _columns = {
'use_phases': fields.boolean('Phases Planing', help="Check this field if project manages phases"), 'use_phases': fields.boolean('Phases Planing', help="Check this field if project manages phases"),
} }
def on_change_template(self, cr, uid, ids, template_id, context=None):
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
if template_id and 'value' in res:
template = self.browse(cr, uid, template_id, context=context)
res['value']['use_phases'] = template.use_phases
return res
def _trigger_project_creation(self, cr, uid, vals, context=None): def _trigger_project_creation(self, cr, uid, vals, context=None):
res= super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context) res= super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)

View File

@ -156,9 +156,11 @@
<button name="invoice_corrected" states="invoice_except" string="Ignore Exception"/> <button name="invoice_corrected" states="invoice_except" string="Ignore Exception"/>
<button name="ship_recreate" states="shipping_except" string="Recreate Delivery Order"/> <button name="ship_recreate" states="shipping_except" string="Recreate Delivery Order"/>
<button name="ship_corrected" states="shipping_except" string="Ignore Exception"/> <button name="ship_corrected" states="shipping_except" string="Ignore Exception"/>
<button name="action_quotation_send" string="Send by Mail" type="object" states="draft,sent"/> <button name="action_quotation_send" string="Send by Mail" type="object" states="draft" class="oe_highlight"/>
<button name="print_quotation" string="Send by Post" type="object" states="draft,sent"/> <button name="action_quotation_send" string="Send by Mail" type="object" states="sent"/>
<button name="action_button_confirm" states="draft" string="Confirm" type="object" class="oe_highlight"/> <button name="print_quotation" string="Send by Post" type="object" states="draft" class="oe_highlight"/>
<button name="print_quotation" string="Send by Post" type="object" states="sent"/>
<button name="action_button_confirm" states="draft" string="Confirm" type="object"/>
<button name="action_button_confirm" states="sent" string="Confirm" class="oe_highlight" type="object"/> <button name="action_button_confirm" states="sent" string="Confirm" class="oe_highlight" type="object"/>
<button name="action_view_invoice" string="Open Invoice" type="object" class="oe_highlight" <button name="action_view_invoice" string="Open Invoice" type="object" class="oe_highlight"
attrs="{'invisible': ['|','|',('state', '!=','progress'), ('invoiced', '=', True),('order_policy','=','picking')]}"/> attrs="{'invisible': ['|','|',('state', '!=','progress'), ('invoiced', '=', True),('order_policy','=','picking')]}"/>

View File

@ -0,0 +1,2 @@
import res_config
import signup

View File

@ -0,0 +1,20 @@
{
'name': 'Signup',
'description': 'Allow users to sign up',
'author': 'OpenERP SA',
'version': '1.0',
'category': 'Tools',
'website': 'http://www.openerp.com',
'installable': True,
'depends': ['anonymous', 'base_setup'],
'data': [
'res_config.xml',
'signup.xml',
],
'js': [
'static/src/js/signup.js',
],
'qweb': [
'static/src/xml/signup.xml',
],
}

View File

@ -0,0 +1,20 @@
from openerp.osv import osv, fields
class base_config_settings(osv.TransientModel):
_inherit = 'base.config.settings'
_columns = {
'signup_template_user_id': fields.many2one('res.users', 'Template user for signup')
}
def get_default_signup(self, cr, uid, fields, context=None):
icp = self.pool.get('ir.config_parameter')
return {
'signup_template_user_id': icp.get_param(cr, uid, 'signup.template_user_id', 0) or False
}
def set_signup(self, cr, uid, ids, context=None):
config = self.browse(cr, uid, ids[0], context=context)
icp = self.pool.get('ir.config_parameter')
icp.set_param(cr, uid, 'signup.template_user_id', config.signup_user_template_id.id)

View File

@ -0,0 +1,16 @@
<openerp>
<data>
<record id="view_general_configuration" model="ir.ui.view">
<field name="name">base.config.settings.signup</field>
<field name="model">base.config.settings</field>
<field name="inherit_id" ref="base_setup.view_general_configuration"/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="module_portal" position="after">
<field name="signup_template_user_id"/>
</field>
</field>
</record>
</data>
</openerp>

57
addons/signup/signup.py Normal file
View File

@ -0,0 +1,57 @@
from openerp.osv import osv, fields
class res_users(osv.Model):
_inherit = 'res.users'
_sql_constraints = [
('email_uniq', 'UNIQUE (user_email)', 'You can not have two users with the same email!')
]
class signup_signup(osv.TransientModel):
_name = 'signup.signup'
_columns = {
'name': fields.char('Name', size=64),
'email': fields.char('Email', size=64),
'password': fields.char('Password', size=64),
'password_confirmation': fields.char('Confirm Password', size=64),
'state': fields.selection([(x, x) for x in 'draft done missmatch'.split()], required=True),
}
_defaults = {
'state': 'draft',
}
def create(self, cr, uid, values, context=None):
# NOTE here, invalid values raises exceptions to avoid storing
# sensitive data into the database (which then are available to anyone)
if values['password'] != values['password_confirmation']:
raise osv.except_osv('Error', 'Passwords missmatch')
new_user = {
'name': values['name'],
'login': values['email'],
'user_email': values['email'],
'password': values['password'],
'active': True,
}
user_template_id = self.pool.get('ir.config_parameter').get_param(cr, uid, 'signup.user_template_id', 0)
if user_template_id:
self.pool.get('res.users').copy(cr, 1, user_template_id, new_user, context=context)
else:
self.pool.get('res.users').create(cr, 1, new_user, context=context)
# Dont store the password
values = {'state': 'done'}
return super(signup_signup, self).create(cr, uid, values, context)
def signup(self, cr, uid, ids, context=None):
return {
'type': 'ir.actions.client',
'tag': 'login',
}
def onchange_pw(self, cr, uid, ids, pw, cpw, context=None):
if pw != cpw:
return {'value': {'state': 'missmatch'}}
return {'value': {'state': 'draft'}}

41
addons/signup/signup.xml Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="signup_form_view" model="ir.ui.view">
<field name="name">signup.signup.form</field>
<field name="model">signup.signup</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Signup" version="7.0">
<field name="state" invisible="1"/>
<group colspan="4" states="draft,missmatch">
<field name="name" required="1"/>
<field name="email" required="1"/>
<field name="password" required='1' on_change="onchange_pw(password,password_confirmation)"/>
<field name="password_confirmation" required='1' on_change="onchange_pw(password,password_confirmation)"/>
<group colspan="4" states="missmatch">
<div>Passwords missmatch</div>
</group>
<group colspan="2" col="1">
<button string="Sign Up" name="signup" attrs="{'readonly': [('state', '=', 'missmatch')]}" type="object"/>
</group>
</group>
<group colspan="4" states="done" col="1">
<div>You can now login.</div>
<button special="cancel" string="Close"/>
</group>
</form>
</field>
</record>
<record id="signup_action" model="ir.actions.act_window">
<field name="name">signup.signup</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">signup.signup</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,21 @@
openerp.signup = function(instance) {
instance.web.UserMenu.include({
start: function() {
var self = this;
this._super.apply(this, arguments);
this.$element.find('a.oe_topbar_signup').click(function() {
var p = self.getParent();
var am = p.action_manager;
am.do_action({
type:'ir.actions.act_window',
res_model: 'signup.signup',
views: [[false, 'form']],
target: 'new',
name: 'Sign Up'
});
});
}
});
};

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim:fdl=1:
-->
<templates id="template" xml:space="preserve">
<t t-extend="UserMenu.anonymous">
<t t-jquery="a" t-operation="after">
<a href="#" class="oe_user_menu oe_topbar_item oe_topbar_signup">
<img class="oe_topbar_avatar" t-att-src="_s + '/web/static/src/img/user_menu_avatar.png'"/>
Sign Up
</a>
</t>
</t>
</templates>

View File

@ -731,9 +731,10 @@
<span groups="base.group_user"> <span groups="base.group_user">
<button name="draft_force_assign" states="draft" string="Confirm" type="object" class="oe_highlight"/> <button name="draft_force_assign" states="draft" string="Confirm" type="object" class="oe_highlight"/>
<button name="draft_validate" states="draft" string="Confirm &amp; Transfer" type="object" class="oe_highlight"/> <button name="draft_validate" states="draft" string="Confirm &amp; Transfer" type="object" class="oe_highlight"/>
<!-- <button name="action_assign" states="confirmed" string="Check Availability" type="object"/> -->
<button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight"/> <button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight"/>
<button name="action_process" states="assigned" string="Confirm &amp; Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/> <button name="action_process" states="assigned" string="Confirm &amp; Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" type="action" class="oe_highlight"/> <button name="%(action_stock_invoice_onshipping)d" string="Create Invoice/Refund" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" type="action" class="oe_highlight"/>
<button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action"/> <button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action"/>
<button name="button_cancel" states="assigned,confirmed,draft" string="_Cancel"/> <button name="button_cancel" states="assigned,confirmed,draft" string="_Cancel"/>
</span> </span>

View File

@ -98,9 +98,15 @@ class stock_partial_picking(osv.osv_memory):
if context is None: context = {} if context is None: context = {}
res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context) res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
picking_ids = context.get('active_ids', []) picking_ids = context.get('active_ids', [])
if context['active_model'] == 'purchase.order': active_model = context.get('active_model')
if active_model == 'purchase.order':
for purchase_order in self.pool.get('purchase.order').browse(cr, uid, picking_ids, context=context): for purchase_order in self.pool.get('purchase.order').browse(cr, uid, picking_ids, context=context):
picking_ids = [picking_id.id for picking_id in purchase_order.picking_ids] picking_ids = [picking_id.id for picking_id in purchase_order.picking_ids]
elif active_model == 'sale.order':
for sale_order in self.pool.get('sale.order').browse(cr, uid, picking_ids, context=context):
picking_ids = [picking.id for picking in sale_order.picking_ids]
if not picking_ids or len(picking_ids) != 1: if not picking_ids or len(picking_ids) != 1:
# Partial Picking Processing may only be done for one picking at a time # Partial Picking Processing may only be done for one picking at a time
return res return res
@ -108,7 +114,7 @@ class stock_partial_picking(osv.osv_memory):
# (already seen in previous bug where context passed was containing ir.ui.menu as active_model and the menu # (already seen in previous bug where context passed was containing ir.ui.menu as active_model and the menu
# ID as active_id). Though this should be fixed in clients now, this place is sensitive enough to ensure the # ID as active_id). Though this should be fixed in clients now, this place is sensitive enough to ensure the
# consistancy of the context. # consistancy of the context.
assert context.get('active_model') in ('stock.picking', 'stock.picking.in', 'stock.picking.out', 'purchase.order'), 'Bad context propagation' assert active_model in ('stock.picking', 'stock.picking.in', 'stock.picking.out', 'purchase.order', 'sale.order'), 'Bad context propagation'
picking_id, = picking_ids picking_id, = picking_ids
if 'picking_id' in fields: if 'picking_id' in fields:
res.update(picking_id=picking_id) res.update(picking_id=picking_id)