diff --git a/addons/account/account.py b/addons/account/account.py
index e92bd3a7879..a68c1de0939 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -648,10 +648,10 @@ class account_account(osv.osv):
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
#Check for 'Closed' type
if old_type == 'closed' and new_type !='closed':
- raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type as it contains journal items!"))
+ raise osv.except_osv(_('Warning!'), _("You cannot change the type of account from 'Closed' to any other type as it contains journal items!"))
# Forbid to change an account type for restricted_groups as it contains journal items (or if one of its children does)
if (new_type in restricted_groups):
- raise osv.except_osv(_('Warning !'), _("You cannot change the type of account to '%s' type as it contains journal items!") % (new_type,))
+ raise osv.except_osv(_('Warning!'), _("You cannot change the type of account to '%s' type as it contains journal items!") % (new_type,))
return True
@@ -1015,14 +1015,14 @@ class account_period(osv.osv):
if not result:
result = self.search(cr, uid, args, context=context)
if not result:
- raise osv.except_osv(_('Error !'), _('There is no period defined for this date: %s.\nPlease create one.')%dt)
+ raise osv.except_osv(_('Error!'), _('There is no period defined for this date: %s.\nPlease create one.')%dt)
return result
def action_draft(self, cr, uid, ids, *args):
mode = 'draft'
for period in self.browse(cr, uid, ids):
if period.fiscalyear_id.state == 'done':
- raise osv.except_osv(_('Warning !'), _('You can not re-open a period which belongs to closed fiscal year'))
+ raise osv.except_osv(_('Warning!'), _('You can not re-open a period which belongs to closed fiscal year'))
cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),))
cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),))
return True
@@ -1034,9 +1034,15 @@ class account_period(osv.osv):
context = {}
ids = []
if name:
- ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit)
+ ids = self.search(cr, user,
+ [('code', 'ilike', name)] + args,
+ limit=limit,
+ context=context)
if not ids:
- ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
+ ids = self.search(cr, user,
+ [('name', operator, name)] + args,
+ limit=limit,
+ context=context)
return self.name_get(cr, user, ids, context=context)
def write(self, cr, uid, ids, vals, context=None):
@@ -1059,10 +1065,14 @@ class account_period(osv.osv):
raise osv.except_osv(_('Error!'), _('You should choose the periods that belong to the same company.'))
if period_date_start > period_date_stop:
raise osv.except_osv(_('Error!'), _('Start period should precede then end period.'))
+
+ # /!\ We do not include a criterion on the company_id field below, to allow producing consolidated reports
+ # on multiple companies. It will only work when start/end periods are selected and no fiscal year is chosen.
+
#for period from = january, we want to exclude the opening period (but it has same date_from, so we have to check if period_from is special or not to include that clause or not in the search).
if period_from.special:
- return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id)])
- return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id), ('special', '=', False)])
+ return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop)])
+ return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('special', '=', False)])
class account_journal_period(osv.osv):
@@ -1854,6 +1864,12 @@ class account_tax_code(osv.osv):
_order = 'code'
+def get_precision_tax():
+ def change_digit_tax(cr):
+ res = openerp.registry(cr.dbname)['decimal.precision'].precision_get(cr, SUPERUSER_ID, 'Account')
+ return (16, res+3)
+ return change_digit_tax
+
class account_tax(osv.osv):
"""
A tax object.
@@ -1874,12 +1890,6 @@ class account_tax(osv.osv):
default.update({'name': name + _(' (Copy)')})
return super(account_tax, self).copy_data(cr, uid, id, default=default, context=context)
- def get_precision_tax():
- def change_digit_tax(cr):
- res = openerp.registry(cr.dbname)['decimal.precision'].precision_get(cr, SUPERUSER_ID, 'Account')
- return (16, res+2)
- return change_digit_tax
-
_name = 'account.tax'
_description = 'Tax'
_columns = {
@@ -2307,7 +2317,7 @@ class account_model(osv.osv):
try:
entry['name'] = model.name%{'year': move_date.strftime('%Y'), 'month': move_date.strftime('%m'), 'date': move_date.strftime('%Y-%m')}
except:
- raise osv.except_osv(_('Wrong model !'), _('You have a wrong expression "%(...)s" in your model !'))
+ raise osv.except_osv(_('Wrong Model!'), _('You have a wrong expression "%(...)s" in your model!'))
move_id = account_move_obj.create(cr, uid, {
'ref': entry['name'],
'period_id': period_id,
@@ -2319,7 +2329,7 @@ class account_model(osv.osv):
analytic_account_id = False
if line.analytic_account_id:
if not model.journal_id.analytic_journal_id:
- raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (model.journal_id.name,))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal!") % (model.journal_id.name,))
analytic_account_id = line.analytic_account_id.id
val = {
'move_id': move_id,
@@ -2795,7 +2805,7 @@ class account_tax_template(osv.osv):
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
'name': fields.char('Tax Name', size=64, required=True),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the taxes lines from lower sequences to higher ones. The order is important if you have a tax that has several tax children. In this case, the evaluation order is important."),
- 'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."),
+ 'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For Tax Type percent enter % ratio between 0-1."),
'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True),
'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True, help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index 023765d73f0..8a15321b9c6 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -420,7 +420,7 @@ class account_bank_statement(osv.osv):
for st_line in st.line_ids:
if st_line.analytic_account_id:
if not st.journal_id.analytic_journal_id:
- raise osv.except_osv(_('No Analytic Journal !'),_("You have to assign an analytic journal on the '%s' journal!") % (st.journal_id.name,))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You have to assign an analytic journal on the '%s' journal!") % (st.journal_id.name,))
if not st_line.amount:
continue
st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)
diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py
index 40f0ca80738..8e3e250d41c 100644
--- a/addons/account/account_cash_statement.py
+++ b/addons/account/account_cash_statement.py
@@ -252,7 +252,7 @@ class account_cash_statement(osv.osv):
for statement in statement_pool.browse(cr, uid, ids, context=context):
vals = {}
if not self._user_allow(cr, uid, statement.id, context=context):
- raise osv.except_osv(_('Error!'), (_('You do not have rights to open this %s journal !') % (statement.journal_id.name, )))
+ raise osv.except_osv(_('Error!'), (_('You do not have rights to open this %s journal!') % (statement.journal_id.name, )))
if statement.name and statement.name == '/':
c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 14aabed86ad..01476374cf4 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -69,7 +69,7 @@ class account_invoice(osv.osv):
tt = type2journal.get(type_inv, 'sale')
result = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=',tt)], context=context)
if not result:
- raise osv.except_osv(_('No Analytic Journal !'),_("You must define an analytic journal of type '%s'!") % (tt,))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You must define an analytic journal of type '%s'!") % (tt,))
return result[0]
def _get_type(self, cr, uid, context=None):
@@ -89,13 +89,43 @@ class account_invoice(osv.osv):
return [('none', _('Free Reference'))]
def _amount_residual(self, cr, uid, ids, name, args, context=None):
+ """Function of the field residua. It computes the residual amount (balance) for each invoice"""
+ if context is None:
+ context = {}
+ ctx = context.copy()
result = {}
+ currency_obj = self.pool.get('res.currency')
for invoice in self.browse(cr, uid, ids, context=context):
+ nb_inv_in_partial_rec = max_invoice_id = 0
result[invoice.id] = 0.0
if invoice.move_id:
- for m in invoice.move_id.line_id:
- if m.account_id.type in ('receivable','payable'):
- result[invoice.id] += m.amount_residual_currency
+ for aml in invoice.move_id.line_id:
+ if aml.account_id.type in ('receivable','payable'):
+ if aml.currency_id and aml.currency_id.id == invoice.currency_id.id:
+ result[invoice.id] += aml.amount_residual_currency
+ else:
+ ctx['date'] = aml.date
+ result[invoice.id] += currency_obj.compute(cr, uid, aml.company_id.currency_id.id, invoice.currency_id.id, aml.amount_residual, context=ctx)
+
+ if aml.reconcile_partial_id.line_partial_ids:
+ #we check if the invoice is partially reconciled and if there are other invoices
+ #involved in this partial reconciliation (and we sum these invoices)
+ for line in aml.reconcile_partial_id.line_partial_ids:
+ if line.invoice:
+ nb_inv_in_partial_rec += 1
+ #store the max invoice id as for this invoice we will make a balance instead of a simple division
+ max_invoice_id = max(max_invoice_id, line.invoice.id)
+ if nb_inv_in_partial_rec:
+ #if there are several invoices in a partial reconciliation, we split the residual by the number
+ #of invoice to have a sum of residual amounts that matches the partner balance
+ new_value = currency_obj.round(cr, uid, invoice.currency_id, result[invoice.id] / nb_inv_in_partial_rec)
+ if invoice.id == max_invoice_id:
+ #if it's the last the invoice of the bunch of invoices partially reconciled together, we make a
+ #balance to avoid rounding errors
+ result[invoice.id] = result[invoice.id] - ((nb_inv_in_partial_rec - 1) * new_value)
+ else:
+ result[invoice.id] = new_value
+
#prevent the residual amount on the invoice to be less than 0
result[invoice.id] = max(result[invoice.id], 0.0)
return result
@@ -600,7 +630,7 @@ class account_invoice(osv.osv):
obj_l = account_obj.browse(cr, uid, inv_line[2]['account_id'])
if obj_l.company_id.id != company_id:
raise osv.except_osv(_('Configuration Error!'),
- _('Invoice line account\'s company and invoice\'s compnay does not match.'))
+ _('Invoice line account\'s company and invoice\'s company does not match.'))
else:
continue
if company_id and type:
@@ -756,7 +786,7 @@ class account_invoice(osv.osv):
else:
ref = self._convert_ref(cr, uid, inv.number)
if not inv.journal_id.analytic_journal_id:
- raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (inv.journal_id.name,))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal!") % (inv.journal_id.name,))
il['analytic_lines'] = [(0,0, {
'name': il['name'],
'date': inv['date_invoice'],
@@ -882,7 +912,7 @@ class account_invoice(osv.osv):
if not inv.journal_id.sequence_id:
raise osv.except_osv(_('Error!'), _('Please define sequence on the journal related to this invoice.'))
if not inv.invoice_line:
- raise osv.except_osv(_('No Invoice Lines !'), _('Please create some invoice lines.'))
+ raise osv.except_osv(_('No Invoice Lines!'), _('Please create some invoice lines.'))
if inv.move_id:
continue
@@ -903,7 +933,7 @@ class account_invoice(osv.osv):
group_check_total = self.pool.get('res.groups').browse(cr, uid, group_check_total_id, context=context)
if group_check_total and uid in [x.id for x in group_check_total.users]:
if (inv.type in ('in_invoice', 'in_refund') and abs(inv.check_total - inv.amount_total) >= (inv.currency_id.rounding/2.0)):
- raise osv.except_osv(_('Bad total !'), _('Please verify the price of the invoice !\nThe encoded total does not match the computed total.'))
+ raise osv.except_osv(_('Bad Total!'), _('Please verify the price of the invoice!\nThe encoded total does not match the computed total.'))
if inv.payment_term:
total_fixed = total_percent = 0
@@ -1445,7 +1475,7 @@ class account_invoice_line(osv.osv):
context = dict(context)
context.update({'company_id': company_id, 'force_company': company_id})
if not partner_id:
- raise osv.except_osv(_('No Partner Defined !'),_("You must first select a partner !") )
+ raise osv.except_osv(_('No Partner Defined!'),_("You must first select a partner!") )
if not product:
if type in ('in_invoice', 'in_refund'):
return {'value': {}, 'domain':{'product_uom':[]}}
@@ -1460,6 +1490,7 @@ class account_invoice_line(osv.osv):
result = {}
res = self.pool.get('product.product').browse(cr, uid, product, context=context)
+ result['name'] = res.partner_ref
if type in ('out_invoice','out_refund'):
a = res.property_account_income.id
if not a:
@@ -1474,19 +1505,21 @@ class account_invoice_line(osv.osv):
if type in ('out_invoice', 'out_refund'):
taxes = res.taxes_id and res.taxes_id or (a and self.pool.get('account.account').browse(cr, uid, a, context=context).tax_ids or False)
+ if res.description_sale:
+ result['name'] += '\n'+res.description_sale
else:
taxes = res.supplier_taxes_id and res.supplier_taxes_id or (a and self.pool.get('account.account').browse(cr, uid, a, context=context).tax_ids or False)
+ if res.description_purchase:
+ result['name'] += '\n'+res.description_purchase
+
tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes)
if type in ('in_invoice', 'in_refund'):
result.update( {'price_unit': price_unit or res.standard_price,'invoice_line_tax_id': tax_id} )
else:
result.update({'price_unit': res.list_price, 'invoice_line_tax_id': tax_id})
- result['name'] = res.partner_ref
result['uos_id'] = uom_id or res.uom_id.id
- if res.description:
- result['name'] += '\n'+res.description
domain = {'uos_id':[('category_id','=',res.uom_id.category_id.id)]}
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index 7469c38decb..c71b97d5796 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -197,7 +197,7 @@
@@ -320,7 +320,7 @@
@@ -353,7 +353,7 @@
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index d6c25364784..e604cc6d1a4 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -192,7 +192,7 @@ class account_move_line(osv.osv):
for obj_line in self.browse(cr, uid, ids, context=context):
if obj_line.analytic_account_id:
if not obj_line.journal_id.analytic_journal_id:
- raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (obj_line.journal_id.name, ))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal!") % (obj_line.journal_id.name, ))
vals_line = self._prepare_analytic_line(cr, uid, obj_line, context=context)
acc_ana_line_obj.create(cr, uid, vals_line)
return True
@@ -1101,7 +1101,7 @@ class account_move_line(osv.osv):
period = period_obj.browse(cr, uid, period_id, context=context)
for (state,) in result:
if state == 'done':
- raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period.name,journal.name)))
+ raise osv.except_osv(_('Error!'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period.name,journal.name)))
if not result:
jour_period_obj.create(cr, uid, {
'name': (journal.code or journal.name)+':'+(period.name or ''),
@@ -1181,7 +1181,7 @@ class account_move_line(osv.osv):
move_id = move_obj.create(cr, uid, v, context)
vals['move_id'] = move_id
else:
- raise osv.except_osv(_('No piece number !'), _('Cannot create an automatic sequence for this piece.\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.'))
+ raise osv.except_osv(_('No Piece Number!'), _('Cannot create an automatic sequence for this piece.\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.'))
ok = not (journal.type_control_ids or journal.account_control_ids)
if ('account_id' in vals):
account = account_obj.browse(cr, uid, vals['account_id'], context=context)
diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml
index 603c4254b19..e921e639642 100644
--- a/addons/account/account_view.xml
+++ b/addons/account/account_view.xml
@@ -907,9 +907,7 @@
diff --git a/addons/account/wizard/account_validate_account_move.py b/addons/account/wizard/account_validate_account_move.py
index 324248284f1..050191db187 100644
--- a/addons/account/wizard/account_validate_account_move.py
+++ b/addons/account/wizard/account_validate_account_move.py
@@ -57,7 +57,7 @@ class validate_account_move_lines(osv.osv_memory):
move_ids.append(line.move_id.id)
move_ids = list(set(move_ids))
if not move_ids:
- raise osv.except_osv(_('Warning!'), _('Selected Entry Lines does not have any account move enties in draft state.'))
+ raise osv.except_osv(_('Warning!'), _('Selected Entry Lines does not have any account move entries in draft state.'))
obj_move.button_validate(cr, uid, move_ids, context)
return {'type': 'ir.actions.act_window_close'}
diff --git a/addons/account/wizard/pos_box.py b/addons/account/wizard/pos_box.py
index bd38e6bbed6..4b7e63585d8 100644
--- a/addons/account/wizard/pos_box.py
+++ b/addons/account/wizard/pos_box.py
@@ -22,7 +22,7 @@ class CashBox(osv.osv_memory):
records = self.pool[active_model].browse(cr, uid, active_ids, context=context)
- return self._run(cr, uid, ids, records, context=None)
+ return self._run(cr, uid, ids, records, context=context)
def _run(self, cr, uid, ids, records, context=None):
for box in self.browse(cr, uid, ids, context=context):
diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index be1e0aac402..b3dd2302a2f 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -478,7 +478,7 @@ class account_analytic_account(osv.osv):
'remaining_hours': fields.function(_remaining_hours_calc, type='float', string='Remaining Time',
help="Computed using the formula: Maximum Time - Total Worked Time"),
'remaining_hours_to_invoice': fields.function(_remaining_hours_to_invoice_calc, type='float', string='Remaining Time',
- help="Computed using the formula: Maximum Time - Total Invoiced Time"),
+ help="Computed using the formula: Expected on timesheets - Total invoiced on timesheets"),
'fix_price_to_invoice': fields.function(_fix_price_to_invoice_calc, type='float', string='Remaining Time',
help="Sum of quotations for this contract."),
'timesheet_ca_invoiced': fields.function(_timesheet_ca_invoiced_calc, type='float', string='Remaining Time',
@@ -653,7 +653,7 @@ class account_analytic_account(osv.osv):
fpos_obj = self.pool.get('account.fiscal.position')
if not contract.partner_id:
- raise osv.except_osv(_('No Customer Defined !'),_("You must first select a Customer for Contract %s!") % contract.name )
+ raise osv.except_osv(_('No Customer Defined!'),_("You must first select a Customer for Contract %s!") % contract.name )
fpos = contract.partner_id.property_account_position.id or False
journal_ids = journal_obj.search(cr, uid, [('type', '=','sale'),('company_id', '=', contract.company_id.id or False)], limit=1)
diff --git a/addons/account_analytic_analysis/i18n/ru.po b/addons/account_analytic_analysis/i18n/ru.po
index 3944c48afb6..339d425c717 100644
--- a/addons/account_analytic_analysis/i18n/ru.po
+++ b/addons/account_analytic_analysis/i18n/ru.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev_rc3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2011-02-19 12:16+0000\n"
+"PO-Revision-Date: 2013-05-31 07:35+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:25+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-01 05:16+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@@ -73,7 +73,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "⇒ Invoice"
-msgstr ""
+msgstr "⇒ Счет"
#. module: account_analytic_analysis
#: field:account.analytic.account,ca_invoiced:0
@@ -196,6 +196,8 @@ msgid ""
"{'required': [('type','=','contract')], 'invisible': [('type','in',['view', "
"'normal','template'])]}"
msgstr ""
+"{'required': [('type','=','contract')], 'invisible': [('type','in',['view', "
+"'normal','template'])]}"
#. module: account_analytic_analysis
#: field:account.analytic.account,real_margin_rate:0
@@ -335,7 +337,7 @@ msgstr "Теоретическая выручка"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "To Renew"
-msgstr ""
+msgstr "К продлению"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@@ -431,7 +433,7 @@ msgstr ""
#. module: account_analytic_analysis
#: field:account.analytic.account,toinvoice_total:0
msgid "Total to Invoice"
-msgstr ""
+msgstr "Всего в счет"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@@ -546,18 +548,18 @@ msgstr "Дата последней операции по этому счету.
#. module: account_analytic_analysis
#: model:ir.model,name:account_analytic_analysis.model_sale_config_settings
msgid "sale.config.settings"
-msgstr ""
+msgstr "sale.config.settings"
#. module: account_analytic_analysis
#: field:sale.config.settings,group_template_required:0
msgid "Mandatory use of templates."
-msgstr ""
+msgstr "Обязательное использование шаблонов."
#. module: account_analytic_analysis
#: model:ir.actions.act_window,name:account_analytic_analysis.template_of_contract_action
#: model:ir.ui.menu,name:account_analytic_analysis.menu_template_of_contract_action
msgid "Contract Template"
-msgstr ""
+msgstr "Шаблон контракта"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@@ -612,7 +614,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Total"
-msgstr ""
+msgstr "Итого"
#~ msgid "Hours summary by user"
#~ msgstr "Итого часов по пользователям"
diff --git a/addons/account_analytic_default/security/account_analytic_default_security.xml b/addons/account_analytic_default/security/account_analytic_default_security.xml
index 63c6e30eb22..cdce2a9955e 100644
--- a/addons/account_analytic_default/security/account_analytic_default_security.xml
+++ b/addons/account_analytic_default/security/account_analytic_default_security.xml
@@ -4,7 +4,7 @@
Analytic Default multi company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
diff --git a/addons/account_analytic_plans/account_analytic_plans.py b/addons/account_analytic_plans/account_analytic_plans.py
index 54b15ad565b..4cf12098fff 100644
--- a/addons/account_analytic_plans/account_analytic_plans.py
+++ b/addons/account_analytic_plans/account_analytic_plans.py
@@ -332,7 +332,7 @@ class account_move_line(osv.osv):
for line in self.browse(cr, uid, ids, context=context):
if line.analytics_id:
if not line.journal_id.analytic_journal_id:
- raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal.") % (line.journal_id.name,))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal.") % (line.journal_id.name,))
toremove = analytic_line_obj.search(cr, uid, [('move_id','=',line.id)], context=context)
if toremove:
@@ -471,7 +471,7 @@ class account_bank_statement(osv.osv):
for st_line in st.line_ids:
if st_line.analytics_id:
if not st.journal_id.analytic_journal_id:
- raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal.") % (st.journal_id.name,))
+ raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal.") % (st.journal_id.name,))
if not st_line.amount:
continue
return True
diff --git a/addons/account_analytic_plans/i18n/ru.po b/addons/account_analytic_plans/i18n/ru.po
index ba32246e8d6..29cb3ea910f 100644
--- a/addons/account_analytic_plans/i18n/ru.po
+++ b/addons/account_analytic_plans/i18n/ru.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-12-28 10:00+0000\n"
+"PO-Revision-Date: 2013-05-31 07:41+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:26+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-01 05:16+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: account_analytic_plans
#: field:account.analytic.plan.instance,account4_ids:0
@@ -48,7 +48,7 @@ msgstr "Ставка (%)"
#: code:addons/account_analytic_plans/account_analytic_plans.py:234
#, python-format
msgid "The total should be between %s and %s."
-msgstr ""
+msgstr "Итог должен быть между %s и %s."
#. module: account_analytic_plans
#: view:account.analytic.plan:0
@@ -131,7 +131,7 @@ msgstr "Не показывать пустые строки"
#: code:addons/account_analytic_plans/wizard/account_crossovered_analytic.py:61
#, python-format
msgid "There are no analytic lines related to account %s."
-msgstr ""
+msgstr "Нет позиций аналитики относящихся к счету %s."
#. module: account_analytic_plans
#: field:account.analytic.plan.instance,account3_ids:0
@@ -315,7 +315,7 @@ msgstr "Журнал аналитики"
#: code:addons/account_analytic_plans/wizard/analytic_plan_create_model.py:38
#, python-format
msgid "Please put a name and a code before saving the model."
-msgstr ""
+msgstr "Пожалуйста, введите имя и код перед сохранением модели."
#. module: account_analytic_plans
#: report:account.analytic.account.crossovered.analytic:0
@@ -347,7 +347,7 @@ msgstr "Журнал"
#: code:addons/account_analytic_plans/account_analytic_plans.py:486
#, python-format
msgid "You have to define an analytic journal on the '%s' journal."
-msgstr ""
+msgstr "Вы должны определить журнал аналитики для журнала '%s'"
#. module: account_analytic_plans
#: code:addons/account_analytic_plans/account_analytic_plans.py:342
@@ -375,7 +375,7 @@ msgstr "Позиция счета"
#: code:addons/account_analytic_plans/wizard/analytic_plan_create_model.py:41
#, python-format
msgid "There is no analytic plan defined."
-msgstr ""
+msgstr "Аналитический план счетов не определен."
#. module: account_analytic_plans
#: model:ir.model,name:account_analytic_plans.model_account_bank_statement
@@ -402,7 +402,7 @@ msgstr "Разнесение аналитики"
#: code:addons/account_analytic_plans/account_analytic_plans.py:221
#, python-format
msgid "A model with this name and code already exists."
-msgstr ""
+msgstr "Модель с таким названием и кодом уже существует."
#. module: account_analytic_plans
#: help:account.analytic.plan.line,root_analytic_id:0
diff --git a/addons/account_asset/i18n/ru.po b/addons/account_asset/i18n/ru.po
index a0950a98370..d6bc83aacb5 100644
--- a/addons/account_asset/i18n/ru.po
+++ b/addons/account_asset/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2011-07-12 12:04+0000\n"
-"Last-Translator: FULL NAME \n"
+"PO-Revision-Date: 2013-05-31 08:06+0000\n"
+"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:50+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-01 05:16+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: account_asset
#: view:account.asset.asset:0
@@ -148,7 +148,7 @@ msgstr ""
#. module: account_asset
#: help:account.asset.asset,method_period:0
msgid "The amount of time between two depreciations, in months"
-msgstr ""
+msgstr "Количество времени между амортизациями, в месяцах"
#. module: account_asset
#: field:account.asset.depreciation.line,depreciation_date:0
@@ -160,7 +160,7 @@ msgstr "Дата амортизации"
#. module: account_asset
#: constraint:account.asset.asset:0
msgid "Error ! You cannot create recursive assets."
-msgstr ""
+msgstr "Ошибка! Нельзя создавать рекурсивные активы."
#. module: account_asset
#: field:asset.asset.report,posted_value:0
@@ -205,7 +205,7 @@ msgstr "# позиций амортизации"
#. module: account_asset
#: field:account.asset.asset,method_period:0
msgid "Number of Months in a Period"
-msgstr ""
+msgstr "Количество месяцев в периоде"
#. module: account_asset
#: view:asset.asset.report:0
@@ -234,7 +234,7 @@ msgstr "Счет активов"
#: model:ir.actions.act_window,name:account_asset.action_asset_depreciation_confirmation_wizard
#: model:ir.ui.menu,name:account_asset.menu_asset_depreciation_confirmation_wizard
msgid "Compute Assets"
-msgstr ""
+msgstr "Вычислить активы"
#. module: account_asset
#: field:account.asset.category,method_period:0
@@ -265,12 +265,12 @@ msgstr "Изменить длительность"
#: help:account.asset.category,method_number:0
#: help:account.asset.history,method_number:0
msgid "The number of depreciations needed to depreciate your asset"
-msgstr ""
+msgstr "Количество амортизаций необходимых для обесценивания актива"
#. module: account_asset
#: view:account.asset.category:0
msgid "Analytic Information"
-msgstr ""
+msgstr "Аналитическая информация"
#. module: account_asset
#: field:account.asset.category,account_analytic_id:0
@@ -293,7 +293,7 @@ msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,remaining_value:0
msgid "Next Period Depreciation"
-msgstr ""
+msgstr "Следующий период амортизации"
#. module: account_asset
#: help:account.asset.history,method_period:0
@@ -344,7 +344,7 @@ msgstr "Поиск категории актива"
#. module: account_asset
#: view:asset.modify:0
msgid "months"
-msgstr ""
+msgstr "месяцы"
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_invoice_line
@@ -372,7 +372,7 @@ msgstr ""
#: view:asset.depreciation.confirmation.wizard:0
#: view:asset.modify:0
msgid "or"
-msgstr ""
+msgstr "или"
#. module: account_asset
#: field:account.asset.asset,note:0
@@ -406,7 +406,7 @@ msgstr ""
#. module: account_asset
#: view:asset.asset.report:0
msgid "Assets in running state"
-msgstr ""
+msgstr "Активы в рабочем состоянии"
#. module: account_asset
#: view:account.asset.asset:0
@@ -427,7 +427,7 @@ msgstr ""
#: field:account.asset.asset,state:0
#: field:asset.asset.report,state:0
msgid "Status"
-msgstr ""
+msgstr "Статус"
#. module: account_asset
#: field:account.asset.asset,partner_id:0
@@ -474,12 +474,12 @@ msgstr "Вычислить"
#. module: account_asset
#: view:account.asset.history:0
msgid "Asset History"
-msgstr ""
+msgstr "История актива"
#. module: account_asset
#: model:ir.model,name:account_asset.model_asset_depreciation_confirmation_wizard
msgid "asset.depreciation.confirmation.wizard"
-msgstr ""
+msgstr "asset.depreciation.confirmation.wizard"
#. module: account_asset
#: field:account.asset.asset,active:0
@@ -505,7 +505,7 @@ msgstr "История"
#. module: account_asset
#: view:asset.depreciation.confirmation.wizard:0
msgid "Compute Asset"
-msgstr ""
+msgstr "Вычислить актив"
#. module: account_asset
#: field:asset.depreciation.confirmation.wizard,period_id:0
@@ -521,7 +521,7 @@ msgstr "Общий"
#: field:account.asset.asset,prorata:0
#: field:account.asset.category,prorata:0
msgid "Prorata Temporis"
-msgstr ""
+msgstr "По истечении срока"
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_invoice
@@ -553,7 +553,7 @@ msgstr "Элементы журнала"
#. module: account_asset
#: view:asset.modify:0
msgid "Asset Durations to Modify"
-msgstr ""
+msgstr "Актив - интервал времени для изменения"
#. module: account_asset
#: field:account.asset.asset,purchase_date:0
@@ -574,6 +574,8 @@ msgid ""
"Choose the period for which you want to automatically post the depreciation "
"lines of running assets"
msgstr ""
+"Выберите период, за который вы хотите автоматически создавать записи "
+"амортизации для актива"
#. module: account_asset
#: view:account.asset.asset:0
@@ -588,12 +590,12 @@ msgstr "Метод амортизации"
#. module: account_asset
#: field:account.asset.depreciation.line,amount:0
msgid "Current Depreciation"
-msgstr ""
+msgstr "Текущая аммортизация"
#. module: account_asset
#: field:account.asset.asset,name:0
msgid "Asset Name"
-msgstr ""
+msgstr "Название актива"
#. module: account_asset
#: field:account.asset.category,open_asset:0
@@ -618,7 +620,7 @@ msgstr "Журнал"
#. module: account_asset
#: field:account.asset.history,name:0
msgid "History name"
-msgstr ""
+msgstr "Название истории"
#. module: account_asset
#: field:account.asset.depreciation.line,depreciated_value:0
@@ -657,7 +659,7 @@ msgstr ""
#. module: account_asset
#: field:account.asset.asset,purchase_value:0
msgid "Gross Value"
-msgstr ""
+msgstr "Валовая стоимость"
#. module: account_asset
#: field:account.asset.category,name:0
@@ -703,12 +705,12 @@ msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Нумерация"
#. module: account_asset
#: help:account.asset.category,method_period:0
msgid "State here the time between 2 depreciations, in months"
-msgstr ""
+msgstr "Время между двумя амортизациями в месяцах"
#. module: account_asset
#: field:account.asset.history,date:0
@@ -729,7 +731,7 @@ msgstr "Число амортизаций"
#. module: account_asset
#: view:account.asset.asset:0
msgid "Create Move"
-msgstr ""
+msgstr "Создать перемещение"
#. module: account_asset
#: view:account.asset.asset:0
diff --git a/addons/account_check_writing/i18n/ru.po b/addons/account_check_writing/i18n/ru.po
index ba474c72a22..8e68dd7152a 100644
--- a/addons/account_check_writing/i18n/ru.po
+++ b/addons/account_check_writing/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-12-11 13:00+0000\n"
-"Last-Translator: FULL NAME \n"
+"PO-Revision-Date: 2013-06-03 07:47+0000\n"
+"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:51+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-04 05:20+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: account_check_writing
#: selection:res.company,check_layout:0
@@ -25,13 +25,13 @@ msgstr ""
#. module: account_check_writing
#: report:account.print.check.top:0
msgid "Open Balance"
-msgstr ""
+msgstr "Открытый баланс"
#. module: account_check_writing
#: view:account.check.write:0
#: view:account.voucher:0
msgid "Print Check"
-msgstr ""
+msgstr "Напечатать чек"
#. module: account_check_writing
#: selection:res.company,check_layout:0
@@ -82,7 +82,7 @@ msgstr "Описание"
#. module: account_check_writing
#: model:ir.model,name:account_check_writing.model_account_journal
msgid "Journal"
-msgstr ""
+msgstr "Журнал"
#. module: account_check_writing
#: model:ir.actions.act_window,name:account_check_writing.action_write_check
@@ -95,14 +95,14 @@ msgstr ""
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Discount"
-msgstr ""
+msgstr "Скидка"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Original Amount"
-msgstr ""
+msgstr "Первоначальная сумма"
#. module: account_check_writing
#: field:res.company,check_layout:0
@@ -119,7 +119,7 @@ msgstr ""
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Payment"
-msgstr ""
+msgstr "Платеж"
#. module: account_check_writing
#: field:account.journal,use_preprint_check:0
@@ -153,7 +153,7 @@ msgstr ""
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Due Date"
-msgstr ""
+msgstr "Дата исполнения"
#. module: account_check_writing
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
@@ -163,13 +163,13 @@ msgstr ""
#. module: account_check_writing
#: model:ir.model,name:account_check_writing.model_res_company
msgid "Companies"
-msgstr ""
+msgstr "Компании"
#. module: account_check_writing
#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
#, python-format
msgid "Error!"
-msgstr ""
+msgstr "Ошибка!"
#. module: account_check_writing
#: help:account.check.write,check_number:0
@@ -202,12 +202,12 @@ msgstr ""
#. module: account_check_writing
#: view:account.check.write:0
msgid "or"
-msgstr ""
+msgstr "или"
#. module: account_check_writing
#: field:account.voucher,amount_in_word:0
msgid "Amount in Word"
-msgstr ""
+msgstr "Сумма прописью"
#. module: account_check_writing
#: model:ir.model,name:account_check_writing.model_account_check_write
@@ -217,7 +217,7 @@ msgstr ""
#. module: account_check_writing
#: view:account.check.write:0
msgid "Cancel"
-msgstr ""
+msgstr "Отмена"
#. module: account_check_writing
#: field:account.check.write,check_number:0
diff --git a/addons/account_followup/account_followup_customers.xml b/addons/account_followup/account_followup_customers.xml
index 6893abe012e..fba0bce460b 100644
--- a/addons/account_followup/account_followup_customers.xml
+++ b/addons/account_followup/account_followup_customers.xml
@@ -9,11 +9,12 @@
res.partner
-
+
+
@@ -97,7 +98,7 @@
+ groups="account.group_account_user"/>
diff --git a/addons/account_followup/i18n/ru.po b/addons/account_followup/i18n/ru.po
index f6cb2cf0412..b57c8e4315e 100644
--- a/addons/account_followup/i18n/ru.po
+++ b/addons/account_followup/i18n/ru.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2011-11-11 15:21+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2013-05-31 10:28+0000\n"
+"Last-Translator: Chertykov Denis \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:11+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-01 05:16+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: account_followup
#: model:email.template,subject:account_followup.email_template_account_followup_default
@@ -22,7 +22,7 @@ msgstr ""
#: model:email.template,subject:account_followup.email_template_account_followup_level1
#: model:email.template,subject:account_followup.email_template_account_followup_level2
msgid "${user.company_id.name} Payment Reminder"
-msgstr ""
+msgstr "${user.company_id.name} напоминание о платеже"
#. module: account_followup
#: help:res.partner,latest_followup_level_id:0
@@ -43,12 +43,12 @@ msgstr "Дальнейшие действия"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(date)s"
-msgstr ""
+msgstr "%(date)s"
#. module: account_followup
#: field:res.partner,payment_next_action_date:0
msgid "Next Action Date"
-msgstr ""
+msgstr "Дата следующего действия"
#. module: account_followup
#: view:account_followup.followup.line:0
@@ -64,7 +64,7 @@ msgstr ""
#. module: account_followup
#: view:res.partner:0
msgid "⇾ Mark as Done"
-msgstr ""
+msgstr "⇾ отметить как сделанное"
#. module: account_followup
#: field:account_followup.followup.line,manual_action_note:0
@@ -94,7 +94,7 @@ msgstr "Тема эл.письма"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(user_signature)s"
-msgstr ""
+msgstr "%(user_signature)s"
#. module: account_followup
#: view:account_followup.followup.line:0
@@ -109,19 +109,19 @@ msgstr ""
#. module: account_followup
#: field:account_followup.print,email_body:0
msgid "Email Body"
-msgstr ""
+msgstr "Тело эл. письма"
#. module: account_followup
#: model:ir.actions.act_window,name:account_followup.action_account_followup_print
msgid "Send Follow-Ups"
-msgstr ""
+msgstr "Послать напоминания"
#. module: account_followup
#: report:account_followup.followup.print:0
#: code:addons/account_followup/account_followup.py:263
#, python-format
msgid "Amount"
-msgstr ""
+msgstr "Сумма"
#. module: account_followup
#: help:res.partner,payment_next_action:0
@@ -133,7 +133,7 @@ msgstr ""
#. module: account_followup
#: view:res.partner:0
msgid "No Responsible"
-msgstr ""
+msgstr "Нет ответственного"
#. module: account_followup
#: model:account_followup.followup.line,description:account_followup.demo_followup_line2
@@ -209,17 +209,17 @@ msgstr "Всего по дебету"
#. module: account_followup
#: field:res.partner,payment_next_action:0
msgid "Next Action"
-msgstr ""
+msgstr "Следующее действие"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid ": Partner Name"
-msgstr ""
+msgstr ": Название партнера"
#. module: account_followup
#: field:account_followup.followup.line,manual_action_responsible_id:0
msgid "Assign a Responsible"
-msgstr ""
+msgstr "Назначить ответственного"
#. module: account_followup
#: view:account_followup.followup:0
@@ -305,7 +305,7 @@ msgstr ""
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(partner_name)s"
-msgstr ""
+msgstr "%(partner_name)s"
#. module: account_followup
#: model:email.template,body_html:account_followup.email_template_account_followup_level1
@@ -377,7 +377,7 @@ msgstr "Определяет порядок вывода списка напом
#: code:addons/account_followup/wizard/account_followup_print.py:166
#, python-format
msgid " will be sent"
-msgstr ""
+msgstr " будет отправлен"
#. module: account_followup
#: view:account_followup.followup.line:0
@@ -388,7 +388,7 @@ msgstr ""
#: view:account_followup.followup.line:0
#: field:account_followup.followup.line,send_letter:0
msgid "Send a Letter"
-msgstr ""
+msgstr "Отправить письмо"
#. module: account_followup
#: model:ir.actions.act_window,name:account_followup.action_account_followup_definition_form
@@ -466,7 +466,7 @@ msgstr "Напечатанное сообщение"
#: code:addons/account_followup/wizard/account_followup_print.py:155
#, python-format
msgid "Anybody"
-msgstr ""
+msgstr "Кто угодно"
#. module: account_followup
#: help:account_followup.followup.line,send_email:0
@@ -528,7 +528,7 @@ msgstr ""
#. module: account_followup
#: view:res.partner:0
msgid "Search Partner"
-msgstr ""
+msgstr "Поиск партнера"
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.account_followup_print_menu
@@ -554,7 +554,7 @@ msgstr ""
#. module: account_followup
#: view:account_followup.print:0
msgid "or"
-msgstr ""
+msgstr "или"
#. module: account_followup
#: view:res.partner:0
diff --git a/addons/account_followup/report/account_followup_report.xml b/addons/account_followup/report/account_followup_report.xml
index 6fee6a77ac1..b7c38e89f5e 100644
--- a/addons/account_followup/report/account_followup_report.xml
+++ b/addons/account_followup/report/account_followup_report.xml
@@ -6,7 +6,7 @@
account_followup.stat.treeaccount_followup.stat
-
+
diff --git a/addons/account_followup/security/account_followup_security.xml b/addons/account_followup/security/account_followup_security.xml
index 1586403d701..69c9a44a1b9 100644
--- a/addons/account_followup/security/account_followup_security.xml
+++ b/addons/account_followup/security/account_followup_security.xml
@@ -4,7 +4,7 @@
Account Follow-up multi company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
diff --git a/addons/account_payment/security/account_payment_security.xml b/addons/account_payment/security/account_payment_security.xml
index 4bca00eaa6d..fbe29699e86 100644
--- a/addons/account_payment/security/account_payment_security.xml
+++ b/addons/account_payment/security/account_payment_security.xml
@@ -15,21 +15,21 @@
Payment Mode company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]Payment order multi company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]Payment line multi company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
diff --git a/addons/account_payment/wizard/account_payment_order.py b/addons/account_payment/wizard/account_payment_order.py
index 08d36c45eff..03e25dfbc45 100644
--- a/addons/account_payment/wizard/account_payment_order.py
+++ b/addons/account_payment/wizard/account_payment_order.py
@@ -23,6 +23,7 @@ import time
from lxml import etree
from openerp.osv import fields, osv
+from openerp.tools.translate import _
class payment_order_create(osv.osv_memory):
"""
@@ -108,7 +109,7 @@ class payment_order_create(osv.osv_memory):
context.update({'line_ids': line_ids})
model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'view_create_payment_order_lines')], context=context)
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
- return {'name': ('Entrie Lines'),
+ return {'name': _('Entry Lines'),
'context': context,
'view_type': 'form',
'view_mode': 'form',
diff --git a/addons/account_test/i18n/ru.po b/addons/account_test/i18n/ru.po
new file mode 100644
index 00000000000..d36d83d2e99
--- /dev/null
+++ b/addons/account_test/i18n/ru.po
@@ -0,0 +1,241 @@
+# Russian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-06-05 07:09+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Russian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-06 05:21+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
+
+#. module: account_test
+#: view:accounting.assert.test:0
+msgid ""
+"Code should always set a variable named `result` with the result of your "
+"test, that can be a list or\n"
+"a dictionary. If `result` is an empty list, it means that the test was "
+"succesful. Otherwise it will\n"
+"try to translate and print what is inside `result`.\n"
+"\n"
+"If the result of your test is a dictionary, you can set a variable named "
+"`column_order` to choose in\n"
+"what order you want to print `result`'s content.\n"
+"\n"
+"Should you need them, you can also use the following variables into your "
+"code:\n"
+" * cr: cursor to the database\n"
+" * uid: ID of the current user\n"
+"\n"
+"In any ways, the code must be legal python statements with correct "
+"indentation (if needed).\n"
+"\n"
+"Example: \n"
+" sql = '''SELECT id, name, ref, date\n"
+" FROM account_move_line \n"
+" WHERE account_id IN (SELECT id FROM account_account WHERE type "
+"= 'view')\n"
+" '''\n"
+" cr.execute(sql)\n"
+" result = cr.dictfetchall()"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_02
+msgid "Test 2: Opening a fiscal year"
+msgstr "Проверка 2: Открытие фискального года"
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_05
+msgid ""
+"Check that reconciled invoice for Sales/Purchases has reconciled entries for "
+"Payable and Receivable Accounts"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_03
+msgid ""
+"Check if movement lines are balanced and have the same date and period"
+msgstr ""
+
+#. module: account_test
+#: field:accounting.assert.test,name:0
+msgid "Test Name"
+msgstr ""
+
+#. module: account_test
+#: report:account.test.assert.print:0
+msgid "Accouting tests on"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_01
+msgid "Test 1: General balance"
+msgstr "Проверка 1: Общий баланс"
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_06
+msgid "Check that paid/reconciled invoices are not in 'Open' state"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_05_2
+msgid ""
+"Check that reconciled account moves, that define Payable and Receivable "
+"accounts, are belonging to reconciled invoices"
+msgstr ""
+
+#. module: account_test
+#: view:accounting.assert.test:0
+msgid "Tests"
+msgstr "Проверки"
+
+#. module: account_test
+#: field:accounting.assert.test,desc:0
+msgid "Test Description"
+msgstr "Описание проверки"
+
+#. module: account_test
+#: view:accounting.assert.test:0
+msgid "Description"
+msgstr "Описание"
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_06_1
+msgid "Check that there's no move for any account with « View » account type"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_08
+msgid "Test 9 : Accounts and partners on account moves"
+msgstr ""
+
+#. module: account_test
+#: model:ir.actions.act_window,name:account_test.action_accounting_assert
+#: model:ir.actions.report.xml,name:account_test.account_assert_test_report
+#: model:ir.ui.menu,name:account_test.menu_action_license
+msgid "Accounting Tests"
+msgstr ""
+
+#. module: account_test
+#: code:addons/account_test/report/account_test_report.py:74
+#, python-format
+msgid "The test was passed successfully"
+msgstr "Проверка прошла успешно"
+
+#. module: account_test
+#: field:accounting.assert.test,active:0
+msgid "Active"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_06
+msgid "Test 6 : Invoices status"
+msgstr ""
+
+#. module: account_test
+#: model:ir.model,name:account_test.model_accounting_assert_test
+msgid "accounting.assert.test"
+msgstr "accounting.assert.test"
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_05
+msgid ""
+"Test 5.1 : Payable and Receivable accountant lines of reconciled invoices"
+msgstr ""
+
+#. module: account_test
+#: field:accounting.assert.test,code_exec:0
+msgid "Python code"
+msgstr "Код на Python"
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_07
+msgid ""
+"Check on bank statement that the Closing Balance = Starting Balance + sum of "
+"statement lines"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_07
+msgid "Test 8 : Closing balance on bank statements"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_03
+msgid "Test 3: Movement lines"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_05_2
+msgid "Test 5.2 : Reconcilied invoices and Payable/Receivable accounts"
+msgstr ""
+
+#. module: account_test
+#: view:accounting.assert.test:0
+msgid "Expression"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_04
+msgid "Test 4: Totally reconciled mouvements"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_04
+msgid "Check if the totally reconciled movements are balanced"
+msgstr ""
+
+#. module: account_test
+#: field:accounting.assert.test,sequence:0
+msgid "Sequence"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_02
+msgid ""
+"Check if the balance of the new opened fiscal year matches with last year's "
+"balance"
+msgstr ""
+
+#. module: account_test
+#: view:accounting.assert.test:0
+msgid "Python Code"
+msgstr "Код на Python"
+
+#. module: account_test
+#: model:ir.actions.act_window,help:account_test.action_accounting_assert
+msgid ""
+"
\n"
+" Click to create Accounting Test.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_01
+msgid "Check the balance: Debit sum = Credit sum"
+msgstr "Проверяет баланс: сумма дебита = сумма кредита"
+
+#. module: account_test
+#: model:accounting.assert.test,desc:account_test.account_test_08
+msgid "Check that general accounts and partners on account moves are active"
+msgstr ""
+
+#. module: account_test
+#: model:accounting.assert.test,name:account_test.account_test_06_1
+msgid "Test 7: « View » account type"
+msgstr ""
+
+#. module: account_test
+#: view:accounting.assert.test:0
+msgid "Code Help"
+msgstr ""
diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py
index 850162ccf84..81eb76ff3a8 100644
--- a/addons/account_voucher/account_voucher.py
+++ b/addons/account_voucher/account_voucher.py
@@ -1622,7 +1622,7 @@ class account_bank_statement(osv.osv):
for bk_st in self.browse(cr, uid, ids, context=context):
if vals.get('journal_id') and bk_st.line_ids:
if any([x.voucher_id and True or False for x in bk_st.line_ids]):
- raise osv.except_osv(_('Unable to change journal !'), _('You can not change the journal as you already reconciled some statement lines!'))
+ raise osv.except_osv(_('Unable to Change Journal!'), _('You can not change the journal as you already reconciled some statement lines!'))
return super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
diff --git a/addons/account_voucher/html/index.html b/addons/account_voucher/html/index.html
index 581dbb4fb96..d59c110dde5 100644
--- a/addons/account_voucher/html/index.html
+++ b/addons/account_voucher/html/index.html
@@ -7,7 +7,6 @@
-
@@ -137,4 +136,5 @@ material. Define recurrencies to produce recurring invoice automatically.
-
+
+
diff --git a/addons/account_voucher/i18n/ru.po b/addons/account_voucher/i18n/ru.po
index 63cad344ed0..ef38a07e478 100644
--- a/addons/account_voucher/i18n/ru.po
+++ b/addons/account_voucher/i18n/ru.po
@@ -7,24 +7,24 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-05-10 17:46+0000\n"
+"PO-Revision-Date: 2013-05-29 13:17+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:33+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-05-30 05:45+0000\n"
+"X-Generator: Launchpad (build 16652)\n"
#. module: account_voucher
#: field:account.bank.statement.line,voucher_id:0
msgid "Reconciliation"
-msgstr ""
+msgstr "Сверка"
#. module: account_voucher
#: model:ir.model,name:account_voucher.model_account_config_settings
msgid "account.config.settings"
-msgstr ""
+msgstr "account.config.settings"
#. module: account_voucher
#: code:addons/account_voucher/account_voucher.py:369
@@ -45,7 +45,7 @@ msgstr "Общая сумма"
#. module: account_voucher
#: view:account.voucher:0
msgid "Open Customer Journal Entries"
-msgstr ""
+msgstr "Открыть записи журнала по заказчику"
#. module: account_voucher
#: view:account.voucher:0
@@ -63,7 +63,7 @@ msgstr ""
#. module: account_voucher
#: view:account.voucher:0
msgid "(Update)"
-msgstr ""
+msgstr "(Обновить)"
#. module: account_voucher
#: view:account.voucher:0
@@ -90,7 +90,7 @@ msgstr "Март"
#. module: account_voucher
#: field:account.voucher,message_unread:0
msgid "Unread Messages"
-msgstr ""
+msgstr "Непрочитанные"
#. module: account_voucher
#: view:account.voucher:0
@@ -115,13 +115,13 @@ msgstr "Номер транзакции."
#. module: account_voucher
#: view:sale.receipt.report:0
msgid "Group by year of Invoice Date"
-msgstr ""
+msgstr "Группировать по году в дате счета"
#. module: account_voucher
#: view:sale.receipt.report:0
#: field:sale.receipt.report,user_id:0
msgid "Salesperson"
-msgstr ""
+msgstr "Продавец"
#. module: account_voucher
#: view:account.voucher:0
@@ -135,6 +135,8 @@ msgid ""
"You can not change the journal as you already reconciled some statement "
"lines!"
msgstr ""
+"Вы не можете изменить журнал, так как вы уже сверили некоторые позиции "
+"документа!"
#. module: account_voucher
#: view:account.voucher:0
@@ -145,7 +147,7 @@ msgstr "Утвердить"
#: model:ir.actions.act_window,name:account_voucher.action_vendor_payment
#: model:ir.ui.menu,name:account_voucher.menu_action_vendor_payment
msgid "Supplier Payments"
-msgstr ""
+msgstr "Оплаты поставщикам"
#. module: account_voucher
#: model:ir.actions.act_window,help:account_voucher.action_purchase_receipt
@@ -167,7 +169,7 @@ msgstr "Искать ваучеры"
#. module: account_voucher
#: field:account.voucher,writeoff_acc_id:0
msgid "Counterpart Account"
-msgstr ""
+msgstr "Корреспондирующий счет"
#. module: account_voucher
#: field:account.voucher,account_id:0
@@ -189,7 +191,7 @@ msgstr "OK"
#. module: account_voucher
#: field:account.voucher.line,reconcile:0
msgid "Full Reconcile"
-msgstr ""
+msgstr "Полная сверка"
#. module: account_voucher
#: field:account.voucher,date_due:0
@@ -207,7 +209,7 @@ msgstr "Примечания"
#. module: account_voucher
#: field:account.voucher,message_ids:0
msgid "Messages"
-msgstr ""
+msgstr "Сообщения"
#. module: account_voucher
#: model:ir.actions.act_window,name:account_voucher.action_purchase_receipt
@@ -225,7 +227,7 @@ msgstr "Элемент журнала"
#: code:addons/account_voucher/account_voucher.py:981
#, python-format
msgid "Error!"
-msgstr ""
+msgstr "Ошибка!"
#. module: account_voucher
#: field:account.voucher.line,amount:0
@@ -235,7 +237,7 @@ msgstr "Суммма"
#. module: account_voucher
#: view:account.voucher:0
msgid "Payment Options"
-msgstr ""
+msgstr "Варианты оплаты"
#. module: account_voucher
#: view:account.voucher:0
@@ -254,6 +256,8 @@ msgstr "Отменено"
msgid ""
"You have to configure account base code and account tax code on the '%s' tax!"
msgstr ""
+"Вы должны настроить код базового счета и код налогового счета для налога "
+"'%s'!"
#. module: account_voucher
#: model:ir.actions.act_window,help:account_voucher.action_sale_receipt
@@ -271,7 +275,7 @@ msgstr ""
#. module: account_voucher
#: help:account.voucher,message_unread:0
msgid "If checked new messages require your attention."
-msgstr ""
+msgstr "Если отмечено, новые сообщения требуют вашего внимания."
#. module: account_voucher
#: model:ir.model,name:account_voucher.model_account_bank_statement_line
@@ -294,12 +298,12 @@ msgstr "Налог"
#: code:addons/account_voucher/account_voucher.py:879
#, python-format
msgid "Invalid Action!"
-msgstr ""
+msgstr "Неверное действие!"
#. module: account_voucher
#: field:account.voucher,comment:0
msgid "Counterpart Comment"
-msgstr ""
+msgstr "Корреспондирующий коментарий"
#. module: account_voucher
#: field:account.voucher.line,account_analytic_id:0
@@ -312,6 +316,8 @@ msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
msgstr ""
+"Содержит сводку по Чаттеру (количество сообщений,...). Эта сводка в формате "
+"html для возможности использования в канбан виде"
#. module: account_voucher
#: view:account.voucher:0
@@ -326,7 +332,7 @@ msgstr "Информация о платеже"
#. module: account_voucher
#: view:account.voucher:0
msgid "(update)"
-msgstr ""
+msgstr "(обновить)"
#. module: account_voucher
#: view:account.voucher:0
@@ -395,7 +401,7 @@ msgstr "Ваучер поставщика"
#. module: account_voucher
#: field:account.voucher,message_follower_ids:0
msgid "Followers"
-msgstr ""
+msgstr "Подписчики"
#. module: account_voucher
#: selection:account.voucher.line,type:0
@@ -406,7 +412,7 @@ msgstr "Дебет"
#: code:addons/account_voucher/account_voucher.py:1547
#, python-format
msgid "Unable to change journal !"
-msgstr ""
+msgstr "Невозможно изменить журнал!"
#. module: account_voucher
#: view:sale.receipt.report:0
@@ -446,7 +452,7 @@ msgstr ""
#. module: account_voucher
#: view:account.voucher:0
msgid "Open Supplier Journal Entries"
-msgstr ""
+msgstr "Открыть журнал проводок по поставщику"
#. module: account_voucher
#: model:ir.actions.act_window,name:account_voucher.action_review_voucher_list
@@ -461,7 +467,7 @@ msgstr "Памятка"
#. module: account_voucher
#: view:account.voucher:0
msgid "Are you sure to unreconcile and cancel this record ?"
-msgstr ""
+msgstr "Вы уверены, что надо отменить сверку и саму запись ?"
#. module: account_voucher
#: field:account.voucher,is_multi_currency:0
@@ -494,13 +500,13 @@ msgstr ""
#. module: account_voucher
#: field:account.voucher,writeoff_amount:0
msgid "Difference Amount"
-msgstr ""
+msgstr "Сумма разницы"
#. module: account_voucher
#: view:sale.receipt.report:0
#: field:sale.receipt.report,due_delay:0
msgid "Avg. Due Delay"
-msgstr ""
+msgstr "Средн. задержка"
#. module: account_voucher
#: code:addons/account_voucher/invoice.py:34
@@ -554,7 +560,7 @@ msgstr "Оплаченная сумма"
#. module: account_voucher
#: field:account.voucher,payment_option:0
msgid "Payment Difference"
-msgstr ""
+msgstr "Оплата разницы"
#. module: account_voucher
#: view:account.voucher:0
@@ -568,7 +574,7 @@ msgstr "Для проверки"
#: code:addons/account_voucher/account_voucher.py:1194
#, python-format
msgid "change"
-msgstr ""
+msgstr "изменить"
#. module: account_voucher
#: code:addons/account_voucher/account_voucher.py:1014
@@ -599,7 +605,7 @@ msgstr ""
#. module: account_voucher
#: view:account.invoice:0
msgid "Register Payment"
-msgstr ""
+msgstr "Регистрация оплаты"
#. module: account_voucher
#: field:account.statement.from.invoice.lines,line_ids:0
@@ -614,7 +620,7 @@ msgstr "декабрём"
#. module: account_voucher
#: view:sale.receipt.report:0
msgid "Group by month of Invoice Date"
-msgstr ""
+msgstr "Группировать по месяцу даты счета"
#. module: account_voucher
#: view:sale.receipt.report:0
@@ -647,7 +653,7 @@ msgstr ""
#. module: account_voucher
#: view:account.voucher:0
msgid "Are you sure to unreconcile this record?"
-msgstr ""
+msgstr "Вы уверены в отмене сверки"
#. module: account_voucher
#: field:account.voucher,company_id:0
@@ -665,13 +671,13 @@ msgstr ""
#. module: account_voucher
#: selection:account.voucher,payment_option:0
msgid "Reconcile Payment Balance"
-msgstr ""
+msgstr "Сверка платежного баланса"
#. module: account_voucher
#: code:addons/account_voucher/account_voucher.py:975
#, python-format
msgid "Configuration Error !"
-msgstr ""
+msgstr "Ошибка конфигурации !"
#. module: account_voucher
#: view:account.voucher:0
@@ -695,18 +701,18 @@ msgstr ""
#: field:account.voucher,state:0
#: view:sale.receipt.report:0
msgid "Status"
-msgstr ""
+msgstr "Статус"
#. module: account_voucher
#: view:account.voucher:0
msgid "Allocation"
-msgstr ""
+msgstr "Распределение"
#. module: account_voucher
#: view:account.statement.from.invoice.lines:0
#: view:account.voucher:0
msgid "or"
-msgstr ""
+msgstr "или"
#. module: account_voucher
#: selection:sale.receipt.report,month:0
@@ -716,7 +722,7 @@ msgstr "Август"
#. module: account_voucher
#: view:account.voucher:0
msgid "Validate Payment"
-msgstr ""
+msgstr "Утвердить оплату"
#. module: account_voucher
#: help:account.voucher,audit:0
@@ -724,6 +730,8 @@ msgid ""
"Check this box if you are unsure of that journal entry and if you want to "
"note it as 'to be reviewed' by an accounting expert."
msgstr ""
+"Отметьте, если вы не уверены в этой проводке журнала и хотите отметить её "
+"\"для проверки\" опытному бухгалтеру."
#. module: account_voucher
#: selection:sale.receipt.report,month:0
@@ -734,7 +742,7 @@ msgstr "Октябрь"
#: code:addons/account_voucher/account_voucher.py:976
#, python-format
msgid "Please activate the sequence of selected journal !"
-msgstr ""
+msgstr "Пожалуйста, включите нумерацию выбранного журнала!"
#. module: account_voucher
#: selection:sale.receipt.report,month:0
@@ -749,7 +757,7 @@ msgstr ""
#. module: account_voucher
#: field:account.voucher,paid:0
msgid "Paid"
-msgstr ""
+msgstr "Оплачено"
#. module: account_voucher
#: model:ir.actions.act_window,name:account_voucher.action_sale_receipt
@@ -760,7 +768,7 @@ msgstr ""
#. module: account_voucher
#: field:account.voucher,message_is_follower:0
msgid "Is a Follower"
-msgstr ""
+msgstr "Подписан"
#. module: account_voucher
#: field:account.voucher,analytic_id:0
@@ -787,7 +795,7 @@ msgstr "Расширенные фильтры..."
#. module: account_voucher
#: field:account.voucher,paid_amount_in_company_currency:0
msgid "Paid Amount in Company Currency"
-msgstr ""
+msgstr "Оплаченная сумма в валюте компании"
#. module: account_voucher
#: field:account.bank.statement.line,amount_reconciled:0
@@ -814,7 +822,7 @@ msgstr "Предыдущие платежи ?"
#: code:addons/account_voucher/account_voucher.py:1112
#, python-format
msgid "The invoice you are willing to pay is not valid anymore."
-msgstr ""
+msgstr "Счет, который вы готовы платить, уже не актуален ."
#. module: account_voucher
#: selection:sale.receipt.report,month:0
@@ -830,30 +838,30 @@ msgstr "Журнал ваучеров"
#. module: account_voucher
#: model:ir.model,name:account_voucher.model_res_company
msgid "Companies"
-msgstr ""
+msgstr "Компании"
#. module: account_voucher
#: field:account.voucher,message_summary:0
msgid "Summary"
-msgstr ""
+msgstr "Итог"
#. module: account_voucher
#: field:account.voucher,active:0
msgid "Active"
-msgstr ""
+msgstr "Активно"
#. module: account_voucher
#: code:addons/account_voucher/account_voucher.py:982
#, python-format
msgid "Please define a sequence on the journal."
-msgstr ""
+msgstr "Пожалуйста, определите нумерацию журнала."
#. module: account_voucher
#: model:ir.actions.act_window,name:account_voucher.act_pay_voucher
#: model:ir.actions.act_window,name:account_voucher.action_vendor_receipt
#: model:ir.ui.menu,name:account_voucher.menu_action_vendor_receipt
msgid "Customer Payments"
-msgstr ""
+msgstr "Платежи клиентов"
#. module: account_voucher
#: model:ir.actions.act_window,name:account_voucher.action_sale_receipt_report_all
@@ -865,7 +873,7 @@ msgstr ""
#. module: account_voucher
#: view:sale.receipt.report:0
msgid "Group by Invoice Date"
-msgstr ""
+msgstr "Группировать по дате счета"
#. module: account_voucher
#: view:account.voucher:0
diff --git a/addons/account_voucher/security/account_voucher_security.xml b/addons/account_voucher/security/account_voucher_security.xml
index 04540fd8aa0..daa5934b256 100644
--- a/addons/account_voucher/security/account_voucher_security.xml
+++ b/addons/account_voucher/security/account_voucher_security.xml
@@ -3,13 +3,13 @@
Voucher multi-company
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]Voucher Line multi-company
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py
index ac298713b04..ce79c4d5ffb 100644
--- a/addons/analytic/analytic.py
+++ b/addons/analytic/analytic.py
@@ -157,7 +157,7 @@ class account_analytic_account(osv.osv):
for account in self.browse(cr, uid, ids, context=context):
if account.company_id:
if account.company_id.currency_id.id != value:
- raise osv.except_osv(_('Error!'), _("If you set a company, the currency selected has to be the same as it's currency. \nYou can remove the company belonging, and thus change the currency, only on analytic account of type 'view'. This can be really usefull for consolidation purposes of several companies charts with different currencies, for example."))
+ raise osv.except_osv(_('Error!'), _("If you set a company, the currency selected has to be the same as it's currency. \nYou can remove the company belonging, and thus change the currency, only on analytic account of type 'view'. This can be really useful for consolidation purposes of several companies charts with different currencies, for example."))
if value:
return cr.execute("""update account_analytic_account set currency_id=%s where id=%s""", (value, account.id, ))
diff --git a/addons/analytic/security/analytic_security.xml b/addons/analytic/security/analytic_security.xml
index 70688275de2..bf103ca8988 100644
--- a/addons/analytic/security/analytic_security.xml
+++ b/addons/analytic/security/analytic_security.xml
@@ -4,14 +4,14 @@
Analytic multi company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]Analytic line multi company rule
-
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
diff --git a/addons/analytic_user_function/analytic_user_function.py b/addons/analytic_user_function/analytic_user_function.py
index 0573292c1f6..1adefb2d59d 100644
--- a/addons/analytic_user_function/analytic_user_function.py
+++ b/addons/analytic_user_function/analytic_user_function.py
@@ -104,7 +104,7 @@ class hr_analytic_timesheet(osv.osv):
a = r.product_id.categ_id.property_account_expense_categ.id
if not a:
raise osv.except_osv(_('Error!'),
- _('There is no expense account define ' \
+ _('There is no expense account defined ' \
'for this product: "%s" (id:%d)') % \
(r.product_id.name, r.product_id.id,))
# Compute based on pricetype
@@ -133,7 +133,7 @@ class hr_analytic_timesheet(osv.osv):
a = r.product_id.categ_id.property_account_expense_categ.id
if not a:
raise osv.except_osv(_('Error!'),
- _('There is no expense account define ' \
+ _('There is no expense account defined ' \
'for this product: "%s" (id:%d)') % \
(r.product_id.name, r.product_id.id,))
# Compute based on pricetype
diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py
index 0477efa5b1f..c82afde103f 100644
--- a/addons/anonymization/anonymization.py
+++ b/addons/anonymization/anonymization.py
@@ -86,11 +86,11 @@ class ir_model_fields_anonymization(osv.osv):
if context.get('manual'):
global_state = self._get_global_state(cr, uid, context=context)
if global_state == 'anonymized':
- raise osv.except_osv('Error !', "The database is currently anonymized, you cannot create, modify or delete fields.")
+ raise osv.except_osv('Error!', "The database is currently anonymized, you cannot create, modify or delete fields.")
elif global_state == 'unstable':
msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \
" while some fields are not anonymized. You should try to solve this problem before trying to create, write or delete fields.")
- raise osv.except_osv('Error !', msg)
+ raise osv.except_osv('Error!', msg)
return True
@@ -357,7 +357,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
else:
msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \
" while some fields are not anonymized. You should try to solve this problem before trying to do anything else.")
- raise osv.except_osv('Error !', msg)
+ raise osv.except_osv('Error!', msg)
res['arch'] = etree.tostring(eview)
@@ -521,11 +521,11 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
# check that all the defined fields are in the 'anonymized' state
state = ir_model_fields_anonymization_model._get_global_state(cr, uid, context=context)
if state == 'clear':
- raise osv.except_osv_('Error !', "The database is not currently anonymized, you cannot reverse the anonymization.")
+ raise osv.except_osv_('Error!', "The database is not currently anonymized, you cannot reverse the anonymization.")
elif state == 'unstable':
msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \
" while some fields are not anonymized. You should try to solve this problem before trying to do anything.")
- raise osv.except_osv('Error !', msg)
+ raise osv.except_osv('Error!', msg)
wizards = self.browse(cr, uid, ids, context=context)
for wizard in wizards:
diff --git a/addons/auth_openid/i18n/ru.po b/addons/auth_openid/i18n/ru.po
index 809589efd37..68b36626056 100644
--- a/addons/auth_openid/i18n/ru.po
+++ b/addons/auth_openid/i18n/ru.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2013-05-27 12:13+0000\n"
+"PO-Revision-Date: 2013-05-28 06:19+0000\n"
"Last-Translator: Глория Хрусталёва \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-05-28 05:17+0000\n"
+"X-Launchpad-Export-Date: 2013-05-29 05:37+0000\n"
"X-Generator: Launchpad (build 16640)\n"
#. module: auth_openid
@@ -46,7 +46,7 @@ msgstr ""
#: code:addons/auth_openid/static/src/xml/auth_openid.xml:10
#, python-format
msgid "Google"
-msgstr ""
+msgstr "Google"
#. module: auth_openid
#. openerp-web
diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py
index f4a985280ac..891837f8813 100644
--- a/addons/auth_signup/res_users.py
+++ b/addons/auth_signup/res_users.py
@@ -23,6 +23,7 @@ import random
from urllib import urlencode
from urlparse import urljoin
+from openerp.addons.base.ir.ir_mail_server import MailDeliveryException
from openerp.osv import osv, fields
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.safe_eval import safe_eval
@@ -55,19 +56,22 @@ class res_partner(osv.Model):
def _get_signup_url_for_action(self, cr, uid, ids, action='login', view_type=None, menu_id=None, res_id=None, model=None, context=None):
""" generate a signup url for the given partner ids and action, possibly overriding
the url state components (menu_id, id, view_type) """
+ if context is None:
+ context= {}
res = dict.fromkeys(ids, False)
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
for partner in self.browse(cr, uid, ids, context):
# when required, make sure the partner has a valid signup token
- if context and context.get('signup_valid') and not partner.user_ids:
+ if context.get('signup_valid') and not partner.user_ids:
self.signup_prepare(cr, uid, [partner.id], context=context)
partner.refresh()
# the parameters to encode for the query and fragment part of url
query = {'db': cr.dbname}
- fragment = {'action': action, 'type': partner.signup_type}
+ signup_type = context.get('signup_force_type_in_url', partner.signup_type or '')
+ fragment = {'action': action, 'type': signup_type}
- if partner.signup_token:
+ if partner.signup_token and signup_type:
fragment['token'] = partner.signup_token
elif partner.user_ids:
fragment['db'] = cr.dbname
@@ -103,6 +107,9 @@ class res_partner(osv.Model):
def action_signup_prepare(self, cr, uid, ids, context=None):
return self.signup_prepare(cr, uid, ids, context=context)
+ def signup_cancel(self, cr, uid, ids, context=None):
+ return self.write(cr, uid, ids, {'signup_token': False, 'signup_type': False, 'signup_expiration': False}, context=context)
+
def signup_prepare(self, cr, uid, ids, signup_type="signup", expiration=False, context=None):
""" generate a new token for the partners with the given validity, if necessary
:param expiration: the expiration datetime of the token (string, optional)
@@ -202,7 +209,7 @@ class res_users(osv.Model):
})
if partner.company_id:
values['company_id'] = partner.company_id.id
- values['company_ids'] = [(6,0,[partner.company_id.id])]
+ values['company_ids'] = [(6, 0, [partner.company_id.id])]
self._signup_create_user(cr, uid, values, context=context)
else:
# no token, sign up an external user
@@ -259,25 +266,26 @@ class res_users(osv.Model):
pass
if not bool(template):
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_signup', 'reset_password_email')
- mail_obj = self.pool.get('mail.mail')
assert template._name == 'email.template'
for user in self.browse(cr, uid, ids, context):
if not user.email:
raise osv.except_osv(_("Cannot send email: user has no email address."), user.name)
- mail_id = self.pool.get('email.template').send_mail(cr, uid, template.id, user.id, True, context=context)
- mail_state = mail_obj.read(cr, uid, mail_id, ['state'], context=context)
-
- if mail_state and mail_state['state'] == 'exception':
- raise self.pool.get('res.config.settings').get_config_warning(cr, _("Cannot send email: no outgoing email server configured.\nYou can configure it under %(menu:base_setup.menu_general_configuration)s."), context)
- else:
- return True
+ try:
+ self.pool.get('email.template').send_mail(cr, uid, template.id, user.id, force_send=True, raise_exception=True, context=context)
+ except Exception:
+ raise
def create(self, cr, uid, values, context=None):
+ if context is None:
+ context = {}
# overridden to automatically invite user to sign up
user_id = super(res_users, self).create(cr, uid, values, context=context)
user = self.browse(cr, uid, user_id, context=context)
- if context and context.get('reset_password') and user.email:
- ctx = dict(context, create_user=True)
- self.action_reset_password(cr, uid, [user.id], context=ctx)
+ if user.email and not context.get('no_reset_password'):
+ context.update({'create_user': True})
+ try:
+ self.action_reset_password(cr, uid, [user.id], context=context)
+ except MailDeliveryException:
+ self.pool.get('res.partner').signup_cancel(cr, uid, [user.partner_id.id], context=context)
return user_id
diff --git a/addons/auth_signup/res_users_view.xml b/addons/auth_signup/res_users_view.xml
index 28f66eb101d..60c419db737 100644
--- a/addons/auth_signup/res_users_view.xml
+++ b/addons/auth_signup/res_users_view.xml
@@ -31,9 +31,11 @@
diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js
index 545ee6cf60e..b825d683099 100644
--- a/addons/auth_signup/static/src/js/auth_signup.js
+++ b/addons/auth_signup/static/src/js/auth_signup.js
@@ -7,7 +7,7 @@ openerp.auth_signup = function(instance) {
var self = this;
this.signup_enabled = false;
this.reset_password_enabled = false;
- return this._super().then(function() {
+ return this._super().always(function() {
// Switches the login box to the select mode whith mode == [default|signup|reset]
self.on('change:login_mode', self, function() {
diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index 9d7d4d34ac4..3497255fa76 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -50,6 +50,7 @@ class base_action_rule(osv.osv):
_name = 'base.action.rule'
_description = 'Action Rules'
+ _order = 'sequence'
_columns = {
'name': fields.char('Rule Name', size=64, required=True),
@@ -61,7 +62,11 @@ class base_action_rule(osv.osv):
help="When unchecked, the rule is hidden and will not be executed."),
'sequence': fields.integer('Sequence',
help="Gives the sequence order when displaying a list of rules."),
+ 'kind': fields.selection(
+ [('on_create', 'On Creation'), ('on_write', 'On Update'), ('on_time', 'Based on Timed Condition')],
+ string='When to Run'),
'trg_date_id': fields.many2one('ir.model.fields', string='Trigger Date',
+ help="When should the condition be triggered. If present, will be checked by the scheduler. If empty, will be checked at creation and update.",
domain="[('model_id', '=', model_id), ('ttype', 'in', ('date', 'datetime'))]"),
'trg_date_range': fields.integer('Delay after trigger date',
help="Delay after the trigger date." \
@@ -78,10 +83,10 @@ class base_action_rule(osv.osv):
ondelete='restrict',
domain="[('model_id', '=', model_id.model)]",
help="If present, this condition must be satisfied before the update of the record."),
- 'filter_id': fields.many2one('ir.filters', string='After Update Filter',
+ 'filter_id': fields.many2one('ir.filters', string='Filter',
ondelete='restrict',
domain="[('model_id', '=', model_id.model)]",
- help="If present, this condition must be satisfied after the update of the record."),
+ help="If present, this condition must be satisfied before executing the action rule."),
'last_run': fields.datetime('Last Run', readonly=1),
}
@@ -90,7 +95,15 @@ class base_action_rule(osv.osv):
'trg_date_range_type': 'day',
}
- _order = 'sequence'
+ def onchange_kind(self, cr, uid, ids, kind, context=None):
+ clear_fields = []
+ if kind == 'on_create':
+ clear_fields = ['filter_pre_id', 'trg_date_id', 'trg_date_range', 'trg_date_range_type']
+ elif kind == 'on_write':
+ clear_fields = ['trg_date_id', 'trg_date_range', 'trg_date_range_type']
+ elif kind == 'on_time':
+ clear_fields = ['filter_pre_id']
+ return {'value': dict.fromkeys(clear_fields, False)}
def _filter(self, cr, uid, action, action_filter, record_ids, context=None):
""" filter the list record_ids that satisfy the action filter """
@@ -105,14 +118,7 @@ class base_action_rule(osv.osv):
def _process(self, cr, uid, action, record_ids, context=None):
""" process the given action on the records """
- # execute server actions
model = self.pool[action.model_id.model]
- if action.server_action_ids:
- server_action_ids = map(int, action.server_action_ids)
- for record in model.browse(cr, uid, record_ids, context):
- action_server_obj = self.pool.get('ir.actions.server')
- ctx = dict(context, active_model=model._name, active_ids=[record.id], active_id=record.id)
- action_server_obj.run(cr, uid, server_action_ids, context=ctx)
# modify records
values = {}
@@ -127,13 +133,21 @@ class base_action_rule(osv.osv):
follower_ids = map(int, action.act_followers)
model.message_subscribe(cr, uid, record_ids, follower_ids, context=context)
+ # execute server actions
+ if action.server_action_ids:
+ server_action_ids = map(int, action.server_action_ids)
+ for record in model.browse(cr, uid, record_ids, context):
+ action_server_obj = self.pool.get('ir.actions.server')
+ ctx = dict(context, active_model=model._name, active_ids=[record.id], active_id=record.id)
+ action_server_obj.run(cr, uid, server_action_ids, context=ctx)
+
return True
def _wrap_create(self, old_create, model):
""" Return a wrapper around `old_create` calling both `old_create` and
`_process`, in that order.
"""
- def wrapper(cr, uid, vals, context=None):
+ def create(cr, uid, vals, context=None):
# avoid loops or cascading actions
if context and context.get('action'):
return old_create(cr, uid, vals, context=context)
@@ -141,8 +155,8 @@ class base_action_rule(osv.osv):
context = dict(context or {}, action=True)
new_id = old_create(cr, uid, vals, context=context)
- # as it is a new record, we do not consider the actions that have a prefilter
- action_dom = [('model', '=', model), ('trg_date_id', '=', False), ('filter_pre_id', '=', False)]
+ # retrieve the action rules to run on creation
+ action_dom = [('model', '=', model), ('kind', '=', 'on_create')]
action_ids = self.search(cr, uid, action_dom, context=context)
# check postconditions, and execute actions on the records that satisfy them
@@ -151,13 +165,13 @@ class base_action_rule(osv.osv):
self._process(cr, uid, action, [new_id], context=context)
return new_id
- return wrapper
+ return create
def _wrap_write(self, old_write, model):
""" Return a wrapper around `old_write` calling both `old_write` and
`_process`, in that order.
"""
- def wrapper(cr, uid, ids, vals, context=None):
+ def write(cr, uid, ids, vals, context=None):
# avoid loops or cascading actions
if context and context.get('action'):
return old_write(cr, uid, ids, vals, context=context)
@@ -165,8 +179,8 @@ class base_action_rule(osv.osv):
context = dict(context or {}, action=True)
ids = [ids] if isinstance(ids, (int, long, str)) else ids
- # retrieve the action rules to possibly execute
- action_dom = [('model', '=', model), ('trg_date_id', '=', False)]
+ # retrieve the action rules to run on update
+ action_dom = [('model', '=', model), ('kind', '=', 'on_write')]
action_ids = self.search(cr, uid, action_dom, context=context)
actions = self.browse(cr, uid, action_ids, context=context)
@@ -185,7 +199,7 @@ class base_action_rule(osv.osv):
self._process(cr, uid, action, post_ids, context=context)
return True
- return wrapper
+ return write
def _register_hook(self, cr, ids=None):
""" Wrap the methods `create` and `write` of the models specified by
@@ -224,8 +238,8 @@ class base_action_rule(osv.osv):
def _check(self, cr, uid, automatic=False, use_new_cursor=False, context=None):
""" This Function is called by scheduler. """
context = context or {}
- # retrieve all the action rules that have a trg_date_id and no precondition
- action_dom = [('trg_date_id', '!=', False), ('filter_pre_id', '=', False)]
+ # retrieve all the action rules to run based on a timed condition
+ action_dom = [('kind', '=', 'on_time')]
action_ids = self.search(cr, uid, action_dom, context=context)
for action in self.browse(cr, uid, action_ids, context=context):
now = datetime.now()
diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml
index 5eaaf08dad4..c2262adde39 100644
--- a/addons/base_action_rule/base_action_rule_view.xml
+++ b/addons/base_action_rule/base_action_rule_view.xml
@@ -26,24 +26,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
- Select a filter or a timer as condition. An action rule is checked when you create or modify the "Related Document Model". The precondition filter is checked right before the modification while the postcondition filter is checked after the modification. A precondition filter will therefore not work during a creation.
- To create a new filter:
- - Go to your "Related Document Model" page and set the filter parameters in the "Search" view (Example of filter based on Leads/Opportunities: Creation Date "is equal to" 01/01/2012)
- - In this same "Search" view, select the menu "Save Current Filter", enter the name (Ex: Create the 01/01/2012) and add the option "Share with all users"
+
+ Select when the action must be run, and add filters and/or timing conditions.
+
+ In order to create a new filter:
+
+
Go to your "Related Document Model" page and set the filter parameters in the "Search" view (Example of filter based on Leads/Opportunities: Creation Date "is equal to" 01/01/2012)
+
In this same "Search" view, select the menu "Save Current Filter", enter the name (Ex: Create the 01/01/2012) and add the option "Share with all users"
+
The filter must therefore be available in this page.
@@ -76,6 +84,7 @@
+
diff --git a/addons/base_action_rule/i18n/ru.po b/addons/base_action_rule/i18n/ru.po
index c8673c26815..3ca5b1eab04 100644
--- a/addons/base_action_rule/i18n/ru.po
+++ b/addons/base_action_rule/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-05-10 18:17+0000\n"
-"Last-Translator: Raphael Collet (OpenERP) \n"
+"PO-Revision-Date: 2013-05-31 10:23+0000\n"
+"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:46+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-01 05:16+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: base_action_rule
#: selection:base.action.rule.lead.test,state:0
@@ -58,7 +58,7 @@ msgstr "Добавить подписчиков"
#. module: base_action_rule
#: field:base.action.rule,act_user_id:0
msgid "Set Responsible"
-msgstr ""
+msgstr "Указать ответственного"
#. module: base_action_rule
#: help:base.action.rule,trg_date_range:0
@@ -71,7 +71,7 @@ msgstr ""
#. module: base_action_rule
#: model:ir.model,name:base_action_rule.model_base_action_rule_lead_test
msgid "base.action.rule.lead.test"
-msgstr ""
+msgstr "base.action.rule.lead.test"
#. module: base_action_rule
#: selection:base.action.rule.lead.test,state:0
@@ -142,7 +142,7 @@ msgstr "Часы"
#. module: base_action_rule
#: view:base.action.rule:0
msgid "To create a new filter:"
-msgstr ""
+msgstr "Для создания нового фильтра:"
#. module: base_action_rule
#: field:base.action.rule,active:0
@@ -167,7 +167,7 @@ msgstr ""
#. module: base_action_rule
#: view:base.action.rule:0
msgid "Filter Condition"
-msgstr ""
+msgstr "Условие фильтра"
#. module: base_action_rule
#: view:base.action.rule:0
@@ -216,7 +216,7 @@ msgstr "Тип задержки"
#. module: base_action_rule
#: view:base.action.rule:0
msgid "Server actions to run"
-msgstr ""
+msgstr "Действия сервера для запуска"
#. module: base_action_rule
#: help:base.action.rule,active:0
@@ -246,7 +246,7 @@ msgstr "Минуты"
#. module: base_action_rule
#: field:base.action.rule,model_id:0
msgid "Related Document Model"
-msgstr ""
+msgstr "Модель связанного документа"
#. module: base_action_rule
#: help:base.action.rule,filter_pre_id:0
@@ -310,7 +310,7 @@ msgstr "Действия сервера"
#. module: base_action_rule
#: field:base.action.rule.lead.test,name:0
msgid "Subject"
-msgstr ""
+msgstr "Тема"
#~ msgid "Set State to"
#~ msgstr "Уснатовить состояние в"
diff --git a/addons/base_action_rule/tests/base_action_rule_test.py b/addons/base_action_rule/tests/base_action_rule_test.py
index 36c928a84e3..54c72ba0607 100644
--- a/addons/base_action_rule/tests/base_action_rule_test.py
+++ b/addons/base_action_rule/tests/base_action_rule_test.py
@@ -19,8 +19,8 @@ class base_action_rule_test(common.TransactionCase):
'name': "Lead is in done state",
'is_default': False,
'model_id': 'base.action.rule.lead.test',
- 'domain' : "[('state','=','done')]",
- }, context=context)
+ 'domain': "[('state','=','done')]",
+ }, context=context)
def create_filter_draft(self, cr, uid, context=None):
filter_pool = self.registry('ir.filters')
@@ -40,16 +40,16 @@ class base_action_rule_test(common.TransactionCase):
'user_id': self.admin,
}, context=context)
- def create_rule(self, cr, uid, filter_id=False, filter_pre_id=False, context=None):
+ def create_rule(self, cr, uid, kind, filter_id=False, filter_pre_id=False, context=None):
"""
The "Rule 1" says that when a lead goes to the 'draft' state, the responsible for that lead changes to user "demo"
"""
return self.base_action_rule.create(cr,uid,{
- 'name' : "Rule 1",
+ 'name': "Rule 1",
'model_id': self.registry('ir.model').search(cr, uid, [('model','=','base.action.rule.lead.test')], context=context)[0],
- 'active' : 1,
- 'filter_pre_id' : filter_pre_id,
- 'filter_id' : filter_id,
+ 'kind': kind,
+ 'filter_pre_id': filter_pre_id,
+ 'filter_id': filter_id,
'act_user_id': self.demo,
}, context=context)
@@ -64,7 +64,7 @@ class base_action_rule_test(common.TransactionCase):
"""
cr, uid = self.cr, self.uid
filter_draft = self.create_filter_draft(cr, uid)
- self.create_rule(cr, uid, filter_pre_id=filter_draft)
+ self.create_rule(cr, uid, 'on_write', filter_pre_id=filter_draft)
new_lead_id = self.create_lead_test_1(cr, uid)
new_lead = self.model.browse(cr, uid, new_lead_id)
self.assertEquals(new_lead.state, 'draft')
@@ -73,11 +73,11 @@ class base_action_rule_test(common.TransactionCase):
def test_01_check_to_state_draft_post(self):
"""
- Check that a new record (with state = draft) changes its responsible when there is a postcondition filter which check that the state is draft.
+ Check that a new record changes its responsible when there is a postcondition filter which check that the state is draft.
"""
cr, uid = self.cr, self.uid
filter_draft = self.create_filter_draft(cr, uid)
- self.create_rule(cr, uid, filter_id=filter_draft)
+ self.create_rule(cr, uid, 'on_create')
new_lead_id = self.create_lead_test_1(cr, uid)
new_lead = self.model.browse(cr, uid, new_lead_id)
self.assertEquals(new_lead.state, 'draft')
@@ -95,7 +95,7 @@ class base_action_rule_test(common.TransactionCase):
cr, uid = self.cr, self.uid
filter_draft = self.create_filter_draft(cr, uid)
filter_done = self.create_filter_done(cr, uid)
- self.create_rule(cr, uid, filter_pre_id=filter_draft, filter_id=filter_done)
+ self.create_rule(cr, uid, 'on_write', filter_pre_id=filter_draft, filter_id=filter_done)
new_lead_id = self.create_lead_test_1(cr, uid)
new_lead = self.model.browse(cr, uid, new_lead_id)
self.assertEquals(new_lead.state, 'draft')
@@ -133,7 +133,7 @@ class base_action_rule_test(common.TransactionCase):
cr, uid = self.cr, self.uid
filter_draft = self.create_filter_draft(cr, uid)
filter_done = self.create_filter_done(cr, uid)
- self.create_rule(cr, uid, filter_pre_id=filter_draft, filter_id=filter_done)
+ self.create_rule(cr, uid, 'on_write', filter_pre_id=filter_draft, filter_id=filter_done)
new_lead_id = self.create_lead_test_1(cr, uid)
new_lead = self.model.browse(cr, uid, new_lead_id)
self.assertEquals(new_lead.state, 'draft')
diff --git a/addons/base_status/base_state.py b/addons/base_status/base_state.py
index b856bbd74ad..3fe59ecbd21 100644
--- a/addons/base_status/base_state.py
+++ b/addons/base_status/base_state.py
@@ -104,7 +104,7 @@ class base_state(object):
if parent_id.change_responsible and parent_id.user_id:
data['user_id'] = parent_id.user_id.id
else:
- raise osv.except_osv(_('Error !'), _('You can not escalate, you are already at the top level regarding your sales-team category.'))
+ raise osv.except_osv(_('Error!'), _('You can not escalate, you are already at the top level regarding your sales-team category.'))
self.write(cr, uid, [case.id], data, context=context)
case.case_escalate_send_note(parent_id, context=context)
return True
diff --git a/addons/base_status/i18n/ru.po b/addons/base_status/i18n/ru.po
index 546f2772af3..2dab7ceaf31 100644
--- a/addons/base_status/i18n/ru.po
+++ b/addons/base_status/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-12-28 10:04+0000\n"
+"PO-Revision-Date: 2013-06-05 07:16+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:52+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-06 05:21+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
#. module: base_status
#: code:addons/base_status/base_state.py:107
@@ -27,13 +27,13 @@ msgstr "Ошибка !"
#: code:addons/base_status/base_state.py:166
#, python-format
msgid "%s has been opened."
-msgstr ""
+msgstr "%s было открыто."
#. module: base_status
#: code:addons/base_status/base_state.py:199
#, python-format
msgid "%s has been renewed."
-msgstr ""
+msgstr "%s было обновлено."
#. module: base_status
#: code:addons/base_status/base_stage.py:210
@@ -55,13 +55,13 @@ msgstr ""
#: code:addons/base_status/base_state.py:193
#, python-format
msgid "%s is now pending."
-msgstr ""
+msgstr "%s сейчас в ожидании."
#. module: base_status
#: code:addons/base_status/base_state.py:187
#, python-format
msgid "%s has been canceled."
-msgstr ""
+msgstr "%s было отменено."
#. module: base_status
#: code:addons/base_status/base_stage.py:210
@@ -70,9 +70,11 @@ msgid ""
"You are already at the top level of your sales-team category.\n"
"Therefore you cannot escalate furthermore."
msgstr ""
+"Вы уже на высшем уровне категории вашей команды продаж.\n"
+"Поэтому вы не можете обострить."
#. module: base_status
#: code:addons/base_status/base_state.py:181
#, python-format
msgid "%s has been closed."
-msgstr ""
+msgstr "%s было закрыто."
diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py
index e7501334997..52db18b7307 100644
--- a/addons/base_vat/base_vat.py
+++ b/addons/base_vat/base_vat.py
@@ -83,6 +83,8 @@ class res_partner(osv.osv):
Check the VAT number depending of the country.
http://sima-pc.com/nif.php
'''
+ if not ustr(country_code).encode('utf-8').isalpha():
+ return False
check_func_name = 'check_vat_' + country_code
check_func = getattr(self, check_func_name, None) or \
getattr(vatnumber, check_func_name, None)
diff --git a/addons/claim_from_delivery/i18n/ru.po b/addons/claim_from_delivery/i18n/ru.po
index 8d97086c22a..ffcf8fc2781 100644
--- a/addons/claim_from_delivery/i18n/ru.po
+++ b/addons/claim_from_delivery/i18n/ru.po
@@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2013-05-27 12:19+0000\n"
+"PO-Revision-Date: 2013-06-05 07:11+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-05-28 05:17+0000\n"
-"X-Generator: Launchpad (build 16640)\n"
+"X-Launchpad-Export-Date: 2013-06-06 05:21+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
#. module: claim_from_delivery
#: view:stock.picking.out:0
msgid "Claims"
-msgstr ""
+msgstr "Рекламации"
#. module: claim_from_delivery
#: model:res.request.link,name:claim_from_delivery.request_link_claim_from_delivery
@@ -30,7 +30,7 @@ msgstr "Заказ доставки"
#. module: claim_from_delivery
#: model:ir.actions.act_window,name:claim_from_delivery.action_claim_from_delivery
msgid "Claim From Delivery"
-msgstr ""
+msgstr "Рекламация по доставке"
#~ msgid "Claim from delivery"
#~ msgstr "Претензия из доставки"
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index 8e17a882076..e7ab7df27ea 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -81,8 +81,6 @@ Dashboard for CRM will include:
'crm_lead_view.xml',
'crm_lead_menu.xml',
- 'crm_case_section_view.xml',
-
'crm_meeting_menu.xml',
'crm_phonecall_view.xml',
@@ -98,6 +96,8 @@ Dashboard for CRM will include:
'res_config_view.xml',
'base_partner_merge_view.xml',
+
+ 'crm_case_section_view.xml',
],
'demo': [
'crm_demo.xml',
@@ -121,7 +121,8 @@ Dashboard for CRM will include:
'static/src/css/crm.css'
],
'js': [
- 'static/src/js/crm.js'
+ 'static/lib/sparkline/jquery.sparkline.js',
+ 'static/src/js/crm_case_section.js',
],
'installable': True,
'application': True,
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index b2645e7fb79..42e1ab7c7ec 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -13,6 +13,7 @@ from openerp.tools import mute_logger
# Validation Library https://pypi.python.org/pypi/validate_email/1.1
from .validate_email import validate_email
+import openerp
from openerp.osv import osv, orm
from openerp.osv import fields
from openerp.osv.orm import browse_record
@@ -101,14 +102,26 @@ class MergePartnerAutomatic(osv.TransientModel):
'current_line_id': fields.many2one('base.partner.merge.line', 'Current Line'),
'line_ids': fields.one2many('base.partner.merge.line', 'wizard_id', 'Lines'),
'partner_ids': fields.many2many('res.partner', string='Contacts'),
+ 'dst_partner_id': fields.many2one('res.partner', string='Destination Contact'),
'exclude_contact': fields.boolean('A user associated to the contact'),
'exclude_journal_item': fields.boolean('Journal Items associated to the contact'),
'maximum_group': fields.integer("Maximum of Group of Contacts"),
}
+ def default_get(self, cr, uid, fields, context=None):
+ if context is None:
+ context = {}
+ res = super(MergePartnerAutomatic, self).default_get(cr, uid, fields, context)
+ if context.get('active_model') == 'res.partner' and context.get('active_ids'):
+ partner_ids = context['active_ids']
+ res['state'] = 'selection'
+ res['partner_ids'] = partner_ids
+ res['dst_partner_id'] = self._get_ordered_partner(cr, uid, partner_ids, context=context)[-1].id
+ return res
+
_defaults = {
- 'state': 'option',
+ 'state': 'option'
}
def get_fk_on(self, cr, table):
@@ -204,8 +217,8 @@ class MergePartnerAutomatic(osv.TransientModel):
if proxy is None:
return
domain = [(field_model, '=', 'res.partner'), (field_id, '=', src.id)]
- ids = proxy.search(cr, uid, domain, context=context)
- return proxy.write(cr, uid, ids, {field_id: dst_partner.id}, context=context)
+ ids = proxy.search(cr, openerp.SUPERUSER_ID, domain, context=context)
+ return proxy.write(cr, openerp.SUPERUSER_ID, ids, {field_id: dst_partner.id}, context=context)
update_records = functools.partial(update_records, context=context)
@@ -219,9 +232,9 @@ class MergePartnerAutomatic(osv.TransientModel):
proxy = self.pool['ir.model.fields']
domain = [('ttype', '=', 'reference')]
- record_ids = proxy.search(cr, uid, domain, context=context)
+ record_ids = proxy.search(cr, openerp.SUPERUSER_ID, domain, context=context)
- for record in proxy.browse(cr, uid, record_ids, context=context):
+ for record in proxy.browse(cr, openerp.SUPERUSER_ID, record_ids, context=context):
proxy_model = self.pool[record.model]
field_type = proxy_model._columns.get(record.name).__class__._type
@@ -233,11 +246,11 @@ class MergePartnerAutomatic(osv.TransientModel):
domain = [
(record.name, '=', 'res.partner,%d' % partner.id)
]
- model_ids = proxy_model.search(cr, uid, domain, context=context)
+ model_ids = proxy_model.search(cr, openerp.SUPERUSER_ID, domain, context=context)
values = {
record.name: 'res.partner,%d' % dst_partner.id,
}
- proxy_model.write(cr, uid, model_ids, values, context=context)
+ proxy_model.write(cr, openerp.SUPERUSER_ID, model_ids, values, context=context)
def _update_values(self, cr, uid, src_partners, dst_partner, context=None):
_logger.debug('_update_values for dst_partner: %s for src_partners: %r', dst_partner.id, list(map(operator.attrgetter('id'), src_partners)))
@@ -251,7 +264,7 @@ class MergePartnerAutomatic(osv.TransientModel):
values = dict()
for column, field in columns.iteritems():
- if field._type not in ('many2many', 'one2many', 'function'):
+ if field._type not in ('many2many', 'one2many') and not isinstance(field, fields.function):
for item in itertools.chain(src_partners, [dst_partner]):
if item[column]:
values[column] = write_serializer(column, item[column])
@@ -266,22 +279,31 @@ class MergePartnerAutomatic(osv.TransientModel):
_logger.info('Skip recursive partner hierarchies for parent_id %s of partner: %s', parent_id, dst_partner.id)
@mute_logger('openerp.osv.expression', 'openerp.osv.orm')
- def _merge(self, cr, uid, partner_ids, context=None):
+ def _merge(self, cr, uid, partner_ids, dst_partner=None, context=None):
proxy = self.pool.get('res.partner')
partner_ids = proxy.exists(cr, uid, list(partner_ids), context=context)
if len(partner_ids) < 2:
return
- partners = proxy.browse(cr, uid, list(partner_ids), context=context)
- ordered_partners = sorted(sorted(partners,
- key=operator.attrgetter('create_date'), reverse=True),
- key=operator.attrgetter('active'), reverse=True)
+ if len(partner_ids) > 3:
+ raise osv.except_osv(_('Error'), _("For safety reasons, you cannot merge more than 3 contacts together. You can re-open the wizard several times if needed."))
- dst_partner = ordered_partners[-1]
- src_partners = ordered_partners[:-1]
+ if openerp.SUPERUSER_ID != uid and len(set(partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context))) > 1:
+ raise osv.except_osv(_('Error'), _("All contacts must have the same email. Only the Administrator can merge contacts with different emails."))
+
+ if dst_partner and dst_partner.id in partner_ids:
+ src_partners = proxy.browse(cr, uid, [id for id in partner_ids if id != dst_partner.id], context=context)
+ else:
+ ordered_partners = self._get_ordered_partner(cr, uid, partner_ids, context)
+ dst_partner = ordered_partners[-1]
+ src_partners = ordered_partners[:-1]
_logger.info("dst_partner: %s", dst_partner.id)
+ if openerp.SUPERUSER_ID != uid and self._model_is_installed(cr, uid, 'account.move.line', context=context) and \
+ self.pool.get('account.move.line').search(cr, openerp.SUPERUSER_ID, [('partner_id', 'in', [partner.id for partner in src_partners])], context=context):
+ raise osv.except_osv(_('Error'), _("Only the destination contact may be linked to existing Journal Items. Please ask the Administrator if you need to merge several contacts linked to existing Journal Items."))
+
call_it = lambda function: function(cr, uid, src_partners, dst_partner,
context=context)
@@ -289,12 +311,12 @@ class MergePartnerAutomatic(osv.TransientModel):
call_it(self._update_reference_fields)
call_it(self._update_values)
- _logger.info("---merged---")
-
+ _logger.info('(uid = %s) merged the partners %r with %s', uid, list(map(operator.attrgetter('id'), src_partners)), dst_partner.id)
+ dst_partner.message_post(body='%s %s'%(_("Merged with the following partners:"), ", ".join('%s<%s>(ID %s)' % (p.name, p.email or 'n/a', p.id) for p in src_partners)))
+
for partner in src_partners:
partner.unlink()
-
def clean_emails(self, cr, uid, context=None):
"""
Clean the email address of the partner, if there is an email field with
@@ -414,9 +436,16 @@ class MergePartnerAutomatic(osv.TransientModel):
this = self.browse(cr, uid, ids[0], context=context)
if this.current_line_id:
this.current_line_id.unlink()
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this, context)
- def _next_screen(self, this):
+ def _get_ordered_partner(self, cr, uid, partner_ids, context=None):
+ partners = self.pool.get('res.partner').browse(cr, uid, list(partner_ids), context=context)
+ ordered_partners = sorted(sorted(partners,
+ key=operator.attrgetter('create_date'), reverse=True),
+ key=operator.attrgetter('active'), reverse=True)
+ return ordered_partners
+
+ def _next_screen(self, cr, uid, this, context=None):
this.refresh()
values = {}
if this.line_ids:
@@ -426,6 +455,7 @@ class MergePartnerAutomatic(osv.TransientModel):
values.update({
'current_line_id': current_line.id,
'partner_ids': [(6, 0, current_partner_ids)],
+ 'dst_partner_id': self._get_ordered_partner(cr, uid, current_partner_ids, context)[-1].id,
'state': 'selection',
})
else:
@@ -525,7 +555,7 @@ class MergePartnerAutomatic(osv.TransientModel):
query = self._generate_query(groups, this.maximum_group)
self._process_query(cr, uid, ids, query, context=context)
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this, context)
def automatic_process_cb(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -666,7 +696,7 @@ class MergePartnerAutomatic(osv.TransientModel):
# p1.parent_id = p1.id
# """)
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this, context)
def merge_cb(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -685,33 +715,12 @@ class MergePartnerAutomatic(osv.TransientModel):
'target': 'new',
}
- self._merge(cr, uid, partner_ids, context=context)
+ self._merge(cr, uid, partner_ids, this.dst_partner_id, context=context)
- this.current_line_id.unlink()
+ if this.current_line_id:
+ this.current_line_id.unlink()
- return self._next_screen(this)
-
- def merge_multi(self, cr, uid, ids, context=None):
-
- active_model = context.get('active_model')
- if active_model != 'res.partner':
- raise osv.except_osv(
- _('Error'),
- _('This wizard can only used with the Partners')
- )
-
- partner_ids = context.get('active_ids', [])
-
- MINIMAL_NUMBER = 2
- if len(partner_ids) < MINIMAL_NUMBER:
- raise osv.except_osv(
- _('Error'),
- _("You can't use this wizard with only one Partner")
- )
-
- self._merge(cr, uid, partner_ids, context=context)
-
- return True
+ return self._next_screen(cr, uid, this, context)
def auto_set_parent_id(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
diff --git a/addons/crm/base_partner_merge_view.xml b/addons/crm/base_partner_merge_view.xml
index 74e7a72d7a8..8ce0b5fd99f 100644
--- a/addons/crm/base_partner_merge_view.xml
+++ b/addons/crm/base_partner_merge_view.xml
@@ -68,9 +68,9 @@
OpenERP will propose you to merge only those having
all these fields in common. (not one of the fields).
-
+
-
+
@@ -98,15 +98,15 @@
redirected to the aggregated contact. You can remove
contacts from this list to avoid merging them.
+
-
+
-
@@ -114,24 +114,9 @@
-
-
- pool.get('base.partner.merge.automatic.wizard').merge_multi(cr, uid, None, context)
- True
-
- Automatic Merge
-
- code
- ir.actions.server
-
-
-
-
- res.partner
- Automatic Merge
-
-
+
+
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 7b6fe02afa8..4c9a60634a5 100644
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -19,13 +19,12 @@
#
##############################################################################
-import base64
-import time
-from lxml import etree
+from datetime import date, datetime
+from dateutil import relativedelta
+
+from openerp import tools
from openerp.osv import fields
from openerp.osv import osv
-from openerp import tools
-from openerp.tools.translate import _
MAX_LEVEL = 15
AVAILABLE_STATES = [
@@ -106,10 +105,57 @@ class crm_case_section(osv.osv):
_inherit = "mail.thread"
_description = "Sales Teams"
_order = "complete_name"
+ # number of periods for lead/opportunities/... tracking in salesteam kanban dashboard/kanban view
+ _period_number = 5
def get_full_name(self, cr, uid, ids, field_name, arg, context=None):
return dict(self.name_get(cr, uid, ids, context=context))
+ def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, context=None):
+ """ Generic method to generate data for bar chart values using SparklineBarWidget.
+ This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field).
+
+ :param obj: the target model (i.e. crm_lead)
+ :param domain: the domain applied to the read_group
+ :param list read_fields: the list of fields to read in the read_group
+ :param str value_field: the field used to compute the value of the bar slice
+ :param str groupby_field: the fields used to group
+
+ :return list section_result: a list of dicts: [
+ { 'value': (int) bar_column_value,
+ 'tootip': (str) bar_column_tooltip,
+ }
+ ]
+ """
+ month_begin = date.today().replace(day=1)
+ section_result = [{
+ 'value': 0,
+ 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B'),
+ } for i in range(self._period_number - 1, -1, -1)]
+ group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context)
+ for group in group_obj:
+ group_begin_date = datetime.strptime(group['__domain'][0][2], tools.DEFAULT_SERVER_DATE_FORMAT)
+ month_delta = relativedelta.relativedelta(month_begin, group_begin_date)
+ section_result[self._period_number - (month_delta.months + 1)] = {'value': group.get(value_field, 0), 'tooltip': group_begin_date.strftime('%B')}
+ return section_result
+
+ def _get_opportunities_data(self, cr, uid, ids, field_name, arg, context=None):
+ """ Get opportunities-related data for salesteam kanban view
+ monthly_open_leads: number of open lead during the last months
+ monthly_planned_revenue: planned revenu of opportunities during the last months
+ """
+ obj = self.pool.get('crm.lead')
+ res = dict.fromkeys(ids, False)
+ month_begin = date.today().replace(day=1)
+ groupby_begin = (month_begin + relativedelta.relativedelta(months=-4)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
+ for id in ids:
+ res[id] = dict()
+ lead_domain = [('type', '=', 'lead'), ('section_id', '=', id), ('create_date', '>=', groupby_begin)]
+ res[id]['monthly_open_leads'] = self.__get_bar_values(cr, uid, obj, lead_domain, ['create_date'], 'create_date_count', 'create_date', context=context)
+ opp_domain = [('type', '=', 'opportunity'), ('section_id', '=', id), ('create_date', '>=', groupby_begin)]
+ res[id]['monthly_planned_revenue'] = self.__get_bar_values(cr, uid, obj, opp_domain, ['planned_revenue', 'create_date'], 'planned_revenue', 'create_date', context=context)
+ return res
+
_columns = {
'name': fields.char('Sales Team', size=64, required=True, translate=True),
'complete_name': fields.function(get_full_name, type='char', size=256, readonly=True, store=True),
@@ -129,15 +175,16 @@ class crm_case_section(osv.osv):
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
help="The email address associated with this team. New emails received will automatically "
"create new leads assigned to the team."),
- 'open_lead_ids': fields.one2many('crm.lead', 'section_id',
- string='Open Leads', readonly=True,
- domain=['&', ('type', '!=', 'opportunity'), ('state', 'not in', ['done', 'cancel'])]),
- 'open_opportunity_ids': fields.one2many('crm.lead', 'section_id',
- string='Open Opportunities', readonly=True,
- domain=['&', '|', ('type', '=', 'opportunity'), ('type', '=', 'both'), ('state', 'not in', ['done', 'cancel'])]),
'color': fields.integer('Color Index'),
'use_leads': fields.boolean('Leads',
- help="This enables the management of leads in the sales team. Otherwise the sales team manages only opportunities."),
+ help="The first contact you get with a potential customer is a lead you qualify before converting it into a real business opportunity. Check this box to manage leads in this sales team."),
+
+ 'monthly_open_leads': fields.function(_get_opportunities_data,
+ type="string", readonly=True, multi='_get_opportunities_data',
+ string='Open Leads per Month'),
+ 'monthly_planned_revenue': fields.function(_get_opportunities_data,
+ type="string", readonly=True, multi='_get_opportunities_data',
+ string='Planned Revenue per Month')
}
def _get_stage_common(self, cr, uid, context):
diff --git a/addons/crm/crm_action_rule_demo.xml b/addons/crm/crm_action_rule_demo.xml
index bf1f7d4082f..7204f666db5 100644
--- a/addons/crm/crm_action_rule_demo.xml
+++ b/addons/crm/crm_action_rule_demo.xml
@@ -26,6 +26,7 @@ Description: [[object.description]]
Set Auto Reminder on leads which are not open since 5 days.1
+ on_time5
@@ -54,12 +55,10 @@ object.write({'section_id': sales_team.id})
Set Auto Followers on leads which are urgent and come from USA.2
+ on_create
-
-
- 0
- minutes
+
diff --git a/addons/crm/crm_case_section_view.xml b/addons/crm/crm_case_section_view.xml
index 703b4ebb254..be5611c03c4 100644
--- a/addons/crm/crm_case_section_view.xml
+++ b/addons/crm/crm_case_section_view.xml
@@ -78,12 +78,12 @@
-
-
+
+
-
- Sales
- Sales
+ Direct Sales
+ DMTrue
+ info
diff --git a/addons/crm/crm_demo.xml b/addons/crm/crm_demo.xml
index 203193dc3bc..2858250e86a 100644
--- a/addons/crm/crm_demo.xml
+++ b/addons/crm/crm_demo.xml
@@ -7,27 +7,13 @@
- Sales Marketing Department
- SMD
-
+ Indirect Sales
+ IM
- Support Department
+ MarketingSPD
-
-
-
-
- Direct Marketing
- DM
-
-
-
-
- Online Support
- OS
-
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 40f71ad5d79..b8673e73927 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -77,12 +77,12 @@ class crm_lead(base_stage, format_address, osv.osv):
_track = {
'state': {
- 'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'new',
+ 'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj['state'] in ['new', 'draft'],
'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'cancel',
},
'stage_id': {
- 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['new', 'cancel', 'done'],
+ 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['new', 'draft', 'cancel', 'done'],
},
}
@@ -103,7 +103,9 @@ class crm_lead(base_stage, format_address, osv.osv):
if vals.get('type'):
ctx['default_type'] = vals['type']
vals['stage_id'] = self._get_default_stage_id(cr, uid, context=ctx)
- return super(crm_lead, self).create(cr, uid, vals, context=context)
+ # context: no_log, because subtype already handle this
+ create_context = dict(context, mail_create_nolog=True)
+ return super(crm_lead, self).create(cr, uid, vals, context=create_context)
def _get_default_section_id(self, cr, uid, context=None):
""" Gives default section by checking if present in the context """
@@ -367,8 +369,8 @@ class crm_lead(base_stage, format_address, osv.osv):
def on_change_user(self, cr, uid, ids, user_id, context=None):
""" When changing the user, also set a section_id or restrict section id
to the ones user_id is member of. """
- section_id = False
- if user_id:
+ section_id = self._get_default_section_id(cr, uid, context=context) or False
+ if user_id and not section_id:
section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
if section_ids:
section_id = section_ids[0]
@@ -678,8 +680,9 @@ class crm_lead(base_stage, format_address, osv.osv):
merged_data['stage_id'] = section_stage_ids and section_stage_ids[0] or False
# Write merged data into first opportunity
self.write(cr, uid, [highest.id], merged_data, context=context)
- # Delete tail opportunities
- self.unlink(cr, uid, [x.id for x in tail_opportunities], context=context)
+ # Delete tail opportunities
+ # We use the SUPERUSER to avoid access rights issues because as the user had the rights to see the records it should be safe to do so
+ self.unlink(cr, SUPERUSER_ID, [x.id for x in tail_opportunities], context=context)
return highest.id
diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml
index 21d60ad2961..e7e6beae33e 100644
--- a/addons/crm/crm_lead_demo.xml
+++ b/addons/crm/crm_lead_demo.xml
@@ -20,7 +20,7 @@
1
-
+ Hello,
@@ -44,7 +44,7 @@ Can you send me the details ?4
-
+
@@ -63,7 +63,7 @@ Can you send me the details ?
2
-
+
@@ -82,7 +82,7 @@ Can you send me the details ?
3
-
+
@@ -133,7 +133,7 @@ Contact: +1 813 494 5005
3
-
+
@@ -152,7 +152,7 @@ Contact: +1 813 494 5005
5
-
+
@@ -197,6 +197,9 @@ Contact: +1 813 494 5005
+
+
+ lead
@@ -211,7 +214,7 @@ Contact: +1 813 494 5005
2
-
+ Hi,
@@ -235,7 +238,7 @@ Andrew3
-
+
@@ -291,7 +294,7 @@ Andrew
Meeting for pricing information.
-
+
@@ -317,7 +320,7 @@ Andrew
Send Catalogue by Email
-
+
@@ -326,7 +329,7 @@ Andrew
opportunityPlan to buy RedHat servers
-
+ 69 rue de Chimay
@@ -339,10 +342,11 @@ Andrew
Call to ask system requirement
-
+
-
+
+
@@ -367,6 +371,7 @@ Andrew
+
@@ -388,10 +393,11 @@ Andrew
Send price list regarding our interventions
-
+
-
+
+
@@ -412,7 +418,7 @@ Andrew
Call to define real needs about training
-
+
@@ -438,8 +444,9 @@ Andrew
Ask for the good receprion of the proposition
-
+
+
@@ -468,10 +475,11 @@ Andrew
3
-
+
-
+
+
@@ -486,7 +494,7 @@ Andrew
3
-
+
@@ -504,14 +512,15 @@ Andrew
5
-
+
+ opportunityNeed 20 Days of Consultancy
-
+ info@mycompany.net
@@ -525,6 +534,7 @@ Andrew
+
@@ -544,7 +554,7 @@ Andrew
2Conf call with technical service
-
+
@@ -569,10 +579,11 @@ Andrew
Send Catalogue by Email
-
+
-
+
+
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 225b2ffc292..6ddd06c1c90 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -157,7 +157,8 @@
-
@@ -343,7 +344,7 @@
help="Leads that are assigned to me"/>
+ help="Leads that are assigned to any sales teams I am member of" groups="base.group_multi_salesteams"/>
-
+
@@ -362,7 +363,7 @@
-
+
@@ -556,7 +557,7 @@
-
-
+
diff --git a/addons/crm/crm_phonecall_demo.xml b/addons/crm/crm_phonecall_demo.xml
index f441c29a7e6..4002e18815e 100644
--- a/addons/crm/crm_phonecall_demo.xml
+++ b/addons/crm/crm_phonecall_demo.xml
@@ -37,7 +37,7 @@
Ask for convenient time of meetingopen+1 786 525 0724
-
+
@@ -50,7 +50,7 @@
done(077) 582-4035(077) 341-3591
-
+
@@ -74,7 +74,7 @@
Proposal for discount offeropen+34 230 953 485
-
+
diff --git a/addons/crm/crm_view.xml b/addons/crm/crm_view.xml
index 63385fa3e17..a84ae553b4a 100644
--- a/addons/crm/crm_view.xml
+++ b/addons/crm/crm_view.xml
@@ -101,7 +101,7 @@
-
+
diff --git a/addons/crm/html/index.html b/addons/crm/html/index.html
index 355fdb0be36..5ae542f5c91 100644
--- a/addons/crm/html/index.html
+++ b/addons/crm/html/index.html
@@ -9,7 +9,6 @@
-
diff --git a/addons/crm/i18n/ru.po b/addons/crm/i18n/ru.po
index 6403f9e57b6..0029293866c 100644
--- a/addons/crm/i18n/ru.po
+++ b/addons/crm/i18n/ru.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-05-27 12:19+0000\n"
-"Last-Translator: leksei \n"
+"PO-Revision-Date: 2013-06-06 09:56+0000\n"
+"Last-Translator: Chertykov Denis \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-05-28 05:17+0000\n"
-"X-Generator: Launchpad (build 16640)\n"
+"X-Launchpad-Export-Date: 2013-06-07 05:48+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
#. module: crm
#: view:crm.lead.report:0
@@ -56,6 +56,11 @@ msgid ""
"Description: [[object.description]]\n"
" "
msgstr ""
+"Внимание, необработанный кандидат создан более 5 дней назад.\n"
+"Название: [[object.name ]]\n"
+"Идентификатор: [[object.id ]]\n"
+"Описание: [[object.description]]\n"
+" "
#. module: crm
#: field:crm.opportunity2phonecall,action:0
@@ -953,7 +958,7 @@ msgstr "Следующее действие"
#: code:addons/crm/crm_lead.py:763
#, python-format
msgid "Partner set to %s."
-msgstr ""
+msgstr "Партнер установлен как %s."
#. module: crm
#: selection:crm.lead.report,state:0
@@ -1108,7 +1113,7 @@ msgstr "Удалить"
#. module: crm
#: model:mail.message.subtype,description:crm.mt_lead_create
msgid "Opportunity created"
-msgstr ""
+msgstr "Предложение создано"
#. module: crm
#: view:crm.lead:0
@@ -1397,7 +1402,7 @@ msgstr "Сделать"
#. module: crm
#: model:mail.message.subtype,description:crm.mt_lead_lost
msgid "Opportunity lost"
-msgstr ""
+msgstr "Предложение отклонено"
#. module: crm
#: field:crm.lead2opportunity.partner,action:0
@@ -1446,7 +1451,7 @@ msgstr "Пользователи"
#. module: crm
#: model:mail.message.subtype,name:crm.mt_lead_stage
msgid "Stage Changed"
-msgstr ""
+msgstr "Стадия изменена"
#. module: crm
#: field:crm.case.stage,section_ids:0
@@ -1759,7 +1764,7 @@ msgstr "Способ оплаты"
#. module: crm
#: model:ir.model,name:crm.model_crm_lead2opportunity_partner_mass
msgid "Mass Lead To Opportunity Partner"
-msgstr "Массовое проведение предложений партнёру"
+msgstr "Массовое преобразование кандидатов в предложения"
#. module: crm
#: view:sale.config.settings:0
@@ -1894,7 +1899,7 @@ msgstr "Кандидаты"
#: code:addons/crm/crm_lead.py:563
#, python-format
msgid "Merged leads"
-msgstr ""
+msgstr "Объединенные кандидаты"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor5
@@ -1917,7 +1922,7 @@ msgstr "Сделать"
#: model:mail.message.subtype,name:crm.mt_lead_convert_to_opportunity
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_opportunity
msgid "Lead to Opportunity"
-msgstr ""
+msgstr "Кандидат в предложение"
#. module: crm
#: field:crm.lead,user_email:0
@@ -2126,7 +2131,7 @@ msgstr ""
#. module: crm
#: view:crm.lead:0
msgid "Address"
-msgstr ""
+msgstr "Адрес"
#. module: crm
#: help:crm.case.section,alias_id:0
@@ -2134,6 +2139,8 @@ msgid ""
"The email address associated with this team. New emails received will "
"automatically create new leads assigned to the team."
msgstr ""
+"Адрес эл. почты связанный с этой командой. Новая полученная эл. почта будет "
+"автоматически создавать новые кандидаты связанные с командой."
#. module: crm
#: view:crm.lead:0
@@ -2192,7 +2199,7 @@ msgstr "Продолжение процесса"
#: selection:crm.lead2opportunity.partner.mass,name:0
#: model:ir.actions.act_window,name:crm.action_crm_lead2opportunity_partner
msgid "Convert to opportunity"
-msgstr "Преобразовать в возможность"
+msgstr "Преобразовать в предложение"
#. module: crm
#: field:crm.opportunity2phonecall,user_id:0
@@ -2234,6 +2241,8 @@ msgid ""
"This stage is not visible, for example in status bar or kanban view, when "
"there are no records in that stage to display."
msgstr ""
+"Эта стадия не видима, например в статус-баре или виде канбан, когда нет "
+"записей этой стадии для отображения."
#. module: crm
#: field:crm.lead.report,nbr:0
@@ -2249,7 +2258,7 @@ msgstr "Отдел продаж, которому принадлежит воп
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead6
msgid "Banner Ads"
-msgstr ""
+msgstr "Баннер"
#. module: crm
#: field:crm.merge.opportunity,opportunity_ids:0
@@ -2279,7 +2288,7 @@ msgstr "Выполняется"
#. module: crm
#: model:mail.message.subtype,description:crm.mt_lead_convert_to_opportunity
msgid "Lead converted into an opportunity"
-msgstr ""
+msgstr "Кандидат превращенный в предложение"
#. module: crm
#: view:crm.lead:0
@@ -2289,7 +2298,7 @@ msgstr "Нераспределенные кандидаты"
#. module: crm
#: model:mail.message.subtype,description:crm.mt_lead_won
msgid "Opportunity won"
-msgstr ""
+msgstr "Предложение принято"
#. module: crm
#: field:crm.case.categ,object_id:0
@@ -2364,7 +2373,7 @@ msgstr ""
#. module: crm
#: field:crm.case.stage,state:0
msgid "Related Status"
-msgstr ""
+msgstr "Связанный статус"
#. module: crm
#: field:crm.phonecall,name:0
@@ -2410,7 +2419,7 @@ msgstr "Подтвердить"
#. module: crm
#: view:crm.lead:0
msgid "Unread messages"
-msgstr ""
+msgstr "Непрочитанные сообщения"
#. module: crm
#: field:crm.phonecall.report,section_id:0
@@ -2501,7 +2510,7 @@ msgstr "Создание предложений из кандидатов"
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead3
msgid "Email Campaign - Products"
-msgstr ""
+msgstr "Кампания эл. почты - Продукция"
#. module: crm
#: model:ir.actions.act_window,help:crm.crm_case_categ_phone_incoming0
@@ -2578,7 +2587,7 @@ msgstr "Август"
#: model:mail.message.subtype,name:crm.mt_lead_lost
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_lost
msgid "Opportunity Lost"
-msgstr ""
+msgstr "Предложение отклонено"
#. module: crm
#: field:crm.lead.report,deadline_month:0
@@ -2644,7 +2653,7 @@ msgstr "Сотрудники отдела"
#: view:crm.opportunity2phonecall:0
#: view:crm.phonecall2phonecall:0
msgid "Schedule/Log a Call"
-msgstr ""
+msgstr "Запланировать/Описать звонок"
#. module: crm
#: field:crm.lead,planned_cost:0
@@ -2654,7 +2663,7 @@ msgstr "Планируемые затраты"
#. module: crm
#: help:crm.lead,date_deadline:0
msgid "Estimate of the date on which the opportunity will be won."
-msgstr ""
+msgstr "Оценка даты на которую это предложение будет принято."
#. module: crm
#: help:crm.lead,email_cc:0
@@ -2676,7 +2685,7 @@ msgstr "Описанные звонки"
#: model:mail.message.subtype,name:crm.mt_lead_won
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_won
msgid "Opportunity Won"
-msgstr ""
+msgstr "Предложение принято"
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_case_section_act_tree
@@ -2717,7 +2726,7 @@ msgstr "Улица (2-я строка)"
#. module: crm
#: field:sale.config.settings,module_crm_helpdesk:0
msgid "Manage Helpdesk and Support"
-msgstr ""
+msgstr "Управление поддержкой"
#. module: crm
#: field:crm.lead.report,delay_open:0
@@ -2826,7 +2835,7 @@ msgstr "Дата создания"
#. module: crm
#: view:crm.lead:0
msgid "at"
-msgstr ""
+msgstr "в"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead1
@@ -2895,7 +2904,7 @@ msgstr ""
#. module: crm
#: view:crm.lead:0
msgid "Internal Notes"
-msgstr ""
+msgstr "Внутренние заметки"
#. module: crm
#: view:crm.lead:0
@@ -2960,6 +2969,7 @@ msgstr "Проиграно"
#, python-format
msgid "Closed/Cancelled leads cannot be converted into opportunities."
msgstr ""
+"Закрытые/Отмененные кандидаты не могут быть конвертированы в возможности."
#. module: crm
#: view:crm.lead:0
@@ -3050,7 +3060,7 @@ msgstr "Рассылка"
#. module: crm
#: model:mail.message.subtype,name:crm.mt_salesteam_lead_stage
msgid "Opportunity Stage Changed"
-msgstr ""
+msgstr "Этап предложения изменен"
#. module: crm
#: model:ir.actions.act_window,help:crm.crm_lead_stage_act
diff --git a/addons/crm/process/crm_configuration_process.xml b/addons/crm/process/crm_configuration_process.xml
index c56bb8935d9..882c9680268 100644
--- a/addons/crm/process/crm_configuration_process.xml
+++ b/addons/crm/process/crm_configuration_process.xml
@@ -60,24 +60,24 @@
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml
index 759063b3c1d..09853c6379e 100644
--- a/addons/crm/report/crm_lead_report_view.xml
+++ b/addons/crm/report/crm_lead_report_view.xml
@@ -75,7 +75,7 @@
+ help="Leads/Opportunities that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
+ help="Phone calls that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
-
+
-
+
diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv
index b09c201df2b..cadb8c24550 100644
--- a/addons/crm/security/ir.model.access.csv
+++ b/addons/crm/security/ir.model.access.csv
@@ -12,7 +12,7 @@ access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.grou
access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_user,1,0,0,0
access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0
access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0
-access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,1,1,0
+access_crm_case_section_user,crm.case.section.user,model_crm_case_section,base.group_sale_salesman,1,0,0,0
access_crm_case_section_manager,crm.case.section.manager,model_crm_case_section,base.group_sale_manager,1,1,1,1
access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0
access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1
diff --git a/addons/crm/static/lib/sparkline/jquery.sparkline.js b/addons/crm/static/lib/sparkline/jquery.sparkline.js
new file mode 100644
index 00000000000..c003923e03b
--- /dev/null
+++ b/addons/crm/static/lib/sparkline/jquery.sparkline.js
@@ -0,0 +1,3047 @@
+/**
+*
+* jquery.sparkline.js
+*
+* v2.1.1
+* (c) Splunk, Inc
+* Contact: Gareth Watts (gareth@splunk.com)
+* http://omnipotent.net/jquery.sparkline/
+*
+* Generates inline sparkline charts from data supplied either to the method
+* or inline in HTML
+*
+* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag
+* (Firefox 2.0+, Safari, Opera, etc)
+*
+* License: New BSD License
+*
+* Copyright (c) 2012, Splunk Inc.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* * Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* * Neither the name of Splunk Inc nor the names of its contributors may
+* be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*
+* Usage:
+* $(selector).sparkline(values, options)
+*
+* If values is undefined or set to 'html' then the data values are read from the specified tag:
+*
Sparkline: 1,4,6,6,8,5,3,5
+* $('.sparkline').sparkline();
+* There must be no spaces in the enclosed data set
+*
+* Otherwise values must be an array of numbers or null values
+*
Sparkline: This text replaced if the browser is compatible
+* $('#sparkline1').sparkline([1,4,6,6,8,5,3,5])
+* $('#sparkline2').sparkline([1,4,6,null,null,5,3,5])
+*
+* Values can also be specified in an HTML comment, or as a values attribute:
+*
Sparkline:
+*
Sparkline:
+* $('.sparkline').sparkline();
+*
+* For line charts, x values can also be specified:
+*
Sparkline: 1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5
+* $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ])
+*
+* By default, options should be passed in as teh second argument to the sparkline function:
+* $('.sparkline').sparkline([1,2,3,4], {type: 'bar'})
+*
+* Options can also be set by passing them on the tag itself. This feature is disabled by default though
+* as there's a slight performance overhead:
+* $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true})
+*
Sparkline: loading
+* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionPrefix)
+*
+* Supported options:
+* lineColor - Color of the line used for the chart
+* fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart
+* width - Width of the chart - Defaults to 3 times the number of values in pixels
+* height - Height of the chart - Defaults to the height of the containing element
+* chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied
+* chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied
+* chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax
+* chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied
+* chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied
+* composite - If true then don't erase any existing chart attached to the tag, but draw
+* another chart over the top - Note that width and height are ignored if an
+* existing chart is detected.
+* tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values'
+* enableTagOptions - Whether to check tags for sparkline options
+* tagOptionPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark'
+* disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a
+* hidden dom element, avoding a browser reflow
+* disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled,
+* making the plugin perform much like it did in 1.x
+* disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled)
+* disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled
+* defaults to false (highlights enabled)
+* highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase
+* tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body
+* tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied
+* tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis
+* tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis
+* tooltipFormatter - Optional callback that allows you to override the HTML displayed in the tooltip
+* callback is given arguments of (sparkline, options, fields)
+* tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title
+* tooltipFormat - A format string or SPFormat object (or an array thereof for multiple entries)
+* to control the format of the tooltip
+* tooltipPrefix - A string to prepend to each field displayed in a tooltip
+* tooltipSuffix - A string to append to each field displayed in a tooltip
+* tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true)
+* tooltipValueLookups - An object or range map to map field values to tooltip strings
+* (eg. to map -1 to "Lost", 0 to "Draw", and 1 to "Win")
+* numberFormatter - Optional callback for formatting numbers in tooltips
+* numberDigitGroupSep - Character to use for group separator in numbers "1,234" - Defaults to ","
+* numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to "."
+* numberDigitGroupCount - Number of digits between group separator - Defaults to 3
+*
+* There are 7 types of sparkline, selected by supplying a "type" option of 'line' (default),
+* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box'
+* line - Line chart. Options:
+* spotColor - Set to '' to not end each line in a circular spot
+* minSpotColor - If set, color of spot at minimum value
+* maxSpotColor - If set, color of spot at maximum value
+* spotRadius - Radius in pixels
+* lineWidth - Width of line in pixels
+* normalRangeMin
+* normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal"
+* or expected range of values
+* normalRangeColor - Color to use for the above bar
+* drawNormalOnTop - Draw the normal range above the chart fill color if true
+* defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart
+* highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable
+* highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable
+* valueSpots - Specify which points to draw spots on, and in which color. Accepts a range map
+*
+* bar - Bar chart. Options:
+* barColor - Color of bars for postive values
+* negBarColor - Color of bars for negative values
+* zeroColor - Color of bars with zero values
+* nullColor - Color of bars with null values - Defaults to omitting the bar entirely
+* barWidth - Width of bars in pixels
+* colorMap - Optional mappnig of values to colors to override the *BarColor values above
+* can be an Array of values to control the color of individual bars or a range map
+* to specify colors for individual ranges of values
+* barSpacing - Gap between bars in pixels
+* zeroAxis - Centers the y-axis around zero if true
+*
+* tristate - Charts values of win (>0), lose (<0) or draw (=0)
+* posBarColor - Color of win values
+* negBarColor - Color of lose values
+* zeroBarColor - Color of draw values
+* barWidth - Width of bars in pixels
+* barSpacing - Gap between bars in pixels
+* colorMap - Optional mappnig of values to colors to override the *BarColor values above
+* can be an Array of values to control the color of individual bars or a range map
+* to specify colors for individual ranges of values
+*
+* discrete - Options:
+* lineHeight - Height of each line in pixels - Defaults to 30% of the graph height
+* thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor
+* thresholdColor
+*
+* bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ...
+* options:
+* targetColor - The color of the vertical target marker
+* targetWidth - The width of the target marker in pixels
+* performanceColor - The color of the performance measure horizontal bar
+* rangeColors - Colors to use for each qualitative range background color
+*
+* pie - Pie chart. Options:
+* sliceColors - An array of colors to use for pie slices
+* offset - Angle in degrees to offset the first slice - Try -90 or +90
+* borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border)
+* borderColor - Color to use for the pie chart border - Defaults to #000
+*
+* box - Box plot. Options:
+* raw - Set to true to supply pre-computed plot points as values
+* values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier
+* When set to false you can supply any number of values and the box plot will
+* be computed for you. Default is false.
+* showOutliers - Set to true (default) to display outliers as circles
+* outlierIQR - Interquartile range used to determine outliers. Default 1.5
+* boxLineColor - Outline color of the box
+* boxFillColor - Fill color for the box
+* whiskerColor - Line color used for whiskers
+* outlierLineColor - Outline color of outlier circles
+* outlierFillColor - Fill color of the outlier circles
+* spotRadius - Radius of outlier circles
+* medianColor - Line color of the median line
+* target - Draw a target cross hair at the supplied value (default undefined)
+*
+*
+*
+* Examples:
+* $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false });
+* $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 });
+* $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }):
+* $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' });
+* $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' });
+* $('#pie').sparkline([1,1,2], { type:'pie' });
+*/
+
+/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */
+
+(function(factory) {
+ if(typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ }
+ else {
+ factory(jQuery);
+ }
+}
+(function($) {
+ 'use strict';
+
+ var UNSET_OPTION = {},
+ getDefaults, createClass, SPFormat, clipval, quartile, normalizeValue, normalizeValues,
+ remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap,
+ MouseHandler, Tooltip, barHighlightMixin,
+ line, bar, tristate, discrete, bullet, pie, box, defaultStyles, initStyles,
+ VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0;
+
+ /**
+ * Default configuration settings
+ */
+ getDefaults = function () {
+ return {
+ // Settings common to most/all chart types
+ common: {
+ type: 'line',
+ lineColor: '#00f',
+ fillColor: '#cdf',
+ defaultPixelsPerValue: 3,
+ width: 'auto',
+ height: 'auto',
+ composite: false,
+ tagValuesAttribute: 'values',
+ tagOptionsPrefix: 'spark',
+ enableTagOptions: false,
+ enableHighlight: true,
+ highlightLighten: 1.4,
+ tooltipSkipNull: true,
+ tooltipPrefix: '',
+ tooltipSuffix: '',
+ disableHiddenCheck: false,
+ numberFormatter: false,
+ numberDigitGroupCount: 3,
+ numberDigitGroupSep: ',',
+ numberDecimalMark: '.',
+ disableTooltips: false,
+ disableInteraction: false
+ },
+ // Defaults for line charts
+ line: {
+ spotColor: '#f80',
+ highlightSpotColor: '#5f5',
+ highlightLineColor: '#f22',
+ spotRadius: 1.5,
+ minSpotColor: '#f80',
+ maxSpotColor: '#f80',
+ lineWidth: 1,
+ normalRangeMin: undefined,
+ normalRangeMax: undefined,
+ normalRangeColor: '#ccc',
+ drawNormalOnTop: false,
+ chartRangeMin: undefined,
+ chartRangeMax: undefined,
+ chartRangeMinX: undefined,
+ chartRangeMaxX: undefined,
+ tooltipFormat: new SPFormat('● {{prefix}}{{y}}{{suffix}}')
+ },
+ // Defaults for bar charts
+ bar: {
+ barColor: '#3366cc',
+ negBarColor: '#f44',
+ stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
+ '#dd4477', '#0099c6', '#990099'],
+ zeroColor: undefined,
+ nullColor: undefined,
+ zeroAxis: true,
+ barWidth: 4,
+ barSpacing: 1,
+ chartRangeMax: undefined,
+ chartRangeMin: undefined,
+ chartRangeClip: false,
+ colorMap: undefined,
+ tooltipFormat: new SPFormat('● {{prefix}}{{value}}{{suffix}}')
+ },
+ // Defaults for tristate charts
+ tristate: {
+ barWidth: 4,
+ barSpacing: 1,
+ posBarColor: '#6f6',
+ negBarColor: '#f44',
+ zeroBarColor: '#999',
+ colorMap: {},
+ tooltipFormat: new SPFormat('● {{value:map}}'),
+ tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } }
+ },
+ // Defaults for discrete charts
+ discrete: {
+ lineHeight: 'auto',
+ thresholdColor: undefined,
+ thresholdValue: 0,
+ chartRangeMax: undefined,
+ chartRangeMin: undefined,
+ chartRangeClip: false,
+ tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}')
+ },
+ // Defaults for bullet charts
+ bullet: {
+ targetColor: '#f33',
+ targetWidth: 3, // width of the target bar in pixels
+ performanceColor: '#33f',
+ rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'],
+ base: undefined, // set this to a number to change the base start number
+ tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'),
+ tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} }
+ },
+ // Defaults for pie charts
+ pie: {
+ offset: 0,
+ sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
+ '#dd4477', '#0099c6', '#990099'],
+ borderWidth: 0,
+ borderColor: '#000',
+ tooltipFormat: new SPFormat('● {{value}} ({{percent.1}}%)')
+ },
+ // Defaults for box plots
+ box: {
+ raw: false,
+ boxLineColor: '#000',
+ boxFillColor: '#cdf',
+ whiskerColor: '#000',
+ outlierLineColor: '#333',
+ outlierFillColor: '#fff',
+ medianColor: '#f00',
+ showOutliers: true,
+ outlierIQR: 1.5,
+ spotRadius: 1.5,
+ target: undefined,
+ targetColor: '#4a2',
+ chartRangeMax: undefined,
+ chartRangeMin: undefined,
+ tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'),
+ tooltipFormatFieldlistKey: 'field',
+ tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median',
+ uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier',
+ lw: 'Left Whisker', rw: 'Right Whisker'} }
+ }
+ };
+ };
+
+ // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname
+ defaultStyles = '.jqstooltip { ' +
+ 'position: absolute;' +
+ 'left: 0px;' +
+ 'top: 0px;' +
+ 'visibility: hidden;' +
+ 'background: rgb(0, 0, 0) transparent;' +
+ 'background-color: rgba(0,0,0,0.6);' +
+ 'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' +
+ '-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";' +
+ 'color: white;' +
+ 'font: 10px arial, san serif;' +
+ 'text-align: left;' +
+ 'white-space: nowrap;' +
+ 'padding: 5px;' +
+ 'border: 1px solid white;' +
+ 'z-index: 10000;' +
+ '}' +
+ '.jqsfield { ' +
+ 'color: white;' +
+ 'font: 10px arial, san serif;' +
+ 'text-align: left;' +
+ '}';
+
+ /**
+ * Utilities
+ */
+
+ createClass = function (/* [baseclass, [mixin, ...]], definition */) {
+ var Class, args;
+ Class = function () {
+ this.init.apply(this, arguments);
+ };
+ if (arguments.length > 1) {
+ if (arguments[0]) {
+ Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);
+ Class._super = arguments[0].prototype;
+ } else {
+ Class.prototype = arguments[arguments.length - 1];
+ }
+ if (arguments.length > 2) {
+ args = Array.prototype.slice.call(arguments, 1, -1);
+ args.unshift(Class.prototype);
+ $.extend.apply($, args);
+ }
+ } else {
+ Class.prototype = arguments[0];
+ }
+ Class.prototype.cls = Class;
+ return Class;
+ };
+
+ /**
+ * Wraps a format string for tooltips
+ * {{x}}
+ * {{x.2}
+ * {{x:months}}
+ */
+ $.SPFormatClass = SPFormat = createClass({
+ fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g,
+ precre: /(\w+)\.(\d+)/,
+
+ init: function (format, fclass) {
+ this.format = format;
+ this.fclass = fclass;
+ },
+
+ render: function (fieldset, lookups, options) {
+ var self = this,
+ fields = fieldset,
+ match, token, lookupkey, fieldvalue, prec;
+ return this.format.replace(this.fre, function () {
+ var lookup;
+ token = arguments[1];
+ lookupkey = arguments[3];
+ match = self.precre.exec(token);
+ if (match) {
+ prec = match[2];
+ token = match[1];
+ } else {
+ prec = false;
+ }
+ fieldvalue = fields[token];
+ if (fieldvalue === undefined) {
+ return '';
+ }
+ if (lookupkey && lookups && lookups[lookupkey]) {
+ lookup = lookups[lookupkey];
+ if (lookup.get) { // RangeMap
+ return lookups[lookupkey].get(fieldvalue) || fieldvalue;
+ } else {
+ return lookups[lookupkey][fieldvalue] || fieldvalue;
+ }
+ }
+ if (isNumber(fieldvalue)) {
+ if (options.get('numberFormatter')) {
+ fieldvalue = options.get('numberFormatter')(fieldvalue);
+ } else {
+ fieldvalue = formatNumber(fieldvalue, prec,
+ options.get('numberDigitGroupCount'),
+ options.get('numberDigitGroupSep'),
+ options.get('numberDecimalMark'));
+ }
+ }
+ return fieldvalue;
+ });
+ }
+ });
+
+ // convience method to avoid needing the new operator
+ $.spformat = function(format, fclass) {
+ return new SPFormat(format, fclass);
+ };
+
+ clipval = function (val, min, max) {
+ if (val < min) {
+ return min;
+ }
+ if (val > max) {
+ return max;
+ }
+ return val;
+ };
+
+ quartile = function (values, q) {
+ var vl;
+ if (q === 2) {
+ vl = Math.floor(values.length / 2);
+ return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2;
+ } else {
+ if (values.length % 2 ) { // odd
+ vl = (values.length * q + q) / 4;
+ return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];
+ } else { //even
+ vl = (values.length * q + 2) / 4;
+ return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];
+
+ }
+ }
+ };
+
+ normalizeValue = function (val) {
+ var nf;
+ switch (val) {
+ case 'undefined':
+ val = undefined;
+ break;
+ case 'null':
+ val = null;
+ break;
+ case 'true':
+ val = true;
+ break;
+ case 'false':
+ val = false;
+ break;
+ default:
+ nf = parseFloat(val);
+ if (val == nf) {
+ val = nf;
+ }
+ }
+ return val;
+ };
+
+ normalizeValues = function (vals) {
+ var i, result = [];
+ for (i = vals.length; i--;) {
+ result[i] = normalizeValue(vals[i]);
+ }
+ return result;
+ };
+
+ remove = function (vals, filter) {
+ var i, vl, result = [];
+ for (i = 0, vl = vals.length; i < vl; i++) {
+ if (vals[i] !== filter) {
+ result.push(vals[i]);
+ }
+ }
+ return result;
+ };
+
+ isNumber = function (num) {
+ return !isNaN(parseFloat(num)) && isFinite(num);
+ };
+
+ formatNumber = function (num, prec, groupsize, groupsep, decsep) {
+ var p, i;
+ num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');
+ p = (p = $.inArray('.', num)) < 0 ? num.length : p;
+ if (p < num.length) {
+ num[p] = decsep;
+ }
+ for (i = p - groupsize; i > 0; i -= groupsize) {
+ num.splice(i, 0, groupsep);
+ }
+ return num.join('');
+ };
+
+ // determine if all values of an array match a value
+ // returns true if the array is empty
+ all = function (val, arr, ignoreNull) {
+ var i;
+ for (i = arr.length; i--; ) {
+ if (ignoreNull && arr[i] === null) continue;
+ if (arr[i] !== val) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ // sums the numeric values in an array, ignoring other values
+ sum = function (vals) {
+ var total = 0, i;
+ for (i = vals.length; i--;) {
+ total += typeof vals[i] === 'number' ? vals[i] : 0;
+ }
+ return total;
+ };
+
+ ensureArray = function (val) {
+ return $.isArray(val) ? val : [val];
+ };
+
+ // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/
+ addCSS = function(css) {
+ var tag;
+ //if ('\v' == 'v') /* ie only */ {
+ if (document.createStyleSheet) {
+ document.createStyleSheet().cssText = css;
+ } else {
+ tag = document.createElement('style');
+ tag.type = 'text/css';
+ document.getElementsByTagName('head')[0].appendChild(tag);
+ tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css;
+ }
+ };
+
+ // Provide a cross-browser interface to a few simple drawing primitives
+ $.fn.simpledraw = function (width, height, useExisting, interact) {
+ var target, mhandler;
+ if (useExisting && (target = this.data('_jqs_vcanvas'))) {
+ return target;
+ }
+ if (width === undefined) {
+ width = $(this).innerWidth();
+ }
+ if (height === undefined) {
+ height = $(this).innerHeight();
+ }
+ if ($.fn.sparkline.hasCanvas) {
+ target = new VCanvas_canvas(width, height, this, interact);
+ } else if ($.fn.sparkline.hasVML) {
+ target = new VCanvas_vml(width, height, this);
+ } else {
+ return false;
+ }
+ mhandler = $(this).data('_jqs_mhandler');
+ if (mhandler) {
+ mhandler.registerCanvas(target);
+ }
+ return target;
+ };
+
+ $.fn.cleardraw = function () {
+ var target = this.data('_jqs_vcanvas');
+ if (target) {
+ target.reset();
+ }
+ };
+
+ $.RangeMapClass = RangeMap = createClass({
+ init: function (map) {
+ var key, range, rangelist = [];
+ for (key in map) {
+ if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {
+ range = key.split(':');
+ range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);
+ range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);
+ range[2] = map[key];
+ rangelist.push(range);
+ }
+ }
+ this.map = map;
+ this.rangelist = rangelist || false;
+ },
+
+ get: function (value) {
+ var rangelist = this.rangelist,
+ i, range, result;
+ if ((result = this.map[value]) !== undefined) {
+ return result;
+ }
+ if (rangelist) {
+ for (i = rangelist.length; i--;) {
+ range = rangelist[i];
+ if (range[0] <= value && range[1] >= value) {
+ return range[2];
+ }
+ }
+ }
+ return undefined;
+ }
+ });
+
+ // Convenience function
+ $.range_map = function(map) {
+ return new RangeMap(map);
+ };
+
+ MouseHandler = createClass({
+ init: function (el, options) {
+ var $el = $(el);
+ this.$el = $el;
+ this.options = options;
+ this.currentPageX = 0;
+ this.currentPageY = 0;
+ this.el = el;
+ this.splist = [];
+ this.tooltip = null;
+ this.over = false;
+ this.displayTooltips = !options.get('disableTooltips');
+ this.highlightEnabled = !options.get('disableHighlight');
+ },
+
+ registerSparkline: function (sp) {
+ this.splist.push(sp);
+ if (this.over) {
+ this.updateDisplay();
+ }
+ },
+
+ registerCanvas: function (canvas) {
+ var $canvas = $(canvas.canvas);
+ this.canvas = canvas;
+ this.$canvas = $canvas;
+ $canvas.mouseenter($.proxy(this.mouseenter, this));
+ $canvas.mouseleave($.proxy(this.mouseleave, this));
+ $canvas.click($.proxy(this.mouseclick, this));
+ },
+
+ reset: function (removeTooltip) {
+ this.splist = [];
+ if (this.tooltip && removeTooltip) {
+ this.tooltip.remove();
+ this.tooltip = undefined;
+ }
+ },
+
+ mouseclick: function (e) {
+ var clickEvent = $.Event('sparklineClick');
+ clickEvent.originalEvent = e;
+ clickEvent.sparklines = this.splist;
+ this.$el.trigger(clickEvent);
+ },
+
+ mouseenter: function (e) {
+ $(document.body).unbind('mousemove.jqs');
+ $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this));
+ this.over = true;
+ this.currentPageX = e.pageX;
+ this.currentPageY = e.pageY;
+ this.currentEl = e.target;
+ if (!this.tooltip && this.displayTooltips) {
+ this.tooltip = new Tooltip(this.options);
+ this.tooltip.updatePosition(e.pageX, e.pageY);
+ }
+ this.updateDisplay();
+ },
+
+ mouseleave: function () {
+ $(document.body).unbind('mousemove.jqs');
+ var splist = this.splist,
+ spcount = splist.length,
+ needsRefresh = false,
+ sp, i;
+ this.over = false;
+ this.currentEl = null;
+
+ if (this.tooltip) {
+ this.tooltip.remove();
+ this.tooltip = null;
+ }
+
+ for (i = 0; i < spcount; i++) {
+ sp = splist[i];
+ if (sp.clearRegionHighlight()) {
+ needsRefresh = true;
+ }
+ }
+
+ if (needsRefresh) {
+ this.canvas.render();
+ }
+ },
+
+ mousemove: function (e) {
+ this.currentPageX = e.pageX;
+ this.currentPageY = e.pageY;
+ this.currentEl = e.target;
+ if (this.tooltip) {
+ this.tooltip.updatePosition(e.pageX, e.pageY);
+ }
+ this.updateDisplay();
+ },
+
+ updateDisplay: function () {
+ var splist = this.splist,
+ spcount = splist.length,
+ needsRefresh = false,
+ offset = this.$canvas.offset(),
+ localX = this.currentPageX - offset.left,
+ localY = this.currentPageY - offset.top,
+ tooltiphtml, sp, i, result, changeEvent;
+ if (!this.over) {
+ return;
+ }
+ for (i = 0; i < spcount; i++) {
+ sp = splist[i];
+ result = sp.setRegionHighlight(this.currentEl, localX, localY);
+ if (result) {
+ needsRefresh = true;
+ }
+ }
+ if (needsRefresh) {
+ changeEvent = $.Event('sparklineRegionChange');
+ changeEvent.sparklines = this.splist;
+ this.$el.trigger(changeEvent);
+ if (this.tooltip) {
+ tooltiphtml = '';
+ for (i = 0; i < spcount; i++) {
+ sp = splist[i];
+ tooltiphtml += sp.getCurrentRegionTooltip();
+ }
+ this.tooltip.setContent(tooltiphtml);
+ }
+ if (!this.disableHighlight) {
+ this.canvas.render();
+ }
+ }
+ if (result === null) {
+ this.mouseleave();
+ }
+ }
+ });
+
+
+ Tooltip = createClass({
+ sizeStyle: 'position: static !important;' +
+ 'display: block !important;' +
+ 'visibility: hidden !important;' +
+ 'float: left !important;',
+
+ init: function (options) {
+ var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'),
+ sizetipStyle = this.sizeStyle,
+ offset;
+ this.container = options.get('tooltipContainer') || document.body;
+ this.tooltipOffsetX = options.get('tooltipOffsetX', 10);
+ this.tooltipOffsetY = options.get('tooltipOffsetY', 12);
+ // remove any previous lingering tooltip
+ $('#jqssizetip').remove();
+ $('#jqstooltip').remove();
+ this.sizetip = $('', {
+ id: 'jqssizetip',
+ style: sizetipStyle,
+ 'class': tooltipClassname
+ });
+ this.tooltip = $('', {
+ id: 'jqstooltip',
+ 'class': tooltipClassname
+ }).appendTo(this.container);
+ // account for the container's location
+ offset = this.tooltip.offset();
+ this.offsetLeft = offset.left;
+ this.offsetTop = offset.top;
+ this.hidden = true;
+ $(window).unbind('resize.jqs scroll.jqs');
+ $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this));
+ this.updateWindowDims();
+ },
+
+ updateWindowDims: function () {
+ this.scrollTop = $(window).scrollTop();
+ this.scrollLeft = $(window).scrollLeft();
+ this.scrollRight = this.scrollLeft + $(window).width();
+ this.updatePosition();
+ },
+
+ getSize: function (content) {
+ this.sizetip.html(content).appendTo(this.container);
+ this.width = this.sizetip.width() + 1;
+ this.height = this.sizetip.height();
+ this.sizetip.remove();
+ },
+
+ setContent: function (content) {
+ if (!content) {
+ this.tooltip.css('visibility', 'hidden');
+ this.hidden = true;
+ return;
+ }
+ this.getSize(content);
+ this.tooltip.html(content)
+ .css({
+ 'width': this.width,
+ 'height': this.height,
+ 'visibility': 'visible'
+ });
+ if (this.hidden) {
+ this.hidden = false;
+ this.updatePosition();
+ }
+ },
+
+ updatePosition: function (x, y) {
+ if (x === undefined) {
+ if (this.mousex === undefined) {
+ return;
+ }
+ x = this.mousex - this.offsetLeft;
+ y = this.mousey - this.offsetTop;
+
+ } else {
+ this.mousex = x = x - this.offsetLeft;
+ this.mousey = y = y - this.offsetTop;
+ }
+ if (!this.height || !this.width || this.hidden) {
+ return;
+ }
+
+ y -= this.height + this.tooltipOffsetY;
+ x += this.tooltipOffsetX;
+
+ if (y < this.scrollTop) {
+ y = this.scrollTop;
+ }
+ if (x < this.scrollLeft) {
+ x = this.scrollLeft;
+ } else if (x + this.width > this.scrollRight) {
+ x = this.scrollRight - this.width;
+ }
+
+ this.tooltip.css({
+ 'left': x,
+ 'top': y
+ });
+ },
+
+ remove: function () {
+ this.tooltip.remove();
+ this.sizetip.remove();
+ this.sizetip = this.tooltip = undefined;
+ $(window).unbind('resize.jqs scroll.jqs');
+ }
+ });
+
+ initStyles = function() {
+ addCSS(defaultStyles);
+ };
+
+ $(initStyles);
+
+ pending = [];
+ $.fn.sparkline = function (userValues, userOptions) {
+ return this.each(function () {
+ var options = new $.fn.sparkline.options(this, userOptions),
+ $this = $(this),
+ render, i;
+ render = function () {
+ var values, width, height, tmp, mhandler, sp, vals;
+ if (userValues === 'html' || userValues === undefined) {
+ vals = this.getAttribute(options.get('tagValuesAttribute'));
+ if (vals === undefined || vals === null) {
+ vals = $this.html();
+ }
+ values = vals.replace(/(^\s*\s*$)|\s+/g, '').split(',');
+ } else {
+ values = userValues;
+ }
+
+ width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width');
+ if (options.get('height') === 'auto') {
+ if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) {
+ // must be a better way to get the line height
+ tmp = document.createElement('span');
+ tmp.innerHTML = 'a';
+ $this.html(tmp);
+ height = $(tmp).innerHeight() || $(tmp).height();
+ $(tmp).remove();
+ tmp = null;
+ }
+ } else {
+ height = options.get('height');
+ }
+
+ if (!options.get('disableInteraction')) {
+ mhandler = $.data(this, '_jqs_mhandler');
+ if (!mhandler) {
+ mhandler = new MouseHandler(this, options);
+ $.data(this, '_jqs_mhandler', mhandler);
+ } else if (!options.get('composite')) {
+ mhandler.reset();
+ }
+ } else {
+ mhandler = false;
+ }
+
+ if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) {
+ if (!$.data(this, '_jqs_errnotify')) {
+ alert('Attempted to attach a composite sparkline to an element with no existing sparkline');
+ $.data(this, '_jqs_errnotify', true);
+ }
+ return;
+ }
+
+ sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height);
+
+ sp.render();
+
+ if (mhandler) {
+ mhandler.registerSparkline(sp);
+ }
+ };
+ // jQuery 1.3.0 completely changed the meaning of :hidden :-/
+ if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || ($.fn.jquery < '1.3.0' && $(this).parents().is(':hidden')) || !$(this).parents('body').length) {
+ if (!options.get('composite') && $.data(this, '_jqs_pending')) {
+ // remove any existing references to the element
+ for (i = pending.length; i; i--) {
+ if (pending[i - 1][0] == this) {
+ pending.splice(i - 1, 1);
+ }
+ }
+ }
+ pending.push([this, render]);
+ $.data(this, '_jqs_pending', true);
+ } else {
+ render.call(this);
+ }
+ });
+ };
+
+ $.fn.sparkline.defaults = getDefaults();
+
+
+ $.sparkline_display_visible = function () {
+ var el, i, pl;
+ var done = [];
+ for (i = 0, pl = pending.length; i < pl; i++) {
+ el = pending[i][0];
+ if ($(el).is(':visible') && !$(el).parents().is(':hidden')) {
+ pending[i][1].call(el);
+ $.data(pending[i][0], '_jqs_pending', false);
+ done.push(i);
+ } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) {
+ // element has been inserted and removed from the DOM
+ // If it was not yet inserted into the dom then the .data request
+ // will return true.
+ // removing from the dom causes the data to be removed.
+ $.data(pending[i][0], '_jqs_pending', false);
+ done.push(i);
+ }
+ }
+ for (i = done.length; i; i--) {
+ pending.splice(done[i - 1], 1);
+ }
+ };
+
+
+ /**
+ * User option handler
+ */
+ $.fn.sparkline.options = createClass({
+ init: function (tag, userOptions) {
+ var extendedOptions, defaults, base, tagOptionType;
+ this.userOptions = userOptions = userOptions || {};
+ this.tag = tag;
+ this.tagValCache = {};
+ defaults = $.fn.sparkline.defaults;
+ base = defaults.common;
+ this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix);
+
+ tagOptionType = this.getTagSetting('type');
+ if (tagOptionType === UNSET_OPTION) {
+ extendedOptions = defaults[userOptions.type || base.type];
+ } else {
+ extendedOptions = defaults[tagOptionType];
+ }
+ this.mergedOptions = $.extend({}, base, extendedOptions, userOptions);
+ },
+
+
+ getTagSetting: function (key) {
+ var prefix = this.tagOptionsPrefix,
+ val, i, pairs, keyval;
+ if (prefix === false || prefix === undefined) {
+ return UNSET_OPTION;
+ }
+ if (this.tagValCache.hasOwnProperty(key)) {
+ val = this.tagValCache.key;
+ } else {
+ val = this.tag.getAttribute(prefix + key);
+ if (val === undefined || val === null) {
+ val = UNSET_OPTION;
+ } else if (val.substr(0, 1) === '[') {
+ val = val.substr(1, val.length - 2).split(',');
+ for (i = val.length; i--;) {
+ val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, ''));
+ }
+ } else if (val.substr(0, 1) === '{') {
+ pairs = val.substr(1, val.length - 2).split(',');
+ val = {};
+ for (i = pairs.length; i--;) {
+ keyval = pairs[i].split(':', 2);
+ val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, ''));
+ }
+ } else {
+ val = normalizeValue(val);
+ }
+ this.tagValCache.key = val;
+ }
+ return val;
+ },
+
+ get: function (key, defaultval) {
+ var tagOption = this.getTagSetting(key),
+ result;
+ if (tagOption !== UNSET_OPTION) {
+ return tagOption;
+ }
+ return (result = this.mergedOptions[key]) === undefined ? defaultval : result;
+ }
+ });
+
+
+ $.fn.sparkline._base = createClass({
+ disabled: false,
+
+ init: function (el, values, options, width, height) {
+ this.el = el;
+ this.$el = $(el);
+ this.values = values;
+ this.options = options;
+ this.width = width;
+ this.height = height;
+ this.currentRegion = undefined;
+ },
+
+ /**
+ * Setup the canvas
+ */
+ initTarget: function () {
+ var interactive = !this.options.get('disableInteraction');
+ if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) {
+ this.disabled = true;
+ } else {
+ this.canvasWidth = this.target.pixelWidth;
+ this.canvasHeight = this.target.pixelHeight;
+ }
+ },
+
+ /**
+ * Actually render the chart to the canvas
+ */
+ render: function () {
+ if (this.disabled) {
+ this.el.innerHTML = '';
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Return a region id for a given x/y co-ordinate
+ */
+ getRegion: function (x, y) {
+ },
+
+ /**
+ * Highlight an item based on the moused-over x,y co-ordinate
+ */
+ setRegionHighlight: function (el, x, y) {
+ var currentRegion = this.currentRegion,
+ highlightEnabled = !this.options.get('disableHighlight'),
+ newRegion;
+ if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) {
+ return null;
+ }
+ newRegion = this.getRegion(el, x, y);
+ if (currentRegion !== newRegion) {
+ if (currentRegion !== undefined && highlightEnabled) {
+ this.removeHighlight();
+ }
+ this.currentRegion = newRegion;
+ if (newRegion !== undefined && highlightEnabled) {
+ this.renderHighlight();
+ }
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Reset any currently highlighted item
+ */
+ clearRegionHighlight: function () {
+ if (this.currentRegion !== undefined) {
+ this.removeHighlight();
+ this.currentRegion = undefined;
+ return true;
+ }
+ return false;
+ },
+
+ renderHighlight: function () {
+ this.changeHighlight(true);
+ },
+
+ removeHighlight: function () {
+ this.changeHighlight(false);
+ },
+
+ changeHighlight: function (highlight) {},
+
+ /**
+ * Fetch the HTML to display as a tooltip
+ */
+ getCurrentRegionTooltip: function () {
+ var options = this.options,
+ header = '',
+ entries = [],
+ fields, formats, formatlen, fclass, text, i,
+ showFields, showFieldsKey, newFields, fv,
+ formatter, format, fieldlen, j;
+ if (this.currentRegion === undefined) {
+ return '';
+ }
+ fields = this.getCurrentRegionFields();
+ formatter = options.get('tooltipFormatter');
+ if (formatter) {
+ return formatter(this, options, fields);
+ }
+ if (options.get('tooltipChartTitle')) {
+ header += '
' + options.get('tooltipChartTitle') + '
\n';
+ }
+ formats = this.options.get('tooltipFormat');
+ if (!formats) {
+ return '';
+ }
+ if (!$.isArray(formats)) {
+ formats = [formats];
+ }
+ if (!$.isArray(fields)) {
+ fields = [fields];
+ }
+ showFields = this.options.get('tooltipFormatFieldlist');
+ showFieldsKey = this.options.get('tooltipFormatFieldlistKey');
+ if (showFields && showFieldsKey) {
+ // user-selected ordering of fields
+ newFields = [];
+ for (i = fields.length; i--;) {
+ fv = fields[i][showFieldsKey];
+ if ((j = $.inArray(fv, showFields)) != -1) {
+ newFields[j] = fields[i];
+ }
+ }
+ fields = newFields;
+ }
+ formatlen = formats.length;
+ fieldlen = fields.length;
+ for (i = 0; i < formatlen; i++) {
+ format = formats[i];
+ if (typeof format === 'string') {
+ format = new SPFormat(format);
+ }
+ fclass = format.fclass || 'jqsfield';
+ for (j = 0; j < fieldlen; j++) {
+ if (!fields[j].isNull || !options.get('tooltipSkipNull')) {
+ $.extend(fields[j], {
+ prefix: options.get('tooltipPrefix'),
+ suffix: options.get('tooltipSuffix')
+ });
+ text = format.render(fields[j], options.get('tooltipValueLookups'), options);
+ entries.push('
' + text + '
');
+ }
+ }
+ }
+ if (entries.length) {
+ return header + entries.join('\n');
+ }
+ return '';
+ },
+
+ getCurrentRegionFields: function () {},
+
+ calcHighlightColor: function (color, options) {
+ var highlightColor = options.get('highlightColor'),
+ lighten = options.get('highlightLighten'),
+ parse, mult, rgbnew, i;
+ if (highlightColor) {
+ return highlightColor;
+ }
+ if (lighten) {
+ // extract RGB values
+ parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
+ if (parse) {
+ rgbnew = [];
+ mult = color.length === 4 ? 16 : 1;
+ for (i = 0; i < 3; i++) {
+ rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255);
+ }
+ return 'rgb(' + rgbnew.join(',') + ')';
+ }
+
+ }
+ return color;
+ }
+
+ });
+
+ barHighlightMixin = {
+ changeHighlight: function (highlight) {
+ var currentRegion = this.currentRegion,
+ target = this.target,
+ shapeids = this.regionShapes[currentRegion],
+ newShapes;
+ // will be null if the region value was null
+ if (shapeids) {
+ newShapes = this.renderRegion(currentRegion, highlight);
+ if ($.isArray(newShapes) || $.isArray(shapeids)) {
+ target.replaceWithShapes(shapeids, newShapes);
+ this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) {
+ return newShape.id;
+ });
+ } else {
+ target.replaceWithShape(shapeids, newShapes);
+ this.regionShapes[currentRegion] = newShapes.id;
+ }
+ }
+ },
+
+ render: function () {
+ var values = this.values,
+ target = this.target,
+ regionShapes = this.regionShapes,
+ shapes, ids, i, j;
+
+ if (!this.cls._super.render.call(this)) {
+ return;
+ }
+ for (i = values.length; i--;) {
+ shapes = this.renderRegion(i);
+ if (shapes) {
+ if ($.isArray(shapes)) {
+ ids = [];
+ for (j = shapes.length; j--;) {
+ shapes[j].append();
+ ids.push(shapes[j].id);
+ }
+ regionShapes[i] = ids;
+ } else {
+ shapes.append();
+ regionShapes[i] = shapes.id; // store just the shapeid
+ }
+ } else {
+ // null value
+ regionShapes[i] = null;
+ }
+ }
+ target.render();
+ }
+ };
+
+ /**
+ * Line charts
+ */
+ $.fn.sparkline.line = line = createClass($.fn.sparkline._base, {
+ type: 'line',
+
+ init: function (el, values, options, width, height) {
+ line._super.init.call(this, el, values, options, width, height);
+ this.vertices = [];
+ this.regionMap = [];
+ this.xvalues = [];
+ this.yvalues = [];
+ this.yminmax = [];
+ this.hightlightSpotId = null;
+ this.lastShapeId = null;
+ this.initTarget();
+ },
+
+ getRegion: function (el, x, y) {
+ var i,
+ regionMap = this.regionMap; // maps regions to value positions
+ for (i = regionMap.length; i--;) {
+ if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) {
+ return regionMap[i][2];
+ }
+ }
+ return undefined;
+ },
+
+ getCurrentRegionFields: function () {
+ var currentRegion = this.currentRegion;
+ return {
+ isNull: this.yvalues[currentRegion] === null,
+ x: this.xvalues[currentRegion],
+ y: this.yvalues[currentRegion],
+ color: this.options.get('lineColor'),
+ fillColor: this.options.get('fillColor'),
+ offset: currentRegion
+ };
+ },
+
+ renderHighlight: function () {
+ var currentRegion = this.currentRegion,
+ target = this.target,
+ vertex = this.vertices[currentRegion],
+ options = this.options,
+ spotRadius = options.get('spotRadius'),
+ highlightSpotColor = options.get('highlightSpotColor'),
+ highlightLineColor = options.get('highlightLineColor'),
+ highlightSpot, highlightLine;
+
+ if (!vertex) {
+ return;
+ }
+ if (spotRadius && highlightSpotColor) {
+ highlightSpot = target.drawCircle(vertex[0], vertex[1],
+ spotRadius, undefined, highlightSpotColor);
+ this.highlightSpotId = highlightSpot.id;
+ target.insertAfterShape(this.lastShapeId, highlightSpot);
+ }
+ if (highlightLineColor) {
+ highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0],
+ this.canvasTop + this.canvasHeight, highlightLineColor);
+ this.highlightLineId = highlightLine.id;
+ target.insertAfterShape(this.lastShapeId, highlightLine);
+ }
+ },
+
+ removeHighlight: function () {
+ var target = this.target;
+ if (this.highlightSpotId) {
+ target.removeShapeId(this.highlightSpotId);
+ this.highlightSpotId = null;
+ }
+ if (this.highlightLineId) {
+ target.removeShapeId(this.highlightLineId);
+ this.highlightLineId = null;
+ }
+ },
+
+ scanValues: function () {
+ var values = this.values,
+ valcount = values.length,
+ xvalues = this.xvalues,
+ yvalues = this.yvalues,
+ yminmax = this.yminmax,
+ i, val, isStr, isArray, sp;
+ for (i = 0; i < valcount; i++) {
+ val = values[i];
+ isStr = typeof(values[i]) === 'string';
+ isArray = typeof(values[i]) === 'object' && values[i] instanceof Array;
+ sp = isStr && values[i].split(':');
+ if (isStr && sp.length === 2) { // x:y
+ xvalues.push(Number(sp[0]));
+ yvalues.push(Number(sp[1]));
+ yminmax.push(Number(sp[1]));
+ } else if (isArray) {
+ xvalues.push(val[0]);
+ yvalues.push(val[1]);
+ yminmax.push(val[1]);
+ } else {
+ xvalues.push(i);
+ if (values[i] === null || values[i] === 'null') {
+ yvalues.push(null);
+ } else {
+ yvalues.push(Number(val));
+ yminmax.push(Number(val));
+ }
+ }
+ }
+ if (this.options.get('xvalues')) {
+ xvalues = this.options.get('xvalues');
+ }
+
+ this.maxy = this.maxyorg = Math.max.apply(Math, yminmax);
+ this.miny = this.minyorg = Math.min.apply(Math, yminmax);
+
+ this.maxx = Math.max.apply(Math, xvalues);
+ this.minx = Math.min.apply(Math, xvalues);
+
+ this.xvalues = xvalues;
+ this.yvalues = yvalues;
+ this.yminmax = yminmax;
+
+ },
+
+ processRangeOptions: function () {
+ var options = this.options,
+ normalRangeMin = options.get('normalRangeMin'),
+ normalRangeMax = options.get('normalRangeMax');
+
+ if (normalRangeMin !== undefined) {
+ if (normalRangeMin < this.miny) {
+ this.miny = normalRangeMin;
+ }
+ if (normalRangeMax > this.maxy) {
+ this.maxy = normalRangeMax;
+ }
+ }
+ if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) {
+ this.miny = options.get('chartRangeMin');
+ }
+ if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) {
+ this.maxy = options.get('chartRangeMax');
+ }
+ if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) {
+ this.minx = options.get('chartRangeMinX');
+ }
+ if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) {
+ this.maxx = options.get('chartRangeMaxX');
+ }
+
+ },
+
+ drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {
+ var normalRangeMin = this.options.get('normalRangeMin'),
+ normalRangeMax = this.options.get('normalRangeMax'),
+ ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),
+ height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);
+ this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append();
+ },
+
+ render: function () {
+ var options = this.options,
+ target = this.target,
+ canvasWidth = this.canvasWidth,
+ canvasHeight = this.canvasHeight,
+ vertices = this.vertices,
+ spotRadius = options.get('spotRadius'),
+ regionMap = this.regionMap,
+ rangex, rangey, yvallast,
+ canvasTop, canvasLeft,
+ vertex, path, paths, x, y, xnext, xpos, xposnext,
+ last, next, yvalcount, lineShapes, fillShapes, plen,
+ valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i;
+
+ if (!line._super.render.call(this)) {
+ return;
+ }
+
+ this.scanValues();
+ this.processRangeOptions();
+
+ xvalues = this.xvalues;
+ yvalues = this.yvalues;
+
+ if (!this.yminmax.length || this.yvalues.length < 2) {
+ // empty or all null valuess
+ return;
+ }
+
+ canvasTop = canvasLeft = 0;
+
+ rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx;
+ rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny;
+ yvallast = this.yvalues.length - 1;
+
+ if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {
+ spotRadius = 0;
+ }
+ if (spotRadius) {
+ // adjust the canvas size as required so that spots will fit
+ hlSpotsEnabled = options.get('highlightSpotColor') && !options.get('disableInteraction');
+ if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) {
+ canvasHeight -= Math.ceil(spotRadius);
+ }
+ if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) {
+ canvasHeight -= Math.ceil(spotRadius);
+ canvasTop += Math.ceil(spotRadius);
+ }
+ if (hlSpotsEnabled ||
+ ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) {
+ canvasLeft += Math.ceil(spotRadius);
+ canvasWidth -= Math.ceil(spotRadius);
+ }
+ if (hlSpotsEnabled || options.get('spotColor') ||
+ (options.get('minSpotColor') || options.get('maxSpotColor') &&
+ (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) {
+ canvasWidth -= Math.ceil(spotRadius);
+ }
+ }
+
+
+ canvasHeight--;
+
+ if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) {
+ this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);
+ }
+
+ path = [];
+ paths = [path];
+ last = next = null;
+ yvalcount = yvalues.length;
+ for (i = 0; i < yvalcount; i++) {
+ x = xvalues[i];
+ xnext = xvalues[i + 1];
+ y = yvalues[i];
+ xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex));
+ xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth;
+ next = xpos + ((xposnext - xpos) / 2);
+ regionMap[i] = [last || 0, next, i];
+ last = next;
+ if (y === null) {
+ if (i) {
+ if (yvalues[i - 1] !== null) {
+ path = [];
+ paths.push(path);
+ }
+ vertices.push(null);
+ }
+ } else {
+ if (y < this.miny) {
+ y = this.miny;
+ }
+ if (y > this.maxy) {
+ y = this.maxy;
+ }
+ if (!path.length) {
+ // previous value was null
+ path.push([xpos, canvasTop + canvasHeight]);
+ }
+ vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))];
+ path.push(vertex);
+ vertices.push(vertex);
+ }
+ }
+
+ lineShapes = [];
+ fillShapes = [];
+ plen = paths.length;
+ for (i = 0; i < plen; i++) {
+ path = paths[i];
+ if (path.length) {
+ if (options.get('fillColor')) {
+ path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]);
+ fillShapes.push(path.slice(0));
+ path.pop();
+ }
+ // if there's only a single point in this path, then we want to display it
+ // as a vertical line which means we keep path[0] as is
+ if (path.length > 2) {
+ // else we want the first value
+ path[0] = [path[0][0], path[1][1]];
+ }
+ lineShapes.push(path);
+ }
+ }
+
+ // draw the fill first, then optionally the normal range, then the line on top of that
+ plen = fillShapes.length;
+ for (i = 0; i < plen; i++) {
+ target.drawShape(fillShapes[i],
+ options.get('fillColor'), options.get('fillColor')).append();
+ }
+
+ if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) {
+ this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);
+ }
+
+ plen = lineShapes.length;
+ for (i = 0; i < plen; i++) {
+ target.drawShape(lineShapes[i], options.get('lineColor'), undefined,
+ options.get('lineWidth')).append();
+ }
+
+ if (spotRadius && options.get('valueSpots')) {
+ valueSpots = options.get('valueSpots');
+ if (valueSpots.get === undefined) {
+ valueSpots = new RangeMap(valueSpots);
+ }
+ for (i = 0; i < yvalcount; i++) {
+ color = valueSpots.get(yvalues[i]);
+ if (color) {
+ target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)),
+ canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))),
+ spotRadius, undefined,
+ color).append();
+ }
+ }
+
+ }
+ if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) {
+ target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)),
+ canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))),
+ spotRadius, undefined,
+ options.get('spotColor')).append();
+ }
+ if (this.maxy !== this.minyorg) {
+ if (spotRadius && options.get('minSpotColor')) {
+ x = xvalues[$.inArray(this.minyorg, yvalues)];
+ target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),
+ canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))),
+ spotRadius, undefined,
+ options.get('minSpotColor')).append();
+ }
+ if (spotRadius && options.get('maxSpotColor')) {
+ x = xvalues[$.inArray(this.maxyorg, yvalues)];
+ target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),
+ canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))),
+ spotRadius, undefined,
+ options.get('maxSpotColor')).append();
+ }
+ }
+
+ this.lastShapeId = target.getLastShapeId();
+ this.canvasTop = canvasTop;
+ target.render();
+ }
+ });
+
+ /**
+ * Bar charts
+ */
+ $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, {
+ type: 'bar',
+
+ init: function (el, values, options, width, height) {
+ var barWidth = parseInt(options.get('barWidth'), 10),
+ barSpacing = parseInt(options.get('barSpacing'), 10),
+ chartRangeMin = options.get('chartRangeMin'),
+ chartRangeMax = options.get('chartRangeMax'),
+ chartRangeClip = options.get('chartRangeClip'),
+ stackMin = Infinity,
+ stackMax = -Infinity,
+ isStackString, groupMin, groupMax, stackRanges,
+ numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,
+ stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;
+ bar._super.init.call(this, el, values, options, width, height);
+
+ // scan values to determine whether to stack bars
+ for (i = 0, vlen = values.length; i < vlen; i++) {
+ val = values[i];
+ isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;
+ if (isStackString || $.isArray(val)) {
+ stacked = true;
+ if (isStackString) {
+ val = values[i] = normalizeValues(val.split(':'));
+ }
+ val = remove(val, null); // min/max will treat null as zero
+ groupMin = Math.min.apply(Math, val);
+ groupMax = Math.max.apply(Math, val);
+ if (groupMin < stackMin) {
+ stackMin = groupMin;
+ }
+ if (groupMax > stackMax) {
+ stackMax = groupMax;
+ }
+ }
+ }
+
+ this.stacked = stacked;
+ this.regionShapes = {};
+ this.barWidth = barWidth;
+ this.barSpacing = barSpacing;
+ this.totalBarWidth = barWidth + barSpacing;
+ this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);
+
+ this.initTarget();
+
+ if (chartRangeClip) {
+ clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;
+ clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;
+ }
+
+ numValues = [];
+ stackRanges = stacked ? [] : numValues;
+ var stackTotals = [];
+ var stackRangesNeg = [];
+ for (i = 0, vlen = values.length; i < vlen; i++) {
+ if (stacked) {
+ vlist = values[i];
+ values[i] = svals = [];
+ stackTotals[i] = 0;
+ stackRanges[i] = stackRangesNeg[i] = 0;
+ for (j = 0, slen = vlist.length; j < slen; j++) {
+ val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];
+ if (val !== null) {
+ if (val > 0) {
+ stackTotals[i] += val;
+ }
+ if (stackMin < 0 && stackMax > 0) {
+ if (val < 0) {
+ stackRangesNeg[i] += Math.abs(val);
+ } else {
+ stackRanges[i] += val;
+ }
+ } else {
+ stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin));
+ }
+ numValues.push(val);
+ }
+ }
+ } else {
+ val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];
+ val = values[i] = normalizeValue(val);
+ if (val !== null) {
+ numValues.push(val);
+ }
+ }
+ }
+ this.max = max = Math.max.apply(Math, numValues);
+ this.min = min = Math.min.apply(Math, numValues);
+ this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;
+ this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;
+
+ if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) {
+ min = options.get('chartRangeMin');
+ }
+ if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) {
+ max = options.get('chartRangeMax');
+ }
+
+ this.zeroAxis = zeroAxis = options.get('zeroAxis', true);
+ if (min <= 0 && max >= 0 && zeroAxis) {
+ xaxisOffset = 0;
+ } else if (zeroAxis == false) {
+ xaxisOffset = min;
+ } else if (min > 0) {
+ xaxisOffset = min;
+ } else {
+ xaxisOffset = max;
+ }
+ this.xaxisOffset = xaxisOffset;
+
+ range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min;
+
+ // as we plot zero/min values a single pixel line, we add a pixel to all other
+ // values - Reduce the effective canvas size to suit
+ this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;
+
+ if (min < xaxisOffset) {
+ yMaxCalc = (stacked && max >= 0) ? stackMax : max;
+ yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;
+ if (yoffset !== Math.ceil(yoffset)) {
+ this.canvasHeightEf -= 2;
+ yoffset = Math.ceil(yoffset);
+ }
+ } else {
+ yoffset = this.canvasHeight;
+ }
+ this.yoffset = yoffset;
+
+ if ($.isArray(options.get('colorMap'))) {
+ this.colorMapByIndex = options.get('colorMap');
+ this.colorMapByValue = null;
+ } else {
+ this.colorMapByIndex = null;
+ this.colorMapByValue = options.get('colorMap');
+ if (this.colorMapByValue && this.colorMapByValue.get === undefined) {
+ this.colorMapByValue = new RangeMap(this.colorMapByValue);
+ }
+ }
+
+ this.range = range;
+ },
+
+ getRegion: function (el, x, y) {
+ var result = Math.floor(x / this.totalBarWidth);
+ return (result < 0 || result >= this.values.length) ? undefined : result;
+ },
+
+ getCurrentRegionFields: function () {
+ var currentRegion = this.currentRegion,
+ values = ensureArray(this.values[currentRegion]),
+ result = [],
+ value, i;
+ for (i = values.length; i--;) {
+ value = values[i];
+ result.push({
+ isNull: value === null,
+ value: value,
+ color: this.calcColor(i, value, currentRegion),
+ offset: currentRegion
+ });
+ }
+ return result;
+ },
+
+ calcColor: function (stacknum, value, valuenum) {
+ var colorMapByIndex = this.colorMapByIndex,
+ colorMapByValue = this.colorMapByValue,
+ options = this.options,
+ color, newColor;
+ if (this.stacked) {
+ color = options.get('stackedBarColor');
+ } else {
+ color = (value < 0) ? options.get('negBarColor') : options.get('barColor');
+ }
+ if (value === 0 && options.get('zeroColor') !== undefined) {
+ color = options.get('zeroColor');
+ }
+ if (colorMapByValue && (newColor = colorMapByValue.get(value))) {
+ color = newColor;
+ } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {
+ color = colorMapByIndex[valuenum];
+ }
+ return $.isArray(color) ? color[stacknum % color.length] : color;
+ },
+
+ /**
+ * Render bar(s) for a region
+ */
+ renderRegion: function (valuenum, highlight) {
+ var vals = this.values[valuenum],
+ options = this.options,
+ xaxisOffset = this.xaxisOffset,
+ result = [],
+ range = this.range,
+ stacked = this.stacked,
+ target = this.target,
+ x = valuenum * this.totalBarWidth,
+ canvasHeightEf = this.canvasHeightEf,
+ yoffset = this.yoffset,
+ y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;
+
+ vals = $.isArray(vals) ? vals : [vals];
+ valcount = vals.length;
+ val = vals[0];
+ isNull = all(null, vals);
+ allMin = all(xaxisOffset, vals, true);
+
+ if (isNull) {
+ if (options.get('nullColor')) {
+ color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);
+ y = (yoffset > 0) ? yoffset - 1 : yoffset;
+ return target.drawRect(x, y, this.barWidth - 1, 0, color, color);
+ } else {
+ return undefined;
+ }
+ }
+ yoffsetNeg = yoffset;
+ for (i = 0; i < valcount; i++) {
+ val = vals[i];
+
+ if (stacked && val === xaxisOffset) {
+ if (!allMin || minPlotted) {
+ continue;
+ }
+ minPlotted = true;
+ }
+
+ if (range > 0) {
+ height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1;
+ } else {
+ height = 1;
+ }
+ if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {
+ y = yoffsetNeg;
+ yoffsetNeg += height;
+ } else {
+ y = yoffset - height;
+ yoffset -= height;
+ }
+ color = this.calcColor(i, val, valuenum);
+ if (highlight) {
+ color = this.calcHighlightColor(color, options);
+ }
+ result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color));
+ }
+ if (result.length === 1) {
+ return result[0];
+ }
+ return result;
+ }
+ });
+
+ /**
+ * Tristate charts
+ */
+ $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, {
+ type: 'tristate',
+
+ init: function (el, values, options, width, height) {
+ var barWidth = parseInt(options.get('barWidth'), 10),
+ barSpacing = parseInt(options.get('barSpacing'), 10);
+ tristate._super.init.call(this, el, values, options, width, height);
+
+ this.regionShapes = {};
+ this.barWidth = barWidth;
+ this.barSpacing = barSpacing;
+ this.totalBarWidth = barWidth + barSpacing;
+ this.values = $.map(values, Number);
+ this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);
+
+ if ($.isArray(options.get('colorMap'))) {
+ this.colorMapByIndex = options.get('colorMap');
+ this.colorMapByValue = null;
+ } else {
+ this.colorMapByIndex = null;
+ this.colorMapByValue = options.get('colorMap');
+ if (this.colorMapByValue && this.colorMapByValue.get === undefined) {
+ this.colorMapByValue = new RangeMap(this.colorMapByValue);
+ }
+ }
+ this.initTarget();
+ },
+
+ getRegion: function (el, x, y) {
+ return Math.floor(x / this.totalBarWidth);
+ },
+
+ getCurrentRegionFields: function () {
+ var currentRegion = this.currentRegion;
+ return {
+ isNull: this.values[currentRegion] === undefined,
+ value: this.values[currentRegion],
+ color: this.calcColor(this.values[currentRegion], currentRegion),
+ offset: currentRegion
+ };
+ },
+
+ calcColor: function (value, valuenum) {
+ var values = this.values,
+ options = this.options,
+ colorMapByIndex = this.colorMapByIndex,
+ colorMapByValue = this.colorMapByValue,
+ color, newColor;
+
+ if (colorMapByValue && (newColor = colorMapByValue.get(value))) {
+ color = newColor;
+ } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {
+ color = colorMapByIndex[valuenum];
+ } else if (values[valuenum] < 0) {
+ color = options.get('negBarColor');
+ } else if (values[valuenum] > 0) {
+ color = options.get('posBarColor');
+ } else {
+ color = options.get('zeroBarColor');
+ }
+ return color;
+ },
+
+ renderRegion: function (valuenum, highlight) {
+ var values = this.values,
+ options = this.options,
+ target = this.target,
+ canvasHeight, height, halfHeight,
+ x, y, color;
+
+ canvasHeight = target.pixelHeight;
+ halfHeight = Math.round(canvasHeight / 2);
+
+ x = valuenum * this.totalBarWidth;
+ if (values[valuenum] < 0) {
+ y = halfHeight;
+ height = halfHeight - 1;
+ } else if (values[valuenum] > 0) {
+ y = 0;
+ height = halfHeight - 1;
+ } else {
+ y = halfHeight - 1;
+ height = 2;
+ }
+ color = this.calcColor(values[valuenum], valuenum);
+ if (color === null) {
+ return;
+ }
+ if (highlight) {
+ color = this.calcHighlightColor(color, options);
+ }
+ return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color);
+ }
+ });
+
+ /**
+ * Discrete charts
+ */
+ $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, {
+ type: 'discrete',
+
+ init: function (el, values, options, width, height) {
+ discrete._super.init.call(this, el, values, options, width, height);
+
+ this.regionShapes = {};
+ this.values = values = $.map(values, Number);
+ this.min = Math.min.apply(Math, values);
+ this.max = Math.max.apply(Math, values);
+ this.range = this.max - this.min;
+ this.width = width = options.get('width') === 'auto' ? values.length * 2 : this.width;
+ this.interval = Math.floor(width / values.length);
+ this.itemWidth = width / values.length;
+ if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) {
+ this.min = options.get('chartRangeMin');
+ }
+ if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) {
+ this.max = options.get('chartRangeMax');
+ }
+ this.initTarget();
+ if (this.target) {
+ this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight');
+ }
+ },
+
+ getRegion: function (el, x, y) {
+ return Math.floor(x / this.itemWidth);
+ },
+
+ getCurrentRegionFields: function () {
+ var currentRegion = this.currentRegion;
+ return {
+ isNull: this.values[currentRegion] === undefined,
+ value: this.values[currentRegion],
+ offset: currentRegion
+ };
+ },
+
+ renderRegion: function (valuenum, highlight) {
+ var values = this.values,
+ options = this.options,
+ min = this.min,
+ max = this.max,
+ range = this.range,
+ interval = this.interval,
+ target = this.target,
+ canvasHeight = this.canvasHeight,
+ lineHeight = this.lineHeight,
+ pheight = canvasHeight - lineHeight,
+ ytop, val, color, x;
+
+ val = clipval(values[valuenum], min, max);
+ x = valuenum * interval;
+ ytop = Math.round(pheight - pheight * ((val - min) / range));
+ color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor');
+ if (highlight) {
+ color = this.calcHighlightColor(color, options);
+ }
+ return target.drawLine(x, ytop, x, ytop + lineHeight, color);
+ }
+ });
+
+ /**
+ * Bullet charts
+ */
+ $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, {
+ type: 'bullet',
+
+ init: function (el, values, options, width, height) {
+ var min, max, vals;
+ bullet._super.init.call(this, el, values, options, width, height);
+
+ // values: target, performance, range1, range2, range3
+ this.values = values = normalizeValues(values);
+ // target or performance could be null
+ vals = values.slice();
+ vals[0] = vals[0] === null ? vals[2] : vals[0];
+ vals[1] = values[1] === null ? vals[2] : vals[1];
+ min = Math.min.apply(Math, values);
+ max = Math.max.apply(Math, values);
+ if (options.get('base') === undefined) {
+ min = min < 0 ? min : 0;
+ } else {
+ min = options.get('base');
+ }
+ this.min = min;
+ this.max = max;
+ this.range = max - min;
+ this.shapes = {};
+ this.valueShapes = {};
+ this.regiondata = {};
+ this.width = width = options.get('width') === 'auto' ? '4.0em' : width;
+ this.target = this.$el.simpledraw(width, height, options.get('composite'));
+ if (!values.length) {
+ this.disabled = true;
+ }
+ this.initTarget();
+ },
+
+ getRegion: function (el, x, y) {
+ var shapeid = this.target.getShapeAt(el, x, y);
+ return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
+ },
+
+ getCurrentRegionFields: function () {
+ var currentRegion = this.currentRegion;
+ return {
+ fieldkey: currentRegion.substr(0, 1),
+ value: this.values[currentRegion.substr(1)],
+ region: currentRegion
+ };
+ },
+
+ changeHighlight: function (highlight) {
+ var currentRegion = this.currentRegion,
+ shapeid = this.valueShapes[currentRegion],
+ shape;
+ delete this.shapes[shapeid];
+ switch (currentRegion.substr(0, 1)) {
+ case 'r':
+ shape = this.renderRange(currentRegion.substr(1), highlight);
+ break;
+ case 'p':
+ shape = this.renderPerformance(highlight);
+ break;
+ case 't':
+ shape = this.renderTarget(highlight);
+ break;
+ }
+ this.valueShapes[currentRegion] = shape.id;
+ this.shapes[shape.id] = currentRegion;
+ this.target.replaceWithShape(shapeid, shape);
+ },
+
+ renderRange: function (rn, highlight) {
+ var rangeval = this.values[rn],
+ rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)),
+ color = this.options.get('rangeColors')[rn - 2];
+ if (highlight) {
+ color = this.calcHighlightColor(color, this.options);
+ }
+ return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color);
+ },
+
+ renderPerformance: function (highlight) {
+ var perfval = this.values[1],
+ perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)),
+ color = this.options.get('performanceColor');
+ if (highlight) {
+ color = this.calcHighlightColor(color, this.options);
+ }
+ return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1,
+ Math.round(this.canvasHeight * 0.4) - 1, color, color);
+ },
+
+ renderTarget: function (highlight) {
+ var targetval = this.values[0],
+ x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)),
+ targettop = Math.round(this.canvasHeight * 0.10),
+ targetheight = this.canvasHeight - (targettop * 2),
+ color = this.options.get('targetColor');
+ if (highlight) {
+ color = this.calcHighlightColor(color, this.options);
+ }
+ return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color);
+ },
+
+ render: function () {
+ var vlen = this.values.length,
+ target = this.target,
+ i, shape;
+ if (!bullet._super.render.call(this)) {
+ return;
+ }
+ for (i = 2; i < vlen; i++) {
+ shape = this.renderRange(i).append();
+ this.shapes[shape.id] = 'r' + i;
+ this.valueShapes['r' + i] = shape.id;
+ }
+ if (this.values[1] !== null) {
+ shape = this.renderPerformance().append();
+ this.shapes[shape.id] = 'p1';
+ this.valueShapes.p1 = shape.id;
+ }
+ if (this.values[0] !== null) {
+ shape = this.renderTarget().append();
+ this.shapes[shape.id] = 't0';
+ this.valueShapes.t0 = shape.id;
+ }
+ target.render();
+ }
+ });
+
+ /**
+ * Pie charts
+ */
+ $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, {
+ type: 'pie',
+
+ init: function (el, values, options, width, height) {
+ var total = 0, i;
+
+ pie._super.init.call(this, el, values, options, width, height);
+
+ this.shapes = {}; // map shape ids to value offsets
+ this.valueShapes = {}; // maps value offsets to shape ids
+ this.values = values = $.map(values, Number);
+
+ if (options.get('width') === 'auto') {
+ this.width = this.height;
+ }
+
+ if (values.length > 0) {
+ for (i = values.length; i--;) {
+ total += values[i];
+ }
+ }
+ this.total = total;
+ this.initTarget();
+ this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);
+ },
+
+ getRegion: function (el, x, y) {
+ var shapeid = this.target.getShapeAt(el, x, y);
+ return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
+ },
+
+ getCurrentRegionFields: function () {
+ var currentRegion = this.currentRegion;
+ return {
+ isNull: this.values[currentRegion] === undefined,
+ value: this.values[currentRegion],
+ percent: this.values[currentRegion] / this.total * 100,
+ color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],
+ offset: currentRegion
+ };
+ },
+
+ changeHighlight: function (highlight) {
+ var currentRegion = this.currentRegion,
+ newslice = this.renderSlice(currentRegion, highlight),
+ shapeid = this.valueShapes[currentRegion];
+ delete this.shapes[shapeid];
+ this.target.replaceWithShape(shapeid, newslice);
+ this.valueShapes[currentRegion] = newslice.id;
+ this.shapes[newslice.id] = currentRegion;
+ },
+
+ renderSlice: function (valuenum, highlight) {
+ var target = this.target,
+ options = this.options,
+ radius = this.radius,
+ borderWidth = options.get('borderWidth'),
+ offset = options.get('offset'),
+ circle = 2 * Math.PI,
+ values = this.values,
+ total = this.total,
+ next = offset ? (2*Math.PI)*(offset/360) : 0,
+ start, end, i, vlen, color;
+
+ vlen = values.length;
+ for (i = 0; i < vlen; i++) {
+ start = next;
+ end = next;
+ if (total > 0) { // avoid divide by zero
+ end = next + (circle * (values[i] / total));
+ }
+ if (valuenum === i) {
+ color = options.get('sliceColors')[i % options.get('sliceColors').length];
+ if (highlight) {
+ color = this.calcHighlightColor(color, options);
+ }
+
+ return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);
+ }
+ next = end;
+ }
+ },
+
+ render: function () {
+ var target = this.target,
+ values = this.values,
+ options = this.options,
+ radius = this.radius,
+ borderWidth = options.get('borderWidth'),
+ shape, i;
+
+ if (!pie._super.render.call(this)) {
+ return;
+ }
+ if (borderWidth) {
+ target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),
+ options.get('borderColor'), undefined, borderWidth).append();
+ }
+ for (i = values.length; i--;) {
+ if (values[i]) { // don't render zero values
+ shape = this.renderSlice(i).append();
+ this.valueShapes[i] = shape.id; // store just the shapeid
+ this.shapes[shape.id] = i;
+ }
+ }
+ target.render();
+ }
+ });
+
+ /**
+ * Box plots
+ */
+ $.fn.sparkline.box = box = createClass($.fn.sparkline._base, {
+ type: 'box',
+
+ init: function (el, values, options, width, height) {
+ box._super.init.call(this, el, values, options, width, height);
+ this.values = $.map(values, Number);
+ this.width = options.get('width') === 'auto' ? '4.0em' : width;
+ this.initTarget();
+ if (!this.values.length) {
+ this.disabled = 1;
+ }
+ },
+
+ /**
+ * Simulate a single region
+ */
+ getRegion: function () {
+ return 1;
+ },
+
+ getCurrentRegionFields: function () {
+ var result = [
+ { field: 'lq', value: this.quartiles[0] },
+ { field: 'med', value: this.quartiles[1] },
+ { field: 'uq', value: this.quartiles[2] }
+ ];
+ if (this.loutlier !== undefined) {
+ result.push({ field: 'lo', value: this.loutlier});
+ }
+ if (this.routlier !== undefined) {
+ result.push({ field: 'ro', value: this.routlier});
+ }
+ if (this.lwhisker !== undefined) {
+ result.push({ field: 'lw', value: this.lwhisker});
+ }
+ if (this.rwhisker !== undefined) {
+ result.push({ field: 'rw', value: this.rwhisker});
+ }
+ return result;
+ },
+
+ render: function () {
+ var target = this.target,
+ values = this.values,
+ vlen = values.length,
+ options = this.options,
+ canvasWidth = this.canvasWidth,
+ canvasHeight = this.canvasHeight,
+ minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'),
+ maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'),
+ canvasLeft = 0,
+ lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i,
+ size, unitSize;
+
+ if (!box._super.render.call(this)) {
+ return;
+ }
+
+ if (options.get('raw')) {
+ if (options.get('showOutliers') && values.length > 5) {
+ loutlier = values[0];
+ lwhisker = values[1];
+ q1 = values[2];
+ q2 = values[3];
+ q3 = values[4];
+ rwhisker = values[5];
+ routlier = values[6];
+ } else {
+ lwhisker = values[0];
+ q1 = values[1];
+ q2 = values[2];
+ q3 = values[3];
+ rwhisker = values[4];
+ }
+ } else {
+ values.sort(function (a, b) { return a - b; });
+ q1 = quartile(values, 1);
+ q2 = quartile(values, 2);
+ q3 = quartile(values, 3);
+ iqr = q3 - q1;
+ if (options.get('showOutliers')) {
+ lwhisker = rwhisker = undefined;
+ for (i = 0; i < vlen; i++) {
+ if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) {
+ lwhisker = values[i];
+ }
+ if (values[i] < q3 + (iqr * options.get('outlierIQR'))) {
+ rwhisker = values[i];
+ }
+ }
+ loutlier = values[0];
+ routlier = values[vlen - 1];
+ } else {
+ lwhisker = values[0];
+ rwhisker = values[vlen - 1];
+ }
+ }
+ this.quartiles = [q1, q2, q3];
+ this.lwhisker = lwhisker;
+ this.rwhisker = rwhisker;
+ this.loutlier = loutlier;
+ this.routlier = routlier;
+
+ unitSize = canvasWidth / (maxValue - minValue + 1);
+ if (options.get('showOutliers')) {
+ canvasLeft = Math.ceil(options.get('spotRadius'));
+ canvasWidth -= 2 * Math.ceil(options.get('spotRadius'));
+ unitSize = canvasWidth / (maxValue - minValue + 1);
+ if (loutlier < lwhisker) {
+ target.drawCircle((loutlier - minValue) * unitSize + canvasLeft,
+ canvasHeight / 2,
+ options.get('spotRadius'),
+ options.get('outlierLineColor'),
+ options.get('outlierFillColor')).append();
+ }
+ if (routlier > rwhisker) {
+ target.drawCircle((routlier - minValue) * unitSize + canvasLeft,
+ canvasHeight / 2,
+ options.get('spotRadius'),
+ options.get('outlierLineColor'),
+ options.get('outlierFillColor')).append();
+ }
+ }
+
+ // box
+ target.drawRect(
+ Math.round((q1 - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight * 0.1),
+ Math.round((q3 - q1) * unitSize),
+ Math.round(canvasHeight * 0.8),
+ options.get('boxLineColor'),
+ options.get('boxFillColor')).append();
+ // left whisker
+ target.drawLine(
+ Math.round((lwhisker - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight / 2),
+ Math.round((q1 - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight / 2),
+ options.get('lineColor')).append();
+ target.drawLine(
+ Math.round((lwhisker - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight / 4),
+ Math.round((lwhisker - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight - canvasHeight / 4),
+ options.get('whiskerColor')).append();
+ // right whisker
+ target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight / 2),
+ Math.round((q3 - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight / 2),
+ options.get('lineColor')).append();
+ target.drawLine(
+ Math.round((rwhisker - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight / 4),
+ Math.round((rwhisker - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight - canvasHeight / 4),
+ options.get('whiskerColor')).append();
+ // median line
+ target.drawLine(
+ Math.round((q2 - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight * 0.1),
+ Math.round((q2 - minValue) * unitSize + canvasLeft),
+ Math.round(canvasHeight * 0.9),
+ options.get('medianColor')).append();
+ if (options.get('target')) {
+ size = Math.ceil(options.get('spotRadius'));
+ target.drawLine(
+ Math.round((options.get('target') - minValue) * unitSize + canvasLeft),
+ Math.round((canvasHeight / 2) - size),
+ Math.round((options.get('target') - minValue) * unitSize + canvasLeft),
+ Math.round((canvasHeight / 2) + size),
+ options.get('targetColor')).append();
+ target.drawLine(
+ Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size),
+ Math.round(canvasHeight / 2),
+ Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size),
+ Math.round(canvasHeight / 2),
+ options.get('targetColor')).append();
+ }
+ target.render();
+ }
+ });
+
+ // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier
+ // This is accessible as $(foo).simpledraw()
+
+ // Detect browser renderer support
+ (function() {
+ if (document.namespaces && !document.namespaces.v) {
+ $.fn.sparkline.hasVML = true;
+ document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');
+ } else {
+ $.fn.sparkline.hasVML = false;
+ }
+
+ var el = document.createElement('canvas');
+ $.fn.sparkline.hasCanvas = !!(el.getContext && el.getContext('2d'));
+
+ })()
+
+ VShape = createClass({
+ init: function (target, id, type, args) {
+ this.target = target;
+ this.id = id;
+ this.type = type;
+ this.args = args;
+ },
+ append: function () {
+ this.target.appendShape(this);
+ return this;
+ }
+ });
+
+ VCanvas_base = createClass({
+ _pxregex: /(\d+)(px)?\s*$/i,
+
+ init: function (width, height, target) {
+ if (!width) {
+ return;
+ }
+ this.width = width;
+ this.height = height;
+ this.target = target;
+ this.lastShapeId = null;
+ if (target[0]) {
+ target = target[0];
+ }
+ $.data(target, '_jqs_vcanvas', this);
+ },
+
+ drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) {
+ return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth);
+ },
+
+ drawShape: function (path, lineColor, fillColor, lineWidth) {
+ return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]);
+ },
+
+ drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) {
+ return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]);
+ },
+
+ drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) {
+ return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]);
+ },
+
+ drawRect: function (x, y, width, height, lineColor, fillColor) {
+ return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]);
+ },
+
+ getElement: function () {
+ return this.canvas;
+ },
+
+ /**
+ * Return the most recently inserted shape id
+ */
+ getLastShapeId: function () {
+ return this.lastShapeId;
+ },
+
+ /**
+ * Clear and reset the canvas
+ */
+ reset: function () {
+ alert('reset not implemented');
+ },
+
+ _insert: function (el, target) {
+ $(target).html(el);
+ },
+
+ /**
+ * Calculate the pixel dimensions of the canvas
+ */
+ _calculatePixelDims: function (width, height, canvas) {
+ // XXX This should probably be a configurable option
+ var match;
+ match = this._pxregex.exec(height);
+ if (match) {
+ this.pixelHeight = match[1];
+ } else {
+ this.pixelHeight = $(canvas).height();
+ }
+ match = this._pxregex.exec(width);
+ if (match) {
+ this.pixelWidth = match[1];
+ } else {
+ this.pixelWidth = $(canvas).width();
+ }
+ },
+
+ /**
+ * Generate a shape object and id for later rendering
+ */
+ _genShape: function (shapetype, shapeargs) {
+ var id = shapeCount++;
+ shapeargs.unshift(id);
+ return new VShape(this, id, shapetype, shapeargs);
+ },
+
+ /**
+ * Add a shape to the end of the render queue
+ */
+ appendShape: function (shape) {
+ alert('appendShape not implemented');
+ },
+
+ /**
+ * Replace one shape with another
+ */
+ replaceWithShape: function (shapeid, shape) {
+ alert('replaceWithShape not implemented');
+ },
+
+ /**
+ * Insert one shape after another in the render queue
+ */
+ insertAfterShape: function (shapeid, shape) {
+ alert('insertAfterShape not implemented');
+ },
+
+ /**
+ * Remove a shape from the queue
+ */
+ removeShapeId: function (shapeid) {
+ alert('removeShapeId not implemented');
+ },
+
+ /**
+ * Find a shape at the specified x/y co-ordinates
+ */
+ getShapeAt: function (el, x, y) {
+ alert('getShapeAt not implemented');
+ },
+
+ /**
+ * Render all queued shapes onto the canvas
+ */
+ render: function () {
+ alert('render not implemented');
+ }
+ });
+
+ VCanvas_canvas = createClass(VCanvas_base, {
+ init: function (width, height, target, interact) {
+ VCanvas_canvas._super.init.call(this, width, height, target);
+ this.canvas = document.createElement('canvas');
+ if (target[0]) {
+ target = target[0];
+ }
+ $.data(target, '_jqs_vcanvas', this);
+ $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' });
+ this._insert(this.canvas, target);
+ this._calculatePixelDims(width, height, this.canvas);
+ this.canvas.width = this.pixelWidth;
+ this.canvas.height = this.pixelHeight;
+ this.interact = interact;
+ this.shapes = {};
+ this.shapeseq = [];
+ this.currentTargetShapeId = undefined;
+ $(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight});
+ },
+
+ _getContext: function (lineColor, fillColor, lineWidth) {
+ var context = this.canvas.getContext('2d');
+ if (lineColor !== undefined) {
+ context.strokeStyle = lineColor;
+ }
+ context.lineWidth = lineWidth === undefined ? 1 : lineWidth;
+ if (fillColor !== undefined) {
+ context.fillStyle = fillColor;
+ }
+ return context;
+ },
+
+ reset: function () {
+ var context = this._getContext();
+ context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
+ this.shapes = {};
+ this.shapeseq = [];
+ this.currentTargetShapeId = undefined;
+ },
+
+ _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {
+ var context = this._getContext(lineColor, fillColor, lineWidth),
+ i, plen;
+ context.beginPath();
+ context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5);
+ for (i = 1, plen = path.length; i < plen; i++) {
+ context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines
+ }
+ if (lineColor !== undefined) {
+ context.stroke();
+ }
+ if (fillColor !== undefined) {
+ context.fill();
+ }
+ if (this.targetX !== undefined && this.targetY !== undefined &&
+ context.isPointInPath(this.targetX, this.targetY)) {
+ this.currentTargetShapeId = shapeid;
+ }
+ },
+
+ _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
+ var context = this._getContext(lineColor, fillColor, lineWidth);
+ context.beginPath();
+ context.arc(x, y, radius, 0, 2 * Math.PI, false);
+ if (this.targetX !== undefined && this.targetY !== undefined &&
+ context.isPointInPath(this.targetX, this.targetY)) {
+ this.currentTargetShapeId = shapeid;
+ }
+ if (lineColor !== undefined) {
+ context.stroke();
+ }
+ if (fillColor !== undefined) {
+ context.fill();
+ }
+ },
+
+ _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
+ var context = this._getContext(lineColor, fillColor);
+ context.beginPath();
+ context.moveTo(x, y);
+ context.arc(x, y, radius, startAngle, endAngle, false);
+ context.lineTo(x, y);
+ context.closePath();
+ if (lineColor !== undefined) {
+ context.stroke();
+ }
+ if (fillColor) {
+ context.fill();
+ }
+ if (this.targetX !== undefined && this.targetY !== undefined &&
+ context.isPointInPath(this.targetX, this.targetY)) {
+ this.currentTargetShapeId = shapeid;
+ }
+ },
+
+ _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {
+ return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor);
+ },
+
+ appendShape: function (shape) {
+ this.shapes[shape.id] = shape;
+ this.shapeseq.push(shape.id);
+ this.lastShapeId = shape.id;
+ return shape.id;
+ },
+
+ replaceWithShape: function (shapeid, shape) {
+ var shapeseq = this.shapeseq,
+ i;
+ this.shapes[shape.id] = shape;
+ for (i = shapeseq.length; i--;) {
+ if (shapeseq[i] == shapeid) {
+ shapeseq[i] = shape.id;
+ }
+ }
+ delete this.shapes[shapeid];
+ },
+
+ replaceWithShapes: function (shapeids, shapes) {
+ var shapeseq = this.shapeseq,
+ shapemap = {},
+ sid, i, first;
+
+ for (i = shapeids.length; i--;) {
+ shapemap[shapeids[i]] = true;
+ }
+ for (i = shapeseq.length; i--;) {
+ sid = shapeseq[i];
+ if (shapemap[sid]) {
+ shapeseq.splice(i, 1);
+ delete this.shapes[sid];
+ first = i;
+ }
+ }
+ for (i = shapes.length; i--;) {
+ shapeseq.splice(first, 0, shapes[i].id);
+ this.shapes[shapes[i].id] = shapes[i];
+ }
+
+ },
+
+ insertAfterShape: function (shapeid, shape) {
+ var shapeseq = this.shapeseq,
+ i;
+ for (i = shapeseq.length; i--;) {
+ if (shapeseq[i] === shapeid) {
+ shapeseq.splice(i + 1, 0, shape.id);
+ this.shapes[shape.id] = shape;
+ return;
+ }
+ }
+ },
+
+ removeShapeId: function (shapeid) {
+ var shapeseq = this.shapeseq,
+ i;
+ for (i = shapeseq.length; i--;) {
+ if (shapeseq[i] === shapeid) {
+ shapeseq.splice(i, 1);
+ break;
+ }
+ }
+ delete this.shapes[shapeid];
+ },
+
+ getShapeAt: function (el, x, y) {
+ this.targetX = x;
+ this.targetY = y;
+ this.render();
+ return this.currentTargetShapeId;
+ },
+
+ render: function () {
+ var shapeseq = this.shapeseq,
+ shapes = this.shapes,
+ shapeCount = shapeseq.length,
+ context = this._getContext(),
+ shapeid, shape, i;
+ context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
+ for (i = 0; i < shapeCount; i++) {
+ shapeid = shapeseq[i];
+ shape = shapes[shapeid];
+ this['_draw' + shape.type].apply(this, shape.args);
+ }
+ if (!this.interact) {
+ // not interactive so no need to keep the shapes array
+ this.shapes = {};
+ this.shapeseq = [];
+ }
+ }
+
+ });
+
+ VCanvas_vml = createClass(VCanvas_base, {
+ init: function (width, height, target) {
+ var groupel;
+ VCanvas_vml._super.init.call(this, width, height, target);
+ if (target[0]) {
+ target = target[0];
+ }
+ $.data(target, '_jqs_vcanvas', this);
+ this.canvas = document.createElement('span');
+ $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'});
+ this._insert(this.canvas, target);
+ this._calculatePixelDims(width, height, this.canvas);
+ this.canvas.width = this.pixelWidth;
+ this.canvas.height = this.pixelHeight;
+ groupel = '';
+ this.canvas.insertAdjacentHTML('beforeEnd', groupel);
+ this.group = $(this.canvas).children()[0];
+ this.rendered = false;
+ this.prerender = '';
+ },
+
+ _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {
+ var vpath = [],
+ initial, stroke, fill, closed, vel, plen, i;
+ for (i = 0, plen = path.length; i < plen; i++) {
+ vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]);
+ }
+ initial = vpath.splice(0, 1);
+ lineWidth = lineWidth === undefined ? 1 : lineWidth;
+ stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
+ fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
+ closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : '';
+ vel = '' +
+ ' ';
+ return vel;
+ },
+
+ _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
+ var stroke, fill, vel;
+ x -= radius;
+ y -= radius;
+ stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
+ fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
+ vel = '';
+ return vel;
+
+ },
+
+ _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
+ var vpath, startx, starty, endx, endy, stroke, fill, vel;
+ if (startAngle === endAngle) {
+ return ''; // VML seems to have problem when start angle equals end angle.
+ }
+ if ((endAngle - startAngle) === (2 * Math.PI)) {
+ startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0
+ endAngle = (2 * Math.PI);
+ }
+
+ startx = x + Math.round(Math.cos(startAngle) * radius);
+ starty = y + Math.round(Math.sin(startAngle) * radius);
+ endx = x + Math.round(Math.cos(endAngle) * radius);
+ endy = y + Math.round(Math.sin(endAngle) * radius);
+
+ if (startx === endx && starty === endy) {
+ if ((endAngle - startAngle) < Math.PI) {
+ // Prevent very small slices from being mistaken as a whole pie
+ return '';
+ }
+ // essentially going to be the entire circle, so ignore startAngle
+ startx = endx = x + radius;
+ starty = endy = y;
+ }
+
+ if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {
+ return '';
+ }
+
+ vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy];
+ stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" ';
+ fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
+ vel = '' +
+ ' ';
+ return vel;
+ },
+
+ _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {
+ return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor);
+ },
+
+ reset: function () {
+ this.group.innerHTML = '';
+ },
+
+ appendShape: function (shape) {
+ var vel = this['_draw' + shape.type].apply(this, shape.args);
+ if (this.rendered) {
+ this.group.insertAdjacentHTML('beforeEnd', vel);
+ } else {
+ this.prerender += vel;
+ }
+ this.lastShapeId = shape.id;
+ return shape.id;
+ },
+
+ replaceWithShape: function (shapeid, shape) {
+ var existing = $('#jqsshape' + shapeid),
+ vel = this['_draw' + shape.type].apply(this, shape.args);
+ existing[0].outerHTML = vel;
+ },
+
+ replaceWithShapes: function (shapeids, shapes) {
+ // replace the first shapeid with all the new shapes then toast the remaining old shapes
+ var existing = $('#jqsshape' + shapeids[0]),
+ replace = '',
+ slen = shapes.length,
+ i;
+ for (i = 0; i < slen; i++) {
+ replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);
+ }
+ existing[0].outerHTML = replace;
+ for (i = 1; i < shapeids.length; i++) {
+ $('#jqsshape' + shapeids[i]).remove();
+ }
+ },
+
+ insertAfterShape: function (shapeid, shape) {
+ var existing = $('#jqsshape' + shapeid),
+ vel = this['_draw' + shape.type].apply(this, shape.args);
+ existing[0].insertAdjacentHTML('afterEnd', vel);
+ },
+
+ removeShapeId: function (shapeid) {
+ var existing = $('#jqsshape' + shapeid);
+ this.group.removeChild(existing[0]);
+ },
+
+ getShapeAt: function (el, x, y) {
+ var shapeid = el.id.substr(8);
+ return shapeid;
+ },
+
+ render: function () {
+ if (!this.rendered) {
+ // batch the intial render into a single repaint
+ this.group.innerHTML = this.prerender;
+ this.rendered = true;
+ }
+ }
+ });
+
+}));
diff --git a/addons/crm/static/src/css/crm.css b/addons/crm/static/src/css/crm.css
index 3ad3840a4e1..ba4473edc26 100644
--- a/addons/crm/static/src/css/crm.css
+++ b/addons/crm/static/src/css/crm.css
@@ -20,15 +20,27 @@
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list {
- margin: 10px 0;
+ position: relative;
+ margin: 10px;
}
-.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a {
- width: 110px;
+.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div {
+ width: 160px;
+ height: 22px;
+ margin: 0 !important;
+ position: relative;
display: inline-block;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover {
text-decoration: underline !important;
}
+.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:nth-child(2n) {
+ position: absolute;
+ left: 90px;
+ top: 0;
+}
+.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a:nth-child(2n) {
+ left: 110px;
+}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center {
text-align: center;
margin: 3px 0;
@@ -40,3 +52,13 @@
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_subsum {
font-size: 10px;
}
+
+.openerp .oe_kanban_view .oe_justgage {
+ color: black;
+ display: inline-block;
+}
+
+.openerp .oe_kanban_view .oe_sparkline_bar {
+ height: 20px;
+ width: 36px;
+}
\ No newline at end of file
diff --git a/addons/crm/static/src/js/crm.js b/addons/crm/static/src/js/crm.js
deleted file mode 100644
index e027313d6dc..00000000000
--- a/addons/crm/static/src/js/crm.js
+++ /dev/null
@@ -1,11 +0,0 @@
-openerp.crm = function(openerp) {
- openerp.web_kanban.KanbanRecord.include({
- on_card_clicked: function() {
- if (this.view.dataset.model === 'crm.case.section') {
- this.$('.oe_kanban_crm_salesteams_list a').first().click();
- } else {
- this._super.apply(this, arguments);
- }
- },
- });
-};
diff --git a/addons/crm/static/src/js/crm_case_section.js b/addons/crm/static/src/js/crm_case_section.js
new file mode 100644
index 00000000000..2b4ca741d75
--- /dev/null
+++ b/addons/crm/static/src/js/crm_case_section.js
@@ -0,0 +1,34 @@
+openerp.crm = function(openerp) {
+ openerp.web_kanban.KanbanRecord.include({
+ on_card_clicked: function() {
+ if (this.view.dataset.model === 'crm.case.section') {
+ this.$('.oe_kanban_crm_salesteams_list a').first().click();
+ } else {
+ this._super.apply(this, arguments);
+ }
+ },
+ });
+
+ openerp.crm.SparklineBarWidget = openerp.web_kanban.AbstractField.extend({
+ className: "oe_sparkline_bar",
+ start: function() {
+ var self = this;
+ var title = this.$node.html();
+ setTimeout(function () {
+ var value = _.pluck(self.field.value, 'value');
+ var tooltips = _.pluck(self.field.value, 'tooltip');
+ self.$el.sparkline(value, {
+ type: 'bar',
+ barWidth: 5,
+ tooltipFormat: '{{offset:offset}} {{value}}',
+ tooltipValueLookups: {
+ 'offset': tooltips
+ },
+ });
+ self.$el.tipsy({'delayIn': 0, 'html': true, 'title': function(){return title}, 'gravity': 'n'});
+ }, 0);
+ },
+ });
+ openerp.web_kanban.fields_registry.add("sparkline_bar", "openerp.crm.SparklineBarWidget");
+
+};
diff --git a/addons/crm/test/crm_lead_cancel.yml b/addons/crm/test/crm_lead_cancel.yml
index edaf844952a..8749675bf23 100644
--- a/addons/crm/test/crm_lead_cancel.yml
+++ b/addons/crm/test/crm_lead_cancel.yml
@@ -1,7 +1,9 @@
-
- I cancel unqualified lead.
+ I set a new sale team (with Marketing at parent) and I cancel unqualified lead .
-
!python {model: crm.lead}: |
+ section_id = self.pool.get('crm.case.section').create(cr, uid, {'name': "Phone Marketing", 'parent_id': ref("crm.crm_case_section_2")})
+ self.write(cr, uid, [ref("crm_case_1")], {'section_id': section_id})
self.case_cancel(cr, uid, [ref("crm_case_1")])
-
I check cancelled lead.
@@ -42,4 +44,4 @@
I check the lead is correctly escalated to the parent team.
-
!assert {model: crm.lead, id: crm.crm_case_1, string: Escalate lead to parent team}:
- - section_id.name == "Support Department"
+ - section_id.name == "Marketing"
diff --git a/addons/crm/wizard/crm_lead_to_opportunity.py b/addons/crm/wizard/crm_lead_to_opportunity.py
index e67b7c0c7be..3c847ade42a 100644
--- a/addons/crm/wizard/crm_lead_to_opportunity.py
+++ b/addons/crm/wizard/crm_lead_to_opportunity.py
@@ -86,7 +86,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
lead_obj = self.pool.get('crm.lead')
for lead in lead_obj.browse(cr, uid, context.get('active_ids', []), context=context):
if lead.state in ['done', 'cancel']:
- raise osv.except_osv(_("Warning !"), _("Closed/Cancelled leads cannot be converted into opportunities."))
+ raise osv.except_osv(_("Warning!"), _("Closed/Cancelled leads cannot be converted into opportunities."))
return False
def _convert_opportunity(self, cr, uid, ids, vals, context=None):
diff --git a/addons/crm_claim/i18n/ru.po b/addons/crm_claim/i18n/ru.po
index afcf4702a67..4579b6d8557 100644
--- a/addons/crm_claim/i18n/ru.po
+++ b/addons/crm_claim/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-10-24 05:01+0000\n"
+"PO-Revision-Date: 2013-05-30 14:03+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:44+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-05-31 05:38+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: crm_claim
#: help:crm.claim.stage,fold:0
@@ -23,6 +23,8 @@ msgid ""
"This stage is not visible, for example in status bar or kanban view, when "
"there are no records in that stage to display."
msgstr ""
+"Эта стадия не видима, например в статус-баре или виде канбан, когда нет "
+"записей этой стадии для отображения."
#. module: crm_claim
#: field:crm.claim.report,nbr:0
@@ -46,11 +48,13 @@ msgid ""
"Allows you to configure your incoming mail server, and create claims from "
"incoming emails."
msgstr ""
+"Позволяет настроить сервер входящей почты и создавать претензии из входящих "
+"эл. писем."
#. module: crm_claim
#: model:ir.model,name:crm_claim.model_crm_claim_stage
msgid "Claim stages"
-msgstr ""
+msgstr "Этапы претензии"
#. module: crm_claim
#: selection:crm.claim.report,month:0
@@ -65,7 +69,7 @@ msgstr "Задержка закрытия"
#. module: crm_claim
#: field:crm.claim,message_unread:0
msgid "Unread Messages"
-msgstr ""
+msgstr "Непрочитанные"
#. module: crm_claim
#: field:crm.claim,resolution:0
@@ -100,12 +104,12 @@ msgstr "# претензий"
#. module: crm_claim
#: field:crm.claim.stage,name:0
msgid "Stage Name"
-msgstr ""
+msgstr "Название этапа"
#. module: crm_claim
#: view:crm.claim.report:0
msgid "Salesperson"
-msgstr ""
+msgstr "Продавец"
#. module: crm_claim
#: selection:crm.claim,priority:0
@@ -149,7 +153,7 @@ msgstr "Предупредительная мера"
#. module: crm_claim
#: help:crm.claim,message_unread:0
msgid "If checked new messages require your attention."
-msgstr ""
+msgstr "Если отмечено, новые сообщения требуют вашего внимания."
#. module: crm_claim
#: field:crm.claim.report,date_closed:0
@@ -182,6 +186,8 @@ msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
msgstr ""
+"Содержит сводку по Чаттеру (количество сообщений,...). Эта сводка в формате "
+"html для возможности использования в канбан виде"
#. module: crm_claim
#: view:crm.claim:0
@@ -235,12 +241,12 @@ msgstr "Важность"
#. module: crm_claim
#: field:crm.claim.stage,fold:0
msgid "Hide in Views when Empty"
-msgstr ""
+msgstr "Скрыть вид, если пусто"
#. module: crm_claim
#: field:crm.claim,message_follower_ids:0
msgid "Followers"
-msgstr ""
+msgstr "Подписчики"
#. module: crm_claim
#: view:crm.claim:0
@@ -254,7 +260,7 @@ msgstr "Новый"
#. module: crm_claim
#: field:crm.claim.stage,section_ids:0
msgid "Sections"
-msgstr ""
+msgstr "Секции"
#. module: crm_claim
#: field:crm.claim,email_from:0
@@ -290,7 +296,7 @@ msgstr "Предмет претензии"
#. module: crm_claim
#: model:crm.claim.stage,name:crm_claim.stage_claim3
msgid "Rejected"
-msgstr ""
+msgstr "Отклонено"
#. module: crm_claim
#: field:crm.claim,date_action_next:0
@@ -344,7 +350,7 @@ msgstr ""
#: code:addons/crm_claim/crm_claim.py:194
#, python-format
msgid "No Subject"
-msgstr ""
+msgstr "Без темы"
#. module: crm_claim
#: help:crm.claim.stage,state:0
@@ -358,7 +364,7 @@ msgstr ""
#. module: crm_claim
#: view:crm.claim:0
msgid "Settle"
-msgstr ""
+msgstr "Решать"
#. module: crm_claim
#: model:ir.ui.menu,name:crm_claim.menu_claim_stage_view
@@ -384,7 +390,7 @@ msgstr "Отчет о претензиях"
#. module: crm_claim
#: view:sale.config.settings:0
msgid "Configure"
-msgstr ""
+msgstr "Настроить"
#. module: crm_claim
#: model:crm.case.resource.type,name:crm_claim.type_claim1
@@ -430,6 +436,8 @@ msgid ""
"If you check this field, this stage will be proposed by default on each "
"sales team. It will not assign this stage to existing teams."
msgstr ""
+"Если вы отметите это поле, этот этап будет предложен по умолчанию каждому "
+"отделу продаж. Этот этап не будет назначен существующим отделам."
#. module: crm_claim
#: field:crm.claim,categ_id:0
@@ -485,7 +493,7 @@ msgstr "Закрыто"
#. module: crm_claim
#: view:crm.claim:0
msgid "Reject"
-msgstr ""
+msgstr "Отклонить"
#. module: crm_claim
#: view:res.partner:0
@@ -495,7 +503,7 @@ msgstr "Претензии партнера"
#. module: crm_claim
#: view:crm.claim.stage:0
msgid "Claim Stage"
-msgstr ""
+msgstr "Этап претензии"
#. module: crm_claim
#: view:crm.claim:0
@@ -513,7 +521,7 @@ msgstr "Отложено"
#: field:crm.claim.report,state:0
#: field:crm.claim.stage,state:0
msgid "Status"
-msgstr ""
+msgstr "Статус"
#. module: crm_claim
#: selection:crm.claim.report,month:0
@@ -529,7 +537,7 @@ msgstr "Обычный"
#. module: crm_claim
#: help:crm.claim.stage,sequence:0
msgid "Used to order stages. Lower is better."
-msgstr ""
+msgstr "Используется для упорядочивания этапов. Меньше - лучше."
#. module: crm_claim
#: selection:crm.claim.report,month:0
@@ -549,7 +557,7 @@ msgstr "Телефон"
#. module: crm_claim
#: field:crm.claim,message_is_follower:0
msgid "Is a Follower"
-msgstr ""
+msgstr "Подписан"
#. module: crm_claim
#: field:crm.claim.report,user_id:0
@@ -581,6 +589,10 @@ msgid ""
"the case needs to be reviewed then the status is set "
"to 'Pending'."
msgstr ""
+"Статус устанавливается в \"Черновик\", при создании дела. Если дело в "
+"процессе, то статус - «Открыт». Когда дело закончено, устанавливается статус "
+"\"Готово\". Если дело должно быть пересмотрено то статус установлен в "
+"'Ожидание'."
#. module: crm_claim
#: field:crm.claim,active:0
@@ -628,7 +640,7 @@ msgstr "Дата претензии"
#. module: crm_claim
#: field:crm.claim,message_summary:0
msgid "Summary"
-msgstr ""
+msgstr "Итог"
#. module: crm_claim
#: model:ir.actions.act_window,name:crm_claim.crm_claim_categ_action
@@ -638,7 +650,7 @@ msgstr "Категории претензий"
#. module: crm_claim
#: field:crm.claim.stage,case_default:0
msgid "Common to All Teams"
-msgstr ""
+msgstr "Общее для всех отделов"
#. module: crm_claim
#: view:crm.claim:0
@@ -677,7 +689,7 @@ msgstr "Претензия"
#. module: crm_claim
#: view:crm.claim.report:0
msgid "My Company"
-msgstr ""
+msgstr "Моя компания"
#. module: crm_claim
#: view:crm.claim.report:0
@@ -807,7 +819,7 @@ msgstr "Февраль"
#. module: crm_claim
#: model:ir.model,name:crm_claim.model_sale_config_settings
msgid "sale.config.settings"
-msgstr ""
+msgstr "sale.config.settings"
#. module: crm_claim
#: view:crm.claim.report:0
@@ -833,22 +845,22 @@ msgstr "Мои дела"
#. module: crm_claim
#: model:crm.claim.stage,name:crm_claim.stage_claim2
msgid "Settled"
-msgstr ""
+msgstr "Решено"
#. module: crm_claim
#: help:crm.claim,message_ids:0
msgid "Messages and communication history"
-msgstr ""
+msgstr "Сообщения и история общения"
#. module: crm_claim
#: field:sale.config.settings,fetchmail_claim:0
msgid "Create claims from incoming mails"
-msgstr ""
+msgstr "Создать претензии из входящей почты"
#. module: crm_claim
#: field:crm.claim.stage,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Нумерация"
#. module: crm_claim
#: view:crm.claim:0
@@ -883,6 +895,8 @@ msgid ""
"Link between stages and sales teams. When set, this limitate the current "
"stage to the selected sales teams."
msgstr ""
+"Связь между этапами и отделами продаж. При установке, ограничивает этап для "
+"выбранного отдела продаж."
#. module: crm_claim
#: help:crm.claim.stage,case_refused:0
diff --git a/addons/crm_claim/report/crm_claim_report_view.xml b/addons/crm_claim/report/crm_claim_report_view.xml
index 530eb6061a3..bae02ef8c0c 100644
--- a/addons/crm_claim/report/crm_claim_report_view.xml
+++ b/addons/crm_claim/report/crm_claim_report_view.xml
@@ -55,7 +55,7 @@
-
+
@@ -78,7 +78,7 @@
-
+
diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml
index 6e3521be6f2..f97fe654166 100644
--- a/addons/crm_helpdesk/crm_helpdesk_view.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_view.xml
@@ -151,14 +151,14 @@
+ help="Helpdesk requests that are assigned to me or to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
-
+
diff --git a/addons/crm_helpdesk/i18n/ru.po b/addons/crm_helpdesk/i18n/ru.po
index e8eb90af9d7..bb53c03294f 100644
--- a/addons/crm_helpdesk/i18n/ru.po
+++ b/addons/crm_helpdesk/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-10-24 05:08+0000\n"
+"PO-Revision-Date: 2013-05-30 14:09+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:46+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-05-31 05:38+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: crm_helpdesk
#: field:crm.helpdesk.report,delay_close:0
@@ -46,7 +46,7 @@ msgstr "Март"
#. module: crm_helpdesk
#: field:crm.helpdesk,message_unread:0
msgid "Unread Messages"
-msgstr ""
+msgstr "Непрочитанные"
#. module: crm_helpdesk
#: field:crm.helpdesk,company_id:0
@@ -63,7 +63,7 @@ msgstr "Адреса наблюдателей"
#. module: crm_helpdesk
#: view:crm.helpdesk.report:0
msgid "Salesperson"
-msgstr ""
+msgstr "Продавец"
#. module: crm_helpdesk
#: selection:crm.helpdesk,priority:0
@@ -106,7 +106,7 @@ msgstr "Отменено"
#. module: crm_helpdesk
#: help:crm.helpdesk,message_unread:0
msgid "If checked new messages require your attention."
-msgstr ""
+msgstr "Если отмечено, новые сообщения требуют вашего внимания."
#. module: crm_helpdesk
#: model:ir.actions.act_window,name:crm_helpdesk.action_report_crm_helpdesk
@@ -136,6 +136,8 @@ msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
msgstr ""
+"Содержит сводку по Чаттеру (количество сообщений,...). Эта сводка в формате "
+"html для возможности использования в канбан виде"
#. module: crm_helpdesk
#: view:crm.helpdesk:0
@@ -176,7 +178,7 @@ msgstr "Приоритет"
#. module: crm_helpdesk
#: field:crm.helpdesk,message_follower_ids:0
msgid "Followers"
-msgstr ""
+msgstr "Подписчики"
#. module: crm_helpdesk
#: view:crm.helpdesk:0
@@ -400,7 +402,7 @@ msgstr "В ожидании"
#: view:crm.helpdesk.report:0
#: field:crm.helpdesk.report,state:0
msgid "Status"
-msgstr ""
+msgstr "Статус"
#. module: crm_helpdesk
#: selection:crm.helpdesk.report,month:0
@@ -454,7 +456,7 @@ msgstr "Планируемая выручка"
#. module: crm_helpdesk
#: field:crm.helpdesk,message_is_follower:0
msgid "Is a Follower"
-msgstr ""
+msgstr "Подписан"
#. module: crm_helpdesk
#: field:crm.helpdesk.report,user_id:0
@@ -501,7 +503,7 @@ msgstr "Январь"
#. module: crm_helpdesk
#: field:crm.helpdesk,message_summary:0
msgid "Summary"
-msgstr ""
+msgstr "Итог"
#. module: crm_helpdesk
#: view:crm.helpdesk:0
@@ -517,7 +519,7 @@ msgstr "Прочее"
#. module: crm_helpdesk
#: view:crm.helpdesk.report:0
msgid "My Company"
-msgstr ""
+msgstr "Моя компания"
#. module: crm_helpdesk
#: view:crm.helpdesk:0
@@ -666,7 +668,7 @@ msgstr ""
#. module: crm_helpdesk
#: help:crm.helpdesk,message_ids:0
msgid "Messages and communication history"
-msgstr ""
+msgstr "Сообщения и история общения"
#. module: crm_helpdesk
#: model:ir.actions.act_window,help:crm_helpdesk.crm_helpdesk_categ_action
diff --git a/addons/crm_helpdesk/i18n/zh_CN.po b/addons/crm_helpdesk/i18n/zh_CN.po
index 4a80e7f9385..13843f911c9 100644
--- a/addons/crm_helpdesk/i18n/zh_CN.po
+++ b/addons/crm_helpdesk/i18n/zh_CN.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-12-14 13:33+0000\n"
-"Last-Translator: 盈通 ccdos \n"
+"PO-Revision-Date: 2013-06-07 05:02+0000\n"
+"Last-Translator: PeterGao <306739889@qq.com>\n"
"Language-Team: Chinese (Simplified) \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:46+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-08 05:52+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
#. module: crm_helpdesk
#: field:crm.helpdesk.report,delay_close:0
@@ -656,6 +656,12 @@ msgid ""
" \n"
"If the case needs to be reviewed then the status is set to 'Pending'."
msgstr ""
+"当一个“case(事件)\"被新创建后,这个“case(事件)\"的状态为“草稿”状态。 "
+" \n"
+"若这个“case(事件)\"正在处理中,这个“case(事件)\"的状态为“开启”状态。\n"
+"若这个“case(事件)\"已处理完结,这个“case(事件)\"的状态为“结单”状态。 "
+" \n"
+"若这个“case(事件)\"需暂停再议,这个“case(事件)\"的状态为“挂起”状态。"
#. module: crm_helpdesk
#: help:crm.helpdesk,message_ids:0
diff --git a/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
index 6ce2c60093f..c1ffc00303d 100644
--- a/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
+++ b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
@@ -56,7 +56,7 @@
-
+
@@ -71,7 +71,7 @@
-
+
diff --git a/addons/crm_helpdesk/test/customer_question.eml b/addons/crm_helpdesk/test/customer_question.eml
index 38a4c95fb0c..9bc7c91cb41 100644
--- a/addons/crm_helpdesk/test/customer_question.eml
+++ b/addons/crm_helpdesk/test/customer_question.eml
@@ -3,7 +3,7 @@ Date: Tue, 25 Oct 2011 13:41:17 +0530
From: Mr. John Right
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Lightning/1.0b2 Thunderbird/3.1.8
MIME-Version: 1.0
-To: info@my.com
+To: _helpdesk@my.com
Subject: Where is download link of user manual of your product ?
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
diff --git a/addons/crm_partner_assign/i18n/ru.po b/addons/crm_partner_assign/i18n/ru.po
index f0a7ff509c9..fa995c8e7a1 100644
--- a/addons/crm_partner_assign/i18n/ru.po
+++ b/addons/crm_partner_assign/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2011-03-23 13:46+0000\n"
+"PO-Revision-Date: 2013-06-06 10:24+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:47+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-07 05:48+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,delay_close:0
@@ -25,7 +25,7 @@ msgstr "Задержка закрытия"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,author_id:0
msgid "Author"
-msgstr ""
+msgstr "Автор"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,planned_revenue:0
@@ -38,6 +38,9 @@ msgid ""
"Message type: email for email message, notification for system message, "
"comment for other messages such as user replies"
msgstr ""
+"Тип сообщения: эл. почта - для эл. почты, уведомление - для системных "
+"сообщений, комментарий - для остальных сообщений таких как сообщения "
+"пользователя"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,nbr:0
@@ -53,7 +56,7 @@ msgstr "Группировать по ..."
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,body:0
msgid "Automatically sanitized HTML contents"
-msgstr ""
+msgstr "Автоматически обработанное HTML содержимое"
#. module: crm_partner_assign
#: view:crm.lead:0
@@ -68,7 +71,7 @@ msgstr "Геолоцировать"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,starred:0
msgid "Starred"
-msgstr ""
+msgstr "Отмеченные"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
@@ -81,6 +84,8 @@ msgid ""
"Email address of the sender. This field is set when no matching partner is "
"found for incoming emails."
msgstr ""
+"Адрес эл. почты отправителя. Это поле устанавливается когда партнер не "
+"определен для входящих писем."
#. module: crm_partner_assign
#: view:crm.partner.report.assign:0
@@ -111,7 +116,7 @@ msgstr "Компания"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,notification_ids:0
msgid "Notifications"
-msgstr ""
+msgstr "Уведомления"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,date_assign:0
@@ -123,7 +128,7 @@ msgstr "Дата партнера"
#: view:crm.partner.report.assign:0
#: view:res.partner:0
msgid "Salesperson"
-msgstr ""
+msgstr "Продавец"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,priority:0
@@ -170,12 +175,12 @@ msgstr "Географическое назначение"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_lead_forward_to_partner
msgid "Email composition wizard"
-msgstr ""
+msgstr "Мастер составления эл. почты"
#. module: crm_partner_assign
#: field:crm.partner.report.assign,turnover:0
msgid "Turnover"
-msgstr ""
+msgstr "Оборот"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,date_closed:0
@@ -199,7 +204,7 @@ msgstr ""
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,type:0
msgid "System notification"
-msgstr ""
+msgstr "Системное уведомление"
#. module: crm_partner_assign
#: code:addons/crm_partner_assign/wizard/crm_forward_to_partner.py:74
@@ -271,7 +276,7 @@ msgstr "Тип"
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,type:0
msgid "Email"
-msgstr ""
+msgstr "Эл. почта"
#. module: crm_partner_assign
#: help:crm.lead,partner_assigned_id:0
@@ -286,7 +291,7 @@ msgstr "Низший"
#. module: crm_partner_assign
#: view:crm.partner.report.assign:0
msgid "Date Invoice"
-msgstr ""
+msgstr "Дата счета"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,template_id:0
@@ -311,12 +316,12 @@ msgstr "Дата создания"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_res_partner_activation
msgid "res.partner.activation"
-msgstr ""
+msgstr "res.partner.activation"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,parent_id:0
msgid "Parent Message"
-msgstr ""
+msgstr "Родительское сообщение"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,res_id:0
@@ -358,12 +363,12 @@ msgstr "Этап"
#: view:crm.lead.report.assign:0
#: field:crm.lead.report.assign,state:0
msgid "Status"
-msgstr ""
+msgstr "Статус"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,to_read:0
msgid "To read"
-msgstr ""
+msgstr "Прочитать"
#. module: crm_partner_assign
#: code:addons/crm_partner_assign/wizard/crm_forward_to_partner.py:74
@@ -418,12 +423,12 @@ msgstr "Количество дней, для закрытия вопроса"
#: help:crm.lead.forward.to.partner,notified_partner_ids:0
msgid ""
"Partners that have a notification pushing this message in their mailboxes"
-msgstr ""
+msgstr "Партнеры которые имеют уведомление доставляемое в их почтовые ящики"
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,type:0
msgid "Comment"
-msgstr ""
+msgstr "Комментарий"
#. module: crm_partner_assign
#: field:res.partner,partner_weight:0
@@ -451,7 +456,7 @@ msgstr "Декабрь"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,vote_user_ids:0
msgid "Users that voted for this message"
-msgstr ""
+msgstr "Пользователи, которые проголосовали за это сообщение"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@@ -467,7 +472,7 @@ msgstr "Дата открытия"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,child_ids:0
msgid "Child Messages"
-msgstr ""
+msgstr "Связанные сообщения"
#. module: crm_partner_assign
#: field:crm.partner.report.assign,date_review:0
@@ -483,17 +488,17 @@ msgstr "Тема"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
msgid "or"
-msgstr ""
+msgstr "или"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,body:0
msgid "Contents"
-msgstr ""
+msgstr "Содержимое"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,vote_user_ids:0
msgid "Votes"
-msgstr ""
+msgstr "Голоса"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@@ -504,6 +509,8 @@ msgstr "# Предложений"
#: help:crm.lead.forward.to.partner,starred:0
msgid "Current user has a starred notification linked to this message"
msgstr ""
+"Текущий пользователь имеет отмеченное уведомление, связанное с этим "
+"сообщением"
#. module: crm_partner_assign
#: field:crm.partner.report.assign,date_partnership:0
@@ -561,7 +568,7 @@ msgstr "Август"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,record_name:0
msgid "Name get of the related document."
-msgstr ""
+msgstr "Название связанного документа."
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,priority:0
@@ -663,7 +670,7 @@ msgstr ""
#. module: crm_partner_assign
#: field:crm.partner.report.assign,period_id:0
msgid "Invoice Period"
-msgstr ""
+msgstr "Период счета"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_res_partner_grade
@@ -684,7 +691,7 @@ msgstr "Вложения"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,record_name:0
msgid "Message Record Name"
-msgstr ""
+msgstr "Название записи сообщения"
#. module: crm_partner_assign
#: field:res.partner.activation,sequence:0
@@ -699,6 +706,8 @@ msgid ""
"Cannot contact geolocation servers. Please make sure that your internet "
"connection is up and running (%s)."
msgstr ""
+"Не удается связаться с сервером геолокации. Пожалуйста, убедитесь, что ваше "
+"подключение к интернету работает (%s)."
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,month:0
@@ -724,7 +733,7 @@ msgstr "Открыто"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,subtype_id:0
msgid "Subtype"
-msgstr ""
+msgstr "Подтип"
#. module: crm_partner_assign
#: field:res.partner,date_localization:0
@@ -739,12 +748,12 @@ msgstr "Текущий"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_lead
msgid "Lead/Opportunity"
-msgstr ""
+msgstr "Кандидат/Предложение"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,notified_partner_ids:0
msgid "Notified partners"
-msgstr ""
+msgstr "Уведомленные партнеры"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
@@ -775,7 +784,7 @@ msgstr "Вероятная выручка"
#: field:res.partner,activation:0
#: view:res.partner.activation:0
msgid "Activation"
-msgstr ""
+msgstr "Активация"
#. module: crm_partner_assign
#: view:crm.lead:0
@@ -792,6 +801,8 @@ msgstr ""
#: help:crm.lead.forward.to.partner,to_read:0
msgid "Current user has an unread notification linked to this message"
msgstr ""
+"Текущий пользователь имеет непрочитанные уведомления, связанные с этим "
+"сообщением"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,type:0
@@ -860,6 +871,8 @@ msgid ""
"Technical field holding the message notifications. Use notified_partner_ids "
"to access notified partners."
msgstr ""
+"Техническое поле, содержащее уведомления. Используйте notified_partner_ids "
+"для доступа к оповещаемым партнерам."
#. module: crm_partner_assign
#: view:crm.partner.report.assign:0
@@ -874,12 +887,12 @@ msgstr "CRM - отчет по кандидатам"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,composition_mode:0
msgid "Composition mode"
-msgstr ""
+msgstr "Режим составления"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,model:0
msgid "Related Document Model"
-msgstr ""
+msgstr "Модель связанного документа"
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,history_mode:0
@@ -892,6 +905,8 @@ msgid ""
"Author of the message. If not set, email_from may hold an email address that "
"did not match any partner."
msgstr ""
+"Автор сообщения. Если не установлен, email_from может содержать адрес почты, "
+"который не соответствует ни одному партнеру."
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_partner_report_assign
@@ -906,12 +921,12 @@ msgstr "Высокий"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,partner_ids:0
msgid "Additional contacts"
-msgstr ""
+msgstr "Дополнительные контакты"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,parent_id:0
msgid "Initial thread message."
-msgstr ""
+msgstr "Первое сообщение цепочки."
#. module: crm_partner_assign
#: field:crm.lead.report.assign,create_date:0
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
index 924f96180cc..724102a84b1 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -124,6 +124,7 @@ class crm_lead_forward_to_partner(osv.TransientModel):
lead_ids = context and context.get('active_ids', []) or []
value = self.default_get(cr, uid, ['body', 'email_to', 'email_cc', 'subject', 'history_mode'], context=context)
value.pop('composition_mode')
+ self.pool.get('crm.lead').message_subscribe(cr, uid, lead_ids, [partner.id for partner in wizard.partner_ids], context=context)
self.write(cr, uid, ids, value, context=context)
return self.send_mail(cr, uid, ids, context=context)
diff --git a/addons/crm_profiling/i18n/ru.po b/addons/crm_profiling/i18n/ru.po
index 8cbe1695e82..a7325d894c5 100644
--- a/addons/crm_profiling/i18n/ru.po
+++ b/addons/crm_profiling/i18n/ru.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-05-10 17:51+0000\n"
+"PO-Revision-Date: 2013-05-30 14:05+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:32+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-05-31 05:38+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: crm_profiling
#: view:crm_profiling.questionnaire:0
@@ -151,7 +151,7 @@ msgstr "Используйте правила профилирования"
#. module: crm_profiling
#: constraint:crm.segmentation:0
msgid "Error ! You cannot create recursive profiles."
-msgstr ""
+msgstr "Ошибка ! Нельзя создать рекурсивный профиль."
#. module: crm_profiling
#: field:crm.segmentation,answer_yes:0
@@ -200,7 +200,7 @@ msgstr "Сохранить данные"
#. module: crm_profiling
#: view:open.questionnaire:0
msgid "or"
-msgstr ""
+msgstr "или"
#~ msgid ""
#~ "The Object name must start with x_ and not contain any special character !"
diff --git a/addons/delivery/sale.py b/addons/delivery/sale.py
index 86a518ebca9..1b797290632 100644
--- a/addons/delivery/sale.py
+++ b/addons/delivery/sale.py
@@ -51,10 +51,10 @@ class sale_order(osv.osv):
for order in self.browse(cr, uid, ids, context=context):
grid_id = carrier_obj.grid_get(cr, uid, [order.carrier_id.id], order.partner_shipping_id.id)
if not grid_id:
- raise osv.except_osv(_('No grid available !'), _('No grid matching for this carrier !'))
+ raise osv.except_osv(_('No Grid Available!'), _('No grid matching for this carrier!'))
if not order.state in ('draft'):
- raise osv.except_osv(_('Order not in draft state !'), _('The order state have to be draft to add delivery lines.'))
+ raise osv.except_osv(_('Order not in Draft State!'), _('The order state have to be draft to add delivery lines.'))
grid = grid_obj.browse(cr, uid, grid_id, context=context)
diff --git a/addons/document_page/document_page_view.xml b/addons/document_page/document_page_view.xml
index 08c77647d17..4d0b5596e75 100644
--- a/addons/document_page/document_page_view.xml
+++ b/addons/document_page/document_page_view.xml
@@ -26,6 +26,7 @@
+
diff --git a/addons/document_webdav/webdav_setup.xml b/addons/document_webdav/webdav_setup.xml
index d75c416a93e..dbf6bc8fbcc 100644
--- a/addons/document_webdav/webdav_setup.xml
+++ b/addons/document_webdav/webdav_setup.xml
@@ -1,4 +1,3 @@
-
+
+ Reserve
+
+
+ Manager
+
+
+ IT
+
+
+ Sales
+
diff --git a/addons/hr_recruitment/hr_recruitment_demo.xml b/addons/hr_recruitment/hr_recruitment_demo.xml
new file mode 100644
index 00000000000..c15e0deb188
--- /dev/null
+++ b/addons/hr_recruitment/hr_recruitment_demo.xml
@@ -0,0 +1,129 @@
+
+
+
+
+ Salesperson
+
+
+
+
+ 2
+ Enrique Jones
+ 9963214587
+
+
+ Send mail regarding our interview
+
+
+ Trainee - MCA
+
+
+
+
+
+ 3
+ Marie Justine
+ 9988774455
+
+ 6633225
+
+ Call to define real needs about training
+
+
+ Fresher
+
+
+
+
+
+ 1
+ Jose
+
+ 999666735
+
+ Send mail regarding our interview
+
+
+ Marketing Job
+
+
+
+
+
+ John Bruno
+
+
+ Call to define real needs about training
+
+
+ More than 5 yrs Experience in PHP
+
+
+
+
+
+ Sandra Elvis
+
+
+ Send mail regarding our interview
+
+
+ Finance Job
+
+
+
+
+
+ 4
+ David Armstrong
+
+ 33968745
+
+ Send mail regarding our interview
+
+
+ Trainee - MCA
+
+
+
+
+ Tina Augustie
+ 9898745745
+
+ 6630125
+
+ Send mail regarding our interview
+
+
+ Programmer
+
+
+
+
+ Shane Williams
+ 9812398524
+
+ 6630125
+ 11000.0
+
+ Send mail regarding our interview
+
+
+ Advertisement
+
+
+
+
+ David Armstrong
+ 9988774455
+
+ 11000.0
+
+ Send mail regarding our interview
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/hr_recruitment/hr_recruitment_demo.yml b/addons/hr_recruitment/hr_recruitment_demo.yml
deleted file mode 100644
index 2554c690c15..00000000000
--- a/addons/hr_recruitment/hr_recruitment_demo.yml
+++ /dev/null
@@ -1,102 +0,0 @@
--
- !record {model: hr.applicant, id: hr_case_salesman0}:
- date: !eval time.strftime('%Y-%m-01 10:35:50')
- type_id: degree_graduate
- priority: '2'
- partner_name: 'Enrique Jones'
- partner_mobile: '9963214587'
- job_id: hr.job_developer
- stage_id: stage_job1
- name: 'Salesperson'
- partner_phone: '1236547890'
-
--
- !record {model: hr.applicant, id: hr_case_traineemca0}:
- date: !eval time.strftime('%Y-%m-10 18:15:00')
- type_id: degree_bac5
- priority: '3'
- user_id: base.user_demo
- partner_name: 'Marie Justine'
- partner_mobile: '9988774455'
- job_id: hr.job_developer
- stage_id: stage_job4
- name: 'Trainee - MCA'
- partner_phone: '6633225'
--
- !record {model: hr.applicant, id: hr_case_fresher0}:
- date: !eval time.strftime('%Y-%m-15 16:10:00')
- type_id: degree_licenced
- priority: '1'
- user_id: base.user_root
- partner_name: 'Jose'
- job_id: hr.job_developer
- stage_id: stage_job3
- name: 'Fresher'
- partner_phone: '999666735'
--
- !record {model: hr.applicant, id: hr_case_yrsexperienceinphp0}:
- date: !eval time.strftime('%Y-%m-25 16:25:52')
- job_id: hr.job_developer
- type_id: degree_bac5
- user_id: base.user_root
- partner_name: 'Sandra Elvis'
- stage_id: stage_job6
- name: 'More than 5 yrs Experience in PHP'
--
- !record {model: hr.applicant, id: hr_case_marketingjob0}:
- date: !eval time.strftime('%Y-%m-26 17:15:32')
- type_id: degree_licenced
- user_id: base.user_demo
- partner_name: 'John Bruno'
- job_id: hr.job_developer
- color: 5
- stage_id: stage_job5
- name: 'Marketing Job'
--
- !record {model: hr.applicant, id: hr_case_financejob0}:
- date: !eval time.strftime('%Y-%m-26 17:39:42')
- type_id: degree_licenced
- priority: '4'
- partner_name: 'David Armstrong'
- partner_mobile: '9966332214'
- job_id: hr.job_developer
- stage_id: stage_job2
- name: 'Finance Job'
- partner_phone: '33968745'
--
- !record {model: hr.applicant, id: hr_case_traineemca1}:
- date: !eval time.strftime('%Y-%m-12 17:49:19')
- type_id: degree_bac5
- partner_name: 'Tina Augustie'
- partner_mobile: '9898745745'
- job_id: hr.job_developer
- stage_id: stage_job4
- name: 'Trainee - MCA'
- partner_phone: '6630125'
-
--
- !record {model: hr.applicant, id: hr_case_programmer}:
- date: !eval time.strftime('%Y-%m-12 17:49:19')
- type_id: degree_bac5
- partner_name: 'Shane Williams'
- partner_mobile: '9812398524'
- stage_id: stage_job4
- name: 'Programmer'
- partner_phone: '6630125'
- job_id: hr.job_developer
- department_id: hr.dep_rd
- salary_expected: 11000.0
-
--
- !record {model: hr.applicant, id: hr_case_advertisement}:
- date: !eval time.strftime('%Y-%m-26 17:39:42')
- type_id: degree_licenced
- partner_name: 'David Armstrong'
- job_id: hr.job_developer
- stage_id: stage_job2
- color: 4
- name: 'Advertisement'
- salary_expected: 11000.0
--
- !record {model: hr.job, id: hr.job_developer}:
- survey_id: hr_recruitment.survey_job_0
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index 716c1cba8d5..f6fb202252c 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -263,9 +263,14 @@
Mobile:
-
-
Thanks for the genuine interest you have shown in OpenERP.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>Thanks for the genuine interest you have shown in OpenERP.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>For OpenERP OnDemand Free Trial 2010
@@ -53,11 +52,11 @@
- Hello,
-
We have very good offer that might suit you.
- We suggest you subscribe to the OpenERP Discovery Day on May 2010.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>We have very good offer that might suit you.
+ We suggest you subscribe to the OpenERP Discovery Day on May 2010.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>For OpenERP Discovery Day on May 2010
@@ -68,10 +67,10 @@
- Hello,
-
Thanks for showing interest and for subscribing to the OpenERP Discovery Day.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>Thanks for showing interest and for subscribing to the OpenERP Discovery Day.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>For OpenERP Discovery Day
@@ -82,10 +81,10 @@
- Hello,
-
Thanks for showing interest and buying the OpenERP book.
+ <p>Hello,</p>
+ <p>Thanks for showing interest and buying the OpenERP book.</p>
If any further information required kindly revert back.
-
We have very good offer that might suit you.
- For our gold partners,We are arranging free technical training on june,2010.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>We have very good offer that might suit you.
+ For our gold partners,We are arranging free technical training on june,2010.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>technical training to gold partners
@@ -110,11 +109,11 @@
- Hello,
-
We have very good offer that might suit you.
- For our silver partners,We are paid technical training on june,2010.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>We have very good offer that might suit you.
+ For our silver partners,We are paid technical training on june,2010.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>training to silver partners
@@ -125,11 +124,11 @@
- Hello,
-
We have very good offer that might suit you.
- For our silver partners, we are offering Gold partnership.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>We have very good offer that might suit you.
+ For our silver partners, we are offering Gold partnership.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>gold partnership to silver partners
@@ -140,11 +139,11 @@
- Hello,
-
Thanks for showing interest and for subscribing to technical training.
- If any further information required kindly revert back.I really appreciate your co-operation on this.
-
If any further information is required, do not hesitate to reply to this message.
-
Regards,OpenERP Team,
]]>
+ <p>Hello,</p>
+ <p>Thanks for showing interest and for subscribing to technical training.</p>
+ If any further information required kindly revert back.I really appreciate your co-operation on this.</p>
+ <p>If any further information is required, do not hesitate to reply to this message.</p>
+ <p>Regards,OpenERP Team,</p>subscribing to technical training
@@ -171,7 +170,7 @@
Propose a 1 month free trial for an OnDemand offer
-
+ report
@@ -180,27 +179,27 @@
Thanks for showing interest
-
+ Propose to subscribe to the OpenERP Discovery Day on May 2010
-
+ Thanks for subscribing to the OpenERP Discovery Day
-
+ Propose to buy the OpenERP Book
-
+ report
@@ -209,81 +208,81 @@
Thanks for buying the OpenERP book
-
+ Propose a free technical training to Gold partners
-
+ Propose paid training to Silver partners
-
+ Propose gold partnership to silver partners
-
+ Thanks for subscribing to technical training
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -296,4 +295,4 @@
-
+
\ No newline at end of file
diff --git a/addons/membership/process/membership_process.xml b/addons/membership/process/membership_process.xml
index d67ee864b34..b3ba426ff4a 100644
--- a/addons/membership/process/membership_process.xml
+++ b/addons/membership/process/membership_process.xml
@@ -87,16 +87,16 @@
-
-
+
+
-
-
+
+
@@ -110,25 +110,25 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/addons/mrp/html/index.html b/addons/mrp/html/index.html
index 3ee973d7874..5777eb5f147 100644
--- a/addons/mrp/html/index.html
+++ b/addons/mrp/html/index.html
@@ -9,7 +9,6 @@
-
@@ -190,4 +189,5 @@ manufacturing operations.
-
+
+
diff --git a/addons/mrp/i18n/mn.po b/addons/mrp/i18n/mn.po
index 8d3c0aee785..53f793c1804 100644
--- a/addons/mrp/i18n/mn.po
+++ b/addons/mrp/i18n/mn.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-07-21 12:33+0000\n"
-"Last-Translator: FULL NAME \n"
+"PO-Revision-Date: 2013-06-04 04:00+0000\n"
+"Last-Translator: erdenebold \n"
"Language-Team: Mongolian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:01+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-05 05:32+0000\n"
+"X-Generator: Launchpad (build 16660)\n"
#. module: mrp
#: help:mrp.config.settings,module_mrp_repair:0
@@ -48,7 +48,7 @@ msgstr "Дамжлагуудын Ашиглалт"
#. module: mrp
#: view:mrp.routing.workcenter:0
msgid "Routing Work Centers"
-msgstr "Дамжлагуудын маршрут"
+msgstr "Шугамын дамжлагууд"
#. module: mrp
#: field:mrp.production.workcenter.line,cycle:0
@@ -86,12 +86,12 @@ msgstr ""
#: model:ir.actions.act_window,name:mrp.mrp_routing_action
#: model:ir.ui.menu,name:mrp.menu_mrp_routing_action
msgid "Routings"
-msgstr "Маршрут"
+msgstr "Шугам"
#. module: mrp
#: view:mrp.bom:0
msgid "Search Bill Of Material"
-msgstr "Жор Хайх"
+msgstr "Орц Хайх"
#. module: mrp
#: model:process.node,note:mrp.process_node_stockproduct1
@@ -112,8 +112,8 @@ msgid ""
"Number of iterations this work center has to do in the specified operation "
"of the routing."
msgstr ""
-"Үйлдвэрлэлийн нэг маршрутын хувьд уг дамжлага өөрийн үйлдлийг давтан "
-"гүйцэтгэх давтамжын тоо."
+"Үйлдвэрлэлийн нэг шугамын хувьд уг дамжлага өөрийн үйлдлийг давтан гүйцэтгэх "
+"давтамжын тоо."
#. module: mrp
#: view:product.product:0
@@ -214,7 +214,7 @@ msgstr ""
#: code:addons/mrp/mrp.py:633
#, python-format
msgid "Cannot cancel manufacturing order!"
-msgstr ""
+msgstr "Үйлдвэрийн захиалгыг цуцлах боломжгүй!"
#. module: mrp
#: field:mrp.workcenter,costs_cycle_account_id:0
@@ -337,7 +337,7 @@ msgstr "Бараа Үйлдвэрлэх"
#. module: mrp
#: constraint:mrp.bom:0
msgid "Error ! You cannot create recursive BoM."
-msgstr "Алдаа ! Тойрог хамааралтай жор үүсгэж болохгүй."
+msgstr "Алдаа ! Тойрог хамааралтай орц үүсгэж болохгүй."
#. module: mrp
#: model:ir.model,name:mrp.model_mrp_routing_workcenter
@@ -423,7 +423,7 @@ msgstr ""
#: field:mrp.production,product_qty:0
#: field:mrp.production.product.line,product_qty:0
msgid "Product Quantity"
-msgstr ""
+msgstr "Барааны тоо"
#. module: mrp
#: help:mrp.production,picking_id:0
@@ -491,13 +491,13 @@ msgstr "Товлогдсон огноо"
#: code:addons/mrp/procurement.py:124
#, python-format
msgid "Manufacturing Order %s created."
-msgstr ""
+msgstr "Үйлдвэрлэлийн захиалга %s үүсгэгдлээ."
#. module: mrp
#: view:mrp.bom:0
#: report:mrp.production.order:0
msgid "Bill Of Material"
-msgstr "Жор"
+msgstr "Орц"
#. module: mrp
#: help:mrp.routing,location_id:0
@@ -518,7 +518,7 @@ msgstr "Нөөцийн Үнийн Хазайлт"
#. module: mrp
#: model:ir.actions.act_window,name:mrp.action2
msgid "Bill of Materials Structure"
-msgstr "Жорын Бүтэц"
+msgstr "Орцын Бүтэц"
#. module: mrp
#: model:process.node,note:mrp.process_node_serviceproduct0
@@ -560,7 +560,7 @@ msgstr ""
msgid ""
"The Bill of Material is linked to a routing, i.e. the succession of work "
"centers."
-msgstr "Жор нь маршруттай холбогдсон, ө.х. дамжлагуудын цуваанууд"
+msgstr "Орц нь шугамтай холбогдсон, ө.х. дамжлагуудын цуваанууд"
#. module: mrp
#: view:mrp.production:0
@@ -592,7 +592,7 @@ msgstr "Нөөцийн үнэ"
#. module: mrp
#: model:ir.actions.act_window,name:mrp.action_product_bom_structure
msgid "Product BoM Structure"
-msgstr "Барааны Жорын Бүтэц"
+msgstr "Барааны Орцын Бүтэц"
#. module: mrp
#: view:mrp.production:0
@@ -603,12 +603,12 @@ msgstr "Үйлдвэрлэл Хайх"
#: help:mrp.routing.workcenter,sequence:0
msgid ""
"Gives the sequence order when displaying a list of routing Work Centers."
-msgstr "Маршруутын дамжлагуудыг жагсаалтаар харуулах дэс дарааллыг өгнө."
+msgstr "Шугамын дамжлагуудыг жагсаалтаар харуулах дэс дарааллыг өгнө."
#. module: mrp
#: field:mrp.bom,child_complete_ids:0
msgid "BoM Hierarchy"
-msgstr "Жорын удамшил"
+msgstr "Орцын удамшил"
#. module: mrp
#: model:process.transition,name:mrp.process_transition_stockproduction0
@@ -637,7 +637,7 @@ msgstr "Бэлтгэлтийн Сондгойрол"
#. module: mrp
#: field:mrp.bom,bom_lines:0
msgid "BoM Lines"
-msgstr "Жорын мөрүүд"
+msgstr "Орцын мөрүүд"
#. module: mrp
#: field:mrp.workcenter,time_start:0
@@ -650,13 +650,13 @@ msgid ""
"If the active field is set to False, it will allow you to hide the routing "
"without removing it."
msgstr ""
-"Идэвхтэй талбар нь худал буюу тэмдэглэгдээгүй байвал машрутыг устгалгүйгээр "
+"Идэвхтэй талбар нь худал буюу тэмдэглэгдээгүй байвал шугамыг устгалгүйгээр "
"нуудаг."
#. module: mrp
#: model:process.transition,name:mrp.process_transition_billofmaterialrouting0
msgid "Material Routing"
-msgstr "Материалын Машрут"
+msgstr "Материалын Шугам"
#. module: mrp
#: view:mrp.production:0
@@ -676,13 +676,13 @@ msgstr "Дамжлагын Ачаалал"
#: code:addons/mrp/procurement.py:50
#, python-format
msgid "No BoM defined for this product !"
-msgstr "Энэ бараанд жор тодорхойлогдоогүй байна !"
+msgstr "Энэ бараанд орц тодорхойлогдоогүй байна !"
#. module: mrp
#: model:ir.actions.act_window,name:mrp.mrp_bom_form_action2
#: model:ir.ui.menu,name:mrp.menu_mrp_bom_form_action2
msgid "Bill of Material Components"
-msgstr "Жорын бүрдэлүүд"
+msgstr "Орцын бүрдэлүүд"
#. module: mrp
#: model:ir.model,name:mrp.model_stock_move
@@ -708,7 +708,7 @@ msgid ""
"operations and to plan future loads on work centers based on production "
"plannification."
msgstr ""
-"Эцсийн барааг үйлдвэрлэх үйлдлүүд (дамжлагууд)-н жагсаалт. Машрут гэдэг нь "
+"Эцсийн барааг үйлдвэрлэх үйлдлүүд (дамжлагууд)-н жагсаалт. Шугам гэдэг нь "
"үндсэндээ дамжлагуудын өртөгийг тооцоолох болон ажлын ачааллыг тооцоолоход "
"үйлдвэрлэлийн төлөвлөгөөн дээр суурилан бодоход хэрэглэгддэг."
@@ -734,7 +734,7 @@ msgstr ""
#. module: mrp
#: constraint:mrp.bom:0
msgid "BoM line product should not be same as BoM product."
-msgstr "Жорын мөр нь жорын бараатайгаа ижил байж болохгүй."
+msgstr "Орцын мөр нь орцын бараатайгаа ижил байж болохгүй."
#. module: mrp
#: view:mrp.production:0
@@ -744,7 +744,7 @@ msgstr "Үйлдвэрлэгдэж буй"
#. module: mrp
#: model:ir.ui.menu,name:mrp.menu_mrp_property
msgid "Master Bill of Materials"
-msgstr "Мастер жор"
+msgstr "Мастер орц"
#. module: mrp
#: help:mrp.config.settings,module_product_manufacturer:0
@@ -907,7 +907,7 @@ msgid ""
"All product quantities must be greater than 0.\n"
"You should install the mrp_byproduct module if you want to manage extra "
"products on BoMs !"
-msgstr ""
+msgstr "Бүх бүтээгдэхүүнийг тоог 0-оос эхэлж үүсгэнэ."
#. module: mrp
#: view:mrp.production:0
@@ -954,7 +954,7 @@ msgstr ""
#. module: mrp
#: field:mrp.bom,type:0
msgid "BoM Type"
-msgstr "Жорын төрөл"
+msgstr "Орцын төрөл"
#. module: mrp
#: code:addons/mrp/procurement.py:52
@@ -962,7 +962,7 @@ msgstr "Жорын төрөл"
msgid ""
"Procurement '%s' has an exception: 'No BoM defined for this product !'"
msgstr ""
-"'%s' татан авалтад сондгойрол байна: 'Бараанд жор тодорхойлогдоогүй !'"
+"'%s' татан авалтад сондгойрол байна: 'Бараанд орц тодорхойлогдоогүй !'"
#. module: mrp
#: view:mrp.property:0
@@ -1077,7 +1077,7 @@ msgstr "Нөөцлүүлэх"
#. module: mrp
#: report:bom.structure:0
msgid "BOM Name"
-msgstr "Жорын нэр"
+msgstr "Орцын нэр"
#. module: mrp
#: model:ir.actions.act_window,name:mrp.act_product_manufacturing_open
@@ -1167,7 +1167,7 @@ msgstr "Хийгдэж байгаа үйлдвэрлэлийн захиалгу
#. module: mrp
#: model:ir.actions.client,name:mrp.action_client_mrp_menu
msgid "Open MRP Menu"
-msgstr ""
+msgstr "Нээлттэй MRP цэс"
#. module: mrp
#: model:ir.actions.act_window,name:mrp.mrp_production_action4
@@ -1194,7 +1194,7 @@ msgstr "Циклийн Өртөг"
#: code:addons/mrp/wizard/change_production_qty.py:88
#, python-format
msgid "Cannot find bill of material for this product."
-msgstr ""
+msgstr "Энэ бараа материалаар хайх боломжгүй."
#. module: mrp
#: selection:mrp.workcenter.load,measure_unit:0
@@ -1216,8 +1216,7 @@ msgstr "Нөөцүүд"
msgid ""
"Time in hours for this Work Center to achieve the operation of the specified "
"routing."
-msgstr ""
-"Заагдсан маршрутын үйлдлийг гүйцэтгэхэд энэ дамжлагын хугацаа цагаар."
+msgstr "Заагдсан шугамын үйлдлийг гүйцэтгэхэд энэ дамжлагын хугацаа цагаар."
#. module: mrp
#: field:mrp.workcenter,costs_journal_id:0
@@ -1272,7 +1271,7 @@ msgstr "Үйлдвэрлэлийг эхлүүлэхэд бэлэн Үйлдвэ
#: field:mrp.production,bom_id:0
#: model:process.node,name:mrp.process_node_billofmaterial0
msgid "Bill of Material"
-msgstr "Жор"
+msgstr "Орц"
#. module: mrp
#: view:mrp.workcenter.load:0
@@ -1304,9 +1303,9 @@ msgid ""
"Routing is indicated then,the third tab of a production order (Work Centers) "
"will be automatically pre-completed."
msgstr ""
-"Маршрут нь дамжлагууд ямар хугацаагаар хэдэн циклээр ашиглагдахыг "
-"илэрхийлдэг. Хэрэв маршрут байгаа бол гурав дахь үйлдвэрлэлийн дарааллын "
-"хавтас автоматаар бөглөгддөг."
+"Шугам нь дамжлагууд ямар хугацаагаар хэдэн циклээр ашиглагдахыг илэрхийлдэг. "
+"Хэрэв шугам байгаа бол гурав дахь үйлдвэрлэлийн дарааллын хавтас автоматаар "
+"бөглөгддөг."
#. module: mrp
#: code:addons/mrp/mrp.py:505
@@ -1431,7 +1430,7 @@ msgstr "Үйлдвэрлэлийн дамжлагыг хайх"
#. module: mrp
#: view:mrp.bom:0
msgid "BoM Structure"
-msgstr "Жорын бүтэц"
+msgstr "Орцын бүтэц"
#. module: mrp
#: field:mrp.production,date_start:0
@@ -1541,7 +1540,7 @@ msgstr "БЗ Дугаар"
#: code:addons/mrp/mrp.py:505
#, python-format
msgid "Cannot delete a manufacturing order in state '%s'."
-msgstr ""
+msgstr "Үйлдвэрлэлийн захиалгын '%s' төлөвт устгах боломжгүй."
#. module: mrp
#: selection:mrp.production,state:0
@@ -1689,7 +1688,7 @@ msgstr "Нөөц"
#: help:mrp.bom,date_stop:0
msgid "Validity of this BoM or component. Keep empty if it's always valid."
msgstr ""
-"Энэ жор эсвэл бүрэлдхүүний зөв эсэхийн шалгалт. Хэрэв байнга зөв бол хоосон "
+"Орц эсвэл бүрэлдэхүүний зөв эсэхийн шалгалт. Хэрэв байнга зөв бол хоосон "
"үлдээнэ."
#. module: mrp
@@ -1710,7 +1709,7 @@ msgid ""
"operations and to plan future loads on work centers based on production "
"planning."
msgstr ""
-"Барааг үйлдвэрлэх үйлдлийн жагсаалт (дамжлагын жагсаалт). Машрут нь "
+"Барааг үйлдвэрлэх үйлдлийн жагсаалт (дамжлагын жагсаалт). Шугам нь "
"үйлдвэрлэлийн захиалга дээр үндэслэн дамжлагуудын өртөгийг тооцох, ажлын "
"ирээдүйн ачааллыг тооцоолох зэрэгт голчлон хэрэглэгддэг."
@@ -1816,8 +1815,8 @@ msgid ""
"are products themselves) can also have their own Bill of Material (multi-"
"level)."
msgstr ""
-"Жор гэдэг нь барааны задаргаа юм. Бүрэлдхүүнүүд (мөн бараанууд) нь мөн "
-"өөрийн жортой буюу олон түвшний жор байж болно."
+"Орц гэдэг нь барааны задаргаа юм. Бүрэлдэхүүнүүд (мөн бараанууд) нь мөн "
+"өөрийн орцтой буюу олон түвшний орц байж болно."
#. module: mrp
#: field:mrp.bom,company_id:0
@@ -1882,7 +1881,7 @@ msgstr "Бүрэлдэхүүнүүд"
#: report:bom.structure:0
#: model:ir.actions.report.xml,name:mrp.report_bom_structure
msgid "BOM Structure"
-msgstr "Жорын бүтэц"
+msgstr "Орцын бүтэц"
#. module: mrp
#: field:mrp.config.settings,module_mrp_jit:0
@@ -1902,7 +1901,7 @@ msgstr "Хүчинтэй байх эхлэл"
#. module: mrp
#: selection:mrp.bom,type:0
msgid "Normal BoM"
-msgstr "Хэвийн жор"
+msgstr "Хэвийн орц"
#. module: mrp
#: field:res.company,manufacturing_lead:0
@@ -1958,7 +1957,7 @@ msgid ""
"If the active field is set to False, it will allow you to hide the bills of "
"material without removing it."
msgstr ""
-"Идэвхтэй талбар худал буюу тэмдэглэгдээгүй бол жорыг устгалгүйгээр нууна."
+"Идэвхтэй талбар худал буюу тэмдэглэгдээгүй бол орцыг устгалгүйгээр нууна."
#. module: mrp
#: field:mrp.bom,product_rounding:0
@@ -2083,7 +2082,7 @@ msgstr ""
#. module: mrp
#: field:procurement.order,bom_id:0
msgid "BoM"
-msgstr "Жор"
+msgstr "Орц"
#. module: mrp
#: model:ir.model,name:mrp.model_report_mrp_inout
@@ -2145,12 +2144,12 @@ msgstr "Хангах болон Үйлдвэрлэх"
#. module: mrp
#: field:mrp.bom,bom_id:0
msgid "Parent BoM"
-msgstr "Эцэг жор"
+msgstr "Эцэг орц"
#. module: mrp
#: report:bom.structure:0
msgid "BOM Ref"
-msgstr "Жорын код"
+msgstr "Орцын код"
#. module: mrp
#: code:addons/mrp/mrp.py:765
@@ -2190,7 +2189,7 @@ msgstr "Тоо хэмжээг сонго"
#: view:product.product:0
#: field:product.product,bom_ids:0
msgid "Bill of Materials"
-msgstr "Жорууд"
+msgstr "Орцууд"
#. module: mrp
#: code:addons/mrp/mrp.py:610
@@ -2322,7 +2321,7 @@ msgstr ""
msgid ""
"a manufacturing\n"
" order"
-msgstr ""
+msgstr "үйлдвэрлэл"
#. module: mrp
#: field:mrp.config.settings,group_mrp_properties:0
@@ -2344,7 +2343,7 @@ msgstr "Үзүүлэлтийн бүлэгүүд"
#: view:mrp.routing:0
#: model:process.node,name:mrp.process_node_routing0
msgid "Routing"
-msgstr "Маршрут"
+msgstr "Шугам"
#. module: mrp
#: model:process.transition,note:mrp.process_transition_procurestockableproduct0
@@ -2390,8 +2389,8 @@ msgid ""
"the BOM, through a run of the schedulers (MRP)."
msgstr ""
"Түүхий эдийг хангахын тулд (худалдан авах эсвэл үйлдвэрлэх) үйлдвэрлэлийн "
-"захиалга нь жорд тодорхойлогдсон бүрдлүүдээр татан авах захиалга үүсгэдэг ба "
-"энэ нь товлогчийг ажиллахад үүсдэг."
+"захиалга нь орцонд тодорхойлогдсон бүрдлүүдээр татан авах захиалга үүсгэдэг "
+"ба энэ нь товлогчийг ажиллахад үүсдэг."
#. module: mrp
#: help:mrp.product_price,number:0
@@ -2423,7 +2422,7 @@ msgstr "Нөөцийн Амралт, Чөлөө"
#. module: mrp
#: help:mrp.bom,sequence:0
msgid "Gives the sequence order when displaying a list of bills of material."
-msgstr "Жорын жагсаалтыг харуулах дэс дарааллыг өгдөг."
+msgstr "Орцын жагсаалтыг харуулах дэс дарааллыг өгдөг."
#. module: mrp
#: model:ir.model,name:mrp.model_mrp_config_settings
diff --git a/addons/mrp/process/procurement_process.xml b/addons/mrp/process/procurement_process.xml
index b827a2731c9..dd52268e2d1 100644
--- a/addons/mrp/process/procurement_process.xml
+++ b/addons/mrp/process/procurement_process.xml
@@ -131,96 +131,96 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/addons/mrp/process/service_product_process.xml b/addons/mrp/process/service_product_process.xml
index 965f3f57d69..0005be6f48c 100644
--- a/addons/mrp/process/service_product_process.xml
+++ b/addons/mrp/process/service_product_process.xml
@@ -39,9 +39,9 @@
-
-
+
+
-
\ No newline at end of file
+
diff --git a/addons/mrp/process/stockable_product_process.xml b/addons/mrp/process/stockable_product_process.xml
index e3fa1136822..a43a09313b8 100644
--- a/addons/mrp/process/stockable_product_process.xml
+++ b/addons/mrp/process/stockable_product_process.xml
@@ -69,16 +69,16 @@
-
-
+
+
-
-
+
+
diff --git a/addons/mrp/procurement.py b/addons/mrp/procurement.py
index 3ad7155dad6..6347e22d576 100644
--- a/addons/mrp/procurement.py
+++ b/addons/mrp/procurement.py
@@ -33,6 +33,11 @@ class procurement_order(osv.osv):
'production_id': fields.many2one('mrp.production', 'Manufacturing Order'),
}
+ def _prepare_order_line_procurement(self, cr, uid, order, line, move_id, date_planned, context=None):
+ result = super(procurement_order, self)._prepare_order_line_procurement(cr, uid, order, line, move_id, date_planned, context)
+ result['property_ids'] = [(6, 0, [x.id for x in line.property_ids])]
+ return result
+
def check_produce_product(self, cr, uid, procurement, context=None):
''' Depict the capacity of the procurement workflow to produce products (not services)'''
return True
diff --git a/addons/mrp/report/order.rml b/addons/mrp/report/order.rml
index 8833d08e596..f413a6cfc70 100644
--- a/addons/mrp/report/order.rml
+++ b/addons/mrp/report/order.rml
@@ -139,37 +139,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -178,16 +159,16 @@
- Product
+ Product
- Quantity
+ Quantity
- Source Location
+ Source Location
- Destination Location
+ Destination Location
@@ -196,20 +177,20 @@
- Production Order N° : [[ o.name ]]
+ Production Order N° : [[ o.name ]]
- Source Document
+ Source Document
- Product
+ Product
- Quantity
+ Quantity
@@ -232,16 +213,16 @@
- Scheduled Date
+ Scheduled Date
- Printing date
+ Printing date
- Partner Ref
+ Partner Ref
- SO Number
+ SO Number
@@ -266,26 +247,26 @@
- Work Orders [[ o.workcenter_lines ==[] and removeParentNode('para')]]
+ Work Orders [[ o.workcenter_lines ==[] and removeParentNode('para')]]
- Sequence
+ Sequence
- Name [[ o.workcenter_lines ==[] and removeParentNode('blockTable')]]
+ Name [[ o.workcenter_lines ==[] and removeParentNode('blockTable')]]
- WorkCenter
+ WorkCenter
- No. Of Cycles
+ No. Of Cycles
- No. Of Hours
+ No. Of Hours
@@ -317,28 +298,28 @@
- Bill Of Material
+ Bill Of Material
- Product
+ Product
- Quantity
+ Quantity
- Source Location
+ Source Location
- Destination Location
+ Destination Location
- Products to Consume [[ o.move_lines ==[] and removeParentNode('section')]]
+ Products to Consume [[ o.move_lines ==[] and removeParentNode('section')]][[ repeatIn(o.move_lines,'line') ]]
@@ -363,7 +344,7 @@
- Consumed Products [[ o.move_lines2 ==[] and removeParentNode('section')]]
+ Consumed Products [[ o.move_lines2 ==[] and removeParentNode('section')]][[ repeatIn(o.move_lines2,'line2') ]]
diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py
index d6f026530dc..87861ba8fc6 100644
--- a/addons/mrp_operations/mrp_operations.py
+++ b/addons/mrp_operations/mrp_operations.py
@@ -128,7 +128,7 @@ class mrp_production_workcenter_line(osv.osv):
elif prod_obj.state =='in_production':
return
else:
- raise osv.except_osv(_('Error!'),_('Manufacturing order cannot start in state "%s"!') % (prod_obj.state,))
+ raise osv.except_osv(_('Error!'),_('Manufacturing order cannot be started in state "%s"!') % (prod_obj.state,))
else:
oper_ids = self.search(cr,uid,[('production_id','=',prod_obj.id)])
obj = self.browse(cr,uid,oper_ids)
@@ -443,7 +443,7 @@ class mrp_operations_operation(osv.osv):
if not oper_objs:
if code.start_stop!='start':
- raise osv.except_osv(_('Sorry!'),_('Operation is not started yet !'))
+ raise osv.except_osv(_('Sorry!'),_('Operation is not started yet!'))
return False
else:
for oper in oper_objs:
diff --git a/addons/mrp_operations/process/mrp_operation_process.xml b/addons/mrp_operations/process/mrp_operation_process.xml
index 452434bbe92..d448b6a299a 100644
--- a/addons/mrp_operations/process/mrp_operation_process.xml
+++ b/addons/mrp_operations/process/mrp_operation_process.xml
@@ -75,32 +75,32 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py
index 43ee34b0c05..f7b082db74b 100644
--- a/addons/mrp_repair/mrp_repair.py
+++ b/addons/mrp_repair/mrp_repair.py
@@ -365,7 +365,7 @@ class mrp_repair(osv.osv):
if repair.state in ('draft','cancel') or repair.invoice_id:
continue
if not (repair.partner_id.id and repair.partner_invoice_id.id):
- raise osv.except_osv(_('No partner !'),_('You have to select a Partner Invoice Address in the repair form !'))
+ raise osv.except_osv(_('No partner!'),_('You have to select a Partner Invoice Address in the repair form!'))
comment = repair.quotation_notes
if (repair.invoice_method != 'none'):
if group and repair.partner_invoice_id.id in invoices_group:
@@ -582,7 +582,7 @@ class ProductChangeMixin(object):
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id or False
if not pricelist:
warning = {
- 'title':'No Pricelist !',
+ 'title':'No Pricelist!',
'message':
'You have to select a pricelist in the Repair form !\n'
'Please set one before choosing a product.'
diff --git a/addons/mrp_repair/security/mrp_repair_security.xml b/addons/mrp_repair/security/mrp_repair_security.xml
index 0b34310fc4e..e94b675b57f 100644
--- a/addons/mrp_repair/security/mrp_repair_security.xml
+++ b/addons/mrp_repair/security/mrp_repair_security.xml
@@ -11,4 +11,4 @@
-
\ No newline at end of file
+
diff --git a/addons/multi_company/i18n/ru.po b/addons/multi_company/i18n/ru.po
index 3dea680c371..e1665d9c838 100644
--- a/addons/multi_company/i18n/ru.po
+++ b/addons/multi_company/i18n/ru.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-08-17 11:09+0000\n"
+"PO-Revision-Date: 2013-06-06 10:25+0000\n"
"Last-Translator: Chertykov Denis \n"
"Language-Team: Russian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:36+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-06-07 05:48+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
#. module: multi_company
#: model:ir.ui.menu,name:multi_company.menu_custom_multicompany
@@ -45,6 +45,16 @@ msgid ""
"Thank you in advance for your cooperation.\n"
"Best Regards,"
msgstr ""
+"Уважаемые господа,\n"
+"\n"
+"Наши записи зафиксировали что некоторые платежи остаются неоплаченными. "
+"Пожалуйста ознакомьтесь с подробностями ниже.\n"
+"Если сумма уже была оплачена, пожалуйста проигнорируйте это оповещение. В "
+"ином случае, пожалуйста перечислите нам всю сумму отображенную ниже.\n"
+"Если у вас есть какие-либо замечания, пожалуйста свяжитесь с нами.\n"
+"\n"
+"Заранее благодарим за сотрудничество.\n"
+"С наилучшими пожеланиями,"
#. module: multi_company
#: view:multi_company.default:0
diff --git a/addons/multi_company/multi_company_demo.xml b/addons/multi_company/multi_company_demo.xml
index 088aa35e915..c772a8fd67d 100644
--- a/addons/multi_company/multi_company_demo.xml
+++ b/addons/multi_company/multi_company_demo.xml
@@ -192,8 +192,8 @@
SAJ-OpenERP INsale
-
-
+
+
@@ -204,8 +204,8 @@
SCNJ-OpenERP INsale_refund
-
-
+
+
@@ -216,8 +216,8 @@
EXJ-OpenERP INpurchase
-
-
+
+
@@ -228,8 +228,8 @@
ECNJ-OpenERP INpurchase_refund
-
-
+
+
@@ -240,8 +240,8 @@
BNK-OpenERP INbank
-
-
+
+
@@ -252,8 +252,8 @@
CHK-OpenERP INbank
-
-
+
+
@@ -264,8 +264,8 @@
CSH-OpenERP INcash
-
-
+
+
@@ -277,8 +277,8 @@
SAJ-OpenERP USsale
-
-
+
+
@@ -289,8 +289,8 @@
SCNJ-OpenERP USsale_refund
-
-
+
+
@@ -301,8 +301,8 @@
EXJ-OpenERP USpurchase
-
-
+
+
@@ -313,8 +313,8 @@
ECNJ-OpenERP USpurchase_refund
-
-
+
+
@@ -325,8 +325,8 @@
BNK-OpenERP USbank
-
-
+
+
@@ -337,8 +337,8 @@
CHK-OpenERP USbank
-
-
+
+
@@ -349,8 +349,8 @@
CSH-OpenERP UScash
-
-
+
+
@@ -363,8 +363,8 @@
SAJ-OpenERP BEsale
-
-
+
+
@@ -375,8 +375,8 @@
SCNJ-OpenERP BEsale_refund
-
-
+
+
@@ -387,8 +387,8 @@
EXJ-OpenERP BEpurchase
-
-
+
+
@@ -399,8 +399,8 @@
ECNJ-OpenERP BEpurchase_refund
-
-
+
+
@@ -411,8 +411,8 @@
BNK-OpenERP BEbank
-
-
+
+
@@ -423,8 +423,8 @@
CHK-OpenERP BEbank
-
-
+
+
@@ -435,8 +435,8 @@
CSH-OpenERP BEcash
-
-
+
+
diff --git a/addons/note/html/index.html b/addons/note/html/index.html
index 97736520f2f..7ef37c646e9 100644
--- a/addons/note/html/index.html
+++ b/addons/note/html/index.html
@@ -7,7 +7,6 @@
-
@@ -113,4 +112,5 @@ The real time collaborative writings on notes makes it the perfect tool to colla
-
+
+
diff --git a/addons/note/i18n/ru.po b/addons/note/i18n/ru.po
new file mode 100644
index 00000000000..ef2cd6be0c1
--- /dev/null
+++ b/addons/note/i18n/ru.po
@@ -0,0 +1,286 @@
+# Russian translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-06-06 10:35+0000\n"
+"Last-Translator: Chertykov Denis \n"
+"Language-Team: Russian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-07 05:48+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
+
+#. module: note
+#: field:note.note,memo:0
+msgid "Note Content"
+msgstr "Содержание заметки"
+
+#. module: note
+#: view:note.stage:0
+msgid "Stages of Notes"
+msgstr "Этапы заметок"
+
+#. module: note
+#: model:note.stage,name:note.demo_note_stage_04
+#: model:note.stage,name:note.note_stage_02
+msgid "This Week"
+msgstr "Эта неделя"
+
+#. module: note
+#: model:ir.model,name:note.model_base_config_settings
+msgid "base.config.settings"
+msgstr "base.config.settings"
+
+#. module: note
+#: model:ir.model,name:note.model_note_tag
+msgid "Note Tag"
+msgstr "Тег заметки"
+
+#. module: note
+#: model:res.groups,name:note.group_note_fancy
+msgid "Notes / Fancy mode"
+msgstr ""
+
+#. module: note
+#: model:ir.model,name:note.model_note_note
+#: view:note.note:0
+msgid "Note"
+msgstr "Заметка"
+
+#. module: note
+#: view:note.note:0
+msgid "Group By..."
+msgstr "Группировать по ..."
+
+#. module: note
+#: field:note.note,message_follower_ids:0
+msgid "Followers"
+msgstr "Подписчики"
+
+#. module: note
+#: model:ir.actions.act_window,help:note.action_note_note
+msgid ""
+"
\n"
+" Click to add a personal note.\n"
+"
\n"
+" Use notes to organize personal tasks or notes. All\n"
+" notes are private; no one else will be able to see them. "
+"However\n"
+" you can share some notes with other people by inviting "
+"followers\n"
+" on the note. (Useful for meeting minutes, especially if\n"
+" you activate the pad feature for collaborative writings).\n"
+"
\n"
+" You can customize how you process your notes/tasks by adding,\n"
+" removing or modifying columns.\n"
+"
Click to add a personal note.
diff --git a/addons/note/security/ir.rule.xml b/addons/note/security/ir.rule.xml
index b0c79561355..2c6e9f3bc7f 100644
--- a/addons/note/security/ir.rule.xml
+++ b/addons/note/security/ir.rule.xml
@@ -3,7 +3,7 @@
Only followers can access a sticky notes
-
+ [('message_follower_ids','=',user.partner_id.id)]
@@ -14,7 +14,7 @@
Each user have his stage name
-
+ ['|',('user_id','=',False),('user_id','=',user.id)]
diff --git a/addons/point_of_sale/html/index.html b/addons/point_of_sale/html/index.html
index 41f935d8ad9..130806ddb11 100644
--- a/addons/point_of_sale/html/index.html
+++ b/addons/point_of_sale/html/index.html
@@ -9,7 +9,6 @@
-
diff --git a/addons/point_of_sale/i18n/he.po b/addons/point_of_sale/i18n/he.po
new file mode 100644
index 00000000000..31f12afc166
--- /dev/null
+++ b/addons/point_of_sale/i18n/he.po
@@ -0,0 +1,4053 @@
+# Hebrew translation for openobject-addons
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:04+0000\n"
+"PO-Revision-Date: 2013-06-09 16:04+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Hebrew \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-06-11 05:40+0000\n"
+"X-Generator: Launchpad (build 16667)\n"
+
+#. module: point_of_sale
+#: field:report.transaction.pos,product_nb:0
+msgid "Product Nb."
+msgstr "מס' מוצר"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_trans_pos_tree_today
+msgid "Sales by day"
+msgstr "מחיר לפי יום"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,help:point_of_sale.pos_category_action
+msgid ""
+"
\n"
+" Click to define a new category.\n"
+"
\n"
+" Categories are used to browse your products through the\n"
+" touchscreen interface.\n"
+"
\n"
+" If you put a photo on the category, the layout of the\n"
+" touchscreen interface will automatically. We suggest not to "
+"put\n"
+" a photo on categories for small (1024x768) screens.\n"
+"
\n"
+" "
+msgstr ""
+"
\n"
+" לחץ כדי להגדיר קטגוריה חדש.\n"
+"
\n"
+" קטגרויות נועדו לכך שתוכל לנווט במוצרים שלך\n"
+" באמצעות מסך המגע.\n"
+"
\n"
+" במידה ותבחר תמונה עבור הקטגוריה תראה אותה בקטלוג\n"
+" מוצרים בתוך הקופה שלך. אנו מציעים לא להשתמש בתמונות\n"
+" עבור מסכים קטנים כגון 1024X768.\n"
+"
\n"
+" "
+
+#. module: point_of_sale
+#: view:pos.receipt:0
+msgid "Print the Receipt of the Sale"
+msgstr "הדפס קבלה עבור המכירה"
+
+#. module: point_of_sale
+#: field:pos.session,cash_register_balance_end:0
+msgid "Computed Balance"
+msgstr "יתרה מחושבת"
+
+#. module: point_of_sale
+#: view:pos.session:0
+#: view:report.pos.order:0
+msgid "Today"
+msgstr "נוכחי"
+
+#. module: point_of_sale
+#: field:pos.config,iface_electronic_scale:0
+msgid "Electronic Scale Interface"
+msgstr "ממשק משקל דיגיטלי"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.plain_water
+msgid "Plain Water"
+msgstr "מיים רגילים"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.poire_conference_product_template
+msgid "Conference pears"
+msgstr "אגסים"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:398
+#, python-format
+msgid "ã"
+msgstr "ã"
+
+#. module: point_of_sale
+#: field:pos.config,journal_id:0
+#: field:pos.order,sale_journal:0
+msgid "Sale Journal"
+msgstr "יומן מכירות"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.spa_2l_product_template
+msgid "Spa Reine 2L"
+msgstr "ספא רני 2 ליטר"
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.pos_lines_detail
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Details of Sales"
+msgstr "פרטי מכירות"
+
+#. module: point_of_sale
+#: constraint:pos.config:0
+msgid "You cannot have two cash controls in one Point Of Sale !"
+msgstr "לא ניתן לשייך שתי בקרי מזומן לקופה רושמת אחת!"
+
+#. module: point_of_sale
+#: field:pos.payment.report.user,user_id:0
+#: field:pos.sale.user,user_id:0
+#: field:pos.sales.user.today,user_id:0
+#: view:report.pos.order:0
+#: field:report.pos.order,user_id:0
+msgid "Salesperson"
+msgstr "איש מכירות"
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+#: field:report.pos.order,day:0
+msgid "Day"
+msgstr "יום"
+
+#. module: point_of_sale
+#: field:report.sales.by.margin.pos,product_name:0
+#: field:report.sales.by.margin.pos.month,product_name:0
+msgid "Product Name"
+msgstr "שם המוצר"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.pamplemousse_rouge_pamplemousse_product_template
+msgid "Red grapefruit"
+msgstr "אשכולית אדומה"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:1373
+#, python-format
+msgid "Assign a Custom EAN"
+msgstr "שייך מספר סידורי מותאם אישית"
+
+#. module: point_of_sale
+#: view:pos.session.opening:0
+msgid ""
+"You may have to control your cash amount in your cash register, before\n"
+" being able to start selling through the "
+"touchscreen interface."
+msgstr ""
+"יתכן ותצתרך לעשות ספירת מזומנים, לפני\n"
+" שתוכל להתחיל למכור באמצעות קופה רושמת."
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: field:pos.box.entries,amount:0
+#: report:pos.invoice:0
+#: field:pos.make.payment,amount:0
+#: report:pos.user.product:0
+#: field:report.transaction.pos,amount:0
+msgid "Amount"
+msgstr "סכום"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_box_out
+#: view:pos.session:0
+msgid "Take Money Out"
+msgstr "הוצא את הכסף"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:105
+#, python-format
+msgid "not used"
+msgstr "לא בשימוש"
+
+#. module: point_of_sale
+#: field:pos.config,iface_vkeyboard:0
+msgid "Virtual KeyBoard Interface"
+msgstr "ממשק מקלדת וירטואלית"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:96
+#, python-format
+msgid "+/-"
+msgstr "+/-"
+
+#. module: point_of_sale
+#: field:pos.ean_wizard,ean13_pattern:0
+msgid "Reference"
+msgstr "ייחוס"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:1066
+#: code:addons/point_of_sale/point_of_sale.py:1083
+#: report:pos.invoice:0
+#: report:pos.lines:0
+#, python-format
+msgid "Tax"
+msgstr "מס"
+
+#. module: point_of_sale
+#: report:pos.user.product:0
+msgid "Starting Date"
+msgstr "תאריך התחלה"
+
+#. module: point_of_sale
+#: constraint:pos.session:0
+msgid "You cannot create two active sessions with the same responsible!"
+msgstr "אתה לא יכול ליצור שני מפגשים פעילים עם אותו אחראי!"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:473
+#, python-format
+msgid "Weighting"
+msgstr "שוקל"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.fenouil_fenouil_product_template
+msgid "Fennel"
+msgstr "שומר"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:472
+#, python-format
+msgid "Help needed"
+msgstr "צריך עזרה"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:760
+#, python-format
+msgid "Configuration Error!"
+msgstr "שגיאת הגדרות!"
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: model:ir.model,name:point_of_sale.model_res_partner
+#: field:report.pos.order,partner_id:0
+msgid "Partner"
+msgstr "שותף"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "Closing Cash Control"
+msgstr "סגירת קופת מזומנים"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Total of the day"
+msgstr "סה\"כ ליום"
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+#: field:report.pos.order,average_price:0
+msgid "Average Price"
+msgstr "מחיר ממוצע"
+
+#. module: point_of_sale
+#: view:pos.order:0
+msgid "Accounting Information"
+msgstr "פרטי חשבון"
+
+#. module: point_of_sale
+#: field:pos.session.opening,show_config:0
+msgid "Show Config"
+msgstr "הצג הגדרות"
+
+#. module: point_of_sale
+#: report:pos.lines:0
+msgid "Disc. (%)"
+msgstr "תיאור (%)"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Total discount"
+msgstr "סה\"כ הנחה"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:441
+#, python-format
+msgid "Debug Window"
+msgstr "חלון ניפוי שגיאות"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:241
+#: code:addons/point_of_sale/static/src/xml/pos.xml:613
+#, python-format
+msgid "Change:"
+msgstr "עודף:"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_regular_2l_product_template
+msgid "Coca-Cola Regular 2L"
+msgstr "קוקה קולה רגילה 2 ליטר"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_trans_pos_tree_month
+msgid "Sales by month"
+msgstr "מכירות לפי חודש"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.soda_orange
+msgid "Orange"
+msgstr "תפוז"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_report_sales_by_user_pos_today
+#: view:report.sales.by.user.pos:0
+#: view:report.sales.by.user.pos.month:0
+msgid "Sales by User"
+msgstr "מכירות למשתמש"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "Disc.(%)"
+msgstr "תיאור (%)"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:1031
+#, python-format
+msgid "Please define income account for this product: \"%s\" (id:%d)."
+msgstr "אנה הגדר חשבון הכנסות עבור מוצר זה: \"%s\" (id:%d)"
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+#: field:report.pos.order,price_total:0
+msgid "Total Price"
+msgstr "סה\"כ מחיר"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.leffe_brune_33cl_product_template
+msgid "Leffe Brune 33cl"
+msgstr "לף קהה 330 מ\"ל"
+
+#. module: point_of_sale
+#: help:pos.config,iface_self_checkout:0
+msgid ""
+"Check this if this point of sale should open by default in a self checkout "
+"mode. If unchecked, OpenERP uses the normal cashier mode by default."
+msgstr ""
+"סמן כאן במידה וקופה זה תומכת ברכישה אצמעית. במידה ולא סומן, OpenERP יגדיר "
+"קופה רגילה כברירת מחדל."
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.pos_sales_user
+#: report:pos.sales.user:0
+msgid "Sales Report"
+msgstr "דוח מכירות"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.beverage
+msgid "Beverages"
+msgstr "משקאות"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_session_opening
+#: model:ir.ui.menu,name:point_of_sale.menu_pos_session_opening
+msgid "Your Session"
+msgstr "חשבון מכירות שלך"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.stella_50cl_product_template
+msgid "Stella Artois 50cl"
+msgstr "סטלה ארטוס 0.5 ליטר"
+
+#. module: point_of_sale
+#: view:pos.details:0
+msgid "Dates"
+msgstr "תאריכים"
+
+#. module: point_of_sale
+#: field:pos.category,parent_id:0
+msgid "Parent Category"
+msgstr "קטגוריית אב"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:482
+#, python-format
+msgid "Open Cashbox"
+msgstr "פתח מגירה"
+
+#. module: point_of_sale
+#: view:pos.session.opening:0
+msgid "Select your Point of Sale"
+msgstr "אנה בחר את הקופה שלך"
+
+#. module: point_of_sale
+#: field:report.sales.by.margin.pos,total:0
+#: field:report.sales.by.margin.pos.month,total:0
+msgid "Margin"
+msgstr "שוליים"
+
+#. module: point_of_sale
+#: field:pos.discount,discount:0
+#: field:pos.order.line,discount:0
+msgid "Discount (%)"
+msgstr "הנחה (%)"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.oetker_speciale_product_template
+msgid "Dr. Oetker Ristorante Speciale"
+msgstr "דר. אוייטקר מומחה מסעדנות"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:480
+#, python-format
+msgid "Payment Request"
+msgstr "בקשת תשלום"
+
+#. module: point_of_sale
+#: field:product.product,to_weight:0
+msgid "To Weight"
+msgstr "עבור משקל"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:476
+#, python-format
+msgid "Hardware Events"
+msgstr "איורעי חומרה"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:301
+#, python-format
+msgid "You should assign a Point of Sale to your session."
+msgstr "הינך חייב לבחור קופה לחשבון המכירות שלך"
+
+#. module: point_of_sale
+#: view:pos.order.line:0
+msgid "Total qty"
+msgstr "כמות כוללת"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.fanta_orange_33cl_product_template
+msgid "Fanta Orange 33cl"
+msgstr "פאנטה תופזים 330 מ\"ל"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:423
+#, python-format
+msgid ""
+"Please set your profit and loss accounts on your payment method '%s'. This "
+"will allow OpenERP to post the difference of %.2f in your ending balance. To "
+"close this session, you can update the 'Closing Cash Control' to avoid any "
+"difference."
+msgstr ""
+"אנה בחר חשבון הרווח וההפסד שלך עבור שיתת תשלום '%s'. זה יאפשר לOpenERP להזין "
+"הפרשי %.2f בתוך חשבון הסופי שלך. על מנת לסגור חשבון מכירות זה, אתה יכול "
+"לעדכן את 'סיגרת קופת מזומנים' על מנת לא לגרום להפרשים."
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:315
+#: code:addons/point_of_sale/point_of_sale.py:514
+#, python-format
+msgid "error!"
+msgstr "שגיא!"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_report_sales_by_user_pos_month
+msgid "Sales by User Monthly"
+msgstr "מכירות חודשיות לפי משתמש"
+
+#. module: point_of_sale
+#: help:pos.session,cash_register_difference:0
+msgid ""
+"Difference between the counted cash control at the closing and the computed "
+"balance."
+msgstr "הפרשים בין ספירה ידנית לספירה ממוחשבת."
+
+#. module: point_of_sale
+#: view:pos.session.opening:0
+msgid ") is \""
+msgstr ") הוא \""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.Onions_product_template
+msgid "Onions"
+msgstr "בצלים"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "Validate & Open Session"
+msgstr "אמת ופתח יומן מכירות"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:99
+#: selection:pos.session,state:0
+#: selection:pos.session.opening,pos_state:0
+#, python-format
+msgid "In Progress"
+msgstr "בתהליך"
+
+#. module: point_of_sale
+#: view:pos.session:0
+#: field:pos.session,opening_details_ids:0
+msgid "Opening Cash Control"
+msgstr "פתח קופת מזומנים"
+
+#. module: point_of_sale
+#: help:res.users,ean13:0
+msgid "BarCode"
+msgstr "ברקוד"
+
+#. module: point_of_sale
+#: help:pos.category,image_medium:0
+msgid ""
+"Medium-sized image of the category. It is automatically resized as a "
+"128x128px image, with aspect ratio preserved. Use this field in form views "
+"or some kanban views."
+msgstr ""
+"תמונה בגודל בינוני עבור קטגוריה זו. התמונות יוקטנו אוטומטית לגודל 128X128 "
+"פיקסל, תוך כדי שמירה על יחס התמונה."
+
+#. module: point_of_sale
+#: view:pos.session.opening:0
+msgid "Open Session"
+msgstr "פתח הפעלה"
+
+#. module: point_of_sale
+#: model:ir.ui.menu,name:point_of_sale.menu_point_of_sale
+msgid "Daily Operations"
+msgstr "פעולות יומיות"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:42
+#, python-format
+msgid "Google Chrome"
+msgstr "גוגל כרום"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.sparkling_water
+msgid "Sparkling Water"
+msgstr "מים מוגזים"
+
+#. module: point_of_sale
+#: view:account.bank.statement:0
+msgid "Search Cash Statements"
+msgstr "חיפוש דוחות מזומנים"
+
+#. module: point_of_sale
+#: view:account.bank.statement:0
+#: field:pos.config,state:0
+#: view:pos.order:0
+#: field:pos.order,state:0
+#: report:pos.sales.user:0
+#: report:pos.sales.user.today:0
+#: field:pos.session,state:0
+#: field:pos.session.opening,pos_state_str:0
+#: field:report.pos.order,state:0
+msgid "Status"
+msgstr "סטטוס"
+
+#. module: point_of_sale
+#: selection:report.pos.order,month:0
+msgid "August"
+msgstr "אוגוסט"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.pepsi_max_lemon_33cl_product_template
+msgid "Pepsi Max Cool Lemon 33cl"
+msgstr "פפסי מקס בטעם לימון 330 מ\"ל"
+
+#. module: point_of_sale
+#: selection:report.pos.order,month:0
+msgid "June"
+msgstr "יוני"
+
+#. module: point_of_sale
+#: view:pos.order.line:0
+msgid "POS Order line"
+msgstr "שורת הזמנה בקופה"
+
+#. module: point_of_sale
+#: view:pos.config:0
+msgid "Point of Sale Configuration"
+msgstr "הגדרות קופה רושמת"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:359
+#, python-format
+msgid "Your order has to be validated by a cashier."
+msgstr "הזמנת חייבת לעבור עימות על ידי קופאי"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.fanta_orange_50cl_product_template
+msgid "Fanta Orange 50cl"
+msgstr "פנטה תפוזים 0.5 ליטר"
+
+#. module: point_of_sale
+#: field:pos.category,child_id:0
+msgid "Children Categories"
+msgstr "קטגוריות ילדים"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,help:point_of_sale.action_pos_session
+msgid ""
+"
\n"
+" Click to start a new session.\n"
+"
\n"
+" A session is a period of time, usually one day, during "
+"which\n"
+" you sell through the point of sale. The user has to check "
+"the\n"
+" currencies in your cash registers at the beginning and the "
+"end\n"
+" of each session.\n"
+"
\n"
+" Note that you should better to use the menu Your "
+"Session\n"
+" to quickly open a new session.\n"
+"
\n"
+" "
+msgstr ""
+"
\n"
+" לחץ כאן על מנת לפתוח יומן מכירות חדש.\n"
+"
\n"
+" יומן מכירות הינה תקופת עבודה בקופה, בדרך כלל\n"
+" יום מכירות אחד, באה הינך מוכר באמצעות הקופה.\n"
+" משתמש חייב לבחור מטבעה בכל תחילת וסוף יום.\n"
+"
\n"
+" שים לב, עדיף שתשתמש ב יומן מכירות שלך\n"
+" על מנת לפתוח במהירות יומן מכירות.\n"
+"
\n"
+" "
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:888
+#, python-format
+msgid "Customer Invoice"
+msgstr "חשבונית לקוח"
+
+#. module: point_of_sale
+#: view:pos.session.opening:0
+msgid ""
+"You can continue sales from the touchscreen interface by clicking on \"Start "
+"Selling\" or close the cash register session."
+msgstr ""
+"הינך יכול להמשיך את המכירות שלך על ידי לחיצה על \"התחל למכור\" או לסגור את "
+"יומן המכירות הנוכחי."
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: report:all.closed.cashbox.of.the.day:0
+#: field:pos.session,stop_at:0
+msgid "Closing Date"
+msgstr "תריך סגירה"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "Opening Cashbox Lines"
+msgstr "שורת פתיחה של קופת מזומנים"
+
+#. module: point_of_sale
+#: selection:report.pos.order,month:0
+msgid "October"
+msgstr "אוקטובר"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_light_1l_product_template
+msgid "Coca-Cola Light 1L"
+msgstr "קוקה קולה דיאט 1 ליטר"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Summary"
+msgstr "סיכום"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lays_naturel_45g_product_template
+msgid "Lays Natural 45g"
+msgstr "לייס בטעם טבעי 45 גר'"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.chaudfontaine_50cl_product_template
+msgid "Chaudfontaine 50cl"
+msgstr "Chaudfontaine 50 מ\"ל"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+#: report:pos.lines:0
+#: field:pos.order.line,qty:0
+#: field:report.sales.by.user.pos,qty:0
+#: field:report.sales.by.user.pos.month,qty:0
+msgid "Quantity"
+msgstr "כמות"
+
+#. module: point_of_sale
+#: field:pos.order.line,name:0
+msgid "Line No"
+msgstr "שורה מס'"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:453
+#, python-format
+msgid "Set Weight"
+msgstr "קבע משקל"
+
+#. module: point_of_sale
+#: view:account.bank.statement:0
+msgid "Period"
+msgstr "תקופה"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "Net Total:"
+msgstr "סה\"כ נטו:"
+
+#. module: point_of_sale
+#: model:ir.actions.client,name:point_of_sale.action_client_pos_menu
+msgid "Open POS Menu"
+msgstr "פתח תפריט קופה"
+
+#. module: point_of_sale
+#: report:pos.details_summary:0
+msgid "Mode of Payment"
+msgstr "צורת תשלום"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_confirm
+msgid "Post POS Journal Entries"
+msgstr "הזן ערך לתוך יומן"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:457
+#, python-format
+msgid "Barcode Scanner"
+msgstr "סורק ברקודים"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.pomme_granny_smith_product_template
+msgid "Granny Smith apples"
+msgstr "תפוחי ספתה טובה"
+
+#. module: point_of_sale
+#: help:product.product,expense_pdt:0
+msgid ""
+"Check if, this is a product you can use to take cash from a statement for "
+"the point of sale backend, example: money lost, transfer to bank, etc."
+msgstr ""
+"סמן כאן במידה ומוצר זה יכול להשתמש ביתרה מיוחדת כגון: חוב אבוד, העבורת לבנק "
+"וכו'."
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+#: field:report.pos.order,total_discount:0
+msgid "Total Discount"
+msgstr "סה\"כ הנחה"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:39
+#, python-format
+msgid ""
+"The Point of Sale is not supported by Microsoft Internet Explorer. Please "
+"use\n"
+" a modern browser like"
+msgstr ""
+"קופה רושמת זו אינה תומכת באינטרנט אקספלורר, אנה השתמש בדפדפן\n"
+" מודרני יותר על מנת להשתמש בקופה רושמת."
+
+#. module: point_of_sale
+#: view:pos.session.opening:0
+msgid "Click to start a session."
+msgstr "הקלק על מנת לפתוח יומן מכירות"
+
+#. module: point_of_sale
+#: view:pos.details:0
+#: view:pos.payment.report:0
+#: view:pos.payment.report.user:0
+#: view:pos.sale.user:0
+msgid "Print Report"
+msgstr "הדפס דוח"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.oetker_bolognese_product_template
+msgid "Dr. Oetker Ristorante Bolognese"
+msgstr ""
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.pizza
+msgid "Pizza"
+msgstr "פיצה"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "= Theoretical Balance"
+msgstr "= יתרה טאורטית"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_return.py:85
+#: code:addons/point_of_sale/wizard/pos_return.py:240
+#, python-format
+msgid "Add Product"
+msgstr "הוסף מוצר"
+
+#. module: point_of_sale
+#: field:pos.config,name:0
+msgid "Point of Sale Name"
+msgstr "שם קופה רושמת"
+
+#. module: point_of_sale
+#: field:report.transaction.pos,invoice_am:0
+msgid "Invoice Amount"
+msgstr "סכום חשבונית"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.coke
+msgid "Coke"
+msgstr "קוקה קולה"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "Tel. :"
+msgstr "טל:"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:254
+#: model:ir.actions.act_window,name:point_of_sale.action_report_pos_receipt
+#, python-format
+msgid "Receipt"
+msgstr "קבלה"
+
+#. module: point_of_sale
+#: field:report.sales.by.margin.pos,net_margin_per_qty:0
+#: field:report.sales.by.margin.pos.month,net_margin_per_qty:0
+msgid "Net margin per Qty"
+msgstr "רווח נקי לכמות"
+
+#. module: point_of_sale
+#: view:pos.confirm:0
+msgid "Post All Orders"
+msgstr "פרסם את כל ההזמנות"
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: report:all.closed.cashbox.of.the.day:0
+#: field:pos.session,cash_register_balance_end_real:0
+msgid "Ending Balance"
+msgstr "יתרה סופית"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_box_out.py:89
+#, python-format
+msgid "please check that account is set to %s."
+msgstr "אנה בדוק שחשבון זה מקושר ל %s."
+
+#. module: point_of_sale
+#: help:pos.category,image:0
+msgid ""
+"This field holds the image used as image for the cateogry, limited to "
+"1024x1024px."
+msgstr ""
+"בשדה זה נמצאת תמונה של קטגוריה, מוגבל לגודל מקסימאלי 1024X1024 פיקסלים."
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.pepsi_max_50cl_product_template
+msgid "Pepsi Max 50cl"
+msgstr "פפסי מאקס 50 מ\"ל"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.san_pellegrino_1l_product_template
+msgid "San Pellegrino 1L"
+msgstr "סאן פלגרינו 1 ליטר"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_open_statement.py:49
+#, python-format
+msgid ""
+"You have to define which payment method must be available in the point of "
+"sale by reusing existing bank and cash through \"Accounting / Configuration "
+"/ Journals / Journals\". Select a journal and check the field \"PoS Payment "
+"Method\" from the \"Point of Sale\" tab. You can also create new payment "
+"methods directly from menu \"PoS Backend / Configuration / Payment Methods\"."
+msgstr ""
+"הינך חייב לבחור בצורת תשלום שתהיה זמינה בקופה על ידי שימוש בחשבון בנק קיים "
+"דרך : \"חשבונות\\ הגדרות\\ יומנים\\ יומים\". בחר יומן זמין וסמן בשורת \"צורת "
+"תשלום עבור קופה רושמת\". אתה יכול ליצור צורת תשלום חדשה ישירות מתוך התפריט : "
+"\"הגדרות\\ צורות תשלום\"."
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.rouges_noyau_fruits
+msgid "Berries"
+msgstr "פירות יער"
+
+#. module: point_of_sale
+#: view:pos.ean_wizard:0
+msgid "Ean13 Generator"
+msgstr "מחולל EAN 13"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.spa_1l_product_template
+msgid "Spa Reine 1L"
+msgstr ""
+
+#. module: point_of_sale
+#: constraint:res.partner:0
+#: constraint:res.users:0
+msgid "Error: Invalid ean code"
+msgstr "שגיאה : קוד EAN אינו תקין"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.legumes_racine
+msgid "Root vegetables"
+msgstr "ירקות שורש"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.act_pos_open_statement
+#: model:ir.model,name:point_of_sale.model_pos_open_statement
+#: view:pos.open.statement:0
+msgid "Open Statements"
+msgstr "פתח דוחות"
+
+#. module: point_of_sale
+#: field:pos.details,date_end:0
+#: field:pos.sale.user,date_end:0
+msgid "Date End"
+msgstr "תאריך סיום"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.pomme_jonagold_product_template
+msgid "Jonagold apples"
+msgstr ""
+
+#. module: point_of_sale
+#: view:account.bank.statement:0
+#: report:account.statement:0
+#: report:all.closed.cashbox.of.the.day:0
+#: model:ir.model,name:point_of_sale.model_account_journal
+#: field:report.pos.order,journal_id:0
+msgid "Journal"
+msgstr "יומן"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "Statements"
+msgstr "דוחות"
+
+#. module: point_of_sale
+#: report:pos.details:0
+msgid "Sales total(Revenue)"
+msgstr "סה\"כ מכירות (רווחים)"
+
+#. module: point_of_sale
+#: help:pos.config,group_by:0
+msgid ""
+"Check this if you want to group the Journal Items by Product while closing a "
+"Session"
+msgstr ""
+"סמן כאן במידה והינך רוצה לשלב פרטי יומן על ידי מוצרים בזמן סגירת יומן מכירות"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Total paid"
+msgstr "שולם סה\"כ"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_session_opening
+msgid "pos.session.opening"
+msgstr ""
+
+#. module: point_of_sale
+#: view:res.users:0
+msgid "Edit EAN"
+msgstr "ערוך EAN"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_open_statement.py:80
+#, python-format
+msgid "List of Cash Registers"
+msgstr "רשימת קופות מזומן"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.maes_50cl_product_template
+msgid "Maes 50cl"
+msgstr ""
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+msgid "Not Invoiced"
+msgstr "ללא חשבונית"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lays_pickles_250g_product_template
+msgid "250g Lays Pickels"
+msgstr ""
+
+#. module: point_of_sale
+#: field:pos.session.opening,pos_session_id:0
+msgid "PoS Session"
+msgstr "יומן מכירות"
+
+#. module: point_of_sale
+#: selection:report.pos.order,month:0
+msgid "March"
+msgstr "מרץ"
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.pos_users_product_re
+#: report:pos.user.product:0
+msgid "User's Product"
+msgstr "מוצרי משתמש"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:1173
+#, python-format
+msgid ""
+"You have to select a pricelist in the sale form !\n"
+"Please set one before choosing a product."
+msgstr ""
+"הינך חייב לבחור מחירון עבור מכירה זו!\n"
+"אנה בחר אחד לפני בחירת המוצר."
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.fanta_orange_2l_product_template
+msgid "Fanta Orange 2L"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.perrier_1l_product_template
+msgid "Perrier 1L"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.spa_33cl_product_template
+msgid "Spa Reine 33cl"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_discount
+msgid "Add a Global Discount"
+msgstr "הוסף הנחה כוללת"
+
+#. module: point_of_sale
+#: view:pos.config:0
+msgid "Journals"
+msgstr "יומנים"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.oetker_prosciutto_product_template
+msgid "Dr. Oetker Ristorante Prosciutto"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lays_light_paprika_170g_product_template
+#: model:product.template,name:point_of_sale.lays_paprika_170g_product_template
+msgid "Lays Light Paprika 170g"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_light_lemon_50cl_product_template
+msgid "Coca-Cola Light Lemon 50cl"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/point_of_sale.py:520
+#: code:addons/point_of_sale/static/src/xml/pos.xml:689
+#: code:addons/point_of_sale/static/src/xml/pos.xml:744
+#, python-format
+msgid "return"
+msgstr "חזרה"
+
+#. module: point_of_sale
+#: view:product.product:0
+msgid "Set a Custom EAN"
+msgstr "בחר מספר EAN מותאם אישית"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:235
+#, python-format
+msgid "Remaining:"
+msgstr "נותרו:"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.legumes
+msgid "Fresh vegetables"
+msgstr "ירקות טריים"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "tab of the"
+msgstr "לשונית של"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:478
+#, python-format
+msgid "Scan Item Success"
+msgstr "סירקת המוצר הושלמה"
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: report:all.closed.cashbox.of.the.day:0
+#: field:pos.session,cash_register_balance_start:0
+msgid "Starting Balance"
+msgstr "יתרת התחלה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lays_naturel_oven_150g_product_template
+msgid "Oven Baked Lays Natural 150g"
+msgstr ""
+
+#. module: point_of_sale
+#: sql_constraint:pos.session:0
+msgid "The name of this POS Session must be unique !"
+msgstr "שם יומן מכירות זה חייב להיות ייחודי !"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "Opening Subtotal"
+msgstr "יתרת פתיחה"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "payment method."
+msgstr "צורת תשלום."
+
+#. module: point_of_sale
+#: view:pos.order:0
+msgid "Re-Print"
+msgstr "הדפס מחדש"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.chimay_bleu_75cl_product_template
+msgid "Chimay Bleu 75cl"
+msgstr ""
+
+#. module: point_of_sale
+#: report:pos.payment.report.user:0
+msgid "Payment By User"
+msgstr "תשלומים ללקוח"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:215
+#: code:addons/point_of_sale/static/src/xml/pos.xml:285
+#: code:addons/point_of_sale/wizard/pos_payment.py:79
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_payment
+#: report:pos.details:0
+#: view:pos.order:0
+#, python-format
+msgid "Payment"
+msgstr "תשלום"
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+#: field:report.pos.order,nbr:0
+msgid "# of Lines"
+msgstr "# שורות"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:89
+#, python-format
+msgid "Disc"
+msgstr "הנחה"
+
+#. module: point_of_sale
+#: view:pos.order:0
+msgid "(update)"
+msgstr "(עדכן)"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.ijsboerke_vanille_2,5l_product_template
+msgid "IJsboerke Vanilla 2.5L"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_report_pos_details
+#: model:ir.ui.menu,name:point_of_sale.menu_pos_details
+msgid "Sale Details"
+msgstr "פרטי מכירה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.evian_2l_product_template
+msgid "2L Evian"
+msgstr ""
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:373
+#: code:addons/point_of_sale/point_of_sale.py:474
+#: code:addons/point_of_sale/wizard/pos_session_opening.py:33
+#, python-format
+msgid "Start Point Of Sale"
+msgstr "התחלה יומן מכירות"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.pils
+msgid "Pils"
+msgstr "כדורים"
+
+#. module: point_of_sale
+#: help:pos.session,cash_register_balance_end_real:0
+msgid "Computed using the cash control lines"
+msgstr "מחושב לפי שורות קופה"
+
+#. module: point_of_sale
+#: report:all.closed.cashbox.of.the.day:0
+msgid "St.Name"
+msgstr "רחוב"
+
+#. module: point_of_sale
+#: report:pos.details_summary:0
+msgid "Sales total"
+msgstr "סה\"כ מכירות"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:741
+#, python-format
+msgid "ABC"
+msgstr "ABC"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.ijsboerke_dame_blanche_2,5l_product_template
+msgid "IJsboerke 2.5L White Lady"
+msgstr ""
+
+#. module: point_of_sale
+#: field:pos.order,lines:0
+msgid "Order Lines"
+msgstr "שורות הזמנה"
+
+#. module: point_of_sale
+#: view:report.transaction.pos:0
+msgid "Total Transaction"
+msgstr "סה\"כ עסקה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.chaudfontaine_petillante_50cl_product_template
+msgid "Chaudfontaine Petillante 50cl"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:485
+#, python-format
+msgid "Read Weighting Scale"
+msgstr "קראה משקל דיגיטלי"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:426
+#, python-format
+msgid "0.00 €"
+msgstr "0.00 ₪"
+
+#. module: point_of_sale
+#: field:pos.order.line,create_date:0
+msgid "Creation Date"
+msgstr "תאריך יצירה"
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.pos_sales_user_today
+msgid "Today's Sales"
+msgstr "מכירות להיום"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:264
+#: code:addons/point_of_sale/static/src/xml/pos.xml:324
+#, python-format
+msgid "Welcome"
+msgstr "ברוכים הבאים"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_box_entries.py:46
+#, python-format
+msgid ""
+"You do not have any open cash register. You must create a payment method or "
+"open a cash register."
+msgstr ""
+"לא נמצאו קופות מזומנים. הינך חייב ליצור שיתת תשלום או לפתוח קופת מזומנים."
+
+#. module: point_of_sale
+#: view:report.sales.by.margin.pos:0
+#: view:report.sales.by.margin.pos.month:0
+#: view:report.sales.by.user.pos:0
+#: view:report.sales.by.user.pos.month:0
+#: view:report.transaction.pos:0
+msgid "POS "
+msgstr "קופה "
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: report:pos.user.product:0
+msgid "Total :"
+msgstr "סה\"כ:"
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+msgid "My Sales"
+msgstr "המכירות שלי"
+
+#. module: point_of_sale
+#: view:pos.config:0
+msgid "Set to Deprecated"
+msgstr "הגדר לחסרי ערך"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.limon_product_template
+msgid "Stringers"
+msgstr "סטרינגרים"
+
+#. module: point_of_sale
+#: field:pos.order,pricelist_id:0
+msgid "Pricelist"
+msgstr "מחירון"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Total invoiced"
+msgstr "סה\"כ עם חשבונית"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_category
+#: field:product.product,pos_categ_id:0
+msgid "Point of Sale Category"
+msgstr "קטגוריית קופה"
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+#: field:report.pos.order,product_qty:0
+msgid "# of Qty"
+msgstr "# כמות"
+
+#. module: point_of_sale
+#: help:pos.config,sequence_id:0
+msgid ""
+"This sequence is automatically created by OpenERP but you can change it to "
+"customize the reference numbers of your orders."
+msgstr ""
+"רצף זה נוצר באופן אוטומטי על ידי OpenERP אבל אתה יכול לשנות את זה כדי להתאים "
+"אישית את התייחסות למספרים של ההזמנות שלך."
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:324
+#, python-format
+msgid "Choose your type of receipt:"
+msgstr "בחר את סוג הקבלה שלך:"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_report_sales_by_margin_pos_month
+msgid "Sales by margin monthly"
+msgstr "מכירות לפי מרווח חודשי"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.poivron_jaunes_product_template
+msgid "Yellow Peppers"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.order:0
+#: field:pos.order,date_order:0
+#: field:report.sales.by.margin.pos,date_order:0
+#: field:report.sales.by.margin.pos.month,date_order:0
+#: field:report.sales.by.user.pos,date_order:0
+#: field:report.sales.by.user.pos.month,date_order:0
+msgid "Order Date"
+msgstr "תאריך הזמנה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.stella_33cl_product_template
+msgid "Stella Artois 33cl"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lays_naturel_300g_product_template
+msgid "Lays Natural XXL 300g"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:479
+#, python-format
+msgid "Scan Item Unrecognized"
+msgstr "סרוק פריט ללא קטגוריה"
+
+#. module: point_of_sale
+#: report:all.closed.cashbox.of.the.day:0
+msgid "Today's Closed Cashbox"
+msgstr "דוח מזומנים להיום"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:920
+#, python-format
+msgid "Selected orders do not have the same session!"
+msgstr "הזמנות שנבחרו לא בוצעו באותו יומן מכירות!"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "Draft Invoice"
+msgstr "חשבונית ברירת מחדל"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lays_paprika_oven_150g_product_template
+msgid "Oven Baked Lays Paprika 150g"
+msgstr ""
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "Fiscal Position Remark :"
+msgstr "הערת מצב פיסקלי:"
+
+#. module: point_of_sale
+#: selection:report.pos.order,month:0
+msgid "September"
+msgstr "ספטמבר"
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: report:all.closed.cashbox.of.the.day:0
+#: field:pos.session,start_at:0
+msgid "Opening Date"
+msgstr "תאריך פתיחה"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_session
+#: model:ir.ui.menu,name:point_of_sale.menu_pos_session_all
+msgid "All Sessions"
+msgstr "כל היומנים"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:663
+#, python-format
+msgid "tab"
+msgstr "לשונית"
+
+#. module: point_of_sale
+#: report:pos.lines:0
+msgid "Taxes :"
+msgstr "מיסים:"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:271
+#, python-format
+msgid "Thank you for shopping with us."
+msgstr "תודה על כך שעשיתה קניות אתנו."
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_light_2l_product_template
+msgid "Coca-Cola Light 2L"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.oetker_funghi_product_template
+msgid "Dr. Oetker Ristorante Funghi"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.pos_category_action
+#: model:ir.ui.menu,name:point_of_sale.menu_pos_category
+msgid "Product Categories"
+msgstr "קטגוריות מוצרים"
+
+#. module: point_of_sale
+#: help:pos.config,journal_id:0
+msgid "Accounting journal used to post sales entries."
+msgstr "יומן מכירות להזנת מכירות."
+
+#. module: point_of_sale
+#: field:report.transaction.pos,disc:0
+msgid "Disc."
+msgstr "תיאור"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:467
+#, python-format
+msgid "Invalid Ean"
+msgstr "EAN שגוי"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.lindemans_kriek_37,5cl_product_template
+msgid "Lindemans Kriek 37.5cl"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.config:0
+msgid "Point of Sale Config"
+msgstr "הגדרות קופה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_zero_33cl_product_template
+msgid "Coca-Cola Zero 33cl"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:405
+#, python-format
+msgid "ä"
+msgstr "ä"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "VAT :"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.order.line:0
+msgid "POS Order lines"
+msgstr "שורות הזמנה לקופה"
+
+#. module: point_of_sale
+#: view:pos.receipt:0
+msgid "Receipt :"
+msgstr "קבלה:"
+
+#. module: point_of_sale
+#: field:account.bank.statement,pos_session_id:0
+#: field:account.bank.statement.line,pos_statement_id:0
+#: field:pos.order,amount_return:0
+#: field:pos.session.opening,pos_session_name:0
+#: field:pos.session.opening,pos_session_username:0
+msgid "unknown"
+msgstr "לא ידוע"
+
+#. module: point_of_sale
+#: field:product.product,income_pdt:0
+msgid "Point of Sale Cash In"
+msgstr "כניסת מזומנים לקופה"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:590
+#, python-format
+msgid "Tax:"
+msgstr "מע\"מ:"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "+ Transactions"
+msgstr "+ עסקאות"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_discount
+#: view:pos.discount:0
+msgid "Apply Discount"
+msgstr "עדכן הנחה"
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: report:all.closed.cashbox.of.the.day:0
+#: field:pos.box.entries,user_id:0
+#: report:pos.sales.user:0
+#: report:pos.sales.user.today:0
+#: view:pos.session:0
+#: report:pos.user.product:0
+#: field:report.sales.by.margin.pos,user_id:0
+#: field:report.sales.by.margin.pos.month,user_id:0
+#: field:report.sales.by.user.pos,user_id:0
+#: field:report.sales.by.user.pos.month,user_id:0
+#: field:report.transaction.pos,user_id:0
+#: model:res.groups,name:point_of_sale.group_pos_user
+msgid "User"
+msgstr "משתמש/ת"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:194
+#, python-format
+msgid "Kg"
+msgstr "ק\"ג"
+
+#. module: point_of_sale
+#: field:product.product,available_in_pos:0
+msgid "Available in the Point of Sale"
+msgstr "זמין בקופה"
+
+#. module: point_of_sale
+#: selection:pos.config,state:0
+msgid "Deprecated"
+msgstr "מומלץ לשימוש"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_light_decaf_33cl_product_template
+msgid "Coca-Cola Light 33cl Decaf"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:338
+#, python-format
+msgid "The scanned product was not recognized"
+msgstr "מוצר נסרק אינו מזוהה"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_report_transaction_pos
+msgid "transaction for the pos"
+msgstr "עסקאות לקופה"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: field:report.transaction.pos,date_create:0
+msgid "Date"
+msgstr "תאריך"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_box_entries
+msgid "Pos Box Entries"
+msgstr "תנועות קופה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.boon_framboise_37,5cl_product_template
+msgid "Boon Framboise 37.5cl"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_config
+msgid "pos.config"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.ean_wizard:0
+msgid ""
+"Enter a reference, it will be converted\n"
+" automatically to a valid EAN number."
+msgstr ""
+"הזן מספק, הוא יומר אוטומטית\n"
+" לקוד EAN חוקי לשימוש."
+
+#. module: point_of_sale
+#: field:product.product,expense_pdt:0
+msgid "Point of Sale Cash Out"
+msgstr "מכירות במזומן"
+
+#. module: point_of_sale
+#: selection:report.pos.order,month:0
+msgid "November"
+msgstr "נובמבר"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:267
+#, python-format
+msgid "Please scan an item or your member card"
+msgstr "אנה סרוק מוצר או כרטיס חבר מועדון"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.poivron_verts_product_template
+msgid "Green Peppers"
+msgstr "פלפלים ירוקים"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.timmermans_faro_37,5cl_product_template
+msgid "Timmermans Faro 37.5cl"
+msgstr ""
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:410
+#, python-format
+msgid ""
+"Your ending balance is too different from the theorical cash closing (%.2f), "
+"the maximum allowed is: %.2f. You can contact your manager to force it."
+msgstr ""
+"בסיגרת הקופה נמצאה הבדל של (%.2f), כאשר המקסימום המותר הינו %.2f. אנה צור "
+"קשר עם אחראי משמרת."
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "Validate Closing & Post Entries"
+msgstr "אמת סגירה ותנועות קופה"
+
+#. module: point_of_sale
+#: field:report.transaction.pos,no_trans:0
+msgid "Number of Transaction"
+msgstr "מספר עסקאות"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:759
+#, python-format
+msgid ""
+"There is no receivable account defined to make payment for the partner: "
+"\"%s\" (id:%d)."
+msgstr "לא נמצא חשבון אשר יכול לקבל כספים עבור שותף : \"%s\" (id:%d)."
+
+#. module: point_of_sale
+#: view:pos.config:0
+#: selection:pos.config,state:0
+msgid "Inactive"
+msgstr "לא פעיל"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:313
+#: view:pos.confirm:0
+#: view:pos.details:0
+#: view:pos.discount:0
+#: view:pos.ean_wizard:0
+#: view:pos.make.payment:0
+#: view:pos.open.statement:0
+#: view:pos.payment.report:0
+#: view:pos.payment.report.user:0
+#: view:pos.receipt:0
+#: view:pos.sale.user:0
+#, python-format
+msgid "Cancel"
+msgstr "ביטול"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:296
+#, python-format
+msgid "Please put your product on the scale"
+msgstr "אנה מקם את המוצר שלך על משקל דיגיטלי"
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.pos_details_summary
+msgid "Sales (summary)"
+msgstr "מכירות (סה\"כ)"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.nectarine_product_template
+msgid "Peach"
+msgstr "אפרסק"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.timmermans_kriek_37,5cl_product_template
+msgid "Timmermans Kriek 37.5cl"
+msgstr ""
+
+#. module: point_of_sale
+#: field:pos.config,sequence_id:0
+msgid "Order IDs Sequence"
+msgstr "רצף מספרי הזמנות"
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+#: report:pos.lines:0
+#: field:pos.order.line,price_unit:0
+#: report:pos.payment.report.user:0
+msgid "Unit Price"
+msgstr "מחיר ליחידה"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:190
+#, python-format
+msgid "Product Weighting"
+msgstr "משקל המוצר"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:704
+#: code:addons/point_of_sale/static/src/xml/pos.xml:746
+#, python-format
+msgid "close"
+msgstr "סגור"
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.report_user_label
+msgid "User Labels"
+msgstr "תוויות משתמש"
+
+#. module: point_of_sale
+#: model:ir.model,name:point_of_sale.model_pos_order_line
+msgid "Lines of Point of Sale"
+msgstr "שורות קופה"
+
+#. module: point_of_sale
+#: view:pos.order:0
+#: view:report.transaction.pos:0
+msgid "Amount total"
+msgstr "סכום כולל"
+
+#. module: point_of_sale
+#: view:pos.session:0
+msgid "End of Session"
+msgstr "סוף ההפעלה"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_new_bank_statement_all_tree
+#: view:pos.session:0
+msgid "Cash Registers"
+msgstr "קופות מזומן"
+
+#. module: point_of_sale
+#: help:pos.session,cash_register_balance_end:0
+msgid "Computed with the initial cash control and the sum of all payments."
+msgstr "מחושב עם שליטה הראשונית במזומן והסכום של כל התשלומים."
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:474
+#, python-format
+msgid "In Transaction"
+msgstr "בעסקה"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.food
+msgid "Food"
+msgstr "מזון"
+
+#. module: point_of_sale
+#: field:pos.box.entries,ref:0
+msgid "Ref"
+msgstr "הפניה"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:94
+#: report:pos.details:0
+#: report:pos.invoice:0
+#: report:pos.lines:0
+#, python-format
+msgid "Price"
+msgstr "מחיר"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_light_33cl_product_template
+msgid "Coca-Cola Light 33cl"
+msgstr ""
+
+#. module: point_of_sale
+#: view:report.sales.by.margin.pos:0
+#: view:report.sales.by.margin.pos.month:0
+#: view:report.sales.by.user.pos:0
+#: view:report.sales.by.user.pos.month:0
+#: view:report.transaction.pos:0
+msgid "POS"
+msgstr "קופה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_regular_33cl_product_template
+msgid "Coca-Cola Regular 33cl"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:325
+#, python-format
+msgid "Ticket"
+msgstr "פנייה"
+
+#. module: point_of_sale
+#: field:pos.session,cash_register_difference:0
+msgid "Difference"
+msgstr "הפרש"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:549
+#, python-format
+msgid "Unable to Delete !"
+msgstr "לא ניתן למחיקה!"
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.autres_agrumes
+msgid "Other Citrus"
+msgstr ""
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+msgid "Start Period"
+msgstr "תקופת הדוח"
+
+#. module: point_of_sale
+#: report:account.statement:0
+#: field:pos.category,complete_name:0
+#: field:pos.category,name:0
+#: report:pos.sales.user:0
+#: report:pos.sales.user.today:0
+msgid "Name"
+msgstr "שם"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.spa_gazeuse_33cl_product_template
+msgid "Spa Barisart 33cl"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.confirm:0
+msgid ""
+"Generate all sale journal entries for non invoiced orders linked to a closed "
+"cash register or statement."
+msgstr "חולל את כל המכירות להם לא הונפקה חשבונית אשר קשורים לקופה זו."
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.unreferenced_product_product_template
+msgid "Unreferenced Products"
+msgstr "מוצרים מנותקים מ"
+
+#. module: point_of_sale
+#: view:pos.ean_wizard:0
+msgid "Apply"
+msgstr "החל"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:288
+#, python-format
+msgid ""
+"Please insert your card in the reader and follow the instructions to "
+"complete\n"
+" your purchase"
+msgstr ""
+"אנה הכנס את הכרטיס שלך לתוך קורא הכרטיסיפ ועקוב אחר ההוראות להשלמת\n"
+" "
+" הקניה שלך"
+
+#. module: point_of_sale
+#: help:product.product,income_pdt:0
+msgid ""
+"Check if, this is a product you can use to put cash into a statement for the "
+"point of sale backend."
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.ijsboerke_moka_2,5l_product_template
+msgid "IJsboerke Mocha 2.5L"
+msgstr ""
+
+#. module: point_of_sale
+#: field:pos.session,cash_control:0
+msgid "Has Cash Control"
+msgstr "יש קופת מזומן"
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_report_pos_order_all
+#: model:ir.ui.menu,name:point_of_sale.menu_report_pos_order_all
+msgid "Orders Analysis"
+msgstr "ניתוח הזמנות"
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:563
+#, python-format
+msgid "User:"
+msgstr "משתמש:"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:316
+#, python-format
+msgid ""
+"Unable to open the session. You have to assign a sale journal to your point "
+"of sale."
+msgstr "לא ניתן לפתוח יומן מכירות. הינך חייב לקשר יומן לקופה."
+
+#. module: point_of_sale
+#: view:report.pos.order:0
+msgid "POS ordered created during current year"
+msgstr "זמנות קופה שנוצרו במהלך השנה הנוכחית"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.peche_product_template
+msgid "Fishing"
+msgstr "דייג"
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.details_summary:0
+#: report:pos.lines:0
+#: report:pos.payment.report.user:0
+#: report:pos.sales.user:0
+#: report:pos.sales.user.today:0
+#: report:pos.user.product:0
+msgid "Print Date"
+msgstr "תאריך הדפסה"
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.poireaux_poireaux_product_template
+msgid "Leeks"
+msgstr "כרישה"
+
+#. module: point_of_sale
+#: help:pos.category,sequence:0
+msgid ""
+"Gives the sequence order when displaying a list of product categories."
+msgstr "נותן את סדר הרצף בעת הצגת רשימה של קטגוריות מוצר."
+
+#. module: point_of_sale
+#: view:account.bank.statement:0
+#: view:pos.order:0
+#: view:pos.session:0
+#: view:report.pos.order:0
+msgid "Group By..."
+msgstr "מקובץ על ידי ..."
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:564
+#, python-format
+msgid "Shop:"
+msgstr "חנות:"
+
+#. module: point_of_sale
+#: field:account.journal,self_checkout_payment_method:0
+msgid "Self Checkout Payment Method"
+msgstr "צורות תשלום ברכישה עצמית"
+
+#. module: point_of_sale
+#: view:pos.order:0
+msgid "POS Orders"
+msgstr "הזמנות קופה"
+
+#. module: point_of_sale
+#: model:ir.actions.report.xml,name:point_of_sale.all_closed_cashbox_of_the_day
+msgid "All Closed CashBox"
+msgstr "כל קופות מזומן סגורות"
+
+#. module: point_of_sale
+#: field:pos.details,user_ids:0
+msgid "Salespeople"
+msgstr "אנשי מכירות"
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:777
+#: code:addons/point_of_sale/wizard/pos_box_entries.py:118
+#: code:addons/point_of_sale/wizard/pos_box_out.py:91
+#, python-format
+msgid "You have to open at least one cashbox."
+msgstr ""
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:1172
+#, python-format
+msgid "No Pricelist !"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.poivron_rouges_product_template
+msgid "Red Pepper"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:677
+#, python-format
+msgid "caps lock"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.grisette_cerise_25cl_product_template
+msgid "Grisette Cherry 25cl"
+msgstr ""
+
+#. module: point_of_sale
+#: report:pos.invoice:0
+msgid "Base"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:702
+#: code:addons/point_of_sale/static/src/xml/pos.xml:742
+#, python-format
+msgid " "
+msgstr ""
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.categ_others
+msgid "Others"
+msgstr ""
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.autres_legumes_frais
+msgid "Other fresh vegetables"
+msgstr ""
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_open_statement.py:49
+#, python-format
+msgid "No Cash Register Defined !"
+msgstr ""
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/point_of_sale.py:515
+#, python-format
+msgid ""
+"No cash statement found for this session. Unable to record returned cash."
+msgstr ""
+
+#. module: point_of_sale
+#: model:pos.category,name:point_of_sale.oignons_ail_echalotes
+msgid "Onions / Garlic / Shallots"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.evian_50cl_product_template
+msgid "Evian 50cl"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.order:0
+msgid "Notes"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_light_lemon_2l_product_template
+msgid "Coca-Cola Light Lemon 2L"
+msgstr ""
+
+#. module: point_of_sale
+#: report:pos.details:0
+#: report:pos.invoice:0
+#: field:pos.order,amount_tax:0
+msgid "Taxes"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_order_line
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_order_line_day
+#: model:ir.actions.act_window,name:point_of_sale.action_pos_order_line_form
+msgid "Sale line"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:741
+#, python-format
+msgid "123"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,name:point_of_sale.product_normal_action
+#: model:ir.ui.menu,name:point_of_sale.menu_point_of_sale_product
+#: model:ir.ui.menu,name:point_of_sale.menu_pos_products
+#: view:pos.order:0
+msgid "Products"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.oetker_4formaggi_product_template
+msgid "Dr. Oetker Ristorante Quattro Formaggi"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.croky_naturel_45g_product_template
+msgid "Croky Natural 45g"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.tomate_en_grappe_product_template
+msgid "In Cluster Tomatoes"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.actions.client,name:point_of_sale.action_pos_pos
+msgid "Start Point of Sale"
+msgstr ""
+
+#. module: point_of_sale
+#. openerp-web
+#: code:addons/point_of_sale/static/src/xml/pos.xml:84
+#: report:pos.details:0
+#: report:pos.payment.report.user:0
+#: report:pos.user.product:0
+#: field:report.sales.by.margin.pos,qty:0
+#: field:report.sales.by.margin.pos.month,qty:0
+#, python-format
+msgid "Qty"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.coca_zero_1l_product_template
+msgid "Coca-Cola Zero 1L"
+msgstr ""
+
+#. module: point_of_sale
+#: report:pos.sales.user:0
+#: report:pos.sales.user.today:0
+#: field:report.pos.order,date:0
+msgid "Date Order"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.order:0
+msgid "Point of Sale Orders"
+msgstr ""
+
+#. module: point_of_sale
+#: model:product.template,name:point_of_sale.spa_et_fruit_50cl_product_template
+msgid "Spa Fruit and Orange 50cl"
+msgstr ""
+
+#. module: point_of_sale
+#: view:pos.config:0
+#: field:pos.config,journal_ids:0
+#: field:pos.session,journal_ids:0
+msgid "Available Payment Methods"
+msgstr ""
+
+#. module: point_of_sale
+#: model:ir.actions.act_window,help:point_of_sale.product_normal_action
+msgid ""
+"
\n"
+" Click to add a new product.\n"
+"
\n"
+" You must define a product for everything you sell through\n"
+" the point of sale interface.\n"
+"
\n"
+" Do not forget to set the price and the point of sale "
+"category\n"
+" in which it should appear. If a product has no point of "
+"sale\n"
+" category, you can not sell it through the point of sale\n"
+" interface.\n"
+"