diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 86166ec0125..ebbd5459cea 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -63,6 +63,8 @@ for a particular financial year and for preparation of vouchers there is a modul 'wizard/account_use_model_view.xml', 'account_installer.xml', 'wizard/account_period_close_view.xml', + 'wizard/account_reconcile_view.xml', + 'wizard/account_unreconcile_view.xml', 'account_view.xml', 'account_report.xml', 'account_financial_report_data.xml', @@ -85,14 +87,12 @@ for a particular financial year and for preparation of vouchers there is a modul 'wizard/account_journal_select_view.xml', 'wizard/account_change_currency_view.xml', 'wizard/account_validate_move_view.xml', - 'wizard/account_unreconcile_view.xml', 'wizard/account_report_general_ledger_view.xml', 'wizard/account_invoice_state_view.xml', 'wizard/account_report_partner_balance_view.xml', 'wizard/account_report_account_balance_view.xml', 'wizard/account_report_aged_partner_balance_view.xml', 'wizard/account_report_partner_ledger_view.xml', - 'wizard/account_reconcile_view.xml', 'wizard/account_reconcile_partner_process_view.xml', 'wizard/account_automatic_reconcile_view.xml', 'wizard/account_financial_report_view.xml', @@ -126,6 +126,14 @@ for a particular financial year and for preparation of vouchers there is a modul 'res_config_view.xml', 'account_pre_install.yml' ], + 'js': [ + 'static/src/js/account_move_reconciliation.js', + ], + 'qweb' : [ + "static/src/xml/account_move_reconciliation.xml", + ], + 'css':['static/src/css/account_move_reconciliation.css' + ], 'demo': [ 'demo/account_demo.xml', 'project/project_demo.xml', diff --git a/addons/account/account.py b/addons/account/account.py index b01da6b1425..d145f0308b0 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -836,6 +836,8 @@ class account_journal(osv.osv): @return: Returns a list of tupples containing id, name """ + if not ids: + return [] if isinstance(ids, (int, long)): ids = [ids] result = self.browse(cr, user, ids, context=context) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index bbcb25fefa9..aff38d71cfe 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1103,10 +1103,10 @@ class account_invoice(osv.osv): if not ids: return [] types = { - 'out_invoice': 'CI: ', - 'in_invoice': 'SI: ', - 'out_refund': 'OR: ', - 'in_refund': 'SR: ', + 'out_invoice': 'Invoice ', + 'in_invoice': 'Sup. Invoice ', + 'out_refund': 'Refund ', + 'in_refund': 'Supplier Refund ', } return [(r['id'], (r['number']) or types[r['type']] + (r['name'] or '')) for r in self.read(cr, uid, ids, ['type', 'number', 'name'], context, load='_classic_write')] diff --git a/addons/account/account_menuitem.xml b/addons/account/account_menuitem.xml index 480d5ec76a6..a2fbf11963b 100644 --- a/addons/account/account_menuitem.xml +++ b/addons/account/account_menuitem.xml @@ -30,7 +30,7 @@ - + diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 18ab1a779a3..5ddbbee74f2 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -215,8 +215,10 @@ class account_move_line(osv.osv): def _default_get(self, cr, uid, fields, context=None): if context is None: context = {} - if not context.get('journal_id', False) and context.get('search_default_journal_id', False): + if not context.get('journal_id', False): context['journal_id'] = context.get('search_default_journal_id') + if not context.get('period_id', False): + context['period_id'] = context.get('search_default_period_id') account_obj = self.pool.get('account.account') period_obj = self.pool.get('account.period') journal_obj = self.pool.get('account.journal') @@ -226,6 +228,9 @@ class account_move_line(osv.osv): partner_obj = self.pool.get('res.partner') currency_obj = self.pool.get('res.currency') context = self.convert_to_period(cr, uid, context) + #pass the right context when search_defaul_journal_id + if context.get('search_default_journal_id',False): + context['journal_id'] = context.get('search_default_journal_id') # Compute simple values data = super(account_move_line, self).default_get(cr, uid, fields, context=context) # Starts: Manual entry from account.move form @@ -480,7 +485,7 @@ class account_move_line(osv.osv): 'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')), 'credit': fields.float('Credit', digits_compute=dp.get_precision('Account')), 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2), - 'move_id': fields.many2one('account.move', 'Move', ondelete="cascade", help="The move of this entry line.", select=2, required=True), + 'move_id': fields.many2one('account.move', 'Journal Entry', ondelete="cascade", help="The move of this entry line.", select=2, required=True), 'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Internal Note'), 'ref': fields.related('move_id', 'ref', string='Reference', type='char', size=64, store=True), 'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1), @@ -703,7 +708,9 @@ class account_move_line(osv.osv): context = {} if context and context.get('next_partner_only', False): if not context.get('partner_id', False): - partner = self.get_next_partner_only(cr, uid, offset, context) + partner = self.list_partners_to_reconcile(cr, uid, context=context) + if partner: + partner = partner[0] else: partner = context.get('partner_id', False) if not partner: @@ -711,26 +718,26 @@ class account_move_line(osv.osv): args.append(('partner_id', '=', partner[0])) return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count) - def get_next_partner_only(self, cr, uid, offset=0, context=None): + def list_partners_to_reconcile(self, cr, uid, context=None): cr.execute( """ - SELECT p.id - FROM res_partner p - RIGHT JOIN ( - SELECT l.partner_id AS partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit + SELECT partner_id + FROM ( + SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit FROM account_move_line l - LEFT JOIN account_account a ON (a.id = l.account_id) - LEFT JOIN res_partner p ON (l.partner_id = p.id) + RIGHT JOIN account_account a ON (a.id = l.account_id) + RIGHT JOIN res_partner p ON (l.partner_id = p.id) WHERE a.reconcile IS TRUE AND l.reconcile_id IS NULL AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date) AND l.state <> 'draft' - GROUP BY l.partner_id - ) AS s ON (p.id = s.partner_id) + GROUP BY l.partner_id, p.last_reconciliation_date + ) AS s WHERE debit > 0 AND credit > 0 - ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset, ) - ) - return cr.fetchone() + ORDER BY last_reconciliation_date""") + ids = cr.fetchall() + ids = len(ids) and [x[0] for x in ids] or [] + return self.pool.get('res.partner').name_get(cr, uid, ids, context=context) def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False): move_rec_obj = self.pool.get('account.move.reconcile') @@ -910,8 +917,8 @@ class account_move_line(osv.osv): if lines and lines[0]: partner_id = lines[0].partner_id and lines[0].partner_id.id or False - if partner_id and context and context.get('stop_reconcile', False): - partner_obj.write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}) + if not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context): + partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context) return r_id def view_header_get(self, cr, user, view_id, view_type, context=None): @@ -926,6 +933,8 @@ class account_move_line(osv.osv): return res if (not context.get('journal_id', False)) or (not context.get('period_id', False)): return False + if context.get('search_default_journal_id', False): + context['journal_id'] = context.get('search_default_journal_id') cr.execute('SELECT code FROM account_journal WHERE id = %s', (context['journal_id'], )) j = cr.fetchone()[0] or '' cr.execute('SELECT code FROM account_period WHERE id = %s', (context['period_id'], )) diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 20aa198c63f..2c204fdf707 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -101,28 +101,29 @@ account.period
-
-
- - - - - - - - - - - - - +
+
+ + + + + + + + + + + + +
@@ -1038,7 +1039,26 @@ Entries lines --> - + + account.move.line.reconcile.tree + account.move.line + + + + + + + + + + + + + + + + + account.move.line.tree account.move.line @@ -1073,64 +1093,64 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -1512,7 +1532,6 @@ Journal Items - ir.actions.act_window account.move.line form tree,form @@ -1531,15 +1550,31 @@ - - + + {'search_default_unreconciled': 1,'view_mode':True} + Journal Items to Reconcile + account.move.line + + form + account_reconciliation_list + +

+ Good job! +

+ There is nothing to reconcile. All invoices and payments + have been reconciled, your partner balance is clean. +

+
+
+ @@ -1718,8 +1753,10 @@ account.payment.term.line
- - + + + + @@ -1767,12 +1804,11 @@ account.payment.term - + - - + diff --git a/addons/account/partner.py b/addons/account/partner.py index 36fd88183f2..f2b9f79bb8a 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -20,8 +20,8 @@ ############################################################################## from operator import itemgetter - from osv import fields, osv +import time class account_fiscal_position(osv.osv): _name = 'account.fiscal.position' @@ -145,6 +145,29 @@ class res_partner(osv.osv): def _debit_search(self, cr, uid, obj, name, args, context=None): return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context) + def has_something_to_reconcile(self, cr, uid, partner_id, context=None): + ''' + at least a debit, a credit and a line older than the last reconciliation date of the partner + ''' + cr.execute(''' + SELECT l.partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit + FROM account_move_line l + RIGHT JOIN account_account a ON (a.id = l.account_id) + RIGHT JOIN res_partner p ON (l.partner_id = p.id) + WHERE a.reconcile IS TRUE + AND p.id = %s + AND l.reconcile_id IS NULL + AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date) + AND l.state <> 'draft' + GROUP BY l.partner_id''', (partner_id,)) + res = cr.dictfetchone() + if res: + return bool(res['debit'] and res['credit']) + return False + + def mark_as_reconciled(self, cr, uid, ids, context=None): + return self.write(cr, uid, ids, {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context) + _columns = { 'credit': fields.function(_credit_debit_get, fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."), @@ -185,7 +208,7 @@ class res_partner(osv.osv): help="This payment term will be used instead of the default one for the current partner"), 'ref_companies': fields.one2many('res.company', 'partner_id', 'Companies that refers to partner'), - 'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were reconciled last time') + 'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the date of the last reconciliation made for this partner, as here we depict the fact that nothing more was to be reconciled at this date. This can be achieved in 2 ways: either the last debit/credit entry was reconciled, either the user pressed the button "Fully Reconciled" in the manual reconciliation process') } res_partner() diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml index d83571b314e..7ac1efd4f9f 100644 --- a/addons/account/partner_view.xml +++ b/addons/account/partner_view.xml @@ -12,7 +12,7 @@ - + @@ -23,6 +23,7 @@ + @@ -93,8 +94,10 @@
- - + + + + diff --git a/addons/account/static/src/css/account_move_reconciliation.css b/addons/account/static/src/css/account_move_reconciliation.css new file mode 100644 index 00000000000..2b407226905 --- /dev/null +++ b/addons/account/static/src/css/account_move_reconciliation.css @@ -0,0 +1,19 @@ + +.openerp .oe_account_reconciliation { + border-bottom: 1px solid #CACACA; + padding: 5px; +} + +.openerp .oe_account_reconciliation button { + margin: 3px; +} + +.openerp .oe_account_reconciliation>div { + display: table; + width: 100%; +} + +.openerp .oe_account_reconciliation>div>div { + display: table-cell; + width: 50%: +} \ No newline at end of file diff --git a/addons/account/static/src/js/account_move_reconciliation.js b/addons/account/static/src/js/account_move_reconciliation.js new file mode 100644 index 00000000000..6b007e2f097 --- /dev/null +++ b/addons/account/static/src/js/account_move_reconciliation.js @@ -0,0 +1,124 @@ +openerp.account = function (instance) { + var _t = instance.web._t, + _lt = instance.web._lt; + var QWeb = instance.web.qweb; + + instance.web.account = {}; + + instance.web.views.add('account_reconciliation_list', 'instance.web.account.ReconciliationListView'); + instance.web.account.ReconciliationListView = instance.web.ListView.extend({ + init: function() { + this._super.apply(this, arguments); + var self = this; + this.current_partner = null; + this.do_select.add(function() { + if (self.get_selected_ids().length === 0) { + self.$(".oe_account_recon_reconcile").attr("disabled", ""); + } else { + self.$(".oe_account_recon_reconcile").removeAttr("disabled"); + } + }); + }, + on_loaded: function() { + var self = this; + var tmp = this._super.apply(this, arguments); + if (this.partners) { + this.$el.prepend(QWeb.render("AccountReconciliation", {widget: this})); + this.$(".oe_account_recon_previous").click(function() { + self.current_partner = (self.current_partner - 1) % self.partners.length; + self.search_by_partner(); + }); + this.$(".oe_account_recon_next").click(function() { + self.current_partner = (self.current_partner + 1) % self.partners.length; + self.search_by_partner(); + }); + this.$(".oe_account_recon_reconcile").click(function() { + self.reconcile(); + }); + this.$(".oe_account_recom_mark_as_reconciled").click(function() { + self.mark_as_reconciled(); + }); + } + return tmp; + }, + do_search: function(domain, context, group_by) { + var self = this; + this.last_domain = domain; + this.last_context = context; + this.last_group_by = group_by; + this.old_search = _.bind(this._super, this); + var mod = new instance.web.Model("account.move.line", context, domain); + return mod.call("list_partners_to_reconcile", []).pipe(function(result) { + var current = self.current_partner !== null ? self.partners[self.current_partner][0] : null; + self.partners = result; + var index = _.find(_.range(self.partners.length), function(el) { + if (current === self.partners[el][0]) + return true; + }); + if (index !== undefined) + self.current_partner = index; + else + self.current_partner = self.partners.length == 0 ? null : 0; + self.search_by_partner(); + }); + }, + search_by_partner: function() { + var self = this; + var fct = function() { + return self.old_search(new instance.web.CompoundDomain(self.last_domain, + [["partner_id", "in", self.current_partner === null ? [] : + [self.partners[self.current_partner][0]] ]]), self.last_context, self.last_group_by); + }; + if (self.current_partner === null) { + self.last_reconciliation_date = _t("Never"); + return fct(); + } else { + return new instance.web.Model("res.partner").call("read", + [self.partners[self.current_partner][0], ["last_reconciliation_date"]]).pipe(function(res) { + self.last_reconciliation_date = + instance.web.format_value(res.last_reconciliation_date, {"type": "datetime"}, _t("Never")); + return fct(); + }); + } + }, + reconcile: function() { + var self = this; + var ids = this.get_selected_ids(); + if (ids.length === 0) { + instance.web.dialog($("
").text(_t("You must choose at least one record.")), { + title: _t("Warning"), + modal: true + }); + return false; + } + + new instance.web.Model("ir.model.data").call("get_object_reference", ["account", "action_view_account_move_line_reconcile"]).pipe(function(result) { + var additional_context = _.extend({ + active_id: ids[0], + active_ids: ids, + active_model: self.model + }); + return self.rpc("/web/action/load", { + action_id: result[1], + context: additional_context + }, function (result) { + result = result.result; + result.context = _.extend(result.context || {}, additional_context); + result.flags = result.flags || {}; + result.flags.new_window = true; + return self.do_action(result, function () { + self.do_search(self.last_domain, self.last_context, self.last_group_by); + }); + }); + }); + }, + mark_as_reconciled: function() { + var self = this; + var id = self.partners[self.current_partner][0]; + new instance.web.Model("res.partner").call("mark_as_reconciled", [[id]]).pipe(function() { + self.do_search(self.last_domain, self.last_context, self.last_group_by); + }); + }, + }); + +}; diff --git a/addons/account/static/src/xml/account_move_reconciliation.xml b/addons/account/static/src/xml/account_move_reconciliation.xml new file mode 100644 index 00000000000..c266e819198 --- /dev/null +++ b/addons/account/static/src/xml/account_move_reconciliation.xml @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/addons/account/wizard/account_move_journal.py b/addons/account/wizard/account_move_journal.py index d87e4d04a0c..da6a142972b 100644 --- a/addons/account/wizard/account_move_journal.py +++ b/addons/account/wizard/account_move_journal.py @@ -92,7 +92,7 @@ class account_move_journal(osv.osv_memory): journal = False if journal_id: - journal = journal_pool.read(cr, uid, journal_id, ['name'], context=context).name + journal = journal_pool.read(cr, uid, journal_id, ['name'], context=context).get('name',False) journal_string = _("Journal: %s") % tools.ustr(journal) else: journal_string = _("Journal: All") diff --git a/addons/account/wizard/account_reconcile.py b/addons/account/wizard/account_reconcile.py index 729792e2222..9fa521c09f7 100644 --- a/addons/account/wizard/account_reconcile.py +++ b/addons/account/wizard/account_reconcile.py @@ -86,19 +86,6 @@ class account_move_line_reconcile(osv.osv_memory): ids = period_obj.find(cr, uid, dt=date, context=context) if ids: period_id = ids[0] - #stop the reconciliation process by partner (manual reconciliation) only if there is nothing more to reconcile for this partner - if 'active_ids' in context and context['active_ids']: - tmp_ml_id = account_move_line_obj.browse(cr, uid, context['active_ids'], context)[0] - partner_id = tmp_ml_id.partner_id and tmp_ml_id.partner_id.id or False - debit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('debit', '>', 0)], context=context) - credit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('credit', '>', 0)], context=context) - for ml_id in context['active_ids']: - if ml_id in debit_ml_ids: - debit_ml_ids.remove(ml_id) - if ml_id in credit_ml_ids: - credit_ml_ids.remove(ml_id) - if not debit_ml_ids and credit_ml_ids: - context.update({'stop_reconcile': True}) account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id, period_id, journal_id, context=context) return {'type': 'ir.actions.act_window_close'} @@ -166,7 +153,6 @@ class account_move_line_reconcile_writeoff(osv.osv_memory): if ids: period_id = ids[0] - context.update({'stop_reconcile': True}) account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id, period_id, journal_id, context=context) return {'type': 'ir.actions.act_window_close'} diff --git a/addons/account/wizard/account_reconcile_partner_process.py b/addons/account/wizard/account_reconcile_partner_process.py index 7cfeff70891..380d25001c7 100644 --- a/addons/account/wizard/account_reconcile_partner_process.py +++ b/addons/account/wizard/account_reconcile_partner_process.py @@ -57,10 +57,10 @@ class account_partner_reconcile_process(osv.osv_memory): def _get_partner(self, cr, uid, context=None): move_line_obj = self.pool.get('account.move.line') - partner = move_line_obj.get_next_partner_only(cr, uid, offset=1, context=context) + partner = move_line_obj.list_partners_to_reconcile(cr, uid, context=context) if not partner: return False - return partner[0] + return partner[0][0] def data_get(self, cr, uid, to_reconcile, today_reconciled, context=None): return {'progress': (100 / (float(to_reconcile + today_reconciled) or 1.0)) * today_reconciled} @@ -100,4 +100,4 @@ class account_partner_reconcile_process(osv.osv_memory): account_partner_reconcile_process() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_analytic_analysis/__openerp__.py b/addons/account_analytic_analysis/__openerp__.py index 40b67289fb1..3e8c579b729 100644 --- a/addons/account_analytic_analysis/__openerp__.py +++ b/addons/account_analytic_analysis/__openerp__.py @@ -36,6 +36,7 @@ Adds menu to show relevant information to each manager.You can also view the rep 'depends': ['hr_timesheet_invoice', 'sale'], #although sale is technically not required to install this module, all menuitems are located under 'Sales' application 'data': [ 'security/ir.model.access.csv', + 'security/account_analytic_analysis_security.xml', 'account_analytic_analysis_view.xml', 'account_analytic_analysis_menu.xml', 'account_analytic_analysis_cron.xml', diff --git a/addons/account_analytic_analysis/security/account_analytic_analysis_security.xml b/addons/account_analytic_analysis/security/account_analytic_analysis_security.xml new file mode 100644 index 00000000000..8bcc7f2d7f0 --- /dev/null +++ b/addons/account_analytic_analysis/security/account_analytic_analysis_security.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/addons/account_asset/account_asset_view.xml b/addons/account_asset/account_asset_view.xml index bb0222d5e4f..3fab306863c 100644 --- a/addons/account_asset/account_asset_view.xml +++ b/addons/account_asset/account_asset_view.xml @@ -129,7 +129,7 @@ - + @@ -159,11 +159,6 @@ - - - - -
+
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py index 66a67ad4219..d3a22782a68 100644 --- a/addons/analytic/analytic.py +++ b/addons/analytic/analytic.py @@ -140,7 +140,7 @@ class account_analytic_account(osv.osv): 'name': fields.char('Account/Contract Name', size=128, required=True), 'complete_name': fields.function(_complete_name_calc, type='char', string='Full Account Name'), 'code': fields.char('Reference', size=24, select=True), - 'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True, + 'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True, help="If you select the View Type, it means you won\'t allow to create journal entries using that account.\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"\ @@ -168,7 +168,7 @@ class account_analytic_account(osv.osv): 'res.company': (_get_analytic_account, ['currency_id'], 10), }, string='Currency', type='many2one', relation='res.currency'), } - + def on_change_template(self, cr, uid, ids, template_id, context=None): if not template_id: return {} @@ -179,7 +179,7 @@ class account_analytic_account(osv.osv): 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={}): res={} if partner_id: @@ -222,8 +222,10 @@ class account_analytic_account(osv.osv): def copy(self, cr, uid, id, default=None, context=None): if not default: default = {} + analytic = self.browse(cr, uid, id, context=context) default['code'] = False default['line_ids'] = [] + default['name'] = analytic['name'] + ' (' + _('copy') + ')' return super(account_analytic_account, self).copy(cr, uid, id, default, context=context) def on_change_company(self, cr, uid, id, company_id): diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py index 6b6db168a4f..43d198b27e2 100644 --- a/addons/anonymization/anonymization.py +++ b/addons/anonymization/anonymization.py @@ -68,8 +68,10 @@ class ir_model_fields_anonymization(osv.osv): return state def _check_write(self, cr, uid, context=None): - # check that the field is created from the menu and not from an database update - # otherwise the database update can crash: + """check that the field is created from the menu and not from an database update + otherwise the database update can crash:""" + if context is None: + context = {} if context.get('manual'): global_state = self._get_global_state(cr, uid, context=context) @@ -295,10 +297,10 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, *args, **kwargs): state = self.pool.get('ir.model.fields.anonymization')._get_global_state(cr, uid, context=context) - + if context is None: context = {} - + step = context.get('step', 'new_window') res = super(ir_model_fields_anonymize_wizard, self).fields_view_get(cr, uid, view_id, view_type, context, *args, **kwargs) diff --git a/addons/auth_signup/auth_signup_data.xml b/addons/auth_signup/auth_signup_data.xml index 4a6bf9ae4b9..39b62148494 100644 --- a/addons/auth_signup/auth_signup_data.xml +++ b/addons/auth_signup/auth_signup_data.xml @@ -13,7 +13,7 @@
- + auth_signup.template_user_id diff --git a/addons/base_calendar/__openerp__.py b/addons/base_calendar/__openerp__.py index 48ec05e2e92..b1afacfbd01 100644 --- a/addons/base_calendar/__openerp__.py +++ b/addons/base_calendar/__openerp__.py @@ -20,7 +20,7 @@ ############################################################################## { - 'name': 'Calendar Layer', + 'name': 'Calendar', 'version': '1.0', 'depends': ['base', 'base_status', 'mail', 'base_action_rule'], 'description': """ @@ -51,6 +51,7 @@ If you need to manage your meetings, you should install the CRM module. ], 'test' : ['test/base_calendar_test.yml'], 'installable': True, + 'application': True, 'auto_install': False, 'certificate': '00694071962960352821', 'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',], diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index a6d5f6859af..85199d09c60 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1431,7 +1431,10 @@ rule or repeating pattern of time to exclude from the recurring rule."), if r['class']=='private': for f in r.keys(): if f not in ('id','date','date_deadline','duration','user_id','state'): - r[f] = False + if isinstance(r[f], list): + r[f] = [] + else: + r[f] = False if f=='name': r[f] = _('Busy') diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml index 89066ce74bb..d374c2e6d88 100644 --- a/addons/base_calendar/base_calendar_view.xml +++ b/addons/base_calendar/base_calendar_view.xml @@ -418,7 +418,7 @@ ir.actions.act_window calendar.event form - tree,form,calendar + calendar,tree,form @@ -428,5 +428,6 @@ name="Events" parent="base.menu_calendar_configuration" sequence="15" action="action_view_event"/> + diff --git a/addons/base_calendar/crm_meeting.py b/addons/base_calendar/crm_meeting.py index 4ea4776ad9b..0ee23ed1d0f 100644 --- a/addons/base_calendar/crm_meeting.py +++ b/addons/base_calendar/crm_meeting.py @@ -53,7 +53,7 @@ class crm_meeting(base_state, osv.Model): 'partner_ids': fields.many2many('res.partner', 'crm_meeting_partner_rel', 'meeting_id','partner_id', string='Attendees', states={'done': [('readonly', True)]}), 'state': fields.selection( - [('draft', 'Unconfirmed'), ('open', 'Confirmed'), ('cancel', 'Cancelled'), ('done', 'Done')], + [('draft', 'Unconfirmed'), ('open', 'Confirmed')], string='Status', size=16, readonly=True), # Meeting fields 'name': fields.char('Meeting Subject', size=128, required=True, states={'done': [('readonly', True)]}), diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml index 928f8d94d5c..b963de68130 100644 --- a/addons/base_calendar/crm_meeting_view.xml +++ b/addons/base_calendar/crm_meeting_view.xml @@ -69,9 +69,7 @@ crm.meeting
-
- -
+
diff --git a/addons/base_calendar/static/src/img/icon.png b/addons/base_calendar/static/src/img/icon.png new file mode 100644 index 00000000000..f612cd9ea4b Binary files /dev/null and b/addons/base_calendar/static/src/img/icon.png differ diff --git a/addons/base_setup/res_partner_view.xml b/addons/base_setup/res_partner_view.xml index 5e54c0b8629..15b80151831 100644 --- a/addons/base_setup/res_partner_view.xml +++ b/addons/base_setup/res_partner_view.xml @@ -9,14 +9,11 @@ - - - - + + - diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index 529e70fdb49..9db3ece7d8b 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -69,7 +69,7 @@ class base_stage(object): return False return uid - def onchange_partner_address_id(self, cr, uid, ids, add, email=False): + def onchange_partner_address_id(self, cr, uid, ids, add, email=False, context=None): """ This function returns value of partner email based on Partner Address :param add: Id of Partner's address :param email: Partner's email ID @@ -77,10 +77,20 @@ class base_stage(object): data = {'value': {'email_from': False, 'phone':False}} if add: address = self.pool.get('res.partner').browse(cr, uid, add) - data['value'] = {'email_from': address and address.email or False , - 'phone': address and address.phone or False} - if 'phone' not in self._columns: - del data['value']['phone'] + data['value'] = {'partner_name': address and address.name or False, + 'email_from': address and address.email or False, + 'phone': address and address.phone or False, + 'street': address and address.street or False, + 'street2': address and address.street2 or False, + 'city': address and address.city or False, + 'state_id': address.state_id and address.state_id.id or False, + 'zip': address and address.zip or False, + 'country_id': address.country_id and address.country_id.id or False, + } + fields = self.fields_get(cr, uid, context=context or {}) + for key in data['value'].keys(): + if key not in fields: + del data['value'][key] return data def onchange_partner_id(self, cr, uid, ids, part, email=False): diff --git a/addons/board/static/src/css/dashboard.css b/addons/board/static/src/css/dashboard.css index ed66e338c81..f2bbcd07071 100644 --- a/addons/board/static/src/css/dashboard.css +++ b/addons/board/static/src/css/dashboard.css @@ -1,3 +1,36 @@ +.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_0 { + width: 100%; +} +.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_1, .openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_2 { + display: none; +} +.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column { + width: 50%; +} +.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column.index_2 { + display: none; +} +.openerp .oe_dashboard_layout_1-1-1 .oe_dashboard_column { + width: 33%; +} +.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_0 { + width: 70%; +} +.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_1 { + width: 30%; +} +.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_2 { + display: none; +} +.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_0 { + width: 30%; +} +.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_1 { + width: 70%; +} +.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_2 { + display: none; +} .openerp .oe_dashboard_layout_selector ul { white-space: nowrap; } diff --git a/addons/board/static/src/css/dashboard.sass b/addons/board/static/src/css/dashboard.sass index 32f0e3b4f3a..122b6dc232c 100644 --- a/addons/board/static/src/css/dashboard.sass +++ b/addons/board/static/src/css/dashboard.sass @@ -9,6 +9,31 @@ box-shadow: $bsval .openerp + .oe_dashboard_layout_1 .oe_dashboard_column + &.index_0 + width: 100% + &.index_1, &.index_2 + display: none + .oe_dashboard_layout_1-1 .oe_dashboard_column + width: 50% + &.index_2 + display: none + .oe_dashboard_layout_1-1-1 .oe_dashboard_column + width: 33% + .oe_dashboard_layout_2-1 .oe_dashboard_column + &.index_0 + width: 70% + &.index_1 + width: 30% + &.index_2 + display: none + .oe_dashboard_layout_1-2 .oe_dashboard_column + &.index_0 + width: 30% + &.index_1 + width: 70% + &.index_2 + display: none .oe_dashboard_layout_selector ul white-space: nowrap @@ -98,3 +123,4 @@ > tbody tr:nth-child(odd) background: transparent + diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js index 9c37924144d..43d7ca76d39 100644 --- a/addons/board/static/src/js/dashboard.js +++ b/addons/board/static/src/js/dashboard.js @@ -24,6 +24,10 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({ scroll: false }).bind('sortstop', self.do_save_dashboard); + var old_title = this.__parentedParent.get('title'); + this.__parentedParent.on_record_loaded.add_last(function(){ + self.__parentedParent.set({ 'title' : old_title}); + }); // Events this.$el.find('.oe_dashboard_link_reset').click(this.on_reset); this.$el.find('.oe_dashboard_link_change_layout').click(this.on_change_layout); @@ -165,8 +169,6 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({ this.rpc('/web/view/add_custom', { view_id: this.view.fields_view.view_id, arch: arch - }, function() { - self.$el.find('.oe_dashboard_link_reset').show(); }); }, on_load_action: function(result, index, action_attrs) { diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml index e13fa707776..03ede793036 100644 --- a/addons/board/static/src/xml/board.xml +++ b/addons/board/static/src/xml/board.xml @@ -1,7 +1,7 @@ diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 1fab5dd1732..57a59e2595f 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -647,3 +647,33 @@ class test_mail(TestMailMockups): msg1.refresh() self.assertEqual(5, len(group_pigs.message_ids), 'group should contain 5 messages') self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now') + + def test_60_vote(self): + """ Test designed for the vote/unvote feature. """ + cr, uid = self.cr, self.uid + group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + user_admin = self.res_users.browse(cr, uid, uid) + msg1 = group_pigs.message_post(body='My Body', subject='1') + msg1 = self.mail_message.browse(cr, uid, msg1) + + # Create user Bert Tartopoils + user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert', 'login': 'bert'}) + user_bert = self.res_users.browse(cr, uid, user_bert_id) + + # Test: msg1 and msg2 have void vote_user_ids + self.assertFalse(msg1.vote_user_ids, 'newly created message msg1 has not void vote_user_ids') + # Do: Admin vote for msg1 + self.mail_message.vote_toggle(cr, uid, [msg1.id]) + msg1.refresh() + # Test: msg1 has Admin as voter + self.assertEqual(set(msg1.vote_user_ids), set([user_admin]), 'after voting, Admin is not the voter') + # Do: Bert vote for msg1 + self.mail_message.vote_toggle(cr, uid, [msg1.id], [user_bert_id]) + msg1.refresh() + # Test: msg1 has Admin and Bert as voters + self.assertEqual(set(msg1.vote_user_ids), set([user_admin, user_bert]), 'after voting, Admin and Bert are not the voters') + # Do: Admin unvote for msg1 + self.mail_message.vote_toggle(cr, uid, [msg1.id]) + msg1.refresh() + # Test: msg1 has Bert as voter + self.assertEqual(set(msg1.vote_user_ids), set([user_bert]), 'after unvoting for Admin, Bert is not the voter') diff --git a/addons/mrp/board_manufacturing_view.xml b/addons/mrp/board_manufacturing_view.xml index cae1fea07dc..6bd07c2648b 100644 --- a/addons/mrp/board_manufacturing_view.xml +++ b/addons/mrp/board_manufacturing_view.xml @@ -30,7 +30,8 @@ icon="terp-graph" id="menu_board_manufacturing" parent="base.menu_reporting_dashboard" - sequence="30"/> + sequence="30" + groups="group_mrp_manager"/> diff --git a/addons/multi_company/__openerp__.py b/addons/multi_company/__openerp__.py index eb882604d22..501740188db 100644 --- a/addons/multi_company/__openerp__.py +++ b/addons/multi_company/__openerp__.py @@ -34,7 +34,7 @@ This module is the base module for other multi-company modules. 'website': 'http://www.openerp.com/', 'depends': [ 'base', - 'sale', + 'sale_stock', 'project', ], 'data': ['res_company_view.xml'], diff --git a/addons/multi_company/multi_company_demo.xml b/addons/multi_company/multi_company_demo.xml index d120550e3b9..00c68186108 100644 --- a/addons/multi_company/multi_company_demo.xml +++ b/addons/multi_company/multi_company_demo.xml @@ -181,7 +181,7 @@ - + diff --git a/addons/note/__openerp__.py b/addons/note/__openerp__.py index 7d6cac5b85b..2c6134e5e3a 100644 --- a/addons/note/__openerp__.py +++ b/addons/note/__openerp__.py @@ -20,7 +20,7 @@ ############################################################################## { - 'name': 'Memos', + 'name': 'Notes', 'version': '1.0', 'category': 'Tools', 'description': """ @@ -28,12 +28,12 @@ This module allows users to create their own notes inside OpenERP ================================================================= Use notes to write meeting minutes, organize ideas, organize personnal todo -lists, etc. Each user manages his own personnal memos. Notes are available to +lists, etc. Each user manages his own personnal Notes. Notes are available to their authors only, but they can share notes to others users so that several people can work on the same note in real time. It's very efficient to share meeting minutes. -Memos can be found in the 'Home' menu. +Notes can be found in the 'Home' menu. """, 'author': 'OpenERP SA', 'website': 'http://openerp.com', diff --git a/addons/note/note.py b/addons/note/note.py index 65848ed7828..9d62f7a2cb7 100644 --- a/addons/note/note.py +++ b/addons/note/note.py @@ -22,6 +22,7 @@ from openerp.osv import osv, fields from tools.translate import _ import re +from openerp.tools.misc import html2plaintext class note_stage(osv.osv): """ Category of Note """ @@ -62,26 +63,24 @@ class note_note(osv.osv): def _get_note_first_line(self, cr, uid, ids, name="", args={}, context=None): res = {} for note in self.browse(cr, uid, ids, context=context): - text_note = (note.memo or '').strip().split('\n')[0] - text_note = re.sub(r'(\S?)(|<[/]?p>|<[/]?div>|)[\s\S]*',r'\1',text_note) - text_note = re.sub(r'<[^>]+>','',text_note) - res[note.id] = text_note + res[note.id] = (note.memo and html2plaintext(note.memo) or "").strip().replace('*','').split("\n")[0] + return res #unactivate a sticky note and record the date def onclick_note_is_done(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, { 'active' : False, 'date_done' : fields.date.today() }) + self.write(cr, uid, ids, { 'open' : False, 'date_done' : fields.date.today() }) self.message_post(cr, uid, ids[0], body='Note is done.', subject=False, type='notification', parent_id=False, attachments=None, context=context) return False #activate a note def onclick_note_not_done(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'active' : True}) + self.write(cr, uid, ids, {'open' : True}) self.message_post(cr, uid, ids[0], body='Note has been activated.', subject=False, type='notification', parent_id=False, attachments=None, context=context) return False - + #used for undisplay the follower if it's the current user def _get_my_current_partner(self, cr, uid, ids, name, args, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) @@ -96,7 +95,8 @@ class note_note(osv.osv): def _set_stage_per_user(self, cr, uid, id, name, value, args=None, context=None): note = self.browse(cr, uid, id, context=context) if not value: return False - return self.write(cr, uid, [id], {'stage_ids': [(4, value)]}, context=context) + stage_ids = [value] + [stage.id for stage in note.stage_ids if stage.user_id.id != uid ] + return self.write(cr, uid, [id], {'stage_ids': [(6, 0, stage_ids)]}, context=context) def _get_stage_per_user(self, cr, uid, ids, name, args, context=None): result = dict.fromkeys(ids, False) @@ -119,14 +119,14 @@ class note_note(osv.osv): type='many2one', relation='note.stage'), 'stage_ids': fields.many2many('note.stage','note_stage_rel','note_id','stage_id','Stages of Users'), - 'active': fields.boolean('Active'), + 'open': fields.boolean('Active'), 'date_done': fields.date('Date done'), 'color': fields.integer('Color Index'), 'tag_ids' : fields.many2many('note.tag','note_tags_rel','note_id','tag_id','Tags'), 'current_partner_id' : fields.function(_get_my_current_partner), } _defaults = { - 'active' : 1, + 'open' : 1, 'stage_id' : _get_default_stage_id, } _order = 'sequence' @@ -185,5 +185,4 @@ class note_base_config_settings(osv.osv_memory): _columns = { 'module_note_pad': fields.boolean('Use collaborative pads (etherpad)'), 'group_note_fancy': fields.boolean('Use fancy layouts for notes', implied_group='note.group_note_fancy'), - 'group_note_tags': fields.boolean('Allow setting tags on notes', implied_group='note.group_note_tags'), } diff --git a/addons/note/note_demo.xml b/addons/note/note_demo.xml index 82601f903c0..7769e3ee303 100644 --- a/addons/note/note_demo.xml +++ b/addons/note/note_demo.xml @@ -4,74 +4,68 @@ Today 1 - + Tomorrow 2 - + Later 3 - + - Notes + Morning 4 - + - Customer report #349872 - Customer report #349872

* Calendar app in Home
* The base_calendar module should create a menu in Home, like described above.
* This module should become a main application (in the first screen at installation)
* We should use the term Calendar, not Meeting. ]]>
- + 2 +
- Call Fabien

* Followed by the telephone conversation and mail about D.544.3 ]]>
- -
- - -
]]> -
- +
- Project N.947.5

]]>
- Shop for family dinner
* stuffed turkey
* wine ]]>
- + +
- Idea to develop

* Create a module note_pad it transforms the html editable memo text field into widget='pad', similar to project_pad depends on 'memo' and 'pad' modules ]]> @@ -79,17 +73,8 @@
- -
* Open ERP: a modern approach to integrated business management -
* Open ERP for Retail and Industrial Management - ]]> -
- -
- - New computer specs

* Motherboard according to processor
* Processor @@ -108,43 +93,27 @@
3 +
- Read those books

* Open ERP: a modern approach to integrated business management
* Open ERP for Retail and Industrial Management ]]>
- -
- - -
* Open ERP: a modern approach to integrated business management -
* Open ERP for Retail and Industrial Management - ]]> -
- +
- Read some documentation about OpenERP before diving into the code

* Open ERP: a modern approach to integrated business management
* Open ERP for Retail and Industrial Management ]]>
- + 7 -
- - -
* Open ERP: a modern approach to integrated business management -
* Open ERP for Retail and Industrial Management - ]]> -
- +
diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml index feb3d3302ec..62b007aab6e 100644 --- a/addons/note/note_view.xml +++ b/addons/note/note_view.xml @@ -1,9 +1,6 @@ - - - note.stage.form @@ -39,8 +36,6 @@ [('user_id','=',uid)] - - note.note.kanban @@ -51,7 +46,7 @@ - + @@ -65,8 +60,8 @@
- W - W + W + W @@ -78,13 +73,12 @@
- -
+
-
+
@@ -105,9 +99,9 @@ - + - + @@ -119,12 +113,10 @@
+
- - - @@ -138,10 +130,9 @@ - - - - + + + @@ -168,10 +159,6 @@
-
- -
@@ -185,10 +172,11 @@ form kanban,tree,form - {'search_default_active_true':True} + {'search_default_open_true':True} - + + diff --git a/addons/note/security/ir.rule.xml b/addons/note/security/ir.rule.xml index 3d2f0d242f6..1195314cc9e 100644 --- a/addons/note/security/ir.rule.xml +++ b/addons/note/security/ir.rule.xml @@ -1,12 +1,19 @@ - - Only followers can access a sticky notes - - ['|',('message_follower_ids','=',False),('message_follower_ids','=',user.partner_id.id)] - - + + Only followers can access a sticky notes + + [('message_follower_ids','=',user.partner_id.id)] + + + + + Each user have his stage name + + ['|',('user_id','=',False),('user_id','=',user.id)] + + diff --git a/addons/note/security/res.groups.csv b/addons/note/security/res.groups.csv index 61c54c964ff..88d7b2cd667 100644 --- a/addons/note/security/res.groups.csv +++ b/addons/note/security/res.groups.csv @@ -1,3 +1,2 @@ id,name,implied_ids/id -group_note_tags,Memo / Display tags, group_note_fancy,Memo / Fancy mode, diff --git a/addons/note_pad/note_pad.py b/addons/note_pad/note_pad.py index 9864f0ae14f..d0c18a9f986 100644 --- a/addons/note_pad/note_pad.py +++ b/addons/note_pad/note_pad.py @@ -31,11 +31,5 @@ class note_pad_note(osv.osv): _pad_fields = ['note_pad'] _columns = { - 'note_pad_url': fields.char('Pad Url', - pad_content_field='memo', - size=250 ), - } - - #_defaults = { - # 'note_pad_url': lambda self, cr, uid, context: self.pad_generate_url(cr, uid, context), - #} + 'note_pad_url': fields.char('Pad Url', pad_content_field='memo'), + } \ No newline at end of file diff --git a/addons/pad/pad.py b/addons/pad/pad.py index d21ccd42d16..0cbb6107979 100644 --- a/addons/pad/pad.py +++ b/addons/pad/pad.py @@ -5,24 +5,56 @@ import re import string import urllib2 from tools.translate import _ +from openerp.tools.misc import html2plaintext +from py_etherpad import EtherpadLiteClient class pad_common(osv.osv_memory): _name = 'pad.common' def pad_generate_url(self, cr, uid, context=None): - pad_server = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.pad_server + company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id; + + pad = { + "server" : company.pad_server, + "key" : company.pad_key or "4DxmsNIbnQUVQMW9S9tx2oLOSjFdrx1l", + } + # make sure pad server in the form of http://hostname - if not pad_server: + if not pad["server"]: return '' - if not pad_server.startswith('http'): - pad_server = 'http://' + pad_server - pad_server = pad_server.rstrip('/') + if not pad["server"].startswith('http'): + pad["server"] = 'http://' + pad["server"] + pad["server"] = pad["server"].rstrip('/') # generate a salt s = string.ascii_uppercase + string.digits salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(10)]) + #path + path = '%s-%s-%s' % (cr.dbname.replace('_','-'), self._name, salt) # contruct the url - url = '%s/p/%s-%s-%s' % (pad_server, cr.dbname, self._name, salt) - return url + url = '%s/p/%s' % (pad["server"], path) + + #if create with content + if "field_name" in context and "model" in context and "object_id" in context: + myPad = EtherpadLiteClient( pad["key"], pad["server"]+'/api') + myPad.createPad(path) + + #get attr on the field model + model = self.pool.get(context["model"]) + field = model._all_columns[context['field_name']] + real_field = field.column.pad_content_field + + #get content of the real field + for record in model.browse(cr, uid, [context["object_id"]]): + if record[real_field]: + myPad.setText(path, html2plaintext(record[real_field])) + #Etherpad for html not functional + #myPad.setHTML(path, record[real_field]) + + return { + "server": pad["server"], + "path": path, + "url": url, + } def pad_get_content(self, cr, uid, url, context=None): content = '' @@ -35,22 +67,21 @@ class pad_common(osv.osv_memory): # TODO # reverse engineer protocol to be setHtml without using the api key - # override read and copy to generate url and store the content if empty - - def default_get(self, cr, uid, fields, context=None): - data = super(pad_common, self).default_get(cr, uid, fields, context) - for k in fields: - field = self._all_columns[k].column - if hasattr(field,'pad_content_field'): - data[k] = self.pad_generate_url(cr, uid, context=context) - return data def write(self, cr, uid, ids, vals, context=None): + self._set_pad_value(cr, uid, vals, context) + return super(pad_common, self).write(cr, uid, ids, vals, context=context) + + def create(self, cr, uid, vals, context=None): + self._set_pad_value(cr, uid, vals, context) + return super(pad_common, self).create(cr, uid, vals, context=context) + + # Set the pad content in vals + def _set_pad_value(self, cr, uid, vals, context=None): for k,v in vals.items(): field = self._all_columns[k].column if hasattr(field,'pad_content_field'): - vals[field.pad_content_field] = self.pad_get_content(cr, uid, v, context=context) - return super(pad_common, self).write(cr, uid, ids, vals, context=context) + vals[field.pad_content_field] = self.pad_get_content(cr, uid, v, context=context) def copy(self, cr, uid, id, default=None, context=None): if not default: @@ -58,7 +89,8 @@ class pad_common(osv.osv_memory): for k,v in self._all_columns: field = v.column if hasattr(field,'pad_content_field'): - default[k] = self.pad_generate_url(cr, uid, context) + pad = self.pad_generate_url(cr, uid, context) + default[k] = pad['url'] return super(pad_common, self).copy(cr, uid, id, default, context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/pad/py_etherpad/__init__.py b/addons/pad/py_etherpad/__init__.py new file mode 100644 index 00000000000..6af310b48aa --- /dev/null +++ b/addons/pad/py_etherpad/__init__.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +"""Module to talk to EtherpadLite API.""" + +import json +import urllib +import urllib2 + + +class EtherpadLiteClient: + """Client to talk to EtherpadLite API.""" + API_VERSION = 1 # TODO probably 1.1 sometime soon + + CODE_OK = 0 + CODE_INVALID_PARAMETERS = 1 + CODE_INTERNAL_ERROR = 2 + CODE_INVALID_FUNCTION = 3 + CODE_INVALID_API_KEY = 4 + TIMEOUT = 20 + + apiKey = "" + baseUrl = "http://localhost:9001/api" + + def __init__(self, apiKey=None, baseUrl=None): + if apiKey: + self.apiKey = apiKey + + if baseUrl: + self.baseUrl = baseUrl + + def call(self, function, arguments=None): + """Create a dictionary of all parameters""" + url = '%s/%d/%s' % (self.baseUrl, self.API_VERSION, function) + + params = arguments or {} + params.update({'apikey': self.apiKey}) + data = urllib.urlencode(params, True) + + try: + opener = urllib2.build_opener() + request = urllib2.Request(url=url, data=data) + response = opener.open(request, timeout=self.TIMEOUT) + result = response.read() + response.close() + except urllib2.HTTPError: + raise + + result = json.loads(result) + if result is None: + raise ValueError("JSON response could not be decoded") + + return self.handleResult(result) + + def handleResult(self, result): + """Handle API call result""" + if 'code' not in result: + raise Exception("API response has no code") + if 'message' not in result: + raise Exception("API response has no message") + + if 'data' not in result: + result['data'] = None + + if result['code'] == self.CODE_OK: + return result['data'] + elif result['code'] == self.CODE_INVALID_PARAMETERS or result['code'] == self.CODE_INVALID_API_KEY: + raise ValueError(result['message']) + elif result['code'] == self.CODE_INTERNAL_ERROR: + raise Exception(result['message']) + elif result['code'] == self.CODE_INVALID_FUNCTION: + raise Exception(result['message']) + else: + raise Exception("An unexpected error occurred whilst handling the response") + + # GROUPS + # Pads can belong to a group. There will always be public pads that do not belong to a group (or we give this group the id 0) + + def createGroup(self): + """creates a new group""" + return self.call("createGroup") + + def createGroupIfNotExistsFor(self, groupMapper): + """this functions helps you to map your application group ids to etherpad lite group ids""" + return self.call("createGroupIfNotExistsFor", { + "groupMapper": groupMapper + }) + + def deleteGroup(self, groupID): + """deletes a group""" + return self.call("deleteGroup", { + "groupID": groupID + }) + + def listPads(self, groupID): + """returns all pads of this group""" + return self.call("listPads", { + "groupID": groupID + }) + + def createGroupPad(self, groupID, padName, text=''): + """creates a new pad in this group""" + params = { + "groupID": groupID, + "padName": padName, + } + if text: + params['text'] = text + return self.call("createGroupPad", params) + + # AUTHORS + # Theses authors are bind to the attributes the users choose (color and name). + + def createAuthor(self, name=''): + """creates a new author""" + params = {} + if name: + params['name'] = name + return self.call("createAuthor", params) + + def createAuthorIfNotExistsFor(self, authorMapper, name=''): + """this functions helps you to map your application author ids to etherpad lite author ids""" + params = { + 'authorMapper': authorMapper + } + if name: + params['name'] = name + return self.call("createAuthorIfNotExistsFor", params) + + # SESSIONS + # Sessions can be created between a group and a author. This allows + # an author to access more than one group. The sessionID will be set as + # a cookie to the client and is valid until a certain date. + + def createSession(self, groupID, authorID, validUntil): + """creates a new session""" + return self.call("createSession", { + "groupID": groupID, + "authorID": authorID, + "validUntil": validUntil + }) + + def deleteSession(self, sessionID): + """deletes a session""" + return self.call("deleteSession", { + "sessionID": sessionID + }) + + def getSessionInfo(self, sessionID): + """returns informations about a session""" + return self.call("getSessionInfo", { + "sessionID": sessionID + }) + + def listSessionsOfGroup(self, groupID): + """returns all sessions of a group""" + return self.call("listSessionsOfGroup", { + "groupID": groupID + }) + + def listSessionsOfAuthor(self, authorID): + """returns all sessions of an author""" + return self.call("listSessionsOfAuthor", { + "authorID": authorID + }) + + # PAD CONTENT + # Pad content can be updated and retrieved through the API + + def getText(self, padID, rev=None): + """returns the text of a pad""" + params = {"padID": padID} + if rev is not None: + params['rev'] = rev + return self.call("getText", params) + + # introduced with pull request merge + def getHtml(self, padID, rev=None): + """returns the html of a pad""" + params = {"padID": padID} + if rev is not None: + params['rev'] = rev + return self.call("getHTML", params) + + def setText(self, padID, text): + """sets the text of a pad""" + return self.call("setText", { + "padID": padID, + "text": text + }) + + def setHtml(self, padID, html): + """sets the text of a pad from html""" + return self.call("setHTML", { + "padID": padID, + "html": html + }) + + # PAD + # Group pads are normal pads, but with the name schema + # GROUPID$PADNAME. A security manager controls access of them and its + # forbidden for normal pads to include a in the name. + + def createPad(self, padID, text=''): + """creates a new pad""" + params = { + "padID": padID, + } + if text: + params['text'] = text + return self.call("createPad", params) + + def getRevisionsCount(self, padID): + """returns the number of revisions of this pad""" + return self.call("getRevisionsCount", { + "padID": padID + }) + + def deletePad(self, padID): + """deletes a pad""" + return self.call("deletePad", { + "padID": padID + }) + + def getReadOnlyID(self, padID): + """returns the read only link of a pad""" + return self.call("getReadOnlyID", { + "padID": padID + }) + + def setPublicStatus(self, padID, publicStatus): + """sets a boolean for the public status of a pad""" + return self.call("setPublicStatus", { + "padID": padID, + "publicStatus": publicStatus + }) + + def getPublicStatus(self, padID): + """return true of false""" + return self.call("getPublicStatus", { + "padID": padID + }) + + def setPassword(self, padID, password): + """returns ok or a error message""" + return self.call("setPassword", { + "padID": padID, + "password": password + }) + + def isPasswordProtected(self, padID): + """returns true or false""" + return self.call("isPasswordProtected", { + "padID": padID + }) diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js index 4f5ecbf1793..1e45b535867 100644 --- a/addons/pad/static/src/js/pad.js +++ b/addons/pad/static/src/js/pad.js @@ -8,8 +8,22 @@ openerp.pad = function(instance) { var self = this; var _super = self._super; _super.apply(self,[val]); + + if (val === false || val === "") { + self.field_manager.dataset.call('pad_generate_url',{context:{ + model: self.field_manager.model, + field_name: self.name, + object_id: self.field_manager.datarecord.id + }}).then(function(data) { + if(data&&data.url){ + _super.apply(self,[data.url]); + self.renderElement(); + } + }); + } else { + self.renderElement(); + } this._dirty_flag = true; - self.renderElement(); }, renderElement: function(){ var self = this; diff --git a/addons/plugin_thunderbird/i18n/is.po b/addons/plugin_thunderbird/i18n/is.po new file mode 100644 index 00000000000..cc846bc56d8 --- /dev/null +++ b/addons/plugin_thunderbird/i18n/is.po @@ -0,0 +1,109 @@ +# Icelandic 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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-02-09 00:36+0000\n" +"PO-Revision-Date: 2012-09-19 10:08+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Icelandic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,pdf_file:0 +msgid "Installation Manual" +msgstr "Uppsetningarhandbók" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,description:0 +msgid "Description" +msgstr "Lýsing" + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "title" +msgstr "titill" + +#. module: plugin_thunderbird +#: model:ir.model,name:plugin_thunderbird.model_plugin_thunderbird_installer +msgid "plugin_thunderbird.installer" +msgstr "plugin_thunderbird.installer" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,config_logo:0 +msgid "Image" +msgstr "Mynd" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,plugin_file:0 +#: field:plugin_thunderbird.installer,thunderbird:0 +msgid "Thunderbird Plug-in" +msgstr "Thunderbird viðbót" + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "" +"This plug-in allows you to link your email to OpenERP's documents. You can " +"attach it to any existing one in OpenERP or create a new one." +msgstr "" + +#. module: plugin_thunderbird +#: help:plugin_thunderbird.installer,thunderbird:0 +msgid "" +"Allows you to select an object that you would like to add to your email and " +"its attachments." +msgstr "" +"Gerir þér kleift að velja hlut sem þú vilt bæta við póstinn og viðhengi hans." + +#. module: plugin_thunderbird +#: help:plugin_thunderbird.installer,pdf_file:0 +msgid "The documentation file :- how to install Thunderbird Plug-in." +msgstr "Handbókin :- hvernig á að setja inn Thunderbird viðbót." + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "_Close" +msgstr "_Loka" + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "Installation and Configuration Steps" +msgstr "" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,name:0 +#: field:plugin_thunderbird.installer,pdf_name:0 +msgid "File name" +msgstr "Skrárheiti" + +#. module: plugin_thunderbird +#: help:plugin_thunderbird.installer,plugin_file:0 +msgid "" +"Thunderbird plug-in file. Save as this file and install this plug-in in " +"thunderbird." +msgstr "" +"Skrá með Thunderbird viðbót. Vistaðu skrána og settu viðbótina inn í " +"Thunderbird." + +#. module: plugin_thunderbird +#: model:ir.actions.act_window,name:plugin_thunderbird.action_thunderbird_installer +#: model:ir.ui.menu,name:plugin_thunderbird.menu_base_config_plugins_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "Install Thunderbird Plug-In" +msgstr "Setja inn Thunderbird viðbót" + +#~ msgid "" +#~ "This plug-in allows you to link your e-mail to OpenERP's documents. You can " +#~ "attach it to any existing one in OpenERP or create a new one." +#~ msgstr "" +#~ "Þessi viðbót gerir þér kleift að tengja tölvupóst við OpenERP skjöl. Þú " +#~ "getur viðhengt póstinn við skjöl sem þegar eru til í OpenERP eða búið til " +#~ "nýtt." diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py index bf0ced67a0f..e9dd628243b 100644 --- a/addons/point_of_sale/__openerp__.py +++ b/addons/point_of_sale/__openerp__.py @@ -49,7 +49,7 @@ Main Features """, 'author': 'OpenERP SA', 'images': ['images/cash_registers.jpeg', 'images/pos_analysis.jpeg','images/register_analysis.jpeg','images/sale_order_pos.jpeg','images/product_pos.jpeg'], - 'depends': ['sale'], + 'depends': ['sale_stock'], 'data': [ 'security/point_of_sale_security.xml', 'security/ir.model.access.csv', diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py index 72c8469c042..a41c28f15e2 100644 --- a/addons/portal/mail_mail.py +++ b/addons/portal/mail_mail.py @@ -43,7 +43,7 @@ class mail_mail_portal(osv.Model): :param partner: browse_record of the specific recipient partner """ if partner: - portal_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'portal') + portal_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal') portal_id = portal_ref and portal_ref[1] or False url = self._generate_signin_url(cr, uid, partner.id, portal_id, 1234, context=context) body = tools.append_content_to_html(mail.body_html, url) diff --git a/addons/portal/portal.py b/addons/portal/portal.py index 3672d87cf30..13cde80f849 100644 --- a/addons/portal/portal.py +++ b/addons/portal/portal.py @@ -20,196 +20,14 @@ ############################################################################## from osv import osv, fields -from tools.translate import _ - class portal(osv.osv): + """ A portal is simply a group of users with the flag 'is_portal' set to True. + The flag 'is_portal' makes a user group usable as a portal. """ - A portal is a group of users with specific menu, widgets, and typically - restricted access rights. - """ - _name = 'res.portal' - _description = 'Portal' - _inherits = {'res.groups': 'group_id'} - + _inherit = 'res.groups' _columns = { - 'group_id': fields.many2one('res.groups', required=True, ondelete='cascade', - string='Group', - help='The group corresponding to this portal'), - 'url': fields.char('URL', - help="The url where portal users can connect to the server"), - 'home_action_id': fields.many2one('ir.actions.actions', - string='Home Action', - help="if set, replaces the standard home action (first screen after loggin) for the portal's users"), - 'menu_action_id': fields.many2one('ir.actions.act_window', readonly=True, - # ISSUE: 'ondelete' constraints do not seem effective on this field... - string='Menu Action', - help="If set, replaces the standard menu for the portal's users"), - 'parent_menu_id': fields.many2one('ir.ui.menu', ondelete='restrict', - string='Parent Menu', - help='The menu action opens the submenus of this menu item'), - 'widget_ids': fields.one2many('res.portal.widget', 'portal_id', - string='Widgets', - help='Widgets assigned to portal users'), + 'is_portal': fields.boolean('Portal', help="If checked, this group is usable as a portal."), } - def copy(self, cr, uid, id, values, context=None): - """ override copy(): menu_action_id must be different """ - values['menu_action_id'] = None - return super(portal, self).copy(cr, uid, id, values, context) - - def create(self, cr, uid, values, context=None): - """ extend create() to assign the portal menu to users """ - if context is None: - context = {} - - # create portal (admin should not be included) - context['noadmin'] = True - portal_id = super(portal, self).create(cr, uid, values, context) - - # assign menu action and widgets to users - if values.get('users') or values.get('menu_action_id'): - self._assign_menu(cr, uid, [portal_id], context) - if values.get('users') or values.get('widget_ids'): - self._assign_widgets(cr, uid, [portal_id], context) - - return portal_id - - def write(self, cr, uid, ids, values, context=None): - """ extend write() to reflect changes on users """ - # first apply portal changes - super(portal, self).write(cr, uid, ids, values, context) - - # assign menu action and widgets to users - if values.get('users') or values.get('menu_action_id'): - self._assign_menu(cr, uid, ids, context) - if values.get('users') or values.get('widget_ids'): - self._assign_widgets(cr, uid, ids, context) - - # if parent_menu_id has changed, apply the change on menu_action_id - if 'parent_menu_id' in values: - act_window_obj = self.pool.get('ir.actions.act_window') - portals = self.browse(cr, uid, ids, context) - action_ids = [p.menu_action_id.id for p in portals if p.menu_action_id] - if action_ids: - action_values = {'domain': [('parent_id', '=', values['parent_menu_id'])]} - act_window_obj.write(cr, uid, action_ids, action_values, context) - - return True - - def _assign_menu(self, cr, uid, ids, context=None): - """ assign portal_menu_settings to users of portals (ids) """ - user_obj = self.pool.get('res.users') - for p in self.browse(cr, uid, ids, context): - # user menu action = portal menu action if set in portal - if p.menu_action_id: - user_ids = [u.id for u in p.users if u.id != 1] - user_values = {'menu_id': p.menu_action_id.id} - user_obj.write(cr, uid, user_ids, user_values, context) - - def _assign_widgets(self, cr, uid, ids, context=None): - """ assign portal widgets to users of portals (ids) """ - widget_user_obj = self.pool.get('res.widget.user') - for p in self.browse(cr, uid, ids, context): - for w in p.widget_ids: - values = {'sequence': w.sequence, 'widget_id': w.widget_id.id} - for u in p.users: - if u.id == 1: continue - values['user_id'] = u.id - widget_user_obj.create(cr, uid, values, context) - - def _res_xml_id(self, cr, uid, module, xml_id): - """ return the resource id associated to the given xml_id """ - data_obj = self.pool.get('ir.model.data') - data_id = data_obj._get_id(cr, uid, module, xml_id) - return data_obj.browse(cr, uid, data_id).res_id - -portal() - - - -class portal_override_menu(osv.osv): - """ - Extend res.portal with a boolean field 'Override Users Menu', that - triggers the creation or removal of menu_action_id - """ - _name = 'res.portal' - _inherit = 'res.portal' - - def _get_override_menu(self, cr, uid, ids, field_name, arg, context=None): - assert field_name == 'override_menu' - result = {} - for p in self.browse(cr, uid, ids, context): - result[p.id] = bool(p.menu_action_id) - return result - - def _set_override_menu(self, cr, uid, id, field_name, field_value, arg, context=None): - assert field_name == 'override_menu' - if field_value: - self.create_menu_action(cr, uid, id, context) - else: - self.write(cr, uid, [id], {'menu_action_id': False}, context) - - def create_menu_action(self, cr, uid, id, context=None): - """ create, if necessary, a menu action that opens the menu items below - parent_menu_id """ - p = self.browse(cr, uid, id, context) - if not p.menu_action_id: - actions_obj = self.pool.get('ir.actions.act_window') - parent_id = p.parent_menu_id.id if p.parent_menu_id else False - action_values = { - 'name': _('%s Menu') % p.name, - 'type': 'ir.actions.act_window', - 'usage': 'menu', - 'res_model': 'ir.ui.menu', - 'view_type': 'tree', - 'view_id': self._res_xml_id(cr, uid, 'base', 'view_menu'), - 'domain': [('parent_id', '=', parent_id)], - } - action_id = actions_obj.create(cr, uid, action_values, context) - self.write(cr, uid, [id], {'menu_action_id': action_id}, context) - - _columns = { - 'override_menu': fields.function( - _get_override_menu, fnct_inv=_set_override_menu, - type='boolean', string='Override Menu Action of Users', - help='Enable this option to override the Menu Action of portal users'), - } - -portal_override_menu() - - - -class portal_widget(osv.osv): - """ - Similar to res.widget.user (res_widget.py), but with a portal instead. - New users in a portal are assigned the portal's widgets. - """ - _name='res.portal.widget' - _description = 'Portal Widgets' - _order = 'sequence' - _columns = { - 'sequence': fields.integer('Sequence'), - 'portal_id': fields.many2one('res.portal', select=1, ondelete='cascade', - string='Portal'), - 'widget_id': fields.many2one('res.widget', required=True, ondelete='cascade', - string='Widget'), - } - - def create(self, cr, uid, values, context=None): - domain = [('portal_id', '=', values.get('portal_id')), - ('widget_id', '=', values.get('widget_id'))] - existing = self.search(cr, uid, domain, context=context) - if existing: - res = existing[0] - else: - res = super(portal_widget, self).create(cr, uid, values, context=context) - return res - -portal_widget() - - - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/portal_data.xml b/addons/portal/portal_data.xml index eb06ca656d6..a980552a854 100644 --- a/addons/portal/portal_data.xml +++ b/addons/portal/portal_data.xml @@ -2,14 +2,6 @@ - - Portal - - - - - - Company's news diff --git a/addons/portal/portal_demo.xml b/addons/portal/portal_demo.xml index 1ace02f3d7d..a8727b99556 100644 --- a/addons/portal/portal_demo.xml +++ b/addons/portal/portal_demo.xml @@ -13,13 +13,13 @@ - + - Our first company's blogpost ! + Our company's first blog-post ! mail.group @@ -21,71 +21,31 @@ - - - Portal List - res.portal + + + Group Search + res.groups + - - - + + + + + - - + + Portal Form - res.portal + res.groups - - - - - - - - - - - - - - - - - - - - - + + + - - - Portals - res.portal - form - tree,form - - {'form_view_ref': 'portal.portal_form_view'} - -

- Click to create a new portal. -

- A portal helps defining specific views and rules for a group of - users (the portal group). A portal menu, widgets and specific - groups may be assigned to the portal's users. -

-
-
- - - - -
diff --git a/addons/portal/security/ir.model.access.csv b/addons/portal/security/ir.model.access.csv index 56b3ae5f269..2d7a17e0016 100644 --- a/addons/portal/security/ir.model.access.csv +++ b/addons/portal/security/ir.model.access.csv @@ -1,12 +1,8 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_all,access.portal.all,model_res_portal,,1,0,0,0 -access_widget_all,access.portal.widget.all,model_res_portal_widget,,1,0,0,0 -access_manager,access.portal.manager,model_res_portal,group_portal_manager,1,1,1,1 -access_widget_manager,access.portal.widget.manager,model_res_portal_widget,group_portal_manager,1,1,1,1 -access_mail_message,mail.message,mail.model_mail_message,group_portal_member,1,0,1,1 -access_mail_message_all,mail.message.all,mail.model_mail_message,group_portal_member,1,0,0,0 -access_mail_thread,mail.thread,mail.model_mail_thread,group_portal_member,1,0,0,0 -access_mail_followers,mail.followers,mail.model_mail_followers,group_portal_member,1,0,1,1 -access_mail_notification,mail.notification,mail.model_mail_notification,group_portal_member,1,0,1,0 -access_mail_group,mail.group,mail.model_mail_group,group_portal_member,1,0,0,0 -access_mail_alias,mail.alias,mail.model_mail_alias,group_portal_member,1,0,0,0 +access_mail_message,mail.message,mail.model_mail_message,group_portal,1,0,1,1 +access_mail_message_all,mail.message.all,mail.model_mail_message,group_portal,1,0,0,0 +access_mail_thread,mail.thread,mail.model_mail_thread,group_portal,1,0,0,0 +access_mail_followers,mail.followers,mail.model_mail_followers,group_portal,1,0,1,1 +access_mail_notification,mail.notification,mail.model_mail_notification,group_portal,1,0,1,0 +access_mail_group,mail.group,mail.model_mail_group,group_portal,1,0,0,0 +access_mail_alias,mail.alias,mail.model_mail_alias,group_portal,1,0,0,0 diff --git a/addons/portal/security/portal_security.xml b/addons/portal/security/portal_security.xml index 4a493204d67..ee0af785599 100644 --- a/addons/portal/security/portal_security.xml +++ b/addons/portal/security/portal_security.xml @@ -2,31 +2,14 @@ - - - Portal Member - Portal members can access information through the portal menu. Also, they are chrooted in this specific menu. - - - + + Portal - - 25 - - - - - Officer - Portal officers can create new portal users with the portal wizard. - - - - - Manager - Portal managers have access to the portal definitions, and can easily configure the users, access rights and menus of portal users. - - - + Portal members have specific access rights (such as record rules and restricted menus). + They usually do not belong to the usual OpenERP groups. + + + diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py index 2c301228859..5e992fa06ea 100644 --- a/addons/portal/tests/test_portal.py +++ b/addons/portal/tests/test_portal.py @@ -42,7 +42,7 @@ class test_portal(test_mail.TestMailMockups): user_admin = self.res_users.browse(cr, uid, uid) self.mail_invite = self.registry('mail.wizard.invite') base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='') - portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'portal') + portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal') portal_id = portal_ref and portal_ref[1] or False # 0 - Admin diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py index 85f6566eba6..3cc706c2129 100644 --- a/addons/portal/wizard/portal_wizard.py +++ b/addons/portal/wizard/portal_wizard.py @@ -23,33 +23,43 @@ import logging import random from osv import osv, fields -from tools.misc import email_re from tools.translate import _ +from tools.misc import email_re +from openerp import SUPERUSER_ID from base.res.res_partner import _lang_get _logger = logging.getLogger(__name__) - -# welcome email sent to new portal users (note that calling tools.translate._ -# has no effect except exporting those strings for translation) +# welcome/goodbye email sent to portal users +# (note that calling '_' has no effect except exporting those strings for translation) WELCOME_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s") WELCOME_EMAIL_BODY = _("""Dear %(name)s, -You have been created an OpenERP account at %(url)s. +You have been given access to %(portal)s at %(url)s. Your login account data is: Database: %(db)s User: %(login)s Password: %(password)s -%(message)s +%(welcome_message)s -- OpenERP - Open Source Business Applications http://www.openerp.com """) -ROOT_UID = 1 +GOODBYE_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s") +GOODBYE_EMAIL_BODY = _("""Dear %(name)s, + +Your access to %(portal)s has been withdrawn. + +%(goodbye_message)s + +-- +OpenERP - Open Source Business Applications +http://www.openerp.com +""") # character sets for passwords, excluding 0, O, o, 1, I, l _PASSU = 'ABCDEFGHIJKLMNPQRSTUVWXYZ' @@ -71,169 +81,173 @@ def extract_email(email): class wizard(osv.osv_memory): """ - A wizard to create portal users from instances of 'res.partner'. The purpose - is to provide an OpenERP database access to customers or suppliers. + A wizard to manage the creation/removal of portal users. """ - _name = 'res.portal.wizard' - _description = 'Portal Wizard' - + _name = 'portal.wizard' + _description = 'Portal Access Management' + _columns = { - 'portal_id': fields.many2one('res.portal', required=True, - string='Portal', - help="The portal in which new users must be added"), - 'user_ids': fields.one2many('res.portal.wizard.user', 'wizard_id', - string='Users'), - 'message': fields.text(string='Invitation message', - help="This text is included in the welcome email sent to the users"), + 'portal_id': fields.many2one('res.groups', domain=[('is_portal', '=', True)], required=True, + string='Portal', help="The portal that users can be added in or removed from."), + 'user_ids': fields.one2many('portal.wizard.user', 'wizard_id', string='Users'), + 'welcome_message': fields.text(string='Invitation Message', + help="This text is included in the email sent to new users of the portal."), + 'goodbye_message': fields.text(string='Withdrawal Message', + help="This text is included in the email sent to users withdrawn from the portal."), } - def _default_user_ids(self, cr, uid, context): - """ determine default user_ids from the active records """ - def create_user_from_address(address): - if isinstance(address, int): - res_partner_obj = self.pool.get('res.partner') - address = res_partner_obj.browse(cr, uid, address, context=context) - lang = address.id and address.lang or 'en_US' - partner_id = address.id - - else: - lang = address.parent_id and address.parent_id.lang or 'en_US' - partner_id = address.parent_id and address.parent_id.id - - return{ - 'name': address.name, - 'email': extract_email(address.email), - 'lang': lang, - 'partner_id': partner_id, - } - - user_ids = [] - if context.get('active_model') == 'res.partner': - partner_obj = self.pool.get('res.partner') - partner_ids = context.get('active_ids', []) - partners = partner_obj.browse(cr, uid, partner_ids, context) - for p in partners: - # add one user per contact, or one user if no contact - if p.child_ids: - user_ids.extend(map(create_user_from_address, p.child_ids)) - elif p.is_company == False and p.customer == True: - user_ids.extend(map(create_user_from_address, [p.id])) - else: - user_ids.append({'lang': p.lang or 'en_US', 'parent_id': p.id}) - - return user_ids + def _default_portal(self, cr, uid, context): + portal_ids = self.pool.get('res.groups').search(cr, uid, [('is_portal', '=', True)]) + return portal_ids and portal_ids[0] or False _defaults = { - 'user_ids': _default_user_ids + 'portal_id': _default_portal, } - def action_create(self, cr, uid, ids, context=None): - """ create new users in portal(s), and notify them by email """ - # we copy the context to change the language for translating emails - context0 = context or {} - context0['noshortcut'] = True # prevent shortcut creation - context = context0.copy() - - user_obj = self.pool.get('res.users') - user = user_obj.browse(cr, ROOT_UID, uid, context0) - if not user.email: - raise osv.except_osv(_('Email required'), - _('You must have an email address in your User Preferences' - ' to send emails.')) - - portal_obj = self.pool.get('res.portal') - for wiz in self.browse(cr, uid, ids, context): - # determine existing users - login_cond = [('login', 'in', [u.email for u in wiz.user_ids])] - existing_uids = user_obj.search(cr, ROOT_UID, login_cond) - existing_users = user_obj.browse(cr, ROOT_UID, existing_uids) - existing_logins = [u.login for u in existing_users] - - # create new users in portal (skip existing logins) - new_users_data = [ { - 'name': u.name, - 'login': u.email, - 'password': random_password(), - 'email': u.email, - 'lang': u.lang, - 'share': True, - 'action_id': wiz.portal_id.home_action_id and wiz.portal_id.home_action_id.id or False, - 'partner_id': u.partner_id and u.partner_id.id, - 'groups_id': [(6, 0, [])], - } for u in wiz.user_ids if u.email not in existing_logins ] - portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id], - {'users': [(0, 0, data) for data in new_users_data]}, context0) - - # send email to all users (translated in their language) - data = { - 'company': user.company_id.name, - 'message': wiz.message or "", - 'url': wiz.portal_id.url or _("(missing url)"), - 'db': cr.dbname, - } - mail_mail_obj = self.pool.get('mail.mail') - dest_uids = user_obj.search(cr, ROOT_UID, login_cond) - dest_users = user_obj.browse(cr, ROOT_UID, dest_uids) - for dest_user in dest_users: - context['lang'] = dest_user.lang - data['login'] = dest_user.login - data['password'] = dest_user.password - data['name'] = dest_user.name - - email_from = user.email - email_to = dest_user.email - subject = _(WELCOME_EMAIL_SUBJECT) % data - body = _(WELCOME_EMAIL_BODY) % data - mail_id = mail_mail_obj.create(cr, uid, { - 'email_from': email_from , - 'email_to': email_to, - 'subject': subject, - 'state': 'outgoing', - 'body_html': '
%s
' % body}, context=context) - + def onchange_portal_id(self, cr, uid, ids, portal_id, context=None): + # for each partner, determine corresponding portal.wizard.user records + res_partner = self.pool.get('res.partner') + partner_ids = context and context.get('active_ids') or [] + contact_ids = set() + user_changes = [] + for partner in res_partner.browse(cr, SUPERUSER_ID, partner_ids, context): + for contact in (partner.child_ids or [partner]): + # make sure that each contact appears at most once in the list + if contact.id not in contact_ids: + contact_ids.add(contact.id) + in_portal = False + if contact.user_ids: + in_portal = portal_id in [g.id for g in contact.user_ids[0].groups_id] + user_changes.append((0, 0, { + 'partner_id': contact.id, + 'email': contact.email, + 'in_portal': in_portal, + })) + return {'value': {'user_ids': user_changes}} + + def action_apply(self, cr, uid, ids, context=None): + wizard = self.browse(cr, uid, ids[0], context) + portal_user_ids = [user.id for user in wizard.user_ids] + self.pool.get('portal.wizard.user').action_apply(cr, uid, portal_user_ids, context) return {'type': 'ir.actions.act_window_close'} -wizard() - - - class wizard_user(osv.osv_memory): """ A model to configure users in the portal wizard. """ - _name = 'res.portal.wizard.user' + _name = 'portal.wizard.user' _description = 'Portal User Config' _columns = { - 'wizard_id': fields.many2one('res.portal.wizard', required=True, - string='Wizard'), - 'name': fields.char(size=64, required=True, - string='User Name', - help="The user's real name"), - 'email': fields.char(size=64, required=True, - string='Email', - help="Will be used as user login. " - "Also necessary to send the account information to new users"), - 'lang': fields.selection(_lang_get, required=True, - string='Language', - help="The language for the user's user interface"), - 'partner_id': fields.many2one('res.partner', - string='Partner'), + 'wizard_id': fields.many2one('portal.wizard', string='Wizard', required=True), + 'partner_id': fields.many2one('res.partner', string='Contact', required=True, readonly=True), + 'email': fields.char(size=240, string='Email'), + 'in_portal': fields.boolean('In Portal'), } - def _check_email(self, cr, uid, ids): - """ check syntax of email address """ - for wuser in self.browse(cr, uid, ids): - if not email_re.match(wuser.email): return False - return True + def create(self, cr, uid, values, context=None): + """ overridden to update the partner's email (if necessary) """ + id = super(wizard_user, self).create(cr, uid, values, context) + wuser = self.browse(cr, uid, id, context) + if wuser.partner_id.email != wuser.email: + wuser.partner_id.write({'email': wuser.email}) + return id - _constraints = [ - (_check_email, 'Invalid email address', ['email']), - ] + def action_apply(self, cr, uid, ids, context=None): + res_users = self.pool.get('res.users') + for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context): + portal = wizard_user.wizard_id.portal_id + user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) + if wizard_user.in_portal: + # create a user if necessary, and make sure it is in the portal group + if not user: + user = self._create_user(cr, SUPERUSER_ID, wizard_user, context) + if (not user.active) or (portal not in user.groups_id): + user.write({'active': True, 'groups_id': [(4, portal.id)]}) + wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context) + self._send_email(cr, uid, wizard_user, context) + else: + # remove the user (if it exists) from the portal group + if user and (portal in user.groups_id): + # if user belongs to portal only, deactivate it + if len(user.groups_id) <= 1: + user.write({'groups_id': [(3, portal.id)], 'active': False}) + else: + user.write({'groups_id': [(3, portal.id)]}) + wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context) + self._send_email(cr, uid, wizard_user, context) -wizard_user() + def _retrieve_user(self, cr, uid, wizard_user, context=None): + """ retrieve the (possibly inactive) user corresponding to wizard_user.partner_id + @param wizard_user: browse record of model portal.wizard.user + @return: browse record of model res.users + """ + if wizard_user.partner_id.user_ids: + return wizard_user.partner_id.user_ids[0] + # the user may be inactive, search for it + res_users = self.pool.get('res.users') + domain = [('partner_id', '=', wizard_user.partner_id.id), ('active', '=', False)] + user_ids = res_users.search(cr, uid, domain) + return user_ids and res_users.browse(cr, uid, user_ids[0], context) or False + def _create_user(self, cr, uid, wizard_user, context=None): + """ create a new user for wizard_user.partner_id + @param wizard_user: browse record of model portal.wizard.user + @return: browse record of model res.users + """ + res_users = self.pool.get('res.users') + create_context = dict(context or {}, noshortcut=True) # to prevent shortcut creation + values = { + 'login': extract_email(wizard_user.email), + 'password': random_password(), + 'partner_id': wizard_user.partner_id.id, + 'groups_id': [(6, 0, [])], + 'share': True, + } + user_id = res_users.create(cr, uid, values, context=create_context) + return res_users.browse(cr, uid, user_id, context) + def _send_email(self, cr, uid, wizard_user, context=None): + """ send notification email to a new/former portal user + @param wizard_user: browse record of model portal.wizard.user + @return: the id of the created mail.mail record + """ + this_context = context + this_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context) + if not this_user.email: + raise osv.except_osv(_('Email required'), + _('You must have an email address in your User Preferences to send emails.')) + # determine subject and body in the portal user's language + url = self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'web.base.url', context=this_context) + user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) + context = dict(this_context or {}, lang=user.lang) + data = { + 'company': this_user.company_id.name, + 'portal': wizard_user.wizard_id.portal_id.name, + 'welcome_message': wizard_user.wizard_id.welcome_message or "", + 'goodbye_message': wizard_user.wizard_id.goodbye_message or "", + 'url': url or _("(missing url)"), + 'db': cr.dbname, + 'login': user.login, + 'password': user.password, + 'name': user.name + } + if wizard_user.in_portal: + subject = _(WELCOME_EMAIL_SUBJECT) % data + body = _(WELCOME_EMAIL_BODY) % data + else: + subject = _(GOODBYE_EMAIL_SUBJECT) % data + body = _(GOODBYE_EMAIL_BODY) % data + + mail_mail = self.pool.get('mail.mail') + mail_values = { + 'email_from': this_user.email, + 'email_to': user.email, + 'subject': subject, + 'body_html': '
%s
' % body, + 'state': 'outgoing', + } + return mail_mail.create(cr, uid, mail_values, context=this_context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/wizard/portal_wizard_view.xml b/addons/portal/wizard/portal_wizard_view.xml index f3cd5c98bb4..c8e3f30b128 100644 --- a/addons/portal/wizard/portal_wizard_view.xml +++ b/addons/portal/wizard/portal_wizard_view.xml @@ -3,28 +3,34 @@ + groups="base.group_partner_manager"/> - Add Portal Access - res.portal.wizard + Portal Access Management + portal.wizard -
- - + + + +
+ Select which contacts should belong to the portal in the list below. + The email address of each selected contact must be valid and unique. + If necessary, you can fix any contact's email address directly in the list. +
-
diff --git a/addons/portal/wizard/share_wizard.py b/addons/portal/wizard/share_wizard.py index ca950a61b08..b1b6e980dec 100644 --- a/addons/portal/wizard/share_wizard.py +++ b/addons/portal/wizard/share_wizard.py @@ -44,9 +44,6 @@ class share_wizard_portal(osv.TransientModel): 'group_ids': fields.many2many('res.groups', 'share_wizard_res_group_rel', 'share_id', 'group_id', 'Existing groups', domain=[('share', '=', False)]), } - def is_portal_manager(self, cr, uid, context=None): - return self.has_group(cr, uid, module='portal', group_xml_id='group_portal_manager', context=context) - def _check_preconditions(self, cr, uid, wizard_data, context=None): if wizard_data.user_type == 'existing': self._assert(wizard_data.user_ids, @@ -122,16 +119,14 @@ class share_wizard_portal(osv.TransientModel): # alter the rules of the groups so they can see the shared data if wizard_data.group_ids: # get the list of portals and the related groups to install their menus. - Portals = self.pool.get('res.portal') - all_portals = Portals.browse(cr, UID_ROOT, Portals.search(cr, UID_ROOT, [])) #no context! - all_portal_group_ids = [p.group_id.id for p in all_portals] + res_groups = self.pool.get('res.groups') + all_portal_group_ids = res_groups.search(cr, UID_ROOT, [('is_portal', '=', True)]) # populate result lines with the users of each group and # setup the menu for portal groups for group in wizard_data.group_ids: if group.id in all_portal_group_ids: - portal = all_portals[all_portal_group_ids.index(group.id)] - self._create_shared_data_menu(cr, uid, wizard_data, portal, context=context) + self._create_shared_data_menu(cr, uid, wizard_data, group.id, context=context) for user in group.users: new_line = {'user_id': user.id, diff --git a/addons/portal/wizard/share_wizard_view.xml b/addons/portal/wizard/share_wizard_view.xml index 72ae857eaaf..065a7aa317e 100644 --- a/addons/portal/wizard/share_wizard_view.xml +++ b/addons/portal/wizard/share_wizard_view.xml @@ -36,12 +36,12 @@ - + - - + + diff --git a/addons/portal_claim/security/ir.model.access.csv b/addons/portal_claim/security/ir.model.access.csv index 554c66cc998..ab2a2f66770 100644 --- a/addons/portal_claim/security/ir.model.access.csv +++ b/addons/portal_claim/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_crm_claim,crm.claim,crm_claim.model_crm_claim,portal.group_portal_member,1,0,0,0 -access_crm_claim_stage,crm.claim.stage,crm_claim.model_crm_claim_stage,portal.group_portal_member,1,0,0,0 +access_crm_claim,crm.claim,crm_claim.model_crm_claim,portal.group_portal,1,0,0,0 +access_crm_claim_stage,crm.claim.stage,crm_claim.model_crm_claim_stage,portal.group_portal,1,0,0,0 diff --git a/addons/portal_claim/security/portal_security.xml b/addons/portal_claim/security/portal_security.xml index e902bd043ad..9fc47c4cfb0 100644 --- a/addons/portal_claim/security/portal_security.xml +++ b/addons/portal_claim/security/portal_security.xml @@ -6,7 +6,7 @@ Portal Personal Claims [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_event/security/ir.model.access.csv b/addons/portal_event/security/ir.model.access.csv index b418acbb9c4..7418b08bb4b 100644 --- a/addons/portal_event/security/ir.model.access.csv +++ b/addons/portal_event/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_event,event,event.model_event_event,portal.group_portal_member,1,0,0,0 -access_registration,registration,event.model_event_registration,portal.group_portal_member,1,0,0,0 +access_event,event,event.model_event_event,portal.group_portal,1,0,0,0 +access_registration,registration,event.model_event_registration,portal.group_portal,1,0,0,0 diff --git a/addons/portal_event/security/portal_security.xml b/addons/portal_event/security/portal_security.xml index 6a3ed0ac786..74b2372c147 100644 --- a/addons/portal_event/security/portal_security.xml +++ b/addons/portal_event/security/portal_security.xml @@ -6,14 +6,14 @@ Portal Visible Events [('visibility', '=', 'public')] - + Portal Personal Registrations [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_hr_employees/security/ir.model.access.csv b/addons/portal_hr_employees/security/ir.model.access.csv index 6131f49d749..d18aeb90e1c 100644 --- a/addons/portal_hr_employees/security/ir.model.access.csv +++ b/addons/portal_hr_employees/security/ir.model.access.csv @@ -1,6 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_hr_employee_user,hr.employee user,hr.model_hr_employee,portal.group_portal_member,1,0,0,0 -access_res_partner,res.partner,base.model_res_partner,portal.group_portal_member,1,0,0,0 -access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal_member,1,0,0,0 -access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal_member,1,0,0,0 -access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal_member,1,0,0,0 +access_hr_employee_user,hr.employee user,hr.model_hr_employee,portal.group_portal,1,0,0,0 +access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0 +access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal,1,0,0,0 +access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal,1,0,0,0 +access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal,1,0,0,0 diff --git a/addons/portal_project/security/ir.model.access.csv b/addons/portal_project/security/ir.model.access.csv index dceca5ba8bb..85463868ee1 100644 --- a/addons/portal_project/security/ir.model.access.csv +++ b/addons/portal_project/security/ir.model.access.csv @@ -1,5 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_task,tasks,project.model_project_task,portal.group_portal_member,1,0,0,0 -access_task_type,task_type,project.model_project_task_type,portal.group_portal_member,1,0,0,0 -access_task_work,task_work,project.model_project_task_work,portal.group_portal_member,1,0,0,0 -access_project_category,project_category,project.model_project_category,portal.group_portal_member,1,0,0,0 +access_task,tasks,project.model_project_task,portal.group_portal,1,0,0,0 +access_task_type,task_type,project.model_project_task_type,portal.group_portal,1,0,0,0 +access_task_work,task_work,project.model_project_task_work,portal.group_portal,1,0,0,0 +access_project_category,project_category,project.model_project_category,portal.group_portal,1,0,0,0 diff --git a/addons/portal_project/security/portal_security.xml b/addons/portal_project/security/portal_security.xml index b995c79bbbc..b9d37cec099 100644 --- a/addons/portal_project/security/portal_security.xml +++ b/addons/portal_project/security/portal_security.xml @@ -6,7 +6,7 @@ Portal Personal Task [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_project_issue/portal_project_issue_view.xml b/addons/portal_project_issue/portal_project_issue_view.xml index 5d0b4ce081e..1030dedbdf8 100644 --- a/addons/portal_project_issue/portal_project_issue_view.xml +++ b/addons/portal_project_issue/portal_project_issue_view.xml @@ -27,6 +27,7 @@ +
Creation: diff --git a/addons/portal_project_issue/security/ir.model.access.csv b/addons/portal_project_issue/security/ir.model.access.csv index 5257f9b6d02..80a38366b51 100644 --- a/addons/portal_project_issue/security/ir.model.access.csv +++ b/addons/portal_project_issue/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_issues,project_issue,project_issue.model_project_issue,portal.group_portal_member,1,0,0,0 -access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal_member,1,0,0,0 +access_issues,project_issue,project_issue.model_project_issue,portal.group_portal,1,0,0,0 +access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal,1,0,0,0 diff --git a/addons/portal_project_issue/security/portal_security.xml b/addons/portal_project_issue/security/portal_security.xml index 4ef8da5e4b6..358b5e6a0ad 100644 --- a/addons/portal_project_issue/security/portal_security.xml +++ b/addons/portal_project_issue/security/portal_security.xml @@ -6,7 +6,7 @@ Portal Personal Issues [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_sale/__openerp__.py b/addons/portal_sale/__openerp__.py index 764eb7b938d..8d7cd8b3935 100644 --- a/addons/portal_sale/__openerp__.py +++ b/addons/portal_sale/__openerp__.py @@ -30,7 +30,7 @@ This module adds sale menu and features to your portal if sale and portal are in ======================================================================================== """, 'author': 'OpenERP SA', - 'depends': ['sale','portal'], + 'depends': ['sale_stock','portal'], 'data': [ 'security/portal_security.xml', 'portal_sale_view.xml', diff --git a/addons/portal_sale/security/ir.model.access.csv b/addons/portal_sale/security/ir.model.access.csv index 32266499af7..751c0b9baff 100644 --- a/addons/portal_sale/security/ir.model.access.csv +++ b/addons/portal_sale/security/ir.model.access.csv @@ -1,33 +1,33 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_sale_order,sale.order,sale.model_sale_order,portal.group_portal_member,1,0,0,0 -access_sale_order_line,sale.order.line,sale.model_sale_order_line,portal.group_portal_member,1,0,0,0 -access_stock_picking,stock.picking,stock.model_stock_picking,portal.group_portal_member,1,0,0,0 -access_stock_picking.out,stock.picking.out,stock.model_stock_picking_out,portal.group_portal_member,1,0,0,0 -access_stock_move,stock.move,stock.model_stock_move,portal.group_portal_member,1,0,0,0 -access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,portal.group_portal_member,1,0,0,0 -access_account_invoice,account.invoice,account.model_account_invoice,portal.group_portal_member,1,0,0,0 -access_account_invoice_tax,account.invoice.tax,account.model_account_invoice_tax,portal.group_portal_member,1,0,0,0 -access_account_invoice_line,account.invoice.line,account.model_account_invoice_line,portal.group_portal_member,1,0,0,0 -access_account_journal,account.journal,account.model_account_journal,portal.group_portal_member,1,0,0,0 -access_account_voucher,account.voucher,account_voucher.model_account_voucher,portal.group_portal_member,1,0,0,0 -access_account_voucher_line,account.voucher.line,account_voucher.model_account_voucher_line,portal.group_portal_member,1,0,0,0 -access_account_move,account.move,account.model_account_move,portal.group_portal_member,1,0,0,0 -access_account_move_line,account.move.line,account.model_account_move_line,portal.group_portal_member,1,0,0,0 -access_account_move_reconcile,account.move.reconcile,account.model_account_move_reconcile,portal.group_portal_member,1,0,0,0 -access_account_fiscalyear,account.sequence.fiscalyear,account.model_account_sequence_fiscalyear,portal.group_portal_member,1,0,0,0 -access_sale_shop,sale.shop,sale.model_sale_shop,portal.group_portal_member,1,0,0,0 -access_product_list,product.pricelist,product.model_product_pricelist,portal.group_portal_member,1,0,0,0 -access_product,product.product,product.model_product_product,portal.group_portal_member,1,0,0,0 -access_res_partner,res.partner,base.model_res_partner,portal.group_portal_member,1,0,0,0 -access_product_uom,product.uom,product.model_product_uom,portal.group_portal_member,1,0,0,0 -access_account_tax,account.tax,account.model_account_tax,portal.group_portal_member,1,0,0,0 -access_mrp_property,mrp.property,procurement.model_mrp_property,portal.group_portal_member,1,0,0,0 -access_product_template,product.template,product.model_product_template,portal.group_portal_member,1,0,0,0 -access_stock_warehouse,stock.warehouse,stock.model_stock_warehouse,portal.group_portal_member,1,0,0,0 -access_stock_location,stock.location,stock.model_stock_location,portal.group_portal_member,1,0,0,0 -access_account_fiscalyear,account.fiscalyear,account.model_account_fiscalyear,portal.group_portal_member,1,0,0,0 -access_res_partner_category,res.partner.category,base.model_res_partner_category,portal.group_portal_member,1,0,0,0 -access_product_supplierinfo,product.supplierinfo,product.model_product_supplierinfo,portal.group_portal_member,1,0,0,0 -access_product_packaging,product.packaging,product.model_product_packaging,portal.group_portal_member,1,0,0,0 -access_account_period,account.period,account.model_account_period,portal.group_portal_member,1,0,0,0 -access_account_account,account.account,account.model_account_account,portal.group_portal_member,1,0,0,0 +access_sale_order,sale.order,sale.model_sale_order,portal.group_portal,1,0,0,0 +access_sale_order_line,sale.order.line,sale.model_sale_order_line,portal.group_portal,1,0,0,0 +access_stock_picking,stock.picking,stock.model_stock_picking,portal.group_portal,1,0,0,0 +access_stock_picking.out,stock.picking.out,stock.model_stock_picking_out,portal.group_portal,1,0,0,0 +access_stock_move,stock.move,stock.model_stock_move,portal.group_portal,1,0,0,0 +access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,portal.group_portal,1,0,0,0 +access_account_invoice,account.invoice,account.model_account_invoice,portal.group_portal,1,0,0,0 +access_account_invoice_tax,account.invoice.tax,account.model_account_invoice_tax,portal.group_portal,1,0,0,0 +access_account_invoice_line,account.invoice.line,account.model_account_invoice_line,portal.group_portal,1,0,0,0 +access_account_journal,account.journal,account.model_account_journal,portal.group_portal,1,0,0,0 +access_account_voucher,account.voucher,account_voucher.model_account_voucher,portal.group_portal,1,0,0,0 +access_account_voucher_line,account.voucher.line,account_voucher.model_account_voucher_line,portal.group_portal,1,0,0,0 +access_account_move,account.move,account.model_account_move,portal.group_portal,1,0,0,0 +access_account_move_line,account.move.line,account.model_account_move_line,portal.group_portal,1,0,0,0 +access_account_move_reconcile,account.move.reconcile,account.model_account_move_reconcile,portal.group_portal,1,0,0,0 +access_account_fiscalyear,account.sequence.fiscalyear,account.model_account_sequence_fiscalyear,portal.group_portal,1,0,0,0 +access_sale_shop,sale.shop,sale.model_sale_shop,portal.group_portal,1,0,0,0 +access_product_list,product.pricelist,product.model_product_pricelist,portal.group_portal,1,0,0,0 +access_product,product.product,product.model_product_product,portal.group_portal,1,0,0,0 +access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0 +access_product_uom,product.uom,product.model_product_uom,portal.group_portal,1,0,0,0 +access_account_tax,account.tax,account.model_account_tax,portal.group_portal,1,0,0,0 +access_mrp_property,mrp.property,procurement.model_mrp_property,portal.group_portal,1,0,0,0 +access_product_template,product.template,product.model_product_template,portal.group_portal,1,0,0,0 +access_stock_warehouse,stock.warehouse,stock.model_stock_warehouse,portal.group_portal,1,0,0,0 +access_stock_location,stock.location,stock.model_stock_location,portal.group_portal,1,0,0,0 +access_account_fiscalyear,account.fiscalyear,account.model_account_fiscalyear,portal.group_portal,1,0,0,0 +access_res_partner_category,res.partner.category,base.model_res_partner_category,portal.group_portal,1,0,0,0 +access_product_supplierinfo,product.supplierinfo,product.model_product_supplierinfo,portal.group_portal,1,0,0,0 +access_product_packaging,product.packaging,product.model_product_packaging,portal.group_portal,1,0,0,0 +access_account_period,account.period,account.model_account_period,portal.group_portal,1,0,0,0 +access_account_account,account.account,account.model_account_account,portal.group_portal,1,0,0,0 diff --git a/addons/portal_sale/security/portal_security.xml b/addons/portal_sale/security/portal_security.xml index f69fd283db6..8028d5360c4 100644 --- a/addons/portal_sale/security/portal_security.xml +++ b/addons/portal_sale/security/portal_security.xml @@ -7,42 +7,42 @@ Portal Personal Quotations/Sales Orders [('partner_id','child_of',user.partner_id.id)] - + Portal Personal Delivery Orders [('partner_id','child_of',[user.partner_id.id])] - + Portal Personal Delivery Orders Out [('partner_id','child_of',[user.partner_id.id])] - + Portal Personal Account Invoices [('partner_id','child_of',user.partner_id.id)] - + Portal Personal Payments [('partner_id','child_of',user.partner_id.id)] - + Portal Personal Contacts [('id','child_of',user.partner_id.id)] - + diff --git a/addons/process/static/src/js/process.js b/addons/process/static/src/js/process.js index bbf9080de95..57c6f196012 100644 --- a/addons/process/static/src/js/process.js +++ b/addons/process/static/src/js/process.js @@ -143,7 +143,7 @@ instance.web.ViewManager.include({ var image_node = nodes.kind == "subflow" ? "node-subflow" : "node"; image_node = nodes.gray ? image_node + "-gray" : image_node; image_node = nodes.active ? 'node-current': image_node; - var img_src = '/web_process/static/src/img/'+ image_node + '.png'; + var img_src = '/process/static/src/img/'+ image_node + '.png'; var image = r['image'](img_src, nodes.x-25, nodes.y,150, 100).attr({"cursor": "default"}) .mousedown(function() { return false; }); //For Node var process_node = r['rect'](nodes.x, nodes.y, 150, 150).attr({stroke: "none"}); diff --git a/addons/procurement/__openerp__.py b/addons/procurement/__openerp__.py index 21f83b8dafc..e797766eb40 100644 --- a/addons/procurement/__openerp__.py +++ b/addons/procurement/__openerp__.py @@ -60,7 +60,7 @@ depending on the product's configuration. 'demo': ['stock_orderpoint.xml'], 'test': ['test/procurement.yml'], 'installable': True, - 'auto_install': False, + 'auto_install': True, 'certificate': '00954248826881074509', 'images': ['images/compute_schedulers.jpeg','images/config_companies_sched.jpeg', 'images/minimum_stock_rules.jpeg'], } diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index ec1dc4b26fb..842f9ec27fa 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -554,7 +554,7 @@ class stock_warehouse_orderpoint(osv.osv): 'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True), 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"), 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"), - 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]), + 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','!=','service')]), 'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True), 'product_min_qty': fields.float('Minimum Quantity', required=True, help="When the virtual stock goes below the Min Quantity specified for this field, OpenERP generates "\ diff --git a/addons/product/product.py b/addons/product/product.py index fc90c72c693..df0ab9122c2 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -511,7 +511,7 @@ class product_product(osv.osv): for obj in self.browse(cr, uid, ids, context=context): result[obj.id] = tools.image_get_resized_images(obj.image, avoid_resize_medium=True) return result - + def _set_image(self, cr, uid, id, name, value, args, context=None): return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) @@ -609,7 +609,7 @@ class product_product(osv.osv): return res - _constraints = [(_check_ean_key, 'You provided an invalid "EAN13 Barcode" reference. You may use the internal reference field instead.', ['ean13'])] + _constraints = [(_check_ean_key, 'You provided an invalid "EAN13 Barcode" reference. You may use the "Internal Reference" field instead.', ['ean13'])] def on_order(self, cr, uid, ids, orderline, quantity): pass @@ -727,7 +727,7 @@ class product_product(osv.osv): context_wo_lang.pop('lang', None) product = self.read(cr, uid, id, ['name'], context=context_wo_lang) default = default.copy() - default['name'] = product['name'] + ' (copy)' + default['name'] = product['name'] + ' (' + _('copy') + ')' if context.get('variant',False): fields = ['product_tmpl_id', 'active', 'variants', 'default_code', @@ -897,4 +897,43 @@ class pricelist_partnerinfo(osv.osv): } _order = 'min_quantity asc' pricelist_partnerinfo() + +class res_currency(osv.osv): + _inherit = 'res.currency' + + def _check_main_currency_rounding(self, cr, uid, ids, context=None): + cr.execute('SELECT digits FROM decimal_precision WHERE name like %s',('Account',)) + digits = cr.fetchone() + if digits and len(digits): + digits = digits[0] + main_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id + for currency_id in ids: + if currency_id == main_currency.id: + if main_currency.rounding < 10 ** -digits: + return False + return True + + _constraints = [ + (_check_main_currency_rounding, 'Error! You cannot define a rounding factor for the company\'s main currency that is smaller than the decimal precision of \'Account\'.', ['rounding']), + ] + +class decimal_precision(osv.osv): + _inherit = 'decimal.precision' + + def _check_main_currency_rounding(self, cr, uid, ids, context=None): + cr.execute('SELECT id, digits FROM decimal_precision WHERE name like %s',('Account',)) + res = cr.fetchone() + if res and len(res): + account_precision_id, digits = res + main_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id + for decimal_precision in ids: + if decimal_precision == account_precision_id: + if main_currency.rounding < 10 ** -digits: + return False + return True + + _constraints = [ + (_check_main_currency_rounding, 'Error! You cannot define the decimal precision of \'Account\' as greater than the rounding factor of the company\'s main currency', ['digits']), + ] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index d04e6f17fe8..c08bbc412e3 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -110,23 +110,25 @@ - +

When you sell this service, nothing special will be trigered - to deliver the customer. + to deliver the customer, as you set the procurement method as + 'Make to Stock'.

- When you sell this product, OpenERP will use the available inventory - for the delivery order. -
+ When you sell this product, OpenERP will use the available + inventory for the delivery order. +

If there are not enough quantities available, the delivery order - will wait for new products. You should create others rules - (orderpoints, manual purchase orders) to fulfill the inventory. + will wait for new products. To fulfill the inventory, you should + create others rules like orderpoints.

When you sell this product, a delivery order will be created. OpenERP will consider that the required quantities are always - available as it's a consumable (the stock on hand may become negative). + available as it's a consumable (as a result of this, the quantity + on hand may become negative).

diff --git a/addons/project/i18n/ar.po b/addons/project/i18n/ar.po index 2daeaaa5198..20df0ff7e60 100644 --- a/addons/project/i18n/ar.po +++ b/addons/project/i18n/ar.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -108,7 +108,7 @@ msgstr "ساعات التحقق من الصلاحية" #. module: project #: view:project.project:0 msgid "Pending Projects" -msgstr "" +msgstr "مشاريع قيد الإنتظار" #. module: project #: help:project.task,remaining_hours:0 @@ -563,7 +563,7 @@ msgstr "فتح المشاريع" #: code:addons/project/project.py:358 #, python-format msgid "You must assign members on the project '%s' !" -msgstr "" +msgstr "يجب تعيين أعضاء في المشروع '%s' !" #. module: project #: view:report.project.task.user:0 @@ -641,7 +641,7 @@ msgstr "وسط" #. module: project #: view:project.task:0 view:project.task.history.cumulative:0 msgid "Pending Tasks" -msgstr "" +msgstr "مهام قيد الإنتظار" #. module: project #: view:project.task:0 field:project.task,remaining_hours:0 @@ -682,7 +682,7 @@ msgstr "معلومات" #. module: project #: view:project.task:0 view:project.task.history.cumulative:0 msgid "Unassigned Tasks" -msgstr "" +msgstr "مهام غير معينة" #. module: project #: view:report.project.task.user:0 @@ -789,6 +789,7 @@ msgid "" "You cannot delete a project containing tasks. I suggest you to desactivate " "it." msgstr "" +"لا يمكنك حذف المهام المحتواة في المشروع. انا اقترح لك جعلها غير نشطة." #. module: project #: view:project.vs.hours:0 @@ -813,7 +814,7 @@ msgstr "ساعات تأخير" #. module: project #: selection:project.task,priority:0 msgid "Very important" -msgstr "" +msgstr "شديد الأهمية" #. module: project #: model:ir.actions.act_window,name:project.action_project_task_user_tree @@ -834,6 +835,8 @@ msgid "" "If you check this field, the project manager will receive an email each time " "a task is completed by his team." msgstr "" +"إذا قمت بتحديد هذا الحقل فإن مدير المشروع سوف يتلقى رسالة بريد إلكتروني في " +"كل مرة يتم الانتهاء من المهمة لفريقه." #. module: project #: model:ir.model,name:project.model_project_project @@ -867,7 +870,7 @@ msgstr "مراحل" #. module: project #: view:project.task:0 msgid "Change to Previous Stage" -msgstr "" +msgstr "التغيير للمرحلة السابقة" #. module: project #: model:ir.actions.todo.category,name:project.category_project_config @@ -910,7 +913,7 @@ msgstr "الرئيسي" #. module: project #: view:project.task:0 msgid "Mark as Blocked" -msgstr "" +msgstr "تحدد كمحظورة" #. module: project #: model:ir.actions.act_window,help:project.action_view_task @@ -999,7 +1002,7 @@ msgstr "الساعات المخططة" #. module: project #: model:ir.actions.act_window,name:project.action_review_task_stage msgid "Review Task Stages" -msgstr "" +msgstr "استعراض مراحل المهمة" #. module: project #: view:project.project:0 @@ -1009,7 +1012,7 @@ msgstr "الحالات: %(الحالة)" #. module: project #: help:project.task,sequence:0 msgid "Gives the sequence order when displaying a list of tasks." -msgstr "" +msgstr "يعطي النظام تسلسل عند عرض قائمة المهام." #. module: project #: view:project.project:0 view:project.task:0 @@ -1021,7 +1024,7 @@ msgstr "تاريخ البدء" #: selection:project.task.history,kanban_state:0 #: selection:project.task.history.cumulative,kanban_state:0 msgid "Ready To Pull" -msgstr "" +msgstr "على استعداد للسحب" #. module: project #: view:project.task:0 field:project.task,parent_ids:0 @@ -1034,7 +1037,7 @@ msgstr "المهام الاساسية" #: view:project.task.history.cumulative:0 #: selection:project.task.history.cumulative,kanban_state:0 msgid "Blocked" -msgstr "" +msgstr "محظورة" #. module: project #: help:project.task,progress:0 @@ -1042,6 +1045,8 @@ msgid "" "If the task has a progress of 99.99% you should close the task if it's " "finished or reevaluate the time" msgstr "" +"إذا كانت المهمة لديها من التقدم 99.99٪ يجب إغلاق المهمة إذا تم الإنتهاء أو " +"إعادة تقييم الوقت" #. module: project #: view:project.project:0 @@ -1070,7 +1075,7 @@ msgstr "عمليات الفواتير" #. module: project #: view:project.task:0 msgid "For changing to delegate state" -msgstr "" +msgstr "لتغيير تفويض حالة" #. module: project #: field:project.task,priority:0 field:report.project.task.user,priority:0 @@ -1097,7 +1102,7 @@ msgstr "اعادة تقييم.المهمة.المشروع" #: code:addons/project/wizard/project_task_delegate.py:81 #, python-format msgid "CHECK: %s" -msgstr "" +msgstr "التحقق: %s" #. module: project #: view:project.project:0 @@ -1152,7 +1157,7 @@ msgstr "" #. module: project #: view:project.task:0 msgid "Change Type" -msgstr "" +msgstr "تغير النوع" #. module: project #: help:project.project,members:0 @@ -1198,7 +1203,7 @@ msgstr "اسم المشروع" #: model:ir.model,name:project.model_project_task_history #: model:ir.model,name:project.model_project_task_history_cumulative msgid "History of Tasks" -msgstr "" +msgstr "تاريخ المهام" #. module: project #: help:project.task.delegate,state:0 @@ -1212,7 +1217,7 @@ msgstr "" #: code:addons/project/wizard/mail_compose_message.py:45 #, python-format msgid "Please specify the Customer or email address of Customer." -msgstr "" +msgstr "يرجى تحديد العميل أو عنوان البريد الإلكتروني للعملاء." #. module: project #: selection:report.project.task.user,month:0 @@ -1265,7 +1270,7 @@ msgstr "نوفمبر" #. module: project #: model:ir.actions.act_window,name:project.action_create_initial_projects_installer msgid "Create your Firsts Projects" -msgstr "" +msgstr "إنشاء أوليات مشاريعك" #. module: project #: code:addons/project/project.py:229 @@ -1276,7 +1281,7 @@ msgstr "تم غلق المشروع ‘%s‘." #. module: project #: view:project.task.history.cumulative:0 msgid "Tasks's Cumulative Flow" -msgstr "" +msgstr "المهام والتدفق التراكمي" #. module: project #: view:project.task:0 @@ -1291,7 +1296,7 @@ msgstr "أكتوبر" #. module: project #: view:project.task:0 msgid "Validate planned time and open task" -msgstr "" +msgstr "التحقق من صحة الوقت المخطط له والمهام المفتوحة" #. module: project #: help:project.task,delay_hours:0 @@ -1299,10 +1304,12 @@ msgid "" "Computed as difference between planned hours by the project manager and the " "total hours of the task." msgstr "" +"تحسب الفرق بين الساعات المخطط لها من قبل مدير المشروع والساعات الإجمالية " +"للمهمة." #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project @@ -1331,7 +1338,7 @@ msgstr "الشركات" #. module: project #: view:project.project:0 msgid "Projects in which I am a member." -msgstr "" +msgstr "المشاريع التي أنا عضو." #. module: project #: view:project.project:0 @@ -1426,7 +1433,7 @@ msgstr "مرشحات مفصلة..." #: code:addons/project/project.py:1148 #, python-format msgid "Please delete the project linked with this account first." -msgstr "" +msgstr "رجاء قم بحذف رابط المشروع مع هذا الحساب أولاً" #. module: project #: field:project.task,total_hours:0 field:project.vs.hours,total_hours:0 @@ -1527,7 +1534,7 @@ msgstr "قيد التقدم" #. module: project #: view:project.task.history.cumulative:0 msgid "Task's Analysis" -msgstr "" +msgstr "تحليل المهمة" #. module: project #: code:addons/project/project.py:789 @@ -1536,11 +1543,13 @@ msgid "" "Child task still open.\n" "Please cancel or complete child task first." msgstr "" +"المهمة الوليدة التي لا تزال مفتوحة .\n" +" يرجى إلغاء أو إكمال المهمة الوليدة أولاص." #. module: project #: view:project.task.type:0 msgid "Stages common to all projects" -msgstr "" +msgstr "مشاريع مشتركة بين جميع المراحل" #. module: project #: constraint:project.task:0 @@ -1561,7 +1570,7 @@ msgstr "" #. module: project #: view:project.project:0 msgid "Projects in which I am a manager" -msgstr "" +msgstr "المشاريع التي أنا مديرها" #. module: project #: code:addons/project/project.py:959 @@ -1660,6 +1669,8 @@ msgid "" "If you check this field, this stage will be proposed by default on each new " "project. It will not assign this stage to existing projects." msgstr "" +"إذا قمت بتحديد هذا الحقل، سيتم اقترح هذه المرحلة بشكل افتراضي على كل مشروع " +"جديد. وسوف يتم تعيين هذه المرحلة للمشاريع القائمة." #. module: project #: view:board.board:0 @@ -1720,7 +1731,7 @@ msgstr "مجموع الساعات الكلية لكل المهام المتعل #. module: project #: field:project.task.type,project_default:0 msgid "Common to All Projects" -msgstr "" +msgstr "مشاريع مشتركة بين الجميع" #. module: project #: model:process.transition,note:project.process_transition_opendonetask0 @@ -1773,7 +1784,7 @@ msgstr "ملخص العمل" #. module: project #: view:project.task.history.cumulative:0 msgid "Month-2" -msgstr "" +msgstr "الشهر-2" #. module: project #: help:report.project.task.user,closing_days:0 @@ -1821,6 +1832,8 @@ msgid "" "The stages can be common to all project or specific to one project. Each " "task will follow the different stages in order to be closed." msgstr "" +"يمكن للمراحل تكون مشتركة بين جميع المشاريع أو محددة لمشروع واحد. كل مهمة سوف " +"تتبع المراحل المختلفة من أجل أن تكون مغلقة." #. module: project #: help:project.project,sequence:0 @@ -1949,7 +1962,7 @@ msgstr "تم الغاء المهمة ‘%s‘." #. module: project #: view:project.task:0 view:res.partner:0 msgid "For changing to open state" -msgstr "" +msgstr "للتغير إلى الحالة المفتوحة" #. module: project #: model:ir.model,name:project.model_res_partner view:project.project:0 @@ -1983,7 +1996,7 @@ msgstr "تذييل البريد" #. module: project #: view:project.task:0 view:project.task.history.cumulative:0 msgid "In Progress Tasks" -msgstr "" +msgstr "مهام في قيد التقدم" #~ msgid "Timesheets" #~ msgstr "الجداول الزمنية" diff --git a/addons/project/i18n/bg.po b/addons/project/i18n/bg.po index a315365a91f..49dcf3643f9 100644 --- a/addons/project/i18n/bg.po +++ b/addons/project/i18n/bg.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/bs.po b/addons/project/i18n/bs.po index 24d31217ffa..5c3eea9984d 100644 --- a/addons/project/i18n/bs.po +++ b/addons/project/i18n/bs.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1275,7 +1275,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/ca.po b/addons/project/i18n/ca.po index 6a40897c8ed..e778a8896b7 100644 --- a/addons/project/i18n/ca.po +++ b/addons/project/i18n/ca.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1322,7 +1322,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/cs.po b/addons/project/i18n/cs.po index a7e4885e245..36e82a8f3b2 100644 --- a/addons/project/i18n/cs.po +++ b/addons/project/i18n/cs.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" "X-Poedit-Language: Czech\n" #. module: project @@ -1298,7 +1298,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/da.po b/addons/project/i18n/da.po index 564c176fed0..98fc1ef4647 100644 --- a/addons/project/i18n/da.po +++ b/addons/project/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/de.po b/addons/project/i18n/de.po index cba84622d8c..c466f2eab86 100644 --- a/addons/project/i18n/de.po +++ b/addons/project/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1336,8 +1336,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Delegationsverlauf" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2573,3 +2573,6 @@ msgstr "Aufgaben in Bearbeitung" #~ msgid "E-mail composition wizard" #~ msgstr "Email-Zusammensetzung Assistent" + +#~ msgid "Delegations History" +#~ msgstr "Delegationsverlauf" diff --git a/addons/project/i18n/el.po b/addons/project/i18n/el.po index 01b1e053d58..816dd09338a 100644 --- a/addons/project/i18n/el.po +++ b/addons/project/i18n/el.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" "X-Poedit-Country: GREECE\n" "X-Poedit-Language: Greek\n" "X-Poedit-SourceCharset: utf-8\n" @@ -1287,7 +1287,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/es.po b/addons/project/i18n/es.po index a66d47e5974..a36f22d27a9 100644 --- a/addons/project/i18n/es.po +++ b/addons/project/i18n/es.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1325,8 +1325,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Histórico de delegaciones" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2568,3 +2568,6 @@ msgstr "" #~ msgid "E-mail composition wizard" #~ msgstr "Asistente de composición de e-mail" + +#~ msgid "Delegations History" +#~ msgstr "Histórico de delegaciones" diff --git a/addons/project/i18n/es_AR.po b/addons/project/i18n/es_AR.po index 3a33ad460f2..7f0221c2cfd 100644 --- a/addons/project/i18n/es_AR.po +++ b/addons/project/i18n/es_AR.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1284,7 +1284,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/es_CR.po b/addons/project/i18n/es_CR.po index 6024d528a28..141882c6f34 100644 --- a/addons/project/i18n/es_CR.po +++ b/addons/project/i18n/es_CR.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" "Language: \n" #. module: project @@ -1333,8 +1333,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Histórico de delegaciones" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2582,3 +2582,6 @@ msgstr "Tarea en progreso" #~ msgid "E-mail composition wizard" #~ msgstr "Asistente de composición de e-mail" + +#~ msgid "Delegations History" +#~ msgstr "Histórico de delegaciones" diff --git a/addons/project/i18n/es_EC.po b/addons/project/i18n/es_EC.po index 89168f88a42..fded4d36c68 100644 --- a/addons/project/i18n/es_EC.po +++ b/addons/project/i18n/es_EC.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:56+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1330,8 +1330,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Histórico de delegaciones" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2568,3 +2568,6 @@ msgstr "Tareas en progreso" #~ msgid "E-mail composition wizard" #~ msgstr "Asistente de composición de e-mail" + +#~ msgid "Delegations History" +#~ msgstr "Histórico de delegaciones" diff --git a/addons/project/i18n/es_PY.po b/addons/project/i18n/es_PY.po index aff45cd4e54..3c62d81eb51 100644 --- a/addons/project/i18n/es_PY.po +++ b/addons/project/i18n/es_PY.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:56+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/et.po b/addons/project/i18n/et.po index 664b39d8b90..7e86ce9ef99 100644 --- a/addons/project/i18n/et.po +++ b/addons/project/i18n/et.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1282,7 +1282,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/eu.po b/addons/project/i18n/eu.po index 3ead5319319..110df09b142 100644 --- a/addons/project/i18n/eu.po +++ b/addons/project/i18n/eu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1280,7 +1280,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/fi.po b/addons/project/i18n/fi.po index fde023a2443..7f9e5bb70e5 100644 --- a/addons/project/i18n/fi.po +++ b/addons/project/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1299,8 +1299,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Delegointien historia" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2338,3 +2338,6 @@ msgstr "Meneilläänolevat tehtävät" #~ msgid "E-mail composition wizard" #~ msgstr "Sähköpostin luonti velho" + +#~ msgid "Delegations History" +#~ msgstr "Delegointien historia" diff --git a/addons/project/i18n/fr.po b/addons/project/i18n/fr.po index 4c0e87af64b..8d1bd208da9 100644 --- a/addons/project/i18n/fr.po +++ b/addons/project/i18n/fr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1338,8 +1338,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Historique des délégations" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2587,5 +2587,8 @@ msgstr "Tâches en cours" #~ msgid "Manager Email" #~ msgstr "Courriel du responsable" +#~ msgid "Delegations History" +#~ msgstr "Historique des délégations" + #~ msgid "E-mail composition wizard" #~ msgstr "Assistant de composition de courriels" diff --git a/addons/project/i18n/gl.po b/addons/project/i18n/gl.po index 2b83f0924db..ad9e073ff1a 100644 --- a/addons/project/i18n/gl.po +++ b/addons/project/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/gu.po b/addons/project/i18n/gu.po index 325d77c09ec..e7d8eb536a7 100644 --- a/addons/project/i18n/gu.po +++ b/addons/project/i18n/gu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/hr.po b/addons/project/i18n/hr.po index 9309d95cd1b..7603340fbfa 100644 --- a/addons/project/i18n/hr.po +++ b/addons/project/i18n/hr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" "Language: hr\n" #. module: project @@ -1283,7 +1283,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/hu.po b/addons/project/i18n/hu.po index ca553216211..4f293a3b302 100644 --- a/addons/project/i18n/hu.po +++ b/addons/project/i18n/hu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -79,7 +79,7 @@ msgstr "Nem engedélyezett művelet!" #: code:addons/project/wizard/project_task_delegate.py:78 #, python-format msgid "CHECK: " -msgstr "" +msgstr "ELLENŐRIZNI: " #. module: project #: field:project.task,user_email:0 @@ -263,7 +263,7 @@ msgstr "Nap" #. module: project #: model:ir.ui.menu,name:project.menu_project_config_project msgid "Projects and Stages" -msgstr "" +msgstr "Projektek és Szakaszok" #. module: project #: view:project.project:0 @@ -485,7 +485,7 @@ msgstr "" #. module: project #: view:project.task:0 msgid "Change Color" -msgstr "" +msgstr "Szín megváltoztatása" #. module: project #: constraint:account.analytic.account:0 @@ -920,7 +920,7 @@ msgstr "" #. module: project #: view:project.task:0 msgid "Mark as Blocked" -msgstr "" +msgstr "Blokkoltnak jelölés" #. module: project #: model:ir.actions.act_window,help:project.action_view_task @@ -1047,7 +1047,7 @@ msgstr "Forrás feladatok" #: view:project.task.history.cumulative:0 #: selection:project.task.history.cumulative,kanban_state:0 msgid "Blocked" -msgstr "" +msgstr "Blokkolva" #. module: project #: help:project.task,progress:0 @@ -1110,7 +1110,7 @@ msgstr "project.task.reevaluate" #: code:addons/project/wizard/project_task_delegate.py:81 #, python-format msgid "CHECK: %s" -msgstr "" +msgstr "ELLENŐRIZNI: %s" #. module: project #: view:project.project:0 @@ -1320,7 +1320,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project @@ -1558,7 +1558,7 @@ msgstr "" #. module: project #: view:project.task.type:0 msgid "Stages common to all projects" -msgstr "" +msgstr "Közös használatú szakaszok" #. module: project #: constraint:project.task:0 @@ -2222,3 +2222,6 @@ msgstr "" #~ msgid "Automatically synchronizes project tasks and crm cases." #~ msgstr "Automatikusan összehangolja a projektfeladatokat és a crm eseteket." + +#~ msgid "Delegations History" +#~ msgstr "Átruházás történet" diff --git a/addons/project/i18n/id.po b/addons/project/i18n/id.po index 22892b050d1..b20dd07eaf3 100644 --- a/addons/project/i18n/id.po +++ b/addons/project/i18n/id.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1275,7 +1275,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/it.po b/addons/project/i18n/it.po index 662ea2bd962..f3e20f78c7e 100644 --- a/addons/project/i18n/it.po +++ b/addons/project/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1320,7 +1320,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/ja.po b/addons/project/i18n/ja.po index fa91a44a984..24a8e1916cb 100644 --- a/addons/project/i18n/ja.po +++ b/addons/project/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1294,8 +1294,8 @@ msgstr "プロジェクトマネジャによる計画時間数とタスクの合 #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "委任の履歴" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -1969,3 +1969,6 @@ msgstr "進行中タスク" #~ msgid "E-mail composition wizard" #~ msgstr "Eメール作成ウィザード" + +#~ msgid "Delegations History" +#~ msgstr "委任の履歴" diff --git a/addons/project/i18n/ko.po b/addons/project/i18n/ko.po index fe17fa20853..db3c7ea98d1 100644 --- a/addons/project/i18n/ko.po +++ b/addons/project/i18n/ko.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/lt.po b/addons/project/i18n/lt.po index 50bca2bd371..6710b832550 100644 --- a/addons/project/i18n/lt.po +++ b/addons/project/i18n/lt.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1285,7 +1285,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/lv.po b/addons/project/i18n/lv.po index 4ef32f1bc1e..0e9fdaa04f6 100644 --- a/addons/project/i18n/lv.po +++ b/addons/project/i18n/lv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1314,7 +1314,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/mn.po b/addons/project/i18n/mn.po index 21fea817261..6feb0623f9e 100644 --- a/addons/project/i18n/mn.po +++ b/addons/project/i18n/mn.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1323,8 +1323,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Ацагласан Түүх" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2335,3 +2335,6 @@ msgstr "Боловсруулагдаж байгаа даалгаврууд" #~ msgid "E-mail composition wizard" #~ msgstr "И-мэйл үүсгэх харилцах цонх" + +#~ msgid "Delegations History" +#~ msgstr "Ацагласан Түүх" diff --git a/addons/project/i18n/nb.po b/addons/project/i18n/nb.po index 59c7111be4f..fed27a5f44c 100644 --- a/addons/project/i18n/nb.po +++ b/addons/project/i18n/nb.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -37,6 +37,7 @@ msgstr "Oppgaven '%s' er tildelt til %s." #: 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: project #: view:report.project.task.user:0 @@ -81,7 +82,7 @@ msgstr "SJEKK: " #. module: project #: field:project.task,user_email:0 msgid "User Email" -msgstr "" +msgstr "E-post for bruker" #. module: project #: field:project.task,work_ids:0 @@ -93,7 +94,7 @@ msgstr "Arbeid utført" #: code:addons/project/project.py:1148 #, python-format msgid "Warning !" -msgstr "" +msgstr "Advarsel !" #. module: project #: model:ir.model,name:project.model_project_task_delegate @@ -121,7 +122,7 @@ msgstr "" #. module: project #: view:project.project:0 msgid "Re-open project" -msgstr "" +msgstr "Gjenåpne prosjekt" #. module: project #: help:project.project,priority:0 @@ -131,7 +132,7 @@ msgstr "" #. module: project #: constraint:project.project:0 msgid "Error! project start-date must be lower then project end-date." -msgstr "" +msgstr "Feil! Startdato for prosjekt må være tidligere enn sluttdato." #. module: project #: view:project.task.reevaluate:0 @@ -180,7 +181,7 @@ msgstr "Mine oppgaver" #. module: project #: constraint:project.task:0 msgid "Error ! You cannot create recursive tasks." -msgstr "" +msgstr "Feil! Du kan ikke lage en uendelig struktur av oppgaver." #. module: project #: field:project.task,company_id:0 field:project.task.work,company_id:0 @@ -201,7 +202,7 @@ msgstr "Din oppgavetittel" #. module: project #: field:project.task.type,name:0 msgid "Stage Name" -msgstr "" +msgstr "Fasenavn" #. module: project #: model:process.transition.action,name:project.process_transition_action_openpendingtask0 @@ -211,7 +212,7 @@ msgstr "" #. module: project #: selection:project.task,priority:0 msgid "Important" -msgstr "" +msgstr "Viktig" #. module: project #: model:process.node,note:project.process_node_drafttask0 @@ -221,7 +222,7 @@ msgstr "Definer krav og oppgi planlagte timer" #. module: project #: view:project.task:0 msgid "Change Stage" -msgstr "" +msgstr "Endre fase" #. module: project #: view:project.project:0 @@ -258,7 +259,7 @@ msgstr "Dag" #. module: project #: model:ir.ui.menu,name:project.menu_project_config_project msgid "Projects and Stages" -msgstr "" +msgstr "Prosjekter og faser" #. module: project #: view:project.project:0 @@ -294,12 +295,12 @@ msgstr "Mine åpne oppgaver" #, python-format msgid "" "Please specify the Project Manager or email address of Project Manager." -msgstr "" +msgstr "Vennligst angi prosjektleder eller e-post-adresse for prosjektleder." #. module: project #: view:project.task:0 msgid "For cancelling the task" -msgstr "" +msgstr "For å avbryte oppgaven" #. module: project #: model:ir.model,name:project.model_project_task_work @@ -361,7 +362,7 @@ msgstr "" #. module: project #: view:project.task:0 msgid "Show only tasks having a deadline" -msgstr "" +msgstr "Vis kun oppgaver med deadline" #. module: project #: selection:project.task,state:0 selection:project.task.history,state:0 @@ -374,7 +375,7 @@ msgstr "Kansellert" #. module: project #: field:project.task,date_end:0 field:report.project.task.user,date_end:0 msgid "Ending Date" -msgstr "" +msgstr "Sluttdato" #. module: project #: view:project.project:0 field:project.project,warn_header:0 @@ -384,7 +385,7 @@ msgstr "E-post topptekst" #. module: project #: view:project.task:0 msgid "Change to Next Stage" -msgstr "" +msgstr "Endre til neste fase" #. module: project #: model:process.node,name:project.process_node_donetask0 @@ -394,7 +395,7 @@ msgstr "Fullførte oppgaver" #. module: project #: field:project.task,color:0 msgid "Color Index" -msgstr "" +msgstr "Fargeindeks" #. module: project #: model:ir.ui.menu,name:project.menu_definitions view:res.company:0 @@ -404,7 +405,7 @@ msgstr "Konfigurasjon" #. module: project #: view:report.project.task.user:0 msgid "Current Month" -msgstr "" +msgstr "Inneværende måned" #. module: project #: model:process.transition,note:project.process_transition_delegate0 @@ -414,7 +415,7 @@ msgstr "Delegerer oppgaver til den andre brukeren" #. module: project #: view:project.project:0 view:project.task:0 view:report.project.task.user:0 msgid "Group By..." -msgstr "" +msgstr "Grupper etter ..." #. module: project #: field:project.task.work,user_id:0 @@ -433,7 +434,7 @@ msgstr "" #. module: project #: model:project.task.type,name:project.project_tt_testing msgid "Testing" -msgstr "" +msgstr "Tester" #. module: project #: code:addons/project/project.py:829 @@ -471,17 +472,17 @@ msgstr "_Avbryt" #. module: project #: view:project.task.history.cumulative:0 msgid "Ready" -msgstr "" +msgstr "Klar" #. module: project #: view:project.task:0 msgid "Change Color" -msgstr "" +msgstr "Bytt farge" #. module: project #: constraint:account.analytic.account:0 msgid "Error! You can not create recursive analytic accounts." -msgstr "" +msgstr "Feil! Du kan ikke opprette uendelig struktur med analytiske kontoer." #. module: project #: code:addons/project/project.py:264 code:addons/project/project.py:303 @@ -492,12 +493,12 @@ msgstr " (kopi)" #. module: project #: view:project.task:0 msgid "New Tasks" -msgstr "" +msgstr "Ny oppgave" #. module: project #: view:report.project.task.user:0 field:report.project.task.user,nbr:0 msgid "# of tasks" -msgstr "" +msgstr "Antall oppgaver" #. module: project #: view:project.task:0 @@ -517,7 +518,7 @@ msgstr "" #. module: project #: sql_constraint:res.users:0 msgid "You can not have two users with the same login !" -msgstr "" +msgstr "Du kan ikke ha to brukere med samme login!" #. module: project #: view:project.project:0 @@ -537,7 +538,7 @@ msgstr "Mine prosjekter" #. module: project #: constraint:res.company:0 msgid "Error! You can not create recursive companies." -msgstr "" +msgstr "Feil! Dukan ikke opprette uendelig struktur av firmaer." #. module: project #: view:project.task:0 @@ -552,23 +553,23 @@ msgstr "From draft state, it will come into the open state." #. module: project #: view:report.project.task.user:0 field:report.project.task.user,no_of_days:0 msgid "# of Days" -msgstr "" +msgstr "Antall dager" #. module: project #: view:project.project:0 msgid "Open Projects" -msgstr "" +msgstr "Åpne prosjekter" #. module: project #: code:addons/project/project.py:358 #, python-format msgid "You must assign members on the project '%s' !" -msgstr "" +msgstr "Du må tilordne deltakere til prosjekt '%s'!" #. module: project #: view:report.project.task.user:0 msgid "In progress tasks" -msgstr "" +msgstr "Oppgaver i arbeid" #. module: project #: help:project.project,progress_rate:0 @@ -592,7 +593,7 @@ msgstr "Prosjektoppgave" #: selection:project.task.history.cumulative,state:0 #: view:report.project.task.user:0 msgid "New" -msgstr "" +msgstr "Ny" #. module: project #: help:project.task,total_hours:0 @@ -625,7 +626,7 @@ msgstr "" #: code:addons/project/project.py:597 #, python-format msgid "%s (copy)" -msgstr "" +msgstr "%s (kopi)" #. module: project #: view:report.project.task.user:0 @@ -641,7 +642,7 @@ msgstr "Medium" #. module: project #: view:project.task:0 view:project.task.history.cumulative:0 msgid "Pending Tasks" -msgstr "" +msgstr "Ventende oppgaver" #. module: project #: view:project.task:0 field:project.task,remaining_hours:0 @@ -659,13 +660,13 @@ msgstr "" #. module: project #: view:report.project.task.user:0 msgid "Creation Date" -msgstr "" +msgstr "Opprettelsesdato" #. module: project #: view:project.task:0 field:project.task.history,remaining_hours:0 #: field:project.task.history.cumulative,remaining_hours:0 msgid "Remaining Time" -msgstr "" +msgstr "Gjenstående tid" #. module: project #: field:project.project,planned_hours:0 @@ -755,7 +756,7 @@ msgstr "Prosjekter" #: field:project.task.history.cumulative,type_id:0 #: view:report.project.task.user:0 field:report.project.task.user,type_id:0 msgid "Stage" -msgstr "" +msgstr "Fase" #. module: project #: model:ir.actions.act_window,help:project.open_task_type_form @@ -769,7 +770,7 @@ msgstr "" #: code:addons/project/project.py:903 #, python-format msgid "The task '%s' is opened." -msgstr "" +msgstr "Oppgaven '%s' er åpnet." #. module: project #: view:project.task:0 @@ -788,6 +789,8 @@ msgid "" "You cannot delete a project containing tasks. I suggest you to desactivate " "it." msgstr "" +"Du kan ikke slette et prosjekt som har oppgaver. Prosjektet kan evt. " +"deaktiveres." #. module: project #: view:project.vs.hours:0 @@ -812,7 +815,7 @@ msgstr "Timer forsinket" #. module: project #: selection:project.task,priority:0 msgid "Very important" -msgstr "" +msgstr "Veldig viktig" #. module: project #: model:ir.actions.act_window,name:project.action_project_task_user_tree @@ -833,6 +836,8 @@ msgid "" "If you check this field, the project manager will receive an email each time " "a task is completed by his team." msgstr "" +"Ved avkryssing vil prosjektleder motta en e-post hver gang en oppgave blir " +"fullført av hans team." #. module: project #: model:ir.model,name:project.model_project_project @@ -861,12 +866,12 @@ msgstr "" #: model:ir.actions.act_window,name:project.open_task_type_form #: model:ir.ui.menu,name:project.menu_task_types_view msgid "Stages" -msgstr "" +msgstr "Faser" #. module: project #: view:project.task:0 msgid "Change to Previous Stage" -msgstr "" +msgstr "Endre til foregående fase" #. module: project #: model:ir.actions.todo.category,name:project.category_project_config @@ -882,7 +887,7 @@ msgstr "Prosjekt time enhet" #. module: project #: view:report.project.task.user:0 msgid "In progress" -msgstr "" +msgstr "I arbeid" #. module: project #: model:ir.actions.act_window,name:project.action_project_task_delegate @@ -909,7 +914,7 @@ msgstr "Overordnet" #. module: project #: view:project.task:0 msgid "Mark as Blocked" -msgstr "" +msgstr "Marker som blokkert" #. module: project #: model:ir.actions.act_window,help:project.action_view_task @@ -952,7 +957,7 @@ msgstr "" #. module: project #: view:project.task.reevaluate:0 msgid "Reevaluate Task" -msgstr "" +msgstr "Evaluer oppgave på nytt" #. module: project #: view:project.task.history.cumulative:0 view:report.project.task.user:0 @@ -969,12 +974,12 @@ msgstr "Prosjektoppgaver" #: model:ir.model,name:project.model_project_task_type #: view:project.task.type:0 msgid "Task Stage" -msgstr "" +msgstr "Oppgavefase" #. module: project #: model:project.task.type,name:project.project_tt_specification msgid "Design" -msgstr "" +msgstr "Utforming" #. module: project #: field:project.task,planned_hours:0 @@ -987,7 +992,7 @@ msgstr "Planlagte timer" #. module: project #: model:ir.actions.act_window,name:project.action_review_task_stage msgid "Review Task Stages" -msgstr "" +msgstr "Gjennomgå oppgavefaser" #. module: project #: view:project.project:0 @@ -997,7 +1002,7 @@ msgstr "" #. module: project #: help:project.task,sequence:0 msgid "Gives the sequence order when displaying a list of tasks." -msgstr "" +msgstr "Gir sorteringsrekkefølge ved listing av oppgaver" #. module: project #: view:project.project:0 view:project.task:0 @@ -1022,7 +1027,7 @@ msgstr "Overordnede oppgaver" #: view:project.task.history.cumulative:0 #: selection:project.task.history.cumulative,kanban_state:0 msgid "Blocked" -msgstr "" +msgstr "Blokkert" #. module: project #: help:project.task,progress:0 @@ -1034,7 +1039,7 @@ msgstr "" #. module: project #: view:project.project:0 msgid "Contact Address" -msgstr "" +msgstr "Kontaktadresse" #. module: project #: help:project.task,kanban_state:0 @@ -1137,7 +1142,7 @@ msgstr "" #. module: project #: view:project.task:0 msgid "Change Type" -msgstr "" +msgstr "Endre type" #. module: project #: help:project.project,members:0 @@ -1145,6 +1150,8 @@ msgid "" "Project's members are users who can have an access to the tasks related to " "this project." msgstr "" +"Prosjektdeltakere er brukere som har tilgang til oppgavene som hører til " +"prosjektet." #. module: project #: view:project.project:0 field:project.task,manager_id:0 @@ -1154,12 +1161,12 @@ msgstr "Prosjektleder" #. module: project #: view:project.task:0 view:res.partner:0 msgid "For changing to done state" -msgstr "" +msgstr "For å bytte til ferdig tilstand" #. module: project #: model:ir.model,name:project.model_report_project_task_user msgid "Tasks by user and project" -msgstr "" +msgstr "Oppgaver pr. bruker og prosjekt" #. module: project #: selection:report.project.task.user,month:0 @@ -1171,7 +1178,7 @@ msgstr "August" #: selection:project.task.history,kanban_state:0 #: selection:project.task.history.cumulative,kanban_state:0 msgid "Normal" -msgstr "" +msgstr "Normal" #. module: project #: view:project.project:0 field:project.project,complete_name:0 @@ -1182,7 +1189,7 @@ msgstr "Prosjektnavn" #: model:ir.model,name:project.model_project_task_history #: model:ir.model,name:project.model_project_task_history_cumulative msgid "History of Tasks" -msgstr "" +msgstr "Oppgavehistorikk" #. module: project #: help:project.task.delegate,state:0 @@ -1211,7 +1218,7 @@ msgstr "Totaltid" #: view:report.project.task.user:0 #: field:report.project.task.user,closing_days:0 msgid "Days to Close" -msgstr "" +msgstr "Dager til lukking" #. module: project #: model:ir.actions.act_window,name:project.open_board_project @@ -1227,7 +1234,7 @@ msgstr "" #. module: project #: model:res.groups,name:project.group_project_user msgid "User" -msgstr "" +msgstr "Bruker" #. module: project #: field:project.project,active:0 @@ -1238,7 +1245,7 @@ msgstr "Aktiv" #: view:report.project.task.user:0 #: field:report.project.task.user,opening_days:0 msgid "Days to Open" -msgstr "" +msgstr "Dager til åpning" #. module: project #: selection:report.project.task.user,month:0 @@ -1254,7 +1261,7 @@ msgstr "" #: code:addons/project/project.py:229 #, python-format msgid "The project '%s' has been closed." -msgstr "" +msgstr "Prosjektet '%s' er lukket." #. module: project #: view:project.task.history.cumulative:0 @@ -1287,7 +1294,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project @@ -1301,6 +1308,8 @@ msgid "" "If the active field is set to False, it will allow you to hide the project " "without removing it." msgstr "" +"Ved å fjerne avkryssing for Aktiv vil prosjektet skjules uten å måtte " +"slettes." #. module: project #: view:project.task:0 @@ -1326,7 +1335,7 @@ msgstr "Søk i prosjekt" #: code:addons/project/project.py:251 #, python-format msgid "The project '%s' has been opened." -msgstr "" +msgstr "Prosjektet '%s' er åpnet." #. module: project #: field:project.task.history,date:0 @@ -1401,7 +1410,7 @@ msgstr "" #. module: project #: view:report.project.task.user:0 msgid "Extended Filters..." -msgstr "" +msgstr "Utvidede filtre ..." #. module: project #: code:addons/project/project.py:1148 @@ -2191,3 +2200,9 @@ msgstr "" #~ msgid "Running projects" #~ msgstr "Løpende prosjekter" + +#~ msgid "Delegations History" +#~ msgstr "Delegeringshistorikk" + +#~ msgid "E-mail composition wizard" +#~ msgstr "Veiviser for opprettelse av e-post" diff --git a/addons/project/i18n/nl.po b/addons/project/i18n/nl.po index f84c1286285..f543f48834e 100644 --- a/addons/project/i18n/nl.po +++ b/addons/project/i18n/nl.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -920,7 +920,7 @@ msgstr "Bovenliggend" #. module: project #: view:project.task:0 msgid "Mark as Blocked" -msgstr "Maarkeer als geblokkeerd" +msgstr "Markeer als geblokkeerd" #. module: project #: model:ir.actions.act_window,help:project.action_view_task @@ -1325,8 +1325,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Deligatiehistorie" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2566,3 +2566,6 @@ msgstr "Lopende taken" #~ msgid "E-mail composition wizard" #~ msgstr "E-mail opmaak wizard" + +#~ msgid "Delegations History" +#~ msgstr "Deligatiehistorie" diff --git a/addons/project/i18n/nl_BE.po b/addons/project/i18n/nl_BE.po index 4593e3cb2be..ffa8dee4875 100644 --- a/addons/project/i18n/nl_BE.po +++ b/addons/project/i18n/nl_BE.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1317,7 +1317,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/pl.po b/addons/project/i18n/pl.po index cb00edd6111..9ed951bf799 100644 --- a/addons/project/i18n/pl.po +++ b/addons/project/i18n/pl.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1322,8 +1322,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Historia przydziałów" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2529,3 +2529,6 @@ msgstr "Zadania w toku" #~ msgid "E-mail composition wizard" #~ msgstr "Kreator tworzenia wiadomości" + +#~ msgid "Delegations History" +#~ msgstr "Historia przydziałów" diff --git a/addons/project/i18n/project.pot b/addons/project/i18n/project.pot index 46cf1a9279a..4f364cc1e66 100644 --- a/addons/project/i18n/project.pot +++ b/addons/project/i18n/project.pot @@ -1293,7 +1293,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/pt.po b/addons/project/i18n/pt.po index 74d51f30434..3abfd72a81b 100644 --- a/addons/project/i18n/pt.po +++ b/addons/project/i18n/pt.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1328,8 +1328,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Histórico das delegações" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2561,5 +2561,8 @@ msgstr "Tarefas em progresso" #~ msgid "Automatically synchronizes project tasks and crm cases." #~ msgstr "Sincroniza automaticamente as tarefas do projecto e os casos de crm." +#~ msgid "Delegations History" +#~ msgstr "Histórico das delegações" + #~ msgid "E-mail composition wizard" #~ msgstr "Assistente de composição de email" diff --git a/addons/project/i18n/pt_BR.po b/addons/project/i18n/pt_BR.po index caf11f137ba..98cd475cc92 100644 --- a/addons/project/i18n/pt_BR.po +++ b/addons/project/i18n/pt_BR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1331,8 +1331,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Histórico de Delegações" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2559,3 +2559,6 @@ msgstr "Tarefas em Progresso" #~ msgid "E-mail composition wizard" #~ msgstr "Assistente de composição de E-mail." + +#~ msgid "Delegations History" +#~ msgstr "Histórico de Delegações" diff --git a/addons/project/i18n/ro.po b/addons/project/i18n/ro.po index 2fafcf110c8..f3eb73dd786 100644 --- a/addons/project/i18n/ro.po +++ b/addons/project/i18n/ro.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1338,8 +1338,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Istoric Delegatii" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2286,3 +2286,6 @@ msgstr "Sarcini in desfasurare" #~ msgid "E-mail composition wizard" #~ msgstr "Asistent compunere e-mail" + +#~ msgid "Delegations History" +#~ msgstr "Istoric Delegatii" diff --git a/addons/project/i18n/ru.po b/addons/project/i18n/ru.po index ff924e375e1..42a882feb17 100644 --- a/addons/project/i18n/ru.po +++ b/addons/project/i18n/ru.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-09-15 04:55+0000\n" -"X-Generator: Launchpad (build 15944)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1330,8 +1330,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "История Делегирования" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2387,5 +2387,8 @@ msgstr "Задания в работе" #~ msgid "project.installer" #~ msgstr "project.installer" +#~ msgid "Delegations History" +#~ msgstr "История Делегирования" + #~ msgid "E-mail composition wizard" #~ msgstr "Мастер создания электронной почты" diff --git a/addons/project/i18n/sk.po b/addons/project/i18n/sk.po index 8fff648e513..e73a5b7e0bb 100644 --- a/addons/project/i18n/sk.po +++ b/addons/project/i18n/sk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/sl.po b/addons/project/i18n/sl.po index a1fbb859a5b..e14fb9acb57 100644 --- a/addons/project/i18n/sl.po +++ b/addons/project/i18n/sl.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1275,7 +1275,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/sq.po b/addons/project/i18n/sq.po index 56deafc1420..75cf3348b8b 100644 --- a/addons/project/i18n/sq.po +++ b/addons/project/i18n/sq.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:41+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/sv.po b/addons/project/i18n/sv.po index 0ddcb5ba646..e48077a544b 100644 --- a/addons/project/i18n/sv.po +++ b/addons/project/i18n/sv.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1326,8 +1326,8 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "Delegeringshistorik" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2349,6 +2349,9 @@ msgstr "Pågående aktiviteter" #~ msgid "Planned" #~ msgstr "Planned" +#~ msgid "Delegations History" +#~ msgstr "Delegeringshistorik" + #~ msgid "E-mail composition wizard" #~ msgstr "E-post editor" diff --git a/addons/project/i18n/tlh.po b/addons/project/i18n/tlh.po index cf9fc993586..b0a60c6fa8e 100644 --- a/addons/project/i18n/tlh.po +++ b/addons/project/i18n/tlh.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1275,7 +1275,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/tr.po b/addons/project/i18n/tr.po index ff2ed9a3b4d..1cb7bd887b2 100644 --- a/addons/project/i18n/tr.po +++ b/addons/project/i18n/tr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1283,7 +1283,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/uk.po b/addons/project/i18n/uk.po index 9aa0fcefa8f..31d082bb410 100644 --- a/addons/project/i18n/uk.po +++ b/addons/project/i18n/uk.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1275,7 +1275,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/vi.po b/addons/project/i18n/vi.po index 5fa2656c267..c60e76d0290 100644 --- a/addons/project/i18n/vi.po +++ b/addons/project/i18n/vi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:42+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1276,7 +1276,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/i18n/zh_CN.po b/addons/project/i18n/zh_CN.po index 85bc1101182..89c2b76e4c7 100644 --- a/addons/project/i18n/zh_CN.po +++ b/addons/project/i18n/zh_CN.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1286,8 +1286,8 @@ msgstr "计算公式为:项目经理估算的时间和实际花费的时间的 #. module: project #: view:project.task:0 -msgid "Delegations History" -msgstr "委派历史" +msgid "Delegation" +msgstr "" #. module: project #: model:ir.model,name:project.model_res_users @@ -2444,3 +2444,6 @@ msgstr "进行中的任务" #~ msgid "E-mail composition wizard" #~ msgstr "邮件合并向导" + +#~ msgid "Delegations History" +#~ msgstr "委派历史" diff --git a/addons/project/i18n/zh_TW.po b/addons/project/i18n/zh_TW.po index 248cb18f42c..3d27b0070cd 100644 --- a/addons/project/i18n/zh_TW.po +++ b/addons/project/i18n/zh_TW.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-08-28 05:55+0000\n" -"X-Generator: Launchpad (build 15864)\n" +"X-Launchpad-Export-Date: 2012-09-21 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" #. module: project #: view:report.project.task.user:0 @@ -1279,7 +1279,7 @@ msgstr "" #. module: project #: view:project.task:0 -msgid "Delegations History" +msgid "Delegation" msgstr "" #. module: project diff --git a/addons/project/project.py b/addons/project/project.py index 35be1d82c6e..f15656905ca 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -49,8 +49,9 @@ class project_task_type(osv.osv): } _defaults = { 'sequence': 1, - 'state': 'draft', + 'state': 'open', 'fold': False, + 'case_default': True, } _order = 'sequence' diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index ff8ac943a67..93d01a5619b 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -130,7 +130,7 @@
- + @@ -143,7 +143,6 @@ - @@ -294,16 +293,14 @@

Click to start a new project. -

-

+

Projects are used to organize your activities; plan tasks, track issues, invoice timesheets. You can define internal projects (R&D, Improve Sales Process), private projects (My Todos) or customer ones. -

-

- You will be able collaborate with internal users on - projects or invite customers to share your activities. +

+ You will be able collaborate with internal users on + projects or invite customers to share your activities.

@@ -402,8 +399,6 @@ states="cancelled,done" context="{'button_reactivate':True}"/>