[MERGE]
bzr revid: apa@tinyerp.com-20120912050023-cxpu65let3au2s7q bzr revid: apa@tinyerp.com-20120913052249-rs4rg0p1ongpc6vm bzr revid: apa@tinyerp.com-20120914050849-9wqodxmnbwbh42tm bzr revid: hmo@tinyerp.com-20120914112458-7oeiiojghecmwxe7
This commit is contained in:
commit
cce3a14b21
|
@ -2338,6 +2338,16 @@ class account_model(osv.osv):
|
|||
|
||||
return move_ids
|
||||
|
||||
def onchange_journal_id(self, cr, uid, ids, journal_id, context=None):
|
||||
company_id = False
|
||||
|
||||
if journal_id:
|
||||
journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context)
|
||||
if journal.company_id.id:
|
||||
company_id = journal.company_id.id
|
||||
|
||||
return {'value': {'company_id': company_id}}
|
||||
|
||||
account_model()
|
||||
|
||||
class account_model_line(osv.osv):
|
||||
|
@ -2516,22 +2526,25 @@ class account_account_template(osv.osv):
|
|||
'nocreate': False,
|
||||
}
|
||||
|
||||
def _check_type(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
accounts = self.browse(cr, uid, ids, context=context)
|
||||
for account in accounts:
|
||||
if account.parent_id and account.parent_id.type != 'view':
|
||||
return False
|
||||
return True
|
||||
|
||||
_check_recursion = check_cycle
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error!\nYou cannot create recursive account templates.', ['parent_id']),
|
||||
(_check_type, 'Configuration Error!\nYou cannot define children to an account that has internal type other than "View".', ['type']),
|
||||
|
||||
]
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if 'parent_id' in vals:
|
||||
parent = self.read(cr, uid, [vals['parent_id']], ['type'])
|
||||
if parent and parent[0]['type'] != 'view':
|
||||
raise osv.except_osv(_('Warning!'), _("You may only select a parent account of type 'View'."))
|
||||
return super(account_account_template, self).create(cr, uid, vals, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if 'parent_id' in vals:
|
||||
parent = self.read(cr, uid, [vals['parent_id']], ['type'])
|
||||
if parent and parent[0]['type'] != 'view':
|
||||
raise osv.except_osv(_('Warning!'), _("You may only select a parent account of type 'View'."))
|
||||
return super(account_account_template, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
if not ids:
|
||||
return []
|
||||
|
@ -3010,9 +3023,9 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
|||
'purchase_tax_rate': fields.float('Purchase Tax(%)'),
|
||||
'complete_tax_set': fields.boolean('Complete Set of Taxes', help='This boolean helps you to choose if you want to propose to the user to encode the sales and purchase rates or use the usual m2o fields. This last choice assumes that the set of tax defined for the chosen template is complete'),
|
||||
}
|
||||
|
||||
|
||||
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
|
||||
currency_id = False
|
||||
currency_id = False
|
||||
if company_id:
|
||||
currency_id = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id.id
|
||||
return {'value': {'currency_id': currency_id}}
|
||||
|
|
|
@ -43,11 +43,15 @@ class bank(osv.osv):
|
|||
"Return the name to use when creating a bank journal"
|
||||
return (bank.bank_name or '') + ' ' + bank.acc_number
|
||||
|
||||
def _prepare_name_get(self, cr, uid, bank_type_obj, bank_obj, context=None):
|
||||
"""Add ability to have %(currency_name)s in the format_layout of
|
||||
res.partner.bank.type"""
|
||||
bank_obj._data[bank_obj.id]['currency_name'] = bank_obj.currency_id and bank_obj.currency_id.name or ''
|
||||
return super(bank, self)._prepare_name_get(cr, uid, bank_type_obj, bank_obj, context=context)
|
||||
def _prepare_name_get(self, cr, uid, bank_dicts, context=None):
|
||||
"""Add ability to have %(currency_name)s in the format_layout of res.partner.bank.type"""
|
||||
currency_ids = list(set(data['currency_id'][0] for data in bank_dicts if data['currency_id']))
|
||||
currencies = self.pool.get('res.currency').browse(cr, uid, currency_ids, context=context)
|
||||
currency_name = dict((currency.id, currency.name) for currency in currencies)
|
||||
|
||||
for data in bank_dicts:
|
||||
data['currency_name'] = data['currency_id'] and currency_name[data['currency_id'][0]] or ''
|
||||
return super(bank, self)._prepare_name_get(cr, uid, bank_dicts, context=context)
|
||||
|
||||
def post_write(self, cr, uid, ids, context={}):
|
||||
if isinstance(ids, (int, long)):
|
||||
|
|
|
@ -14,8 +14,12 @@
|
|||
</footer>
|
||||
</footer>
|
||||
<separator string="title" position="replace">
|
||||
<p class="oe_grey">
|
||||
Select a configuration package to setup automatically your
|
||||
taxes and chart of accounts.
|
||||
</p>
|
||||
<group>
|
||||
<field name="charts"/>
|
||||
<field name="charts" class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Configure your Fiscal Year" groups="account.group_account_user">
|
||||
<field name="has_default_company" invisible="1" />
|
||||
|
@ -32,7 +36,7 @@
|
|||
</record>
|
||||
|
||||
<record id="action_account_configuration_installer" model="ir.actions.act_window">
|
||||
<field name="name">Configure your Chart of Accounts</field>
|
||||
<field name="name">Configure Accounting Data</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">account.installer</field>
|
||||
<field name="view_id" ref="view_account_configuration_installer"/>
|
||||
|
|
|
@ -395,18 +395,23 @@ class account_invoice(osv.osv):
|
|||
template_id = template and template[1] or False
|
||||
res = mod_obj.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')
|
||||
res_id = res and res[1] or False
|
||||
ctx = dict(context, active_model='account.invoice', active_id=ids[0])
|
||||
ctx.update({'mail.compose.template_id': template_id})
|
||||
ctx = dict(context)
|
||||
ctx.update({
|
||||
'default_model': 'account.invoice',
|
||||
'default_res_id': ids[0],
|
||||
'default_use_template': True,
|
||||
'default_template_id': template_id,
|
||||
})
|
||||
return {
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.compose.message',
|
||||
'views': [(res_id, 'form')],
|
||||
'view_id': res_id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
'nodestroy': True,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.compose.message',
|
||||
'views': [(res_id, 'form')],
|
||||
'view_id': res_id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
'nodestroy': True,
|
||||
}
|
||||
|
||||
def confirm_paid(self, cr, uid, ids, context=None):
|
||||
|
@ -767,17 +772,20 @@ class account_invoice(osv.osv):
|
|||
if not key in tax_key:
|
||||
raise osv.except_osv(_('Warning!'), _('Taxes are missing!\nClick on compute button.'))
|
||||
|
||||
def compute_invoice_totals(self, cr, uid, inv, company_currency, ref, invoice_move_lines):
|
||||
def compute_invoice_totals(self, cr, uid, inv, company_currency, ref, invoice_move_lines, context=None):
|
||||
if context is None:
|
||||
context={}
|
||||
total = 0
|
||||
total_currency = 0
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
for i in invoice_move_lines:
|
||||
if inv.currency_id.id != company_currency:
|
||||
context.update({'date': inv.date_invoice or time.strftime('%Y-%m-%d')})
|
||||
i['currency_id'] = inv.currency_id.id
|
||||
i['amount_currency'] = i['price']
|
||||
i['price'] = cur_obj.compute(cr, uid, inv.currency_id.id,
|
||||
company_currency, i['price'],
|
||||
context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')})
|
||||
context=context)
|
||||
else:
|
||||
i['amount_currency'] = False
|
||||
i['currency_id'] = False
|
||||
|
@ -887,7 +895,7 @@ class account_invoice(osv.osv):
|
|||
# create one move line for the total and possibly adjust the other lines amount
|
||||
total = 0
|
||||
total_currency = 0
|
||||
total, total_currency, iml = self.compute_invoice_totals(cr, uid, inv, company_currency, ref, iml)
|
||||
total, total_currency, iml = self.compute_invoice_totals(cr, uid, inv, company_currency, ref, iml, context=ctx)
|
||||
acc_id = inv.account_id.id
|
||||
|
||||
name = inv['name'] or '/'
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
<field name="fiscalyear_id" widget="selection"/>
|
||||
<label for="date_start" string="Duration"/>
|
||||
<div>
|
||||
<field name="date_start" class="oe_inline" nolabel="1"/> -
|
||||
<field name="date_start" class="oe_inline" nolabel="1"/> -
|
||||
<field name="date_stop" nolabel="1" class="oe_inline"/>
|
||||
</div>
|
||||
</group>
|
||||
|
@ -181,7 +181,7 @@
|
|||
<form string="Account" version="7.0">
|
||||
<label for="code" class="oe_edit_only" string="Account Code and Name"/>
|
||||
<h1>
|
||||
<field name="code" class="oe_inline" placeholder="Account code" style="width: 6em"/> -
|
||||
<field name="code" class="oe_inline" placeholder="Account code" style="width: 6em"/> -
|
||||
<field name="name" class="oe_inline" placeholder="Account name"/>
|
||||
</h1>
|
||||
<group>
|
||||
|
@ -1082,7 +1082,7 @@
|
|||
<field eval="2" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Journal Item" version="7.0">
|
||||
<sheet>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
|
@ -1349,7 +1349,7 @@
|
|||
<field name="date"/>
|
||||
<field name="to_check"/>
|
||||
<field name="amount" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Journal Items">
|
||||
|
@ -1651,8 +1651,8 @@
|
|||
<form string="Journal Entry Model" version="7.0">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="journal_id"/>
|
||||
<field name="company_id" widget='selection' groups="base.group_multi_company"/>
|
||||
<field name="journal_id" on_change="onchange_journal_id(journal_id)"/>
|
||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
|
||||
<field name="lines_id" widget="one2many_list"/>
|
||||
|
@ -2369,22 +2369,15 @@
|
|||
<group string="res_config_contents" position="replace">
|
||||
<field name="only_one_chart_template" invisible="1"/>
|
||||
<field name="complete_tax_set" invisible="1"/>
|
||||
<div groups="base.group_multi_company">
|
||||
<label for="company_id"/>
|
||||
<field name="company_id" widget="selection" on_change="onchange_company_id(company_id)"/> <!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
|
||||
</div>
|
||||
<label for="currency_id"/>
|
||||
<field name="currency_id" />
|
||||
<group>
|
||||
<div attrs="{'invisible': [('only_one_chart_template','=',True)]}">
|
||||
<label for="chart_template_id"/>
|
||||
<group col="1">
|
||||
<group attrs="{'invisible': [('only_one_chart_template','=',True)]}">
|
||||
<field name="chart_template_id" widget="selection" on_change="onchange_chart_template_id(chart_template_id)" domain="[('visible','=', True)]"/>
|
||||
</div>
|
||||
<newline/>
|
||||
<group groups="account.group_account_user">
|
||||
<field name="code_digits"/>
|
||||
</group>
|
||||
<group groups="base.group_multi_company">
|
||||
<field name="company_id" widget="selection" on_change="onchange_company_id(company_id)"/> <!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
|
||||
</group>
|
||||
<group>
|
||||
<field name="currency_id" class="oe_inline"/>
|
||||
<field name="sale_tax" attrs="{'invisible': [('complete_tax_set', '!=', True)]}" domain="[('chart_template_id', '=', chart_template_id),('parent_id','=',False),('type_tax_use','in',('sale','all'))]"/>
|
||||
<label for="sale_tax_rate" string="Sale Tax" attrs="{'invisible': [('complete_tax_set', '=', True)]}"/>
|
||||
<div attrs="{'invisible': [('complete_tax_set', '=', True)]}">
|
||||
|
@ -2396,17 +2389,10 @@
|
|||
<field name="purchase_tax_rate" class="oe_inline"/> %%
|
||||
</div>
|
||||
</group>
|
||||
<group groups="account.group_account_user">
|
||||
<field name="code_digits"/>
|
||||
</group>
|
||||
</group>
|
||||
<div groups="account.group_account_user">
|
||||
<label for="bank_accounts_id" string="Bank Information"/>
|
||||
<field name="bank_accounts_id">
|
||||
<tree editable="bottom">
|
||||
<field name="acc_name"/>
|
||||
<field name="account_type"/>
|
||||
<field name="currency_id" widget="selection" groups="base.group_multi_currency"/>
|
||||
</tree>
|
||||
</field>
|
||||
</div>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
<record id="conf_chart0" model="account.account.template">
|
||||
<field name="code">0</field>
|
||||
<field name="name">Configurable Account Chart</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="data_account_type_view"/>
|
||||
</record>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
<record id="chart0" model="account.account">
|
||||
<field name="code">X0</field>
|
||||
<field name="name">Chart For Automated Tests</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="data_account_type_view"/>
|
||||
</record>
|
||||
|
|
|
@ -45,12 +45,12 @@ class account_installer(osv.osv_memory):
|
|||
sorted(((m.name, m.shortdesc)
|
||||
for m in modules.browse(cr, uid, ids, context=context)),
|
||||
key=itemgetter(1)))
|
||||
charts.insert(0, ('configurable', 'Generic Chart Of Accounts'))
|
||||
charts.insert(0, ('configurable', _('Custom')))
|
||||
return charts
|
||||
|
||||
_columns = {
|
||||
# Accounting
|
||||
'charts': fields.selection(_get_charts, 'Chart of Accounts',
|
||||
'charts': fields.selection(_get_charts, 'Accounting Package',
|
||||
required=True,
|
||||
help="Installs localized accounting charts to match as closely as "
|
||||
"possible the accounting needs of your company based on your "
|
||||
|
|
|
@ -44,17 +44,17 @@ class account_config_settings(osv.osv_memory):
|
|||
'paypal_account': fields.related('company_id', 'paypal_account', type='char', size=128,
|
||||
string='Paypal account', help="Paypal account (email) for receiving online payments (credit card, etc.) If you set a paypal account, the customer will be able to pay your invoices or quotations with a button \"Pay with Paypal\" in automated emails or through the OpenERP portal."),
|
||||
'company_footer': fields.related('company_id', 'rml_footer', type='text', readonly=True,
|
||||
string='Bank accounts on reports will displayed as followed', help="Bank accounts as printed in the footer of each customer's document. This is for information purpose only, you should configure these bank accounts through the above button \"Configure Bank Accounts\"."),
|
||||
string='Bank accounts footer preview', help="Bank accounts as printed in the footer of each printed document"),
|
||||
|
||||
'has_chart_of_accounts': fields.boolean('Company has a chart of accounts'),
|
||||
'chart_template_id': fields.many2one('account.chart.template', 'Template', domain="[('visible','=', True)]"),
|
||||
'code_digits': fields.integer('# of Digits', help="No. of digits to use for account code"),
|
||||
'tax_calculation_rounding_method': fields.related('company_id',
|
||||
'tax_calculation_rounding_method', type='selection', selection=[
|
||||
('round_per_line', 'Round per Line'),
|
||||
('round_globally', 'Round Globally'),
|
||||
('round_per_line', 'Round per line'),
|
||||
('round_globally', 'Round globally'),
|
||||
], string='Tax calculation rounding method',
|
||||
help="If you select 'Round per Line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round Globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
|
||||
help="If you select 'Round per line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
|
||||
'sale_tax': fields.many2one("account.tax.template", "Default sale tax"),
|
||||
'purchase_tax': fields.many2one("account.tax.template", "Default purchase tax"),
|
||||
'sale_tax_rate': fields.float('Sales tax (%)'),
|
||||
|
@ -72,40 +72,40 @@ class account_config_settings(osv.osv_memory):
|
|||
'sale_refund_journal_id': fields.many2one('account.journal', 'Sale refund journal'),
|
||||
'sale_refund_sequence_prefix': fields.related('sale_refund_journal_id', 'sequence_id', 'prefix', type='char', string='Credit note sequence'),
|
||||
'sale_refund_sequence_next': fields.related('sale_refund_journal_id', 'sequence_id', 'number_next', type='integer', string='Next credit note number'),
|
||||
'purchase_journal_id': fields.many2one('account.journal', 'Purchase Journal'),
|
||||
'purchase_journal_id': fields.many2one('account.journal', 'Purchase journal'),
|
||||
'purchase_sequence_prefix': fields.related('purchase_journal_id', 'sequence_id', 'prefix', type='char', string='Supplier invoice sequence'),
|
||||
'purchase_sequence_next': fields.related('purchase_journal_id', 'sequence_id', 'number_next', type='integer', string='Next supplier invoice number'),
|
||||
'purchase_refund_journal_id': fields.many2one('account.journal', 'Purchase refund journal'),
|
||||
'purchase_refund_sequence_prefix': fields.related('purchase_refund_journal_id', 'sequence_id', 'prefix', type='char', string='Supplier credit note sequence'),
|
||||
'purchase_refund_sequence_next': fields.related('purchase_refund_journal_id', 'sequence_id', 'number_next', type='integer', string='Next supplier credit note number'),
|
||||
|
||||
'module_account_check_writing': fields.boolean('pay your suppliers by check',
|
||||
'module_account_check_writing': fields.boolean('Pay your suppliers by check',
|
||||
help="""This allows you to check writing and printing.
|
||||
This installs the module account_check_writing."""),
|
||||
'module_account_accountant': fields.boolean('full accounting features: journals, legal statements, chart of accounts, etc.',
|
||||
'module_account_accountant': fields.boolean('Full accounting features: journals, legal statements, chart of accounts, etc.',
|
||||
help="""If you do not check this box, you will be able to do invoicing & payments, but not accounting (Journal Items, Chart of Accounts, ...)"""),
|
||||
'module_account_asset': fields.boolean('assets management',
|
||||
'module_account_asset': fields.boolean('Assets management',
|
||||
help="""This allows you to manage the assets owned by a company or a person.
|
||||
It keeps track of the depreciation occurred on those assets, and creates account move for those depreciation lines.
|
||||
This installs the module account_asset. If you do not check this box, you will be able to do invoicing & payments,
|
||||
but not accounting (Journal Items, Chart of Accounts, ...)"""),
|
||||
'module_account_budget': fields.boolean('budget management',
|
||||
'module_account_budget': fields.boolean('Budget management',
|
||||
help="""This allows accountants to manage analytic and crossovered budgets.
|
||||
Once the master budgets and the budgets are defined,
|
||||
the project managers can set the planned amount on each analytic account.
|
||||
This installs the module account_budget."""),
|
||||
'module_account_payment': fields.boolean('manage payment orders',
|
||||
'module_account_payment': fields.boolean('Manage payment orders',
|
||||
help="""This allows you to create and manage your payment orders, with purposes to
|
||||
* serve as base for an easy plug-in of various automated payment mechanisms, and
|
||||
* provide a more efficient way to manage invoice payments.
|
||||
This installs the module account_payment."""),
|
||||
'module_account_voucher': fields.boolean('manage customer payments',
|
||||
'module_account_voucher': fields.boolean('Manage customer payments',
|
||||
help="""This includes all the basic requirements of voucher entries for bank, cash, sales, purchase, expense, contra, etc.
|
||||
This installs the module account_voucher."""),
|
||||
'module_account_followup': fields.boolean('manage customer payment follow-ups',
|
||||
'module_account_followup': fields.boolean('Manage customer payment follow-ups',
|
||||
help="""This allows to automate letters for unpaid invoices, with multi-level recalls.
|
||||
This installs the module account_followup."""),
|
||||
'group_proforma_invoices': fields.boolean('allow pro-forma invoices',
|
||||
'group_proforma_invoices': fields.boolean('Allow pro-forma invoices',
|
||||
implied_group='account.group_proforma_invoices',
|
||||
help="Allows you to put invoices in pro-forma state."),
|
||||
'default_sale_tax': fields.many2one('account.tax', 'Default sale tax',
|
||||
|
@ -114,6 +114,9 @@ class account_config_settings(osv.osv_memory):
|
|||
help="This purchase tax will be assigned by default on new products."),
|
||||
'decimal_precision': fields.integer('Decimal precision on journal entries',
|
||||
help="""As an example, a decimal precision of 2 will allow journal entries like: 9.99 EUR, whereas a decimal precision of 4 will allow journal entries like: 0.0231 EUR."""),
|
||||
'group_multi_currency': fields.boolean('Allow multi currencies',
|
||||
implied_group='base.group_multi_currency',
|
||||
help="Allows you multi currency environment"),
|
||||
}
|
||||
|
||||
def _default_company(self, cr, uid, context=None):
|
||||
|
@ -220,6 +223,16 @@ class account_config_settings(osv.osv_memory):
|
|||
return {'value': {'date_stop': end_date.strftime('%Y-%m-%d')}}
|
||||
return {}
|
||||
|
||||
def open_company_form(self, cr, uid, ids, context=None):
|
||||
config = self.browse(cr, uid, ids[0], context)
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Configure your Company',
|
||||
'res_model': 'res.company',
|
||||
'res_id': config.company_id.id,
|
||||
'view_mode': 'form',
|
||||
}
|
||||
|
||||
def set_default_taxes(self, cr, uid, ids, context=None):
|
||||
""" set default sale and purchase taxes for products """
|
||||
ir_values = self.pool.get('ir.values')
|
||||
|
|
|
@ -121,6 +121,10 @@
|
|||
</div>
|
||||
<label for="id" string="Features"/>
|
||||
<div>
|
||||
<div>
|
||||
<field name="group_multi_currency" class="oe_inline"/>
|
||||
<label for="group_multi_currency"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="module_account_accountant" class="oe_inline"/>
|
||||
<label for="module_account_accountant"/>
|
||||
|
@ -219,12 +223,10 @@
|
|||
<label for="id" string="Configuration"/>
|
||||
<div>
|
||||
<div>
|
||||
<button name="%(action_bank_tree)d"
|
||||
string="Configure your bank accounts"
|
||||
icon="gtk-go-forward"
|
||||
type="action"
|
||||
class="oe_inline oe_link"/>
|
||||
<label for="company_footer"/>
|
||||
<button name="open_company_form" type="object"
|
||||
string="Configure your company bank accounts" icon="gtk-go-forward"
|
||||
class="oe_inline oe_link"/>
|
||||
<field name="company_footer"/>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -0,0 +1,385 @@
|
|||
# Brazilian Portuguese translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
|
||||
"PO-Revision-Date: 2012-09-11 18:35+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-12 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build 15930)\n"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Search Bank Transactions"
|
||||
msgstr "Procurar Transações Bancárias"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
#: selection:account.bank.statement.line,state:0
|
||||
msgid "Confirmed"
|
||||
msgstr "Confirmado"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement:0
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Glob. Id"
|
||||
msgstr "ID Global"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: selection:account.bank.statement.line.global,type:0
|
||||
msgid "CODA"
|
||||
msgstr "CODA"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,parent_id:0
|
||||
msgid "Parent Code"
|
||||
msgstr "Código da Conta-pai"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Debit"
|
||||
msgstr "Débito"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:cancel.statement.line:0
|
||||
#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_cancel_statement_line
|
||||
#: model:ir.model,name:account_bank_statement_extensions.model_cancel_statement_line
|
||||
msgid "Cancel selected statement lines"
|
||||
msgstr "Cancelar linhas de instrução selecionadas"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid "The RIB and/or IBAN is not valid"
|
||||
msgstr "A RIB e/ ou IBAN não é válido."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Group By..."
|
||||
msgstr "Agrupar Por..."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,state:0
|
||||
msgid "State"
|
||||
msgstr "Situação"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
#: selection:account.bank.statement.line,state:0
|
||||
msgid "Draft"
|
||||
msgstr "Provisório"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Statement"
|
||||
msgstr "Demonstrativo"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:confirm.statement.line:0
|
||||
#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_confirm_statement_line
|
||||
#: model:ir.model,name:account_bank_statement_extensions.model_confirm_statement_line
|
||||
msgid "Confirm selected statement lines"
|
||||
msgstr "Confirme as linhas do demonstrativo selecionadas"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: report:bank.statement.balance.report:0
|
||||
#: model:ir.actions.report.xml,name:account_bank_statement_extensions.bank_statement_balance_report
|
||||
msgid "Bank Statement Balances Report"
|
||||
msgstr "Relatório de Balanço Bancário"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:cancel.statement.line:0
|
||||
msgid "Cancel Lines"
|
||||
msgstr "Cancelar Linhas"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line.global:0
|
||||
#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement_line_global
|
||||
msgid "Batch Payment Info"
|
||||
msgstr "Informações de Pagamento em Lote"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:confirm.statement.line:0
|
||||
msgid "Confirm Lines"
|
||||
msgstr "Confirmar Linhas"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: code:addons/account_bank_statement_extensions/account_bank_statement.py:130
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Delete operation not allowed ! Please go to the associated bank "
|
||||
"statement in order to delete and/or modify this bank statement line"
|
||||
msgstr ""
|
||||
"Não é permitido excluir! Vá a linha do demonstrativo bancário associada para "
|
||||
"excluir ou modificar esta linha do demonstrativo"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,type:0
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
#: field:account.bank.statement.line,journal_id:0
|
||||
#: report:bank.statement.balance.report:0
|
||||
msgid "Journal"
|
||||
msgstr "Diário"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Confirmed Statement Lines."
|
||||
msgstr "Linhas do Demonstrativo Confirmadas."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Credit Transactions."
|
||||
msgstr "Transações de Crédito"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: model:ir.actions.act_window,help:account_bank_statement_extensions.action_cancel_statement_line
|
||||
msgid "cancel selected statement lines."
|
||||
msgstr "cancelar linhas do demonstrativo selecionadas."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,counterparty_number:0
|
||||
msgid "Counterparty Number"
|
||||
msgstr "Número da Contrapartida"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line.global:0
|
||||
msgid "Transactions"
|
||||
msgstr "Transações"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: code:addons/account_bank_statement_extensions/account_bank_statement.py:130
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr "Aviso"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: report:bank.statement.balance.report:0
|
||||
msgid "Closing Balance"
|
||||
msgstr "Saldo final"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: report:bank.statement.balance.report:0
|
||||
msgid "Date"
|
||||
msgstr "Data"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
#: field:account.bank.statement.line,globalisation_amount:0
|
||||
msgid "Glob. Amount"
|
||||
msgstr "Valor Global"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Debit Transactions."
|
||||
msgstr "Transações de Débito."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Extended Filters..."
|
||||
msgstr "Filtros Extendidos..."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:confirm.statement.line:0
|
||||
msgid "Confirmed lines cannot be changed anymore."
|
||||
msgstr "Linhas confirmadas não podem ser alteradas."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid ""
|
||||
"\n"
|
||||
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
|
||||
"valid payments"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Por favor defina o BIC/Swift code no Banco para o tipo de conta IBAN para "
|
||||
"fazer pagamentos válidos"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,val_date:0
|
||||
msgid "Valuta Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: model:ir.actions.act_window,help:account_bank_statement_extensions.action_confirm_statement_line
|
||||
msgid "Confirm selected statement lines."
|
||||
msgstr "Confirmar as linhas do demonstrativo."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:cancel.statement.line:0
|
||||
msgid "Are you sure you want to cancel the selected Bank Statement lines ?"
|
||||
msgstr ""
|
||||
"Você tem certeza de que deseja cancelar as Linhas de Demonstrativo Bancário "
|
||||
"selecionadas?"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: report:bank.statement.balance.report:0
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: selection:account.bank.statement.line.global,type:0
|
||||
msgid "ISO 20022"
|
||||
msgstr "ISO 20022"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Notes"
|
||||
msgstr "Notas"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: selection:account.bank.statement.line.global,type:0
|
||||
msgid "Manual"
|
||||
msgstr "Manual"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Credit"
|
||||
msgstr "Crédito"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,amount:0
|
||||
msgid "Amount"
|
||||
msgstr "Valor"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Fin.Account"
|
||||
msgstr "Fin.Account"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,counterparty_currency:0
|
||||
msgid "Counterparty Currency"
|
||||
msgstr "Moeda da Contrapartida"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,counterparty_bic:0
|
||||
msgid "Counterparty BIC"
|
||||
msgstr "BIC da Contrapartida"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,child_ids:0
|
||||
msgid "Child Codes"
|
||||
msgstr "Códigos derivados (sub-contas)"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:confirm.statement.line:0
|
||||
msgid "Are you sure you want to confirm the selected Bank Statement lines ?"
|
||||
msgstr ""
|
||||
"Você deseja confirmar as Linhas do Demonstrativo Bancário selecionadas?"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: constraint:account.bank.statement.line:0
|
||||
msgid ""
|
||||
"The amount of the voucher must be the same amount as the one on the "
|
||||
"statement line"
|
||||
msgstr ""
|
||||
"O valor do recibo deve ser o mesmo valor da linha equivalente no extrato"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: help:account.bank.statement.line,globalisation_id:0
|
||||
msgid ""
|
||||
"Code to identify transactions belonging to the same globalisation level "
|
||||
"within a batch payment"
|
||||
msgstr ""
|
||||
"Código para identificar transações que pertencem ao nível de globalização "
|
||||
"dentro de um mesmo lote de pagamento"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Draft Statement Lines."
|
||||
msgstr "Linhas de Demonstrativo Provisórias."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Glob. Am."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement_line
|
||||
msgid "Bank Statement Line"
|
||||
msgstr "Linha do Demonstrativo Bancário"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,code:0
|
||||
msgid "Code"
|
||||
msgstr "Código"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,counterparty_name:0
|
||||
msgid "Counterparty Name"
|
||||
msgstr "Nome da Contrapartida"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,name:0
|
||||
msgid "Communication"
|
||||
msgstr "Comunicação"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: model:ir.model,name:account_bank_statement_extensions.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr "Contas Bancárias"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: constraint:account.bank.statement:0
|
||||
msgid "The journal and period chosen have to belong to the same company."
|
||||
msgstr "O diário e o período escolhido tem que pertencer à mesma empresa."
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement
|
||||
msgid "Bank Statement"
|
||||
msgstr "Extrato Bancário"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Statement Line"
|
||||
msgstr "Linha do Demonstrativo"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: sql_constraint:account.bank.statement.line.global:0
|
||||
msgid "The code must be unique !"
|
||||
msgstr "O código precisa ser único!"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line.global,bank_statement_line_ids:0
|
||||
#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_bank_statement_line
|
||||
#: model:ir.ui.menu,name:account_bank_statement_extensions.bank_statement_line
|
||||
msgid "Bank Statement Lines"
|
||||
msgstr "Linhas do Demonstrativo Bancário"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line.global:0
|
||||
msgid "Child Batch Payments"
|
||||
msgstr "Lote de Pagamentos Filho"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:cancel.statement.line:0
|
||||
#: view:confirm.statement.line:0
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Statement Lines"
|
||||
msgstr "Linhas do Demonstrativo"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: view:account.bank.statement.line:0
|
||||
msgid "Total Amount"
|
||||
msgstr "Valor Total"
|
||||
|
||||
#. module: account_bank_statement_extensions
|
||||
#: field:account.bank.statement.line,globalisation_id:0
|
||||
msgid "Globalisation ID"
|
||||
msgstr "ID Globalização"
|
|
@ -0,0 +1,207 @@
|
|||
# Spanish (Ecuador) translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
|
||||
"PO-Revision-Date: 2012-09-12 01:39+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
msgid "Check on Top"
|
||||
msgstr "Cheque on Top"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.act_window,help:account_check_writing.action_write_check
|
||||
msgid ""
|
||||
"The check payment form allows you to track the payment you do to your "
|
||||
"suppliers specially by check. When you select a supplier, the payment method "
|
||||
"and an amount for the payment, OpenERP will propose to reconcile your "
|
||||
"payment with the open supplier invoices or bills.You can print the check"
|
||||
msgstr ""
|
||||
"El pago de cheques permite rastrear el pago a sus proveedores. Cuando "
|
||||
"selecciona un proveedor, el método de pago y monto, OpenERP propondrá "
|
||||
"conciliarlo con tu factura, y podrá imprimir el cheque."
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:account.voucher:0
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_bottom
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
|
||||
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
|
||||
msgid "Print Check"
|
||||
msgstr "Imprimir Cheque"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
msgid "Check in middle"
|
||||
msgstr "Cheque in middle"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: help:res.company,check_layout:0
|
||||
msgid ""
|
||||
"Check on top is compatible with Quicken, QuickBooks and Microsoft Money. "
|
||||
"Check in middle is compatible with Peachtree, ACCPAC and DacEasy. Check on "
|
||||
"bottom is compatible with Peachtree, ACCPAC and DacEasy only"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: selection:res.company,check_layout:0
|
||||
msgid "Check on bottom"
|
||||
msgstr "Cheque on bottom"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: constraint:res.company:0
|
||||
msgid "Error! You can not create recursive companies."
|
||||
msgstr "Error! No puede crear compañías recursivas."
|
||||
|
||||
#. module: account_check_writing
|
||||
#: help:account.journal,allow_check_writing:0
|
||||
msgid "Check this if the journal is to be used for writing checks."
|
||||
msgstr "Activar si este diario es usado para emitir cheques"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.journal,allow_check_writing:0
|
||||
msgid "Allow Check writing"
|
||||
msgstr "Permitir emisión de cheques"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_account_journal
|
||||
msgid "Journal"
|
||||
msgstr "Diario"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.actions.act_window,name:account_check_writing.action_write_check
|
||||
#: model:ir.ui.menu,name:account_check_writing.menu_action_write_check
|
||||
msgid "Write Checks"
|
||||
msgstr "Escribir Cheque"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Discount"
|
||||
msgstr "Descuento"
|
||||
|
||||
#. 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 "Monto Inicial"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:res.company:0
|
||||
msgid "Configuration"
|
||||
msgstr "Configuración"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.voucher,allow_check:0
|
||||
msgid "Allow Check Writing"
|
||||
msgstr "Permitir Emisión de Cheques"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Payment"
|
||||
msgstr "Pagos"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.journal,use_preprint_check:0
|
||||
msgid "Use Preprinted Check"
|
||||
msgstr "Usar cheque preimpreso"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: sql_constraint:res.company:0
|
||||
msgid "The company name must be unique !"
|
||||
msgstr "¡El nombre de la compañía debe ser único!"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Due Date"
|
||||
msgstr "Fecha de vencimiento"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr "Compañias"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: view:res.company:0
|
||||
msgid "Default Check Layout"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_check_writing
|
||||
#: constraint:account.journal:0
|
||||
msgid ""
|
||||
"Configuration error! The currency chosen should be shared by the default "
|
||||
"accounts too."
|
||||
msgstr ""
|
||||
"Error de Configuración! La moneda seleccionada debe ser compartida por las "
|
||||
"cuentas por defecto tambíen"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
msgid "Balance Due"
|
||||
msgstr "Saldo Deudor"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.bottom:0
|
||||
#: report:account.print.check.middle:0
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Check Amount"
|
||||
msgstr "Monto Cheque"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: model:ir.model,name:account_check_writing.model_account_voucher
|
||||
msgid "Accounting Voucher"
|
||||
msgstr "Comprobantes de Pago"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The name of the journal must be unique per company !"
|
||||
msgstr "El nombre del diaro debe ser único por compañía !"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The code of the journal must be unique per company !"
|
||||
msgstr "El código del diario debe ser único por compañía !"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:account.voucher,amount_in_word:0
|
||||
msgid "Amount in Word"
|
||||
msgstr "Monto en Letras"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: report:account.print.check.top:0
|
||||
msgid "Open Balance"
|
||||
msgstr "Saldo Inicial"
|
||||
|
||||
#. module: account_check_writing
|
||||
#: field:res.company,check_layout:0
|
||||
msgid "Choose Check layout"
|
||||
msgstr "Elegir diseño de cheque"
|
||||
|
||||
#~ msgid "Default Check layout"
|
||||
#~ msgstr "Diseño de cheque por defecto"
|
|
@ -1045,6 +1045,8 @@ class account_voucher(osv.osv):
|
|||
# if the amount encoded in voucher is equal to the amount unreconciled, we need to compute the
|
||||
# currency rate difference
|
||||
if line.amount == line.amount_unreconciled:
|
||||
if not line.move_line_id.amount_residual:
|
||||
raise osv.except_osv(_('Wrong bank statement line'),_("You have to delete the bank statement line which the payment was reconciled to manually. Please check the payment of the partner %s by the amount of %s.")%(line.voucher_id.partner_id.name, line.voucher_id.amount))
|
||||
currency_rate_difference = line.move_line_id.amount_residual - amount
|
||||
else:
|
||||
currency_rate_difference = 0.0
|
||||
|
|
|
@ -96,22 +96,6 @@ class account_analytic_account(osv.osv):
|
|||
res[row['id']][field] = row[field]
|
||||
return self._compute_level_tree(cr, uid, ids, child_ids, res, fields, context)
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
if isinstance(ids, (int, long)):
|
||||
ids=[ids]
|
||||
if not ids:
|
||||
return []
|
||||
res = []
|
||||
for account in self.browse(cr, uid, ids, context=context):
|
||||
data = []
|
||||
acc = account
|
||||
while acc:
|
||||
data.insert(0, acc.name)
|
||||
acc = acc.parent_id
|
||||
data = ' / '.join(data)
|
||||
res.append((account.id, data))
|
||||
return res
|
||||
|
||||
def _complete_name_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
|
||||
res = self.name_get(cr, uid, ids)
|
||||
return dict(res)
|
||||
|
|
|
@ -25,7 +25,7 @@ class base_config_settings(osv.TransientModel):
|
|||
_inherit = 'base.config.settings'
|
||||
|
||||
_columns = {
|
||||
'auth_signup_uninvited': fields.boolean('allow public users to sign up', help="If unchecked only invited users may sign up"),
|
||||
'auth_signup_uninvited': fields.boolean('Allow public users to sign up', help="If unchecked only invited users may sign up"),
|
||||
'auth_signup_template_user_id': fields.many2one('res.users', 'Template user for new users created through signup'),
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import controllers
|
||||
import models
|
||||
import test_models
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
'name': 'Base import',
|
||||
'description': """
|
||||
New extensible file import for OpenERP
|
||||
======================================
|
||||
|
||||
Re-implement openerp's file import system:
|
||||
|
||||
* Server side, the previous system forces most of the logic into the
|
||||
client which duplicates the effort (between clients), makes the
|
||||
import system much harder to use without a client (direct RPC or
|
||||
other forms of automation) and makes knowledge about the
|
||||
import/export system much harder to gather as it is spread over
|
||||
3+ different projects.
|
||||
|
||||
* In a more extensible manner, so users and partners can build their
|
||||
own front-end to import from other file formats (e.g. OpenDocument
|
||||
files) which may be simpler to handle in their work flow or from
|
||||
their data production sources.
|
||||
|
||||
* In a module, so that administrators and users of OpenERP who do not
|
||||
need or want an online import can avoid it being available to users.
|
||||
""",
|
||||
'category': 'Uncategorized',
|
||||
'website': 'http://www.openerp.com',
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['base'],
|
||||
'installable': True,
|
||||
'auto_install': False, # set to true and allow uninstall?
|
||||
'css': [
|
||||
'static/lib/select2/select2.css',
|
||||
'static/src/css/import.css',
|
||||
],
|
||||
'js': [
|
||||
'static/lib/select2/select2.js',
|
||||
'static/src/js/import.js',
|
||||
],
|
||||
'qweb': ['static/src/xml/import.xml'],
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import simplejson
|
||||
|
||||
try:
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
except ImportError:
|
||||
import web.common.http as openerpweb
|
||||
|
||||
class ImportController(openerpweb.Controller):
|
||||
_cp_path = '/base_import'
|
||||
|
||||
@openerpweb.httprequest
|
||||
def set_file(self, req, file, import_id, jsonp='callback'):
|
||||
import_id = int(import_id)
|
||||
|
||||
written = req.session.model('base_import.import').write(import_id, {
|
||||
'file': file.read(),
|
||||
'file_name': file.filename,
|
||||
'file_type': file.content_type,
|
||||
}, req.session.eval_context(req.context))
|
||||
|
||||
return 'window.top.%s(%s)' % (
|
||||
jsonp, simplejson.dumps({'result': written}))
|
|
@ -0,0 +1,352 @@
|
|||
import csv
|
||||
import itertools
|
||||
import logging
|
||||
import operator
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
import psycopg2
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
FIELDS_RECURSION_LIMIT = 2
|
||||
ERROR_PREVIEW_BYTES = 200
|
||||
_logger = logging.getLogger(__name__)
|
||||
class ir_import(orm.TransientModel):
|
||||
_name = 'base_import.import'
|
||||
# allow imports to survive for 12h in case user is slow
|
||||
_transient_max_hours = 12.0
|
||||
|
||||
_columns = {
|
||||
'res_model': fields.char('Model', size=64),
|
||||
'file': fields.binary(
|
||||
'File', help="File to check and/or import, raw binary (not base64)"),
|
||||
'file_name': fields.char('File Name', size=None),
|
||||
'file_type': fields.char('File Type', size=None),
|
||||
}
|
||||
|
||||
def get_fields(self, cr, uid, model, context=None,
|
||||
depth=FIELDS_RECURSION_LIMIT):
|
||||
""" Recursively get fields for the provided model (through
|
||||
fields_get) and filter them according to importability
|
||||
|
||||
The output format is a list of ``Field``, with ``Field``
|
||||
defined as:
|
||||
|
||||
.. class:: Field
|
||||
|
||||
.. attribute:: id (str)
|
||||
|
||||
A non-unique identifier for the field, used to compute
|
||||
the span of the ``required`` attribute: if multiple
|
||||
``required`` fields have the same id, only one of them
|
||||
is necessary.
|
||||
|
||||
.. attribute:: name (str)
|
||||
|
||||
The field's logical (OpenERP) name within the scope of
|
||||
its parent.
|
||||
|
||||
.. attribute:: string (str)
|
||||
|
||||
The field's human-readable name (``@string``)
|
||||
|
||||
.. attribute:: required (bool)
|
||||
|
||||
Whether the field is marked as required in the
|
||||
model. Clients must provide non-empty import values
|
||||
for all required fields or the import will error out.
|
||||
|
||||
.. attribute:: fields (list(Field))
|
||||
|
||||
The current field's subfields. The database and
|
||||
external identifiers for m2o and m2m fields; a
|
||||
filtered and transformed fields_get for o2m fields (to
|
||||
a variable depth defined by ``depth``).
|
||||
|
||||
Fields with no sub-fields will have an empty list of
|
||||
sub-fields.
|
||||
|
||||
:param str model: name of the model to get fields form
|
||||
:param int landing: depth of recursion into o2m fields
|
||||
"""
|
||||
fields = [{
|
||||
'id': 'id',
|
||||
'name': 'id',
|
||||
'string': _("External ID"),
|
||||
'required': False,
|
||||
'fields': [],
|
||||
}]
|
||||
fields_got = self.pool[model].fields_get(cr, uid, context=context)
|
||||
for name, field in fields_got.iteritems():
|
||||
if field.get('readonly'):
|
||||
states = field.get('states')
|
||||
if not states:
|
||||
continue
|
||||
# states = {state: [(attr, value), (attr2, value2)], state2:...}
|
||||
if not any(attr == 'readonly' and value is False
|
||||
for attr, value in itertools.chain.from_iterable(
|
||||
states.itervalues())):
|
||||
continue
|
||||
|
||||
f = {
|
||||
'id': name,
|
||||
'name': name,
|
||||
'string': field['string'],
|
||||
# Y U NO ALWAYS HAVE REQUIRED
|
||||
'required': bool(field.get('required')),
|
||||
'fields': [],
|
||||
}
|
||||
|
||||
if field['type'] in ('many2many', 'many2one'):
|
||||
f['fields'] = [
|
||||
dict(f, name='id', string=_("External ID")),
|
||||
dict(f, name='.id', string=_("Database ID")),
|
||||
]
|
||||
elif field['type'] == 'one2many' and depth:
|
||||
f['fields'] = self.get_fields(
|
||||
cr, uid, field['relation'], context=context, depth=depth-1)
|
||||
|
||||
fields.append(f)
|
||||
|
||||
# TODO: cache on model?
|
||||
return fields
|
||||
|
||||
def _read_csv(self, record, options):
|
||||
""" Returns a CSV-parsed iterator of all empty lines in the file
|
||||
|
||||
:throws csv.Error: if an error is detected during CSV parsing
|
||||
:throws UnicodeDecodeError: if ``options.encoding`` is incorrect
|
||||
"""
|
||||
csv_iterator = csv.reader(
|
||||
StringIO(record.file),
|
||||
quotechar=options['quoting'],
|
||||
delimiter=options['separator'])
|
||||
csv_nonempty = itertools.ifilter(None, csv_iterator)
|
||||
# TODO: guess encoding with chardet? Or https://github.com/aadsm/jschardet
|
||||
encoding = options.get('encoding', 'utf-8')
|
||||
return itertools.imap(
|
||||
lambda row: [item.decode(encoding) for item in row],
|
||||
csv_nonempty)
|
||||
|
||||
def _match_header(self, header, fields, options):
|
||||
""" Attempts to match a given header to a field of the
|
||||
imported model.
|
||||
|
||||
:param str header: header name from the CSV file
|
||||
:param fields:
|
||||
:param dict options:
|
||||
:returns: an empty list if the header couldn't be matched, or
|
||||
all the fields to traverse
|
||||
:rtype: list(Field)
|
||||
"""
|
||||
for field in fields:
|
||||
# FIXME: should match all translations & original
|
||||
# TODO: use string distance (levenshtein? hamming?)
|
||||
if header == field['name'] \
|
||||
or header.lower() == field['string'].lower():
|
||||
return [field]
|
||||
|
||||
if '/' not in header:
|
||||
return []
|
||||
|
||||
# relational field path
|
||||
traversal = []
|
||||
subfields = fields
|
||||
# Iteratively dive into fields tree
|
||||
for section in header.split('/'):
|
||||
# Strip section in case spaces are added around '/' for
|
||||
# readability of paths
|
||||
match = self._match_header(section.strip(), subfields, options)
|
||||
# Any match failure, exit
|
||||
if not match: return []
|
||||
# prep subfields for next iteration within match[0]
|
||||
field = match[0]
|
||||
subfields = field['fields']
|
||||
traversal.append(field)
|
||||
return traversal
|
||||
|
||||
def _match_headers(self, rows, fields, options):
|
||||
""" Attempts to match the imported model's fields to the
|
||||
titles of the parsed CSV file, if the file is supposed to have
|
||||
headers.
|
||||
|
||||
Will consume the first line of the ``rows`` iterator.
|
||||
|
||||
Returns a pair of (None, None) if headers were not requested
|
||||
or the list of headers and a dict mapping cell indices
|
||||
to key paths in the ``fields`` tree
|
||||
|
||||
:param Iterator rows:
|
||||
:param dict fields:
|
||||
:param dict options:
|
||||
:rtype: (None, None) | (list(str), dict(int: list(str)))
|
||||
"""
|
||||
if not options.get('headers'):
|
||||
return None, None
|
||||
|
||||
headers = next(rows)
|
||||
return headers, dict(
|
||||
(index, [field['name'] for field in self._match_header(header, fields, options)] or None)
|
||||
for index, header in enumerate(headers)
|
||||
)
|
||||
|
||||
def parse_preview(self, cr, uid, id, options, count=10, context=None):
|
||||
""" Generates a preview of the uploaded files, and performs
|
||||
fields-matching between the import's file data and the model's
|
||||
columns.
|
||||
|
||||
If the headers are not requested (not options.headers),
|
||||
``matches`` and ``headers`` are both ``False``.
|
||||
|
||||
:param id: identifier of the import
|
||||
:param int count: number of preview lines to generate
|
||||
:param options: format-specific options.
|
||||
CSV: {encoding, quoting, separator, headers}
|
||||
:type options: {str, str, str, bool}
|
||||
:returns: {fields, matches, headers, preview} | {error, preview}
|
||||
:rtype: {dict(str: dict(...)), dict(int, list(str)), list(str), list(list(str))} | {str, str}
|
||||
"""
|
||||
(record,) = self.browse(cr, uid, [id], context=context)
|
||||
fields = self.get_fields(cr, uid, record.res_model, context=context)
|
||||
|
||||
try:
|
||||
rows = self._read_csv(record, options)
|
||||
|
||||
headers, matches = self._match_headers(rows, fields, options)
|
||||
# Match should have consumed the first row (iif headers), get
|
||||
# the ``count`` next rows for preview
|
||||
preview = itertools.islice(rows, count)
|
||||
return {
|
||||
'fields': fields,
|
||||
'matches': matches or False,
|
||||
'headers': headers or False,
|
||||
'preview': list(preview),
|
||||
}
|
||||
except Exception, e:
|
||||
# Due to lazy generators, UnicodeDecodeError (for
|
||||
# instance) may only be raised when serializing the
|
||||
# preview to a list in the return.
|
||||
_logger.debug("Error during CSV parsing preview", exc_info=True)
|
||||
return {
|
||||
'error': str(e),
|
||||
# iso-8859-1 ensures decoding will always succeed,
|
||||
# even if it yields non-printable characters. This is
|
||||
# in case of UnicodeDecodeError (or csv.Error
|
||||
# compounded with UnicodeDecodeError)
|
||||
'preview': record.file[:ERROR_PREVIEW_BYTES]
|
||||
.decode( 'iso-8859-1'),
|
||||
}
|
||||
|
||||
def _convert_import_data(self, record, fields, options, context=None):
|
||||
""" Extracts the input browse_record and fields list (with
|
||||
``False``-y placeholders for fields to *not* import) into a
|
||||
format Model.import_data can use: a fields list without holes
|
||||
and the precisely matching data matrix
|
||||
|
||||
:param browse_record record:
|
||||
:param list(str|bool): fields
|
||||
:returns: (data, fields)
|
||||
:rtype: (list(list(str)), list(str))
|
||||
:raises ValueError: in case the import data could not be converted
|
||||
"""
|
||||
# Get indices for non-empty fields
|
||||
indices = [index for index, field in enumerate(fields) if field]
|
||||
if not indices:
|
||||
raise ValueError(_("You must configure at least one field to import"))
|
||||
# If only one index, itemgetter will return an atom rather
|
||||
# than a 1-tuple
|
||||
if len(indices) == 1: mapper = lambda row: [row[indices[0]]]
|
||||
else: mapper = operator.itemgetter(*indices)
|
||||
# Get only list of actually imported fields
|
||||
import_fields = filter(None, fields)
|
||||
|
||||
rows_to_import = self._read_csv(record, options)
|
||||
if options.get('headers'):
|
||||
rows_to_import = itertools.islice(
|
||||
rows_to_import, 1, None)
|
||||
data = [
|
||||
row for row in itertools.imap(mapper, rows_to_import)
|
||||
# don't try inserting completely empty rows (e.g. from
|
||||
# filtering out o2m fields)
|
||||
if any(row)
|
||||
]
|
||||
|
||||
return data, import_fields
|
||||
|
||||
def do(self, cr, uid, id, fields, options, dryrun=False, context=None):
|
||||
""" Actual execution of the import
|
||||
|
||||
:param fields: import mapping: maps each column to a field,
|
||||
``False`` for the columns to ignore
|
||||
:type fields: list(str|bool)
|
||||
:param dict options:
|
||||
:param bool dryrun: performs all import operations (and
|
||||
validations) but rollbacks writes, allows
|
||||
getting as much errors as possible without
|
||||
the risk of clobbering the database.
|
||||
:returns: A list of errors. If the list is empty the import
|
||||
executed fully and correctly. If the list is
|
||||
non-empty it contains dicts with 3 keys ``type`` the
|
||||
type of error (``error|warning``); ``message`` the
|
||||
error message associated with the error (a string)
|
||||
and ``record`` the data which failed to import (or
|
||||
``false`` if that data isn't available or provided)
|
||||
:rtype: list({type, message, record})
|
||||
"""
|
||||
cr.execute('SAVEPOINT import')
|
||||
|
||||
(record,) = self.browse(cr, uid, [id], context=context)
|
||||
try:
|
||||
data, import_fields = self._convert_import_data(
|
||||
record, fields, options, context=context)
|
||||
except ValueError, e:
|
||||
return [{
|
||||
'type': 'error',
|
||||
'message': str(e),
|
||||
'record': False,
|
||||
}]
|
||||
|
||||
try:
|
||||
_logger.info('importing %d rows...', len(data))
|
||||
(code, record, message, _wat) = self.pool[record.res_model].import_data(
|
||||
cr, uid, import_fields, data, context=context)
|
||||
_logger.info('done')
|
||||
|
||||
except Exception, e:
|
||||
_logger.exception("Import failed")
|
||||
# TODO: remove when exceptions stop being an "expected"
|
||||
# behavior of import_data on some (most) invalid
|
||||
# input.
|
||||
code, record, message = -1, None, str(e)
|
||||
|
||||
# If transaction aborted, RELEASE SAVEPOINT is going to raise
|
||||
# an InternalError (ROLLBACK should work, maybe). Ignore that.
|
||||
# TODO: to handle multiple errors, create savepoint around
|
||||
# write and release it in case of write error (after
|
||||
# adding error to errors array) => can keep on trying to
|
||||
# import stuff, and rollback at the end if there is any
|
||||
# error in the results.
|
||||
try:
|
||||
if dryrun:
|
||||
cr.execute('ROLLBACK TO SAVEPOINT import')
|
||||
else:
|
||||
cr.execute('RELEASE SAVEPOINT import')
|
||||
except psycopg2.InternalError:
|
||||
pass
|
||||
|
||||
if code != -1:
|
||||
return []
|
||||
|
||||
# TODO: add key for error location?
|
||||
# TODO: error not within normal preview, how to display? Re-preview
|
||||
# with higher ``count``?
|
||||
return [{
|
||||
'type': 'error',
|
||||
'message': message,
|
||||
'record': record or False
|
||||
}]
|
|
@ -0,0 +1,12 @@
|
|||
Copyright 2012 Igor Vaynberg
|
||||
|
||||
Version: @@ver@@ Timestamp: @@timestamp@@
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in
|
||||
compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and limitations under the License.
|
|
@ -0,0 +1,68 @@
|
|||
Select2
|
||||
=================
|
||||
|
||||
Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results. Look and feel of Select2 is based on the excellent [Chosen](http://harvesthq.github.com/chosen/) library.
|
||||
|
||||
To get started -- checkout http://ivaynberg.github.com/select2!
|
||||
|
||||
What Does Select2 Support That Chosen Does Not?
|
||||
-------------------------------------------------
|
||||
|
||||
* Working with large datasets: Chosen requires the entire dataset to be loaded as `option` tags in the DOM, which limits
|
||||
it to working with small-ish datasets. Select2 uses a function to find results on-the-fly, which allows it to partially
|
||||
load results.
|
||||
* Paging of results: Since Select2 works with large datasets and only loads a small amount of matching results at a time
|
||||
it has to support paging. Select2 will call the search function when the user scrolls to the bottom of currently loaded
|
||||
result set allowing for the 'infinite scrolling' of results.
|
||||
* Custom markup for results: Chosen only supports rendering text results because that is the only markup supported by
|
||||
`option` tags. Select2 provides an extension point which can be used to produce any kind of markup to represent results.
|
||||
* Ability to add results on the fly: Select2 provides the ability to add results from the search term entered by the user, which allows it to be used for
|
||||
tagging.
|
||||
|
||||
Browser Compatibility
|
||||
--------------------
|
||||
* IE 8+ (7 mostly works except for [issue with z-index](https://github.com/ivaynberg/select2/issues/37))
|
||||
* Chrome 8+
|
||||
* Firefox 3.5+
|
||||
* Safari 3+
|
||||
* Opera 10.6+
|
||||
|
||||
Integrations
|
||||
------------
|
||||
|
||||
* [Wicket-Select2](https://github.com/ivaynberg/wicket-select2) (Java / Apache Wicket)
|
||||
* [select2-rails](https://github.com/argerim/select2-rails) (Ruby on Rails)
|
||||
* [AngularUI](http://angular-ui.github.com/#directives-select2) ([AngularJS](angularjs.org))
|
||||
* [Django](https://github.com/applegrew/django-select2)
|
||||
|
||||
Bug tracker
|
||||
-----------
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
|
||||
https://github.com/ivaynberg/select2/issues
|
||||
|
||||
|
||||
Mailing list
|
||||
------------
|
||||
|
||||
Have a question? Ask on our mailing list!
|
||||
|
||||
select2@googlegroups.com
|
||||
|
||||
https://groups.google.com/d/forum/select2
|
||||
|
||||
|
||||
Copyright and License
|
||||
---------------------
|
||||
|
||||
Copyright 2012 Igor Vaynberg
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in
|
||||
compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and limitations under the License.
|
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo -n "Enter the version for this release: "
|
||||
|
||||
read ver
|
||||
|
||||
if [ ! $ver ]; then
|
||||
echo "Invalid version."
|
||||
exit
|
||||
fi
|
||||
|
||||
name="select2"
|
||||
js="$name.js"
|
||||
mini="$name.min.js"
|
||||
css="$name.css"
|
||||
release="$name-$ver"
|
||||
releasedir="/tmp/$release"
|
||||
tag="release-$ver"
|
||||
branch="build-$ver"
|
||||
curbranch=`git branch | grep "*" | sed "s/* //"`
|
||||
timestamp=$(date)
|
||||
tokens="s/@@ver@@/$ver/g;s/\@@timestamp@@/$timestamp/g"
|
||||
remote="github"
|
||||
|
||||
git branch "$branch"
|
||||
git checkout "$branch"
|
||||
|
||||
echo "Tokenizing..."
|
||||
|
||||
find . -name "$js" | xargs sed -i -e "$tokens"
|
||||
find . -name "$css" | xargs sed -i -e "$tokens"
|
||||
|
||||
git add "$js"
|
||||
git add "$css"
|
||||
|
||||
echo "Minifying..."
|
||||
|
||||
echo "/*" > "$mini"
|
||||
cat LICENSE | sed "$tokens" >> "$mini"
|
||||
echo "*/" >> "$mini"
|
||||
|
||||
curl -s \
|
||||
-d compilation_level=SIMPLE_OPTIMIZATIONS \
|
||||
-d output_format=text \
|
||||
-d output_info=compiled_code \
|
||||
--data-urlencode "js_code@$js" \
|
||||
http://closure-compiler.appspot.com/compile \
|
||||
>> "$mini"
|
||||
|
||||
git add "$mini"
|
||||
|
||||
git commit -m "release $ver"
|
||||
|
||||
echo "Tagging..."
|
||||
|
||||
git tag -a "$tag" -m "tagged version $ver"
|
||||
git push "$remote" --tags
|
||||
|
||||
echo "Archiving..."
|
||||
|
||||
rm -rf "$releasedir"
|
||||
mkdir "$releasedir"
|
||||
|
||||
cp $name.* "$releasedir"
|
||||
cp spinner.gif "$releasedir"
|
||||
cp README.* "$releasedir"
|
||||
|
||||
zip -r "$releasedir.zip" "$releasedir"
|
||||
rm -rf "$releasedir"
|
||||
|
||||
echo "Cleaning Up..."
|
||||
|
||||
git checkout "$curbranch"
|
||||
git branch -D "$branch"
|
||||
|
||||
echo "Done. Release archive created: $releasedir.zip"
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
Version: @@ver@@ Timestamp: @@timestamp@@
|
||||
*/
|
||||
.select2-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
/* inline-block for ie7 */
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.select2-container,
|
||||
.select2-drop,
|
||||
.select2-search,
|
||||
.select2-search input{
|
||||
/*
|
||||
Force border-box so that % widths fit the parent
|
||||
container without overlap because of margin/padding.
|
||||
|
||||
More Info : http://www.quirksmode.org/css/box.html
|
||||
*/
|
||||
-moz-box-sizing: border-box; /* firefox */
|
||||
-ms-box-sizing: border-box; /* ie */
|
||||
-webkit-box-sizing: border-box; /* webkit */
|
||||
-khtml-box-sizing: border-box; /* konqueror */
|
||||
box-sizing: border-box; /* css3 */
|
||||
}
|
||||
|
||||
.select2-container .select2-choice {
|
||||
background-color: #fff;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
|
||||
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
|
||||
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
|
||||
background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0);
|
||||
background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-moz-background-clip: padding;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #aaa;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
padding: 0 0 0 8px;
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.select2-container.select2-drop-above .select2-choice
|
||||
{
|
||||
border-bottom-color: #aaa;
|
||||
-webkit-border-radius:0px 0px 4px 4px;
|
||||
-moz-border-radius:0px 0px 4px 4px;
|
||||
border-radius:0px 0px 4px 4px;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white));
|
||||
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%);
|
||||
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%);
|
||||
background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
|
||||
background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%);
|
||||
}
|
||||
|
||||
.select2-container .select2-choice span {
|
||||
margin-right: 26px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
-o-text-overflow: ellipsis;
|
||||
-ms-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice abbr {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 26px;
|
||||
top: 8px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
font-size: 1px;
|
||||
background: url('select2.png') right top no-repeat;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
border:0;
|
||||
outline: 0;
|
||||
}
|
||||
.select2-container .select2-choice abbr:hover {
|
||||
background-position: right -11px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select2-drop {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border: 1px solid #aaa;
|
||||
border-top: 0;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
-webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
-moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
-o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||
z-index: 9999;
|
||||
width:100%;
|
||||
margin-top:-1px;
|
||||
|
||||
-webkit-border-radius: 0 0 4px 4px;
|
||||
-moz-border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
.select2-drop.select2-drop-above {
|
||||
-webkit-border-radius: 4px 4px 0px 0px;
|
||||
-moz-border-radius: 4px 4px 0px 0px;
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
margin-top:1px;
|
||||
border-top: 1px solid #aaa;
|
||||
border-bottom: 0;
|
||||
|
||||
-webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
-moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
-o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
.select2-container .select2-choice div {
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
-moz-background-clip: padding;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
background: #ccc;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
|
||||
background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
|
||||
background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
|
||||
background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
|
||||
background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#cccccc', endColorstr = '#eeeeee', GradientType = 0);
|
||||
background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%);
|
||||
border-left: 1px solid #aaa;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice div b {
|
||||
background: url('select2.png') no-repeat 0 1px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.select2-search {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
z-index: 10000;
|
||||
min-height: 26px;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.select2-search-hidden {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: -10000px;
|
||||
}
|
||||
|
||||
.select2-search input {
|
||||
background: #fff url('select2.png') no-repeat 100% -22px;
|
||||
background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
|
||||
background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
padding: 4px 20px 4px 5px;
|
||||
outline: 0;
|
||||
border: 1px solid #aaa;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
width:100%;
|
||||
margin:0;
|
||||
height:auto !important;
|
||||
min-height: 26px;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
}
|
||||
|
||||
.select2-drop.select2-drop-above .select2-search input
|
||||
{
|
||||
margin-top:4px;
|
||||
}
|
||||
|
||||
.select2-search input.select2-active {
|
||||
background: #fff url('spinner.gif') no-repeat 100%;
|
||||
background: url('spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
|
||||
background: url('spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
|
||||
background: url('spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
|
||||
background: url('spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
background: url('spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
|
||||
}
|
||||
|
||||
|
||||
.select2-container-active .select2-choice,
|
||||
.select2-container-active .select2-choices {
|
||||
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
|
||||
-o-box-shadow : 0 0 5px rgba(0,0,0,.3);
|
||||
box-shadow : 0 0 5px rgba(0,0,0,.3);
|
||||
border: 1px solid #5897fb;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select2-dropdown-open .select2-choice {
|
||||
border: 1px solid #aaa;
|
||||
border-bottom-color: transparent;
|
||||
-webkit-box-shadow: 0 1px 0 #fff inset;
|
||||
-moz-box-shadow : 0 1px 0 #fff inset;
|
||||
-o-box-shadow : 0 1px 0 #fff inset;
|
||||
box-shadow : 0 1px 0 #fff inset;
|
||||
background-color: #eee;
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
|
||||
background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
|
||||
background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);
|
||||
-webkit-border-bottom-left-radius : 0;
|
||||
-webkit-border-bottom-right-radius: 0;
|
||||
-moz-border-radius-bottomleft : 0;
|
||||
-moz-border-radius-bottomright: 0;
|
||||
border-bottom-left-radius : 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.select2-dropdown-open .select2-choice div {
|
||||
background: transparent;
|
||||
border-left: none;
|
||||
}
|
||||
.select2-dropdown-open .select2-choice div b {
|
||||
background-position: -18px 1px;
|
||||
}
|
||||
|
||||
/* results */
|
||||
.select2-results {
|
||||
margin: 4px 4px 4px 0;
|
||||
padding: 0 0 0 4px;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.select2-results ul.select2-result-sub {
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }
|
||||
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }
|
||||
|
||||
.select2-results li {
|
||||
list-style: none;
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
.select2-results li.select2-result-with-children > .select2-result-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.select2-results .select2-result-label {
|
||||
padding: 3px 7px 4px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select2-results .select2-highlighted {
|
||||
background: #3875d7;
|
||||
color: #fff;
|
||||
}
|
||||
.select2-results li em {
|
||||
background: #feffde;
|
||||
font-style: normal;
|
||||
}
|
||||
.select2-results .select2-highlighted em {
|
||||
background: transparent;
|
||||
}
|
||||
.select2-results .select2-no-results,
|
||||
.select2-results .select2-searching,
|
||||
.select2-results .select2-selection-limit {
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
disabled look for already selected choices in the results dropdown
|
||||
.select2-results .select2-disabled.select2-highlighted {
|
||||
color: #666;
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
cursor: default;
|
||||
}
|
||||
.select2-results .select2-disabled {
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
cursor: default;
|
||||
}
|
||||
*/
|
||||
.select2-results .select2-disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-more-results.select2-active {
|
||||
background: #f4f4f4 url('spinner.gif') no-repeat 100%;
|
||||
}
|
||||
|
||||
.select2-more-results {
|
||||
background: #f4f4f4;
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* disabled styles */
|
||||
|
||||
.select2-container.select2-container-disabled .select2-choice {
|
||||
background-color: #f4f4f4;
|
||||
background-image: none;
|
||||
border: 1px solid #ddd;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.select2-container.select2-container-disabled .select2-choice div {
|
||||
background-color: #f4f4f4;
|
||||
background-image: none;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
|
||||
/* multiselect */
|
||||
|
||||
.select2-container-multi .select2-choices {
|
||||
background-color: #fff;
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
||||
background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
||||
border: 1px solid #aaa;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
cursor: text;
|
||||
overflow: hidden;
|
||||
height: auto !important;
|
||||
height: 1%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices {
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.select2-container-multi.select2-container-active .select2-choices {
|
||||
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
||||
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
|
||||
-o-box-shadow : 0 0 5px rgba(0,0,0,.3);
|
||||
box-shadow : 0 0 5px rgba(0,0,0,.3);
|
||||
border: 1px solid #5897fb;
|
||||
outline: none;
|
||||
}
|
||||
.select2-container-multi .select2-choices li {
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-field {
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field input {
|
||||
color: #666;
|
||||
background: transparent !important;
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
height: 15px;
|
||||
padding: 5px;
|
||||
margin: 1px 0;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow : none;
|
||||
-o-box-shadow : none;
|
||||
box-shadow : none;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field input.select2-active {
|
||||
background: #fff url('spinner.gif') no-repeat 100% !important;
|
||||
}
|
||||
|
||||
.select2-default {
|
||||
color: #999 !important;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-choice {
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius : 3px;
|
||||
border-radius : 3px;
|
||||
-moz-background-clip : padding;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip : padding-box;
|
||||
background-color: #e4e4e4;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
||||
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
||||
-webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
||||
-moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
||||
box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
||||
color: #333;
|
||||
border: 1px solid #aaaaaa;
|
||||
line-height: 13px;
|
||||
padding: 3px 5px 3px 18px;
|
||||
margin: 3px 0 3px 5px;
|
||||
position: relative;
|
||||
cursor: default;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-choice span {
|
||||
cursor: default;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-choice-focus {
|
||||
background: #d4d4d4;
|
||||
}
|
||||
|
||||
.select2-search-choice-close {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 3px;
|
||||
top: 4px;
|
||||
width: 12px;
|
||||
height: 13px;
|
||||
font-size: 1px;
|
||||
background: url('select2.png') right top no-repeat;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-search-choice-close {
|
||||
left: 3px;
|
||||
}
|
||||
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
|
||||
background-position: right -11px;
|
||||
}
|
||||
.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
|
||||
background-position: right -11px;
|
||||
}
|
||||
|
||||
/* disabled styles */
|
||||
|
||||
.select2-container-multi.select2-container-disabled .select2-choices{
|
||||
background-color: #f4f4f4;
|
||||
background-image: none;
|
||||
border: 1px solid #ddd;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
|
||||
background-image: none;
|
||||
background-color: #f4f4f4;
|
||||
border: 1px solid #ddd;
|
||||
padding: 3px 5px 3px 5px;
|
||||
}
|
||||
|
||||
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {
|
||||
display: none;
|
||||
}
|
||||
/* end multiselect */
|
||||
|
||||
.select2-result-selectable .select2-match,
|
||||
.select2-result-unselectable .select2-result-selectable .select2-match { text-decoration: underline; }
|
||||
.select2-result-unselectable .select2-match { text-decoration: none; }
|
||||
|
||||
.select2-offscreen { position: absolute; left: -10000px; }
|
||||
|
||||
/* Retina-ize icons */
|
||||
|
||||
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
|
||||
.select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
|
||||
background-image: url(select2x2.png) !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-size: 60px 40px !important;
|
||||
}
|
||||
.select2-search input {
|
||||
background-position: 100% -21px !important;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 613 B |
Binary file not shown.
After Width: | Height: | Size: 845 B |
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,57 @@
|
|||
.openerp .oe_list_buttons .oe_alternative {
|
||||
visibility: visible;
|
||||
}
|
||||
.openerp .oe_list_buttons.oe_editing .oe_list_button_import {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.oe_import dd,
|
||||
.oe_import .oe_import_toggled,
|
||||
.oe_import .oe_import_grid,
|
||||
.oe_import .oe_import_error_report,
|
||||
.oe_import .oe_import_with_file,
|
||||
.oe_import .oe_import_noheaders {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.oe_import.oe_import_preview .oe_import_grid {
|
||||
display: table;
|
||||
}
|
||||
.oe_import.oe_import_error .oe_import_error_report,
|
||||
.oe_import.oe_import_with_file .oe_import_with_file,
|
||||
.oe_import.oe_import_noheaders .oe_import_noheaders {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.oe_import .oe_import_error_report ul .oe_import_report_error {
|
||||
background-color: #FFD9DB;
|
||||
}
|
||||
.oe_import .oe_import_error_report ul .oe_import_report_warning {
|
||||
background-color: #FEFFD9;
|
||||
}
|
||||
|
||||
.oe_import .oe_import_noheaders {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.oe_import a.oe_import_toggle {
|
||||
display: block;
|
||||
}
|
||||
.oe_import a.oe_import_toggle:before {
|
||||
content: '> '
|
||||
}
|
||||
|
||||
.oe_import .oe_import_options p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.oe_import .oe_import_options label {
|
||||
display: inline-block;
|
||||
width: 10em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.oe_import_selector ul,
|
||||
.oe_import_selector li {
|
||||
margin: 0; padding: 0;
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
openerp.base_import = function (instance) {
|
||||
var QWeb = instance.web.qweb;
|
||||
var _t = instance.web._t;
|
||||
var _lt = instance.web._lt;
|
||||
|
||||
/**
|
||||
* Safari does not deal well at all with raw JSON data being
|
||||
* returned. As a result, we're going to cheat by using a
|
||||
* pseudo-jsonp: instead of getting JSON data in the iframe, we're
|
||||
* getting a ``script`` tag which consists of a function call and
|
||||
* the returned data (the json dump).
|
||||
*
|
||||
* The function is an auto-generated name bound to ``window``,
|
||||
* which calls back into the callback provided here.
|
||||
*
|
||||
* @param {Object} form the form element (DOM or jQuery) to use in the call
|
||||
* @param {Object} attributes jquery.form attributes object
|
||||
* @param {Function} callback function to call with the returned data
|
||||
*/
|
||||
function jsonp(form, attributes, callback) {
|
||||
attributes = attributes || {};
|
||||
var options = {jsonp: _.uniqueId('import_callback_')};
|
||||
window[options.jsonp] = function () {
|
||||
delete window[options.jsonp];
|
||||
callback.apply(null, arguments);
|
||||
};
|
||||
if ('data' in attributes) {
|
||||
_.extend(attributes.data, options);
|
||||
} else {
|
||||
_.extend(attributes, {data: options});
|
||||
}
|
||||
_.extend(attributes, {
|
||||
dataType: 'script',
|
||||
});
|
||||
$(form).ajaxSubmit(attributes);
|
||||
}
|
||||
|
||||
// if true, the 'Import', 'Export', etc... buttons will be shown
|
||||
instance.web.ListView.prototype.defaults.import_enabled = true;
|
||||
instance.web.ListView.include({
|
||||
on_loaded: function () {
|
||||
var self = this;
|
||||
var add_button = false;
|
||||
if (!this.$buttons) {
|
||||
add_button = true;
|
||||
}
|
||||
this._super.apply(this, arguments);
|
||||
if(add_button) {
|
||||
this.$buttons.on('click', '.oe_list_button_import', function() {
|
||||
new instance.web.DataImport(self, self.dataset).open();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
instance.web.DataImport = instance.web.Dialog.extend({
|
||||
template: 'ImportView',
|
||||
dialog_title: _lt("Import Data"),
|
||||
opts: [
|
||||
{name: 'encoding', label: _lt("Encoding:"), value: 'utf-8'},
|
||||
{name: 'separator', label: _lt("Separator:"), value: ','},
|
||||
{name: 'quoting', label: _lt("Quoting:"), value: '"'}
|
||||
],
|
||||
events: {
|
||||
'change .oe_import_grid input': 'import_dryrun',
|
||||
'change input.oe_import_file': 'file_update',
|
||||
'change input.oe_import_has_header, .oe_import_options input': 'settings_updated',
|
||||
'click a.oe_import_csv': function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
'click a.oe_import_export': function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
'click a.oe_import_toggle': function (e) {
|
||||
e.preventDefault();
|
||||
var $el = $(e.target);
|
||||
($el.next().length
|
||||
? $el.next()
|
||||
: $el.parent().next())
|
||||
.toggle();
|
||||
}
|
||||
},
|
||||
init: function (parent, dataset) {
|
||||
var self = this;
|
||||
this._super(parent, {
|
||||
buttons: [
|
||||
{text: _t("Import File"), click: function () {
|
||||
self.do_import();
|
||||
}, 'class': 'oe_import_dialog_button'}
|
||||
]
|
||||
});
|
||||
this.res_model = parent.model;
|
||||
// import object id
|
||||
this.id = null;
|
||||
this.Import = new instance.web.Model('base_import.import');
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this.Import.call('create', [{
|
||||
'res_model': this.res_model
|
||||
}]).then(function (id) {
|
||||
self.id = id;
|
||||
self.$('input[name=import_id]').val(id);
|
||||
});
|
||||
},
|
||||
|
||||
import_options: function () {
|
||||
var self = this;
|
||||
var options = {
|
||||
headers: this.$('input.oe_import_has_header').prop('checked')
|
||||
};
|
||||
_(this.opts).each(function (opt) {
|
||||
options[opt.name] =
|
||||
self.$('input.oe_import_' + opt.name).val();
|
||||
});
|
||||
return options;
|
||||
},
|
||||
|
||||
//- File & settings change section
|
||||
file_update: function (e) {
|
||||
if (!this.$('input.oe_import_file').val()) { return; }
|
||||
|
||||
this.$el.removeClass('oe_import_preview oe_import_error');
|
||||
jsonp(this.$el, {
|
||||
url: '/base_import/set_file'
|
||||
}, this.proxy('settings_updated'));
|
||||
},
|
||||
settings_updated: function () {
|
||||
this.$el.addClass('oe_import_with_file');
|
||||
// TODO: test that write // succeeded?
|
||||
this.Import.call(
|
||||
'parse_preview', [this.id, this.import_options()])
|
||||
.then(this.proxy('preview'));
|
||||
},
|
||||
preview: function (result) {
|
||||
this.$el.toggleClass(
|
||||
'oe_import_noheaders',
|
||||
!this.$('input.oe_import_has_header').prop('checked'));
|
||||
if (result.error) {
|
||||
this.$el.addClass('oe_import_error');
|
||||
this.$('.oe_import_error_report').html(
|
||||
QWeb.render('ImportView.preview.error', result));
|
||||
return;
|
||||
}
|
||||
this.$el.addClass('oe_import_preview');
|
||||
this.$('table').html(QWeb.render('ImportView.preview', result));
|
||||
|
||||
var $fields = this.$('.oe_import_fields input');
|
||||
this.render_fields_matches(result, $fields);
|
||||
var data = this.generate_fields_completion(result);
|
||||
var item_finder = function (id, items) {
|
||||
items = items || data;
|
||||
for (var i=0; i < items.length; ++i) {
|
||||
var item = items[i];
|
||||
if (item.id === id) {
|
||||
return item;
|
||||
}
|
||||
var val;
|
||||
if (item.children && (val = item_finder(id, item.children))) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
$fields.select2({
|
||||
allowClear: true,
|
||||
minimumInputLength: 0,
|
||||
data: data,
|
||||
initSelection: function (element, callback) {
|
||||
var default_value = element.val();
|
||||
if (!default_value) {
|
||||
callback('');
|
||||
return;
|
||||
}
|
||||
|
||||
callback(item_finder(default_value));
|
||||
},
|
||||
|
||||
width: 'resolve',
|
||||
dropdownCssClass: 'oe_import_selector'
|
||||
});
|
||||
this.import_dryrun();
|
||||
},
|
||||
generate_fields_completion: function (root) {
|
||||
var basic = [];
|
||||
var regulars = [];
|
||||
var o2m = [];
|
||||
function traverse(field, ancestors, collection) {
|
||||
var subfields = field.fields;
|
||||
var field_path = ancestors.concat(field);
|
||||
var label = _(field_path).pluck('string').join(' / ');
|
||||
var id = _(field_path).pluck('name').join('/');
|
||||
|
||||
// If non-relational, m2o or m2m, collection is regulars
|
||||
if (!collection) {
|
||||
if (field.name === 'id') {
|
||||
collection = basic
|
||||
} else if (_.isEmpty(subfields)
|
||||
|| _.isEqual(_.pluck(subfields, 'name'), ['id', '.id'])) {
|
||||
collection = regulars;
|
||||
} else {
|
||||
collection = o2m;
|
||||
}
|
||||
}
|
||||
|
||||
collection.push({
|
||||
id: id,
|
||||
text: label,
|
||||
required: field.required
|
||||
});
|
||||
|
||||
for(var i=0, end=subfields.length; i<end; ++i) {
|
||||
traverse(subfields[i], field_path, collection);
|
||||
}
|
||||
}
|
||||
_(root.fields).each(function (field) {
|
||||
traverse(field, []);
|
||||
});
|
||||
|
||||
var cmp = function (field1, field2) {
|
||||
return field1.text.localeCompare(field2.text);
|
||||
|
||||
};
|
||||
regulars.sort(cmp);
|
||||
o2m.sort(cmp);
|
||||
return basic.concat([
|
||||
{ text: _t("Normal Fields"), children: regulars },
|
||||
{ text: _t("Relation Fields"), children: o2m }
|
||||
]);
|
||||
},
|
||||
render_fields_matches: function (result, $fields) {
|
||||
if (_(result.matches).isEmpty()) { return; }
|
||||
$fields.each(function (index, input) {
|
||||
var match = result.matches[index];
|
||||
if (!match) { return; }
|
||||
|
||||
var current_field = result;
|
||||
input.value = _(match).chain()
|
||||
.map(function (name) {
|
||||
// WARNING: does both mapping and folding (over the
|
||||
// ``field`` iterator variable)
|
||||
return current_field = _(current_field.fields).find(function (subfield) {
|
||||
return subfield.name === name;
|
||||
});
|
||||
})
|
||||
.pluck('name')
|
||||
.value()
|
||||
.join('/');
|
||||
});
|
||||
},
|
||||
|
||||
//- import itself
|
||||
call_import: function (options) {
|
||||
var self = this;
|
||||
var fields = this.$('.oe_import_fields input.oe_import_match_field').map(function (index, el) {
|
||||
return $(el).select2('val') || false;
|
||||
}).get();
|
||||
return this.Import.call(
|
||||
'do', [this.id, fields, this.import_options()], options);
|
||||
},
|
||||
import_dryrun: function () {
|
||||
// this.call_import({ dryrun: true })
|
||||
// .then(this.proxy('render_import_errors'));
|
||||
},
|
||||
do_import: function () {
|
||||
var self = this;
|
||||
this.call_import({ dryrun: false }).then(function (errors) {
|
||||
if (_.isEmpty(errors)) {
|
||||
if (self.getParent().reload_content) {
|
||||
self.getParent().reload_content();
|
||||
}
|
||||
self.close();
|
||||
return;
|
||||
}
|
||||
self.render_import_errors(errors);
|
||||
});
|
||||
},
|
||||
render_import_errors: function (errors) {
|
||||
if (_.isEmpty(errors)) {
|
||||
this.$el.removeClass('oe_import_error');
|
||||
return;
|
||||
}
|
||||
// import failed (or maybe just warnings, if we ever get
|
||||
// warnings?)
|
||||
this.$el.addClass('oe_import_error');
|
||||
this.$('.oe_import_error_report').html(
|
||||
QWeb.render('ImportView.error', {errors: errors}));
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,103 @@
|
|||
<templates>
|
||||
<t t-name="ImportView">
|
||||
<t t-set="_id" t-value="_.uniqueId('export')"/>
|
||||
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
|
||||
<input type="hidden" name="session_id"
|
||||
t-att-value="widget.session.session_id"/>
|
||||
<input type="hidden" name="import_id"/>
|
||||
<h2>Upload your file</h2>
|
||||
<p>Select the <a href="#" class="oe_import_csv">.CSV</a>
|
||||
file to import. If you need a sample importable file, you
|
||||
can use <a href="#" class="oe_import_export">the export
|
||||
tool</a> to generate one.</p>
|
||||
<label t-attf-for="file_#{_id}" autofocus="autofocus">CSV File:</label>
|
||||
<input type="file" id-attf-id="file_#{_id}"
|
||||
name="file" class="oe_import_file"/>
|
||||
|
||||
<div class="oe_import_with_file">
|
||||
<h2>Map your data to OpenERP</h2>
|
||||
<input type="checkbox" class="oe_import_has_header"
|
||||
id="oe_import_has_header" checked="checked"/>
|
||||
<label for="oe_import_has_header">The first row of the
|
||||
file contains the label of the column</label>
|
||||
<p class="oe_import_noheaders">If the file contains
|
||||
the column names, OpenERP can try auto-detecting the
|
||||
field corresponding to the column. This makes imports
|
||||
simpler especially when the file has many columns.</p>
|
||||
|
||||
<div class="oe_import_error_report"></div>
|
||||
<table class="oe_import_grid" width="100%"/>
|
||||
<a href="#" class="oe_import_toggle">
|
||||
File Format Options…</a>
|
||||
<div class="oe_import_toggled oe_import_options">
|
||||
<p t-foreach="widget.opts" t-as="option">
|
||||
<!-- no @name, avoid submission when file_update called -->
|
||||
<label t-attf-for="#{option.name}_#{_id}">
|
||||
<t t-esc="option.label"/></label>
|
||||
<input t-attf-id="#{option.name}_#{_id}"
|
||||
t-attf-class="oe_import_#{option.name}"
|
||||
t-att-value="option.value"/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2>Frequently Asked Questions</h2>
|
||||
<dl>
|
||||
<dt><a href="#" class="oe_import_toggle">
|
||||
Need to import data from an other application?</a></dt>
|
||||
<dd>
|
||||
<p>In order to re-create relationships between
|
||||
different records, you should use the unique
|
||||
identifier from the original application and
|
||||
map it to the <abbr title="External ID">ID</abbr>
|
||||
column in OpenERP. When you
|
||||
import an other record that links to the first
|
||||
one, use <abbr title="XXX/External ID">XXX/ID</abbr>
|
||||
to the original unique identifier.</p>
|
||||
<p>The <abbr title="External ID">ID</abbr>
|
||||
will also be used to update the original
|
||||
import if you need to re-import modified data
|
||||
later, it's thus good practice to specify it
|
||||
whenever possible</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</form>
|
||||
</t>
|
||||
<t t-name="ImportView.preview">
|
||||
<tr t-if="headers" class="oe_import_grid-header">
|
||||
<td t-foreach="headers" t-as="header" class="oe_import_grid-cell"
|
||||
><t t-esc="header"/></td>
|
||||
</tr>
|
||||
<tr class="oe_import_fields">
|
||||
<!-- Iterate on first row to ensure we have all columns -->
|
||||
<td t-foreach="preview[0]" t-as="column">
|
||||
<input placeholder="Don't Import"
|
||||
class="oe_import_match_field"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-foreach="preview" t-as="row" class="oe_import_grid-row">
|
||||
<td t-foreach="row" t-as="cell" class="oe_import_grid-cell"
|
||||
><t t-esc="cell"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-name="ImportView.preview.error">
|
||||
<p>Import preview failed due to: <t t-esc="error"/></p>
|
||||
<p>Here is the start of the file we could not import:</p>
|
||||
<pre><t t-esc="preview"/></pre>
|
||||
</t>
|
||||
<ul t-name="ImportView.error">
|
||||
<li t-foreach="errors" t-as="error" t-attf-class="oe_import_report_#{error.type}">
|
||||
<!-- can also have error.record, but may be *huge* if
|
||||
e.g. has image fields -->
|
||||
<t t-esc="error.message"/>
|
||||
</li>
|
||||
</ul>
|
||||
<t t-extend="ListView.buttons">
|
||||
<t t-jquery="span.oe_alternative">
|
||||
this.attr('t-if', 'widget.options.import_enabled');
|
||||
</t>
|
||||
<t t-jquery="span.oe_alternative" t-operation="append">
|
||||
<a href="#" class="oe_bold oe_list_button_import">Import</a>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
|
@ -0,0 +1,101 @@
|
|||
from openerp.osv import orm, fields
|
||||
|
||||
def name(n): return 'base_import.tests.models.%s' % n
|
||||
|
||||
class char(orm.Model):
|
||||
_name = name('char')
|
||||
|
||||
_columns = {
|
||||
'value': fields.char('unknown', size=None)
|
||||
}
|
||||
|
||||
class char_required(orm.Model):
|
||||
_name = name('char.required')
|
||||
|
||||
_columns = {
|
||||
'value': fields.char('unknown', size=None, required=True)
|
||||
}
|
||||
|
||||
class char_readonly(orm.Model):
|
||||
_name = name('char.readonly')
|
||||
|
||||
_columns = {
|
||||
'value': fields.char('unknown', size=None, readonly=True)
|
||||
}
|
||||
|
||||
class char_states(orm.Model):
|
||||
_name = name('char.states')
|
||||
|
||||
_columns = {
|
||||
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('readonly', False)]})
|
||||
}
|
||||
|
||||
class char_noreadonly(orm.Model):
|
||||
_name = name('char.noreadonly')
|
||||
|
||||
_columns = {
|
||||
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('invisible', True)]})
|
||||
}
|
||||
|
||||
class char_stillreadonly(orm.Model):
|
||||
_name = name('char.stillreadonly')
|
||||
|
||||
_columns = {
|
||||
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('readonly', True)]})
|
||||
}
|
||||
|
||||
# TODO: complex field (m2m, o2m, m2o)
|
||||
class m2o(orm.Model):
|
||||
_name = name('m2o')
|
||||
|
||||
_columns = {
|
||||
'value': fields.many2one(name('m2o.related'))
|
||||
}
|
||||
class m2o_related(orm.Model):
|
||||
_name = name('m2o.related')
|
||||
|
||||
_columns = {
|
||||
'value': fields.integer()
|
||||
}
|
||||
_defaults = {
|
||||
'value': 42
|
||||
}
|
||||
|
||||
class m2o_required(orm.Model):
|
||||
_name = name('m2o.required')
|
||||
|
||||
_columns = {
|
||||
'value': fields.many2one(name('m2o.required.related'), required=True)
|
||||
}
|
||||
class m2o_required_related(orm.Model):
|
||||
_name = name('m2o.required.related')
|
||||
|
||||
_columns = {
|
||||
'value': fields.integer()
|
||||
}
|
||||
_defaults = {
|
||||
'value': 42
|
||||
}
|
||||
|
||||
class o2m(orm.Model):
|
||||
_name = name('o2m')
|
||||
|
||||
_columns = {
|
||||
'value': fields.one2many(name('o2m.child'), 'parent_id')
|
||||
}
|
||||
class o2m_child(orm.Model):
|
||||
_name = name('o2m.child')
|
||||
|
||||
_columns = {
|
||||
'parent_id': fields.many2one(name('o2m')),
|
||||
'value': fields.integer()
|
||||
}
|
||||
|
||||
class preview_model(orm.Model):
|
||||
_name = name('preview')
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=None),
|
||||
'somevalue': fields.integer('Some Value', required=True),
|
||||
'othervalue': fields.integer('Other Variable'),
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
from . import test_cases
|
||||
|
||||
checks = [test_cases]
|
|
@ -0,0 +1,342 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
import unittest2
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
from .. import models
|
||||
|
||||
ID_FIELD = {'id': 'id', 'name': 'id', 'string': "External ID", 'required': False, 'fields': []}
|
||||
def make_field(name='value', string='unknown', required=False, fields=[]):
|
||||
return [
|
||||
ID_FIELD,
|
||||
{'id': name, 'name': name, 'string': string, 'required': required, 'fields': fields},
|
||||
]
|
||||
|
||||
class test_basic_fields(TransactionCase):
|
||||
def get_fields(self, field):
|
||||
return self.registry('base_import.import')\
|
||||
.get_fields(self.cr, self.uid, 'base_import.tests.models.' + field)
|
||||
|
||||
def test_base(self):
|
||||
""" A basic field is not required """
|
||||
self.assertEqual(self.get_fields('char'), make_field())
|
||||
|
||||
def test_required(self):
|
||||
""" Required fields should be flagged (so they can be fill-required) """
|
||||
self.assertEqual(self.get_fields('char.required'), make_field(required=True))
|
||||
|
||||
def test_readonly(self):
|
||||
""" Readonly fields should be filtered out"""
|
||||
self.assertEqual(self.get_fields('char.readonly'), [ID_FIELD])
|
||||
|
||||
def test_readonly_states(self):
|
||||
""" Readonly fields with states should not be filtered out"""
|
||||
self.assertEqual(self.get_fields('char.states'), make_field())
|
||||
|
||||
def test_readonly_states_noreadonly(self):
|
||||
""" Readonly fields with states having nothing to do with
|
||||
readonly should still be filtered out"""
|
||||
self.assertEqual(self.get_fields('char.noreadonly'), [ID_FIELD])
|
||||
|
||||
def test_readonly_states_stillreadonly(self):
|
||||
""" Readonly fields with readonly states leaving them readonly
|
||||
always... filtered out"""
|
||||
self.assertEqual(self.get_fields('char.stillreadonly'), [ID_FIELD])
|
||||
|
||||
def test_m2o(self):
|
||||
""" M2O fields should allow import of themselves (name_get),
|
||||
their id and their xid"""
|
||||
self.assertEqual(self.get_fields('m2o'), make_field(fields=[
|
||||
{'id': 'value', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []},
|
||||
{'id': 'value', 'name': '.id', 'string': 'Database ID', 'required': False, 'fields': []},
|
||||
]))
|
||||
|
||||
def test_m2o_required(self):
|
||||
""" If an m2o field is required, its three sub-fields are
|
||||
required as well (the client has to handle that: requiredness
|
||||
is id-based)
|
||||
"""
|
||||
self.assertEqual(self.get_fields('m2o.required'), make_field(required=True, fields=[
|
||||
{'id': 'value', 'name': 'id', 'string': 'External ID', 'required': True, 'fields': []},
|
||||
{'id': 'value', 'name': '.id', 'string': 'Database ID', 'required': True, 'fields': []},
|
||||
]))
|
||||
|
||||
class test_o2m(TransactionCase):
|
||||
def get_fields(self, field):
|
||||
return self.registry('base_import.import')\
|
||||
.get_fields(self.cr, self.uid, 'base_import.tests.models.' + field)
|
||||
|
||||
def test_shallow(self):
|
||||
self.assertEqual(self.get_fields('o2m'), make_field(fields=[
|
||||
{'id': 'id', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []},
|
||||
# FIXME: should reverse field be ignored?
|
||||
{'id': 'parent_id', 'name': 'parent_id', 'string': 'unknown', 'required': False, 'fields': [
|
||||
{'id': 'parent_id', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []},
|
||||
{'id': 'parent_id', 'name': '.id', 'string': 'Database ID', 'required': False, 'fields': []},
|
||||
]},
|
||||
{'id': 'value', 'name': 'value', 'string': 'unknown', 'required': False, 'fields': []},
|
||||
]))
|
||||
|
||||
class test_match_headers_single(TransactionCase):
|
||||
def test_match_by_name(self):
|
||||
match = self.registry('base_import.import')._match_header(
|
||||
'f0', [{'name': 'f0'}], {})
|
||||
|
||||
self.assertEqual(match, [{'name': 'f0'}])
|
||||
|
||||
def test_match_by_string(self):
|
||||
match = self.registry('base_import.import')._match_header(
|
||||
'some field', [{'name': 'bob', 'string': "Some Field"}], {})
|
||||
|
||||
self.assertEqual(match, [{'name': 'bob', 'string': "Some Field"}])
|
||||
|
||||
def test_nomatch(self):
|
||||
match = self.registry('base_import.import')._match_header(
|
||||
'should not be', [{'name': 'bob', 'string': "wheee"}], {})
|
||||
|
||||
self.assertEqual(match, [])
|
||||
|
||||
def test_recursive_match(self):
|
||||
f = {
|
||||
'name': 'f0',
|
||||
'string': "My Field",
|
||||
'fields': [
|
||||
{'name': 'f0', 'string': "Sub field 0", 'fields': []},
|
||||
{'name': 'f1', 'string': "Sub field 2", 'fields': []},
|
||||
]
|
||||
}
|
||||
match = self.registry('base_import.import')._match_header(
|
||||
'f0/f1', [f], {})
|
||||
|
||||
self.assertEqual(match, [f, f['fields'][1]])
|
||||
|
||||
def test_recursive_nomatch(self):
|
||||
""" Match first level, fail to match second level
|
||||
"""
|
||||
f = {
|
||||
'name': 'f0',
|
||||
'string': "My Field",
|
||||
'fields': [
|
||||
{'name': 'f0', 'string': "Sub field 0", 'fields': []},
|
||||
{'name': 'f1', 'string': "Sub field 2", 'fields': []},
|
||||
]
|
||||
}
|
||||
match = self.registry('base_import.import')._match_header(
|
||||
'f0/f2', [f], {})
|
||||
|
||||
self.assertEqual(match, [])
|
||||
|
||||
class test_match_headers_multiple(TransactionCase):
|
||||
def test_noheaders(self):
|
||||
self.assertEqual(
|
||||
self.registry('base_import.import')._match_headers(
|
||||
[], [], {}),
|
||||
(None, None)
|
||||
)
|
||||
def test_nomatch(self):
|
||||
self.assertEqual(
|
||||
self.registry('base_import.import')._match_headers(
|
||||
iter([
|
||||
['foo', 'bar', 'baz', 'qux'],
|
||||
['v1', 'v2', 'v3', 'v4'],
|
||||
]),
|
||||
[],
|
||||
{'headers': True}),
|
||||
(
|
||||
['foo', 'bar', 'baz', 'qux'],
|
||||
dict.fromkeys(range(4))
|
||||
)
|
||||
)
|
||||
|
||||
def test_mixed(self):
|
||||
self.assertEqual(
|
||||
self.registry('base_import.import')._match_headers(
|
||||
iter(['foo bar baz qux/corge'.split()]),
|
||||
[
|
||||
{'name': 'bar', 'string': 'Bar'},
|
||||
{'name': 'bob', 'string': 'Baz'},
|
||||
{'name': 'qux', 'string': 'Qux', 'fields': [
|
||||
{'name': 'corge', 'fields': []},
|
||||
]}
|
||||
],
|
||||
{'headers': True}),
|
||||
(['foo', 'bar', 'baz', 'qux/corge'], {
|
||||
0: None,
|
||||
1: ['bar'],
|
||||
2: ['bob'],
|
||||
3: ['qux', 'corge'],
|
||||
})
|
||||
)
|
||||
|
||||
class test_preview(TransactionCase):
|
||||
def make_import(self):
|
||||
Import = self.registry('base_import.import')
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'res.users',
|
||||
'file': u"로그인,언어\nbob,1\n".encode('euc_kr'),
|
||||
})
|
||||
return Import, id
|
||||
|
||||
def test_encoding(self):
|
||||
Import, id = self.make_import()
|
||||
result = Import.parse_preview(self.cr, self.uid, id, {
|
||||
'quoting': '"',
|
||||
'separator': ',',
|
||||
})
|
||||
self.assertTrue('error' in result)
|
||||
|
||||
def test_csv_errors(self):
|
||||
Import, id = self.make_import()
|
||||
|
||||
result = Import.parse_preview(self.cr, self.uid, id, {
|
||||
'quoting': 'foo',
|
||||
'separator': ',',
|
||||
'encoding': 'euc_kr',
|
||||
})
|
||||
self.assertTrue('error' in result)
|
||||
|
||||
def test_csv_errors(self):
|
||||
Import, id = self.make_import()
|
||||
|
||||
result = Import.parse_preview(self.cr, self.uid, id, {
|
||||
'quoting': '"',
|
||||
'separator': 'bob',
|
||||
'encoding': 'euc_kr',
|
||||
})
|
||||
self.assertTrue('error' in result)
|
||||
|
||||
def test_success(self):
|
||||
Import = self.registry('base_import.import')
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'base_import.tests.models.preview',
|
||||
'file': 'name,Some Value,Counter\n'
|
||||
'foo,1,2\n'
|
||||
'bar,3,4\n'
|
||||
'qux,5,6\n'
|
||||
})
|
||||
|
||||
result = Import.parse_preview(self.cr, self.uid, id, {
|
||||
'quoting': '"',
|
||||
'separator': ',',
|
||||
'headers': True,
|
||||
})
|
||||
|
||||
self.assertEqual(result['matches'], {0: ['name'], 1: ['somevalue'], 2: None})
|
||||
self.assertEqual(result['headers'], ['name', 'Some Value', 'Counter'])
|
||||
# Order depends on iteration order of fields_get
|
||||
self.assertItemsEqual(result['fields'], [
|
||||
{'id': 'id', 'name': 'id', 'string': 'External ID', 'required':False, 'fields': []},
|
||||
{'id': 'name', 'name': 'name', 'string': 'Name', 'required':False, 'fields': []},
|
||||
{'id': 'somevalue', 'name': 'somevalue', 'string': 'Some Value', 'required':True, 'fields': []},
|
||||
{'id': 'othervalue', 'name': 'othervalue', 'string': 'Other Variable', 'required':False, 'fields': []},
|
||||
])
|
||||
self.assertEqual(result['preview'], [
|
||||
['foo', '1', '2'],
|
||||
['bar', '3', '4'],
|
||||
['qux', '5', '6'],
|
||||
])
|
||||
# Ensure we only have the response fields we expect
|
||||
self.assertItemsEqual(result.keys(), ['matches', 'headers', 'fields', 'preview'])
|
||||
|
||||
class test_convert_import_data(TransactionCase):
|
||||
""" Tests conversion of base_import.import input into data which
|
||||
can be fed to Model.import_data
|
||||
"""
|
||||
def test_all(self):
|
||||
Import = self.registry('base_import.import')
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'base_import.tests.models.preview',
|
||||
'file': 'name,Some Value,Counter\n'
|
||||
'foo,1,2\n'
|
||||
'bar,3,4\n'
|
||||
'qux,5,6\n'
|
||||
})
|
||||
record = Import.browse(self.cr, self.uid, id)
|
||||
data, fields = Import._convert_import_data(
|
||||
record, ['name', 'somevalue', 'othervalue'],
|
||||
{'quoting': '"', 'separator': ',', 'headers': True,})
|
||||
|
||||
self.assertItemsEqual(fields, ['name', 'somevalue', 'othervalue'])
|
||||
self.assertItemsEqual(data, [
|
||||
('foo', '1', '2'),
|
||||
('bar', '3', '4'),
|
||||
('qux', '5', '6'),
|
||||
])
|
||||
|
||||
def test_filtered(self):
|
||||
""" If ``False`` is provided as field mapping for a column,
|
||||
that column should be removed from importable data
|
||||
"""
|
||||
Import = self.registry('base_import.import')
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'base_import.tests.models.preview',
|
||||
'file': 'name,Some Value,Counter\n'
|
||||
'foo,1,2\n'
|
||||
'bar,3,4\n'
|
||||
'qux,5,6\n'
|
||||
})
|
||||
record = Import.browse(self.cr, self.uid, id)
|
||||
data, fields = Import._convert_import_data(
|
||||
record, ['name', False, 'othervalue'],
|
||||
{'quoting': '"', 'separator': ',', 'headers': True,})
|
||||
|
||||
self.assertItemsEqual(fields, ['name', 'othervalue'])
|
||||
self.assertItemsEqual(data, [
|
||||
('foo', '2'),
|
||||
('bar', '4'),
|
||||
('qux', '6'),
|
||||
])
|
||||
|
||||
def test_norow(self):
|
||||
""" If a row is composed only of empty values (due to having
|
||||
filtered out non-empty values from it), it should be removed
|
||||
"""
|
||||
Import = self.registry('base_import.import')
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'base_import.tests.models.preview',
|
||||
'file': 'name,Some Value,Counter\n'
|
||||
'foo,1,2\n'
|
||||
',3,\n'
|
||||
',5,6\n'
|
||||
})
|
||||
record = Import.browse(self.cr, self.uid, id)
|
||||
data, fields = Import._convert_import_data(
|
||||
record, ['name', False, 'othervalue'],
|
||||
{'quoting': '"', 'separator': ',', 'headers': True,})
|
||||
|
||||
self.assertItemsEqual(fields, ['name', 'othervalue'])
|
||||
self.assertItemsEqual(data, [
|
||||
('foo', '2'),
|
||||
('', '6'),
|
||||
])
|
||||
|
||||
def test_nofield(self):
|
||||
Import = self.registry('base_import.import')
|
||||
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'base_import.tests.models.preview',
|
||||
'file': 'name,Some Value,Counter\n'
|
||||
'foo,1,2\n'
|
||||
})
|
||||
|
||||
record = Import.browse(self.cr, self.uid, id)
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
Import._convert_import_data,
|
||||
record, [],
|
||||
{'quoting': '"', 'separator': ',', 'headers': True,})
|
||||
|
||||
def test_falsefields(self):
|
||||
Import = self.registry('base_import.import')
|
||||
|
||||
id = Import.create(self.cr, self.uid, {
|
||||
'res_model': 'base_import.tests.models.preview',
|
||||
'file': 'name,Some Value,Counter\n'
|
||||
'foo,1,2\n'
|
||||
})
|
||||
|
||||
record = Import.browse(self.cr, self.uid, id)
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
Import._convert_import_data,
|
||||
record, [False, False, False],
|
||||
{'quoting': '"', 'separator': ',', 'headers': True,})
|
|
@ -25,16 +25,17 @@ class base_config_settings(osv.osv_memory):
|
|||
_name = 'base.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
_columns = {
|
||||
'module_multi_company': fields.boolean('manage multiple companies',
|
||||
'module_multi_company': fields.boolean('Manage multiple companies',
|
||||
help="""Work in multi-company environments, with appropriate security access between companies.
|
||||
This installs the module multi_company."""),
|
||||
'module_share': fields.boolean('allow documents sharing',
|
||||
'module_share': fields.boolean('Allow documents sharing',
|
||||
help="""Share or embbed any screen of openerp."""),
|
||||
'module_portal': fields.boolean('activate the customer/supplier portal',
|
||||
'module_portal': fields.boolean('Activate the customer/supplier portal',
|
||||
help="""Give access your customers and suppliers to their documents."""),
|
||||
'module_auth_anonymous': fields.boolean('activate the public portal',
|
||||
'module_auth_anonymous': fields.boolean('Activate the public portal',
|
||||
help="""Enable the public part of openerp, openerp becomes a public website."""),
|
||||
'module_auth_oauth': fields.boolean('use external authentication providers, sign in with google, facebook, ...'),
|
||||
'module_auth_oauth': fields.boolean('Use external authentication providers, sign in with google, facebook, ...'),
|
||||
'module_base_import': fields.boolean("Allow users to import data from CSV files"),
|
||||
}
|
||||
|
||||
def open_company(self, cr, uid, ids, context=None):
|
||||
|
@ -56,17 +57,17 @@ class sale_config_settings(osv.osv_memory):
|
|||
_name = 'sale.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
_columns = {
|
||||
'module_web_linkedin': fields.boolean('get contacts automatically from LinkedIn',
|
||||
'module_web_linkedin': fields.boolean('Get contacts automatically from linkedIn',
|
||||
help="""When you create a new contact (person or company), you will be able to load all the data from LinkedIn (photos, address, etc)."""),
|
||||
'module_crm': fields.boolean('CRM'),
|
||||
'module_plugin_thunderbird': fields.boolean('enable Thunderbird plugin',
|
||||
'module_plugin_thunderbird': fields.boolean('Enable Thunderbird plugin',
|
||||
help="""The plugin allows you archive email and its attachments to the selected
|
||||
OpenERP objects. You can select a partner, or a lead and
|
||||
attach the selected mail as a .eml file in
|
||||
the attachment of a selected record. You can create documents for CRM Lead,
|
||||
Partner from the selected emails.
|
||||
This installs the module plugin_thunderbird."""),
|
||||
'module_plugin_outlook': fields.boolean('enable Outlook plugin',
|
||||
'module_plugin_outlook': fields.boolean('Enable Outlook plugin',
|
||||
help="""The Outlook plugin allows you to select an object that you would like to add
|
||||
to your email and its attachments from MS Outlook. You can select a partner,
|
||||
or a lead object and archive a selected
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
</header>
|
||||
<separator string="General Settings"/>
|
||||
<div>
|
||||
<label string="You will also find several configuration options on your company data:
|
||||
address for the header and footer, overdue payments texts, etc."/>
|
||||
<button type="object" name="open_company" string="Configure Your Company Data" icon="gtk-execute" class="oe_inline oe_link"/>
|
||||
<p>
|
||||
<label string="You will find more options in your company details: address for the header and footer, overdue payments texts, etc."/>
|
||||
<button type="object" name="open_company" string="Configure your company data" icon="gtk-execute" class="oe_inline oe_link"/>
|
||||
</p>
|
||||
</div>
|
||||
<group>
|
||||
<label for="id" string="Options"/>
|
||||
|
@ -59,6 +60,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<label for="id" string="Import / Export"/>
|
||||
<div>
|
||||
<div>
|
||||
<field name="module_base_import" class="oe_inline"/>
|
||||
<label for="module_base_import"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -75,7 +75,9 @@ class crm_case_stage(osv.osv):
|
|||
'requirements': fields.text('Requirements'),
|
||||
'section_ids':fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', string='Sections',
|
||||
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'State', required=True, help="The related state for the stage. The state of your document will automatically change regarding the selected stage. For example, if a stage is related to the state 'Close', when your document reaches this stage, it will be automatically have the 'closed' state."),
|
||||
'state': fields.selection(AVAILABLE_STATES, 'Related Status', required=True,
|
||||
help="The status of your document will automatically change regarding the selected stage. " \
|
||||
"For example, if a stage is related to the state 'Close', when your document reaches this stage, it is automatically closed."),
|
||||
'case_default': fields.boolean('Common to All Teams',
|
||||
help="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."),
|
||||
'fold': fields.boolean('Hide in Views when Empty',
|
||||
|
|
|
@ -27,13 +27,15 @@ import time
|
|||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
from base.res.res_partner import format_address
|
||||
|
||||
CRM_LEAD_PENDING_STATES = (
|
||||
crm.AVAILABLE_STATES[2][0], # Cancelled
|
||||
crm.AVAILABLE_STATES[3][0], # Done
|
||||
crm.AVAILABLE_STATES[4][0], # Pending
|
||||
)
|
||||
|
||||
class crm_lead(base_stage, osv.osv):
|
||||
class crm_lead(base_stage, format_address, osv.osv):
|
||||
""" CRM Lead Case """
|
||||
_name = "crm.lead"
|
||||
_description = "Lead/Opportunity"
|
||||
|
@ -105,6 +107,12 @@ class crm_lead(base_stage, osv.osv):
|
|||
|
||||
return result, fold
|
||||
|
||||
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
res = super(crm_lead,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
|
||||
if view_type == 'form':
|
||||
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
|
||||
return res
|
||||
|
||||
_group_by_full = {
|
||||
'stage_id': _read_group_stage_ids
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
<form string="Stage" version="7.0">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="state" string="Related State" />
|
||||
<field name="state" />
|
||||
<field name="probability"/>
|
||||
<field name="type"/>
|
||||
<field name="on_change"/>
|
||||
|
|
|
@ -26,19 +26,19 @@ class crm_configuration(osv.osv_memory):
|
|||
_inherit = ['sale.config.settings', 'fetchmail.config.settings']
|
||||
|
||||
_columns = {
|
||||
'fetchmail_lead': fields.boolean("create leads from incoming mails",
|
||||
'fetchmail_lead': fields.boolean("Create leads from incoming mails",
|
||||
fetchmail_model='crm.lead', fetchmail_name='Incoming Leads',
|
||||
help="""Allows you to configure your incoming mail server, and create leads from incoming emails."""),
|
||||
'module_crm_caldav': fields.boolean("applications with Caldav protocol",
|
||||
'module_crm_caldav': fields.boolean("Applications with Caldav protocol",
|
||||
help="""Use protocol caldav to synchronize meetings with other calendar applications (like Sunbird).
|
||||
This installs the module crm_caldav."""),
|
||||
'module_import_sugarcrm': fields.boolean("SugarCRM",
|
||||
help="""Import SugarCRM leads, opportunities, users, accounts, contacts, employees, meetings, phonecalls, emails, project and project tasks data.
|
||||
This installs the module import_sugarcrm."""),
|
||||
'module_import_google': fields.boolean("Google (Contacts and Calendar)",
|
||||
'module_import_google': fields.boolean("Google (contacts and calendar)",
|
||||
help="""Import google contact in partner address and add google calendar events details in Meeting.
|
||||
This installs the module import_google."""),
|
||||
'module_google_map': fields.boolean("add google maps on customers",
|
||||
'module_google_map': fields.boolean("Add google maps on customers",
|
||||
help="""Locate customers on Google Map.
|
||||
This installs the module google_map."""),
|
||||
'group_fund_raising': fields.boolean("Manage Fund Raising",
|
||||
|
|
|
@ -30,10 +30,10 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
_inherit = 'crm.lead2partner'
|
||||
|
||||
_columns = {
|
||||
'action': fields.selection([('exist', 'Link to an existing partner'), \
|
||||
('create', 'Create a new partner'), \
|
||||
('nothing', 'Do not link to a partner')], \
|
||||
'Related Partner', required=True),
|
||||
'action': fields.selection([('exist', 'Link to an existing customer'), \
|
||||
('create', 'Create a new customer'), \
|
||||
('nothing', 'Do not link to a customer')], \
|
||||
'Related Customer', required=True),
|
||||
'name': fields.selection([('convert', 'Convert to Opportunities'), ('merge', 'Merge with existing Opportunities')], 'Conversion Action', required=True),
|
||||
'opportunity_ids': fields.many2many('crm.lead', string='Opportunities', domain=[('type', '=', 'opportunity')]),
|
||||
}
|
||||
|
|
|
@ -7,22 +7,23 @@
|
|||
<field name="model">crm.lead2opportunity.partner</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Convert to Opportunity" version="7.0">
|
||||
<field name="action"/>
|
||||
<group attrs="{'invisible':[('action','!=','exist')]}">
|
||||
<field name="partner_id" attrs="{'required': [('action', '=', 'exist')]}"/>
|
||||
<group>
|
||||
<field name="action" class="oe_inline"/>
|
||||
<field name="partner_id"
|
||||
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
|
||||
class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Convert to Opportunity">
|
||||
<field name="name" colspan="4"/>
|
||||
<group>
|
||||
<field name="name" class="oe_inline"/>
|
||||
<field name="opportunity_ids" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<separator string="Select Opportunities" attrs="{'invisible': [('name', '=', 'convert')]}"/>
|
||||
<field name="opportunity_ids" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
<footer>
|
||||
<button name="action_apply" string="Create Opportunity" type="object" class="oe_highlight"/>
|
||||
or
|
||||
|
@ -72,7 +73,7 @@
|
|||
</record>
|
||||
|
||||
<record id="action_crm_lead2opportunity_partner" model="ir.actions.act_window">
|
||||
<field name="name">Create a Partner</field>
|
||||
<field name="name">Convert to opportunity</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">crm.lead2opportunity.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
|
|
|
@ -28,10 +28,10 @@ class crm_lead2partner(osv.osv_memory):
|
|||
_description = 'Lead to Partner'
|
||||
|
||||
_columns = {
|
||||
'action': fields.selection([('exist', 'Link to an existing partner'), \
|
||||
('create', 'Create a new partner')], \
|
||||
'action': fields.selection([('exist', 'Link to an existing customer'), \
|
||||
('create', 'Create a new customer')], \
|
||||
'Action', required=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'partner_id': fields.many2one('res.partner', 'Customer'),
|
||||
}
|
||||
def view_init(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
|
|
|
@ -32,7 +32,7 @@ class crm_partner2opportunity(osv.osv_memory):
|
|||
'name' : fields.char('Opportunity Name', size=64, required=True),
|
||||
'planned_revenue': fields.float('Expected Revenue', digits=(16,2)),
|
||||
'probability': fields.float('Success Probability', digits=(16,2)),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'partner_id': fields.many2one('res.partner', 'Customer'),
|
||||
}
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -9,11 +9,14 @@
|
|||
<field name="model">crm.phonecall2opportunity</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Convert To Opportunity " version="7.0">
|
||||
<group col="4">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="partner_id" />
|
||||
<field name="planned_revenue"/>
|
||||
<field name="probability"/>
|
||||
<label for="planned_revenue"/>
|
||||
<div>
|
||||
<field name="planned_revenue" class="oe_inline"/> at
|
||||
<field name="probability" class="oe_inline"/> %%
|
||||
</div>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="make_opportunity" type="object" string="_Convert" class="oe_highlight"/>
|
||||
|
@ -27,7 +30,7 @@
|
|||
<!-- Phonecall to Opportunity action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="phonecall2opportunity_act">
|
||||
<field name="name">Convert To Opportunity</field>
|
||||
<field name="name">Convert to opportunity</field>
|
||||
<field name="res_model">crm.phonecall2opportunity</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
|
|
|
@ -26,7 +26,7 @@ class crm_claim_settings(osv.osv_memory):
|
|||
_inherit = ['sale.config.settings', 'fetchmail.config.settings']
|
||||
|
||||
_columns = {
|
||||
'fetchmail_claim': fields.boolean("create claims from incoming mails",
|
||||
'fetchmail_claim': fields.boolean("Create claims from incoming mails",
|
||||
fetchmail_model='crm.claim', fetchmail_name='Incoming Claims',
|
||||
help="""Allows you to configure your incoming mail server, and create claims from incoming emails."""),
|
||||
}
|
||||
|
|
|
@ -20,17 +20,10 @@
|
|||
##############################################################################
|
||||
|
||||
import base64
|
||||
from openerp.tests import common
|
||||
from openerp.addons.mail.tests import test_mail
|
||||
|
||||
class test_message_compose(common.TransactionCase):
|
||||
|
||||
def _mock_smtp_gateway(self, *args, **kwargs):
|
||||
return True
|
||||
|
||||
def _mock_build_email(self, *args, **kwargs):
|
||||
self._build_email_args = args
|
||||
self._build_email_kwargs = kwargs
|
||||
return self.build_email_real(*args, **kwargs)
|
||||
class test_message_compose(test_mail.TestMailMockups):
|
||||
|
||||
def setUp(self):
|
||||
super(test_message_compose, self).setUp()
|
||||
|
@ -40,11 +33,6 @@ class test_message_compose(common.TransactionCase):
|
|||
self.res_users = self.registry('res.users')
|
||||
self.res_partner = self.registry('res.partner')
|
||||
|
||||
# Install mock SMTP gateway
|
||||
self.build_email_real = self.registry('ir.mail_server').build_email
|
||||
self.registry('ir.mail_server').build_email = self._mock_build_email
|
||||
self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
|
||||
|
||||
# create a 'pigs' and 'bird' groups that will be used through the various tests
|
||||
self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
|
||||
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
|
||||
|
|
|
@ -51,9 +51,11 @@ class mail_compose_message(osv.osv_memory):
|
|||
context = {}
|
||||
result = super(mail_compose_message, self).default_get(cr, uid, fields, context=context)
|
||||
result['template_id'] = context.get('default_template_id', context.get('mail.compose.template_id', False))
|
||||
# force html when using templates
|
||||
# pre-render the template if any
|
||||
if result.get('use_template'):
|
||||
result['content_subtype'] = 'html'
|
||||
onchange_res = self.onchange_use_template(cr, uid, [], result.get('use_template'), result.get('template_id'),
|
||||
result.get('composition_mode'), result.get('model'), result.get('res_id'), context=context)
|
||||
result.update(onchange_res['value'])
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
<xpath expr="//form/footer/button" position="before">
|
||||
<field name="use_template" invisible="1"/>
|
||||
<button icon="gtk-paste" type="object" name="toggle_template"
|
||||
string="" help="Use a message template" />
|
||||
string="" help="Use a message template" invisible="1"/>
|
||||
<button icon="gtk-save" type="object" name="save_as_template"
|
||||
string="" help="Save as a new template"/>
|
||||
string="" help="Save as a new template" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//form/notebook" position="after">
|
||||
<group attrs="{'invisible':[('use_template','=',False)]}" colspan="4" col="4">
|
||||
<field name="use_template" invisible="1"/>
|
||||
<field name="template_id" colspan="3"
|
||||
<field name="template_id" colspan="3" invisible="1"
|
||||
on_change="onchange_template_id(use_template, template_id, composition_mode, model, res_id, context)"/>
|
||||
</group>
|
||||
</xpath>
|
||||
|
|
|
@ -26,23 +26,23 @@ class hr_config_settings(osv.osv_memory):
|
|||
_inherit = 'res.config.settings'
|
||||
|
||||
_columns = {
|
||||
'module_hr_timesheet_sheet': fields.boolean('allow timesheets validation by managers',
|
||||
'module_hr_timesheet_sheet': fields.boolean('Allow timesheets validation by managers',
|
||||
help ="""This installs the module hr_timesheet_sheet."""),
|
||||
'module_hr_attendance': fields.boolean('track attendances',
|
||||
'module_hr_attendance': fields.boolean('Track attendances',
|
||||
help ="""This installs the module hr_attendance."""),
|
||||
'module_hr_timesheet': fields.boolean('manage timesheets',
|
||||
'module_hr_timesheet': fields.boolean('Manage timesheets',
|
||||
help ="""This installs the module hr_timesheet."""),
|
||||
'module_hr_holidays': fields.boolean('manage holidays, leaves and allocation requests',
|
||||
'module_hr_holidays': fields.boolean('Manage holidays, leaves and allocation requests',
|
||||
help ="""This installs the module hr_holidays."""),
|
||||
'module_hr_expense': fields.boolean('manage employees expenses',
|
||||
'module_hr_expense': fields.boolean('Manage employees expenses',
|
||||
help ="""This installs the module hr_expense."""),
|
||||
'module_hr_recruitment': fields.boolean('manage the recruitment process',
|
||||
'module_hr_recruitment': fields.boolean('Manage the recruitment process',
|
||||
help ="""This installs the module hr_recruitment."""),
|
||||
'module_hr_contract': fields.boolean('record contracts per employee',
|
||||
'module_hr_contract': fields.boolean('Record contracts per employee',
|
||||
help ="""This installs the module hr_contract."""),
|
||||
'module_hr_evaluation': fields.boolean('organize employees periodic evaluation',
|
||||
'module_hr_evaluation': fields.boolean('Organize employees periodic evaluation',
|
||||
help ="""This installs the module hr_evaluation."""),
|
||||
'module_hr_payroll': fields.boolean('manage payroll',
|
||||
'module_hr_payroll': fields.boolean('Manage payroll',
|
||||
help ="""This installs the module hr_payroll."""),
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,19 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="res.groups" id="base.group_user">
|
||||
<field name="comment">the user will be able to manage his own human resources stuff (leave request, timesheets, ...), if he is linked to an employee in the system.</field>
|
||||
</record>
|
||||
|
||||
<record id="base.group_hr_user" model="res.groups">
|
||||
<field name="name">Officer</field>
|
||||
<field name="category_id" ref="base.module_category_human_resources"/>
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||
<field name="comment">the user will be able to approve document created by employees.</field>
|
||||
</record>
|
||||
<record id="base.group_hr_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="comment">the user will have an access to the human resources configuration as well as statistic reports.</field>
|
||||
<field name="category_id" ref="base.module_category_human_resources"/>
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_hr_user'))]"/>
|
||||
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||
|
|
|
@ -24,6 +24,6 @@ from osv import osv, fields
|
|||
class human_resources_configuration(osv.osv_memory):
|
||||
_inherit = 'hr.config.settings'
|
||||
_columns = {
|
||||
'module_hr_payroll_account': fields.boolean('link your payroll to accounting system',
|
||||
help ="""Create Journal Entries from Payslips"""),
|
||||
'module_hr_payroll_account': fields.boolean('Link your payroll to accounting system',
|
||||
help ="""Create journal entries from payslips"""),
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ class hr_applicant_settings(osv.osv_memory):
|
|||
_inherit = ['hr.config.settings', 'fetchmail.config.settings']
|
||||
|
||||
_columns = {
|
||||
'module_document_ftp': fields.boolean('allow the automatic indexation of resumes',
|
||||
'module_document_ftp': fields.boolean('Allow the automatic indexation of resumes',
|
||||
help="""Manage your CV's and motivation letter related to all applicants.
|
||||
This installs the module document_ftp. This will install the knowledge management module in order to allow you to search using specific keywords through the content of all documents (PDF, .DOCx...)"""),
|
||||
'fetchmail_applicants': fields.boolean('create applicants from an incoming email account',
|
||||
'fetchmail_applicants': fields.boolean('Create applicants from an incoming email account',
|
||||
fetchmail_model='hr.applicant', fetchmail_name='Incoming HR Applications',
|
||||
help ="""Allow applicants to send their job application to an email address (jobs@mycompany.com),
|
||||
and create automatically application documents in the system."""),
|
||||
|
|
|
@ -25,16 +25,16 @@ class knowledge_config_settings(osv.osv_memory):
|
|||
_name = 'knowledge.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
_columns = {
|
||||
'module_document_page': fields.boolean('create static web pages',
|
||||
'module_document_page': fields.boolean('Create static web pages',
|
||||
help="""This installs the module document_page."""),
|
||||
'module_document': fields.boolean('manage documents',
|
||||
'module_document': fields.boolean('Manage documents',
|
||||
help="""This is a complete document management system, with: user authentication,
|
||||
full document search (but pptx and docx are not supported), and a document dashboard.
|
||||
This installs the module document."""),
|
||||
'module_document_ftp': fields.boolean('share repositories (FTP)',
|
||||
'module_document_ftp': fields.boolean('Share repositories (FTP)',
|
||||
help="""Access your documents in OpenERP through an FTP interface.
|
||||
This installs the module document_ftp."""),
|
||||
'module_document_webdav': fields.boolean('share repositories (WebDAV)',
|
||||
'module_document_webdav': fields.boolean('Share repositories (WebDAV)',
|
||||
help="""Access your documents in OpenERP through WebDAV.
|
||||
This installs the module document_webdav."""),
|
||||
}
|
||||
|
|
|
@ -8,15 +8,13 @@
|
|||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="account.invoice_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="payment_term" position="after">
|
||||
<group col="4" colspan="2">
|
||||
<field name="reference_type" nolabel="1" size="0" attrs="{'readonly':[('state','!=','draft')]}"
|
||||
on_change="generate_bbacomm(type,reference_type, partner_id,reference, context)" colspan="1"/>
|
||||
<field name="reference" nolabel="1" colspan="3" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
</group>
|
||||
<field name="date_due" position="after">
|
||||
<field name="reference_type" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}"
|
||||
on_change="generate_bbacomm(type,reference_type, partner_id,reference, context)"/>
|
||||
<field name="reference" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<record id="chart0_en" model="account.account.template">
|
||||
<field name="code">0</field>
|
||||
<field name="name">Account Chart CA EN</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="account.data_account_type_view"/>
|
||||
</record>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<record id="chartgr_0" model="account.account.template">
|
||||
<field name="code">0</field>
|
||||
<field name="name">Γενικό Λογιστικό Σχέδιο</field>
|
||||
<!--<field eval="0" name="parent_id"/> -->
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="account_type_view"/>
|
||||
</record>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<record id="plan_raiz" model="account.account.template">
|
||||
<field name="code">-</field>
|
||||
<field name="name">Plan contable de Guatemala (sencillo)</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="cuenta_vista"/>
|
||||
</record>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<record id="plan_raiz" model="account.account.template">
|
||||
<field name="code">-</field>
|
||||
<field name="name">Plan contable de Honduras (sencillo)</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="cuenta_vista"/>
|
||||
</record>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<field name="name">Partnership/Private Firm Chart of Account</field>
|
||||
<field name="code">0</field>
|
||||
<field name="type">view</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="user_type" ref="account.data_account_type_view"/>
|
||||
<field name="reconcile" eval="False"/>
|
||||
</record>
|
||||
|
@ -520,4 +519,4 @@
|
|||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<field name="name">Public Firm Chart of Account</field>
|
||||
<field name="code">0</field>
|
||||
<field name="type">view</field>
|
||||
<field eval="0" name="parent_id"/>
|
||||
<field name="user_type" ref="account.data_account_type_view"/>
|
||||
<field name="reconcile" eval="False"/>
|
||||
</record>
|
||||
|
@ -673,4 +672,4 @@
|
|||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
<record id="a_root" model="account.account.template">
|
||||
<field name="code">0</field>
|
||||
<field name="name">Simple chart of accounts</field>
|
||||
<field name="parent_id" eval="False"/>
|
||||
<field name="type">view</field>
|
||||
<field name="user_type" ref="acc_type_view"/>
|
||||
</record>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<record id="uy_code_0" model="account.account.template">
|
||||
<field name="code">0</field>
|
||||
<field name="type">view</field>
|
||||
<field name="parent_id" eval="False"/>
|
||||
<field name="name">Uruguay - Plan de Cuentas</field>
|
||||
<field name="user_type" ref="type_view"/>
|
||||
</record>
|
||||
|
|
|
@ -30,27 +30,27 @@ A business oriented Social Networking with a fully-integrated email and message
|
|||
===========================================================================================
|
||||
|
||||
The Social Networking module provides an unified social network
|
||||
abstraction layer allowing applications to display a complete
|
||||
abstraction layer allowing applications to display a complete
|
||||
communication history on documents. It gives the users the possibility
|
||||
to read and send messages and emails in an unified way.
|
||||
|
||||
It also provides a feeds page combined to a subscription mechanism, that
|
||||
It also provides a feeds page combined to a subscription mechanism, that
|
||||
allows to follow documents, and to be constantly updated about recent
|
||||
news.
|
||||
|
||||
|
||||
The main features of the module are:
|
||||
------------------------------------
|
||||
* a clean and renewed communication history for any OpenERP
|
||||
document that can act as a discussion topic,
|
||||
* a discussion mean on documents,
|
||||
* a subscription mechanism to be updated about new messages on
|
||||
* a subscription mechanism to be updated about new messages on
|
||||
interesting documents,
|
||||
* an unified feeds page to see recent messages and activity
|
||||
* an unified feeds page to see recent messages and activity
|
||||
on followed documents,
|
||||
* user communication through the feeds page,
|
||||
* a threaded discussion design,
|
||||
* relies on the global outgoing mail server, an integrated email
|
||||
management system allowing to send emails with a configurable
|
||||
management system allowing to send emails with a configurable
|
||||
scheduler-based processing engine
|
||||
* includes an extensible generic email composition assistant, that can turn
|
||||
into a mass-mailing assistant, and is capable of interpreting
|
||||
|
@ -61,6 +61,7 @@ The main features of the module are:
|
|||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base', 'base_tools', 'base_setup'],
|
||||
'data': [
|
||||
'wizard/invite_view.xml',
|
||||
'wizard/mail_compose_message_view.xml',
|
||||
'res_config_view.xml',
|
||||
'mail_message_view.xml',
|
||||
|
|
|
@ -86,7 +86,7 @@ class mail_alias(osv.Model):
|
|||
help="Optional ID of a thread (record) to which all incoming "
|
||||
"messages will be attached, even if they did not reply to it. "
|
||||
"If set, this will disable the creation of new records completely."),
|
||||
'alias_domain': fields.function(_get_alias_domain, string="Alias Domain", type='char', size=None),
|
||||
'alias_domain': fields.function(_get_alias_domain, string="Alias domain", type='char', size=None),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -23,6 +23,7 @@ from osv import osv
|
|||
from osv import fields
|
||||
import tools
|
||||
|
||||
|
||||
class mail_followers(osv.Model):
|
||||
""" mail_followers holds the data related to the follow mechanism inside
|
||||
OpenERP. Partners can choose to follow documents (records) of any kind
|
||||
|
@ -84,16 +85,44 @@ class mail_notification(osv.Model):
|
|||
notif_ids = self.search(cr, uid, [('partner_id', '=', partner_id), ('message_id', '=', msg_id)], context=context)
|
||||
return self.write(cr, uid, notif_ids, {'read': True}, context=context)
|
||||
|
||||
def get_partners_to_notify(self, cr, uid, partner_ids, message, context=None):
|
||||
""" Return the list of partners to notify, based on their preferences.
|
||||
|
||||
:param browse_record message: mail.message to notify
|
||||
"""
|
||||
notify_pids = []
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
# Do not send an email to the writer
|
||||
if partner.user_ids and partner.user_ids[0].id == uid:
|
||||
continue
|
||||
# Do not send to partners without email address defined
|
||||
if not partner.email:
|
||||
continue
|
||||
# Partner does not want to receive any emails
|
||||
if partner.notification_email_send == 'none':
|
||||
continue
|
||||
# Partner wants to receive only emails and comments
|
||||
if partner.notification_email_send == 'comment' and message.type not in ('email', 'comment'):
|
||||
continue
|
||||
# Partner wants to receive only emails
|
||||
if partner.notification_email_send == 'email' and message.type != 'email':
|
||||
continue
|
||||
notify_pids.append(partner.id)
|
||||
return notify_pids
|
||||
|
||||
def notify(self, cr, uid, partner_ids, msg_id, context=None):
|
||||
""" Send by email the notification depending on the user preferences """
|
||||
context = context or {}
|
||||
# mail_noemail (do not send email) or no partner_ids: do not send, return
|
||||
if context.get('mail_noemail') or not partner_ids:
|
||||
return True
|
||||
|
||||
mail_mail = self.pool.get('mail.mail')
|
||||
msg = self.pool.get('mail.message').browse(cr, uid, msg_id, context=context)
|
||||
|
||||
notify_partner_ids = self.get_partners_to_notify(cr, uid, partner_ids, msg, context=context)
|
||||
if not notify_partner_ids:
|
||||
return True
|
||||
|
||||
mail_mail = self.pool.get('mail.mail')
|
||||
# add signature
|
||||
body_html = msg.body
|
||||
signature = msg.author_id and msg.author_id.user_ids[0].signature or ''
|
||||
|
@ -107,27 +136,6 @@ class mail_notification(osv.Model):
|
|||
'body_html': body_html,
|
||||
'state': 'outgoing',
|
||||
}
|
||||
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
# Do not send an email to the writer
|
||||
if partner.user_ids and partner.user_ids[0].id == uid:
|
||||
continue
|
||||
# Do not send to partners without email address defined
|
||||
if not partner.email:
|
||||
continue
|
||||
# Partner does not want to receive any emails
|
||||
if partner.notification_email_send == 'none':
|
||||
continue
|
||||
# Partner wants to receive only emails and comments
|
||||
if partner.notification_email_send == 'comment' and msg.type not in ('email', 'comment'):
|
||||
continue
|
||||
# Partner wants to receive only emails
|
||||
if partner.notification_email_send == 'email' and msg.type != 'email':
|
||||
continue
|
||||
if partner.email not in mail_values['email_to']:
|
||||
mail_values['email_to'].append(partner.email)
|
||||
if mail_values['email_to']:
|
||||
mail_values['email_to'] = ', '.join(mail_values['email_to'])
|
||||
email_notif_id = mail_mail.create(cr, uid, mail_values, context=context)
|
||||
mail_mail.send(cr, uid, [email_notif_id], context=context)
|
||||
return True
|
||||
mail_values['email_to'] = ', '.join(mail_values['email_to'])
|
||||
email_notif_id = mail_mail.create(cr, uid, mail_values, context=context)
|
||||
return mail_mail.send(cr, uid, [email_notif_id], recipient_ids=notify_partner_ids, context=context)
|
||||
|
|
|
@ -19,13 +19,11 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import datetime as DT
|
||||
import openerp
|
||||
import openerp.tools as tools
|
||||
from operator import itemgetter
|
||||
from osv import osv
|
||||
from osv import fields
|
||||
from tools.translate import _
|
||||
|
||||
|
||||
class mail_group(osv.Model):
|
||||
""" A mail_group is a collection of users sharing messages in a discussion
|
||||
|
@ -47,7 +45,7 @@ class mail_group(osv.Model):
|
|||
_columns = {
|
||||
'description': fields.text('Description'),
|
||||
'menu_id': fields.many2one('ir.ui.menu', string='Related Menu', required=True, ondelete="cascade"),
|
||||
'public': fields.selection([('public','Public'),('private','Private'),('groups','Selected Group Only')], 'Privacy', required=True,
|
||||
'public': fields.selection([('public', 'Public'), ('private', 'Private'), ('groups', 'Selected Group Only')], 'Privacy', required=True,
|
||||
help='This group is visible by non members. \
|
||||
Invisible groups can add members through the invite button.'),
|
||||
'group_public_id': fields.many2one('res.groups', string='Authorized Group'),
|
||||
|
@ -126,14 +124,14 @@ class mail_group(osv.Model):
|
|||
search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search')
|
||||
params = {
|
||||
'search_view_id': search_ref and search_ref[1] or False,
|
||||
'domain': [('model','=','mail.group'), ('res_id','=',mail_group_id)],
|
||||
'domain': [('model', '=', 'mail.group'), ('res_id', '=', mail_group_id)],
|
||||
'context': {'default_model': 'mail.group', 'default_res_id': mail_group_id},
|
||||
'res_model': 'mail.message',
|
||||
'thread_level': 1,
|
||||
}
|
||||
cobj = self.pool.get('ir.actions.client')
|
||||
newref = cobj.copy(cr, uid, ref[1], default={'params': str(params), 'name': vals['name']}, context=context)
|
||||
self.write(cr, uid, [mail_group_id], {'action': 'ir.actions.client,'+str(newref), 'mail_group_id': mail_group_id}, context=context)
|
||||
self.write(cr, uid, [mail_group_id], {'action': 'ir.actions.client,' + str(newref), 'mail_group_id': mail_group_id}, context=context)
|
||||
|
||||
mail_alias.write(cr, uid, [vals['alias_id']], {"alias_force_thread_id": mail_group_id}, context)
|
||||
|
||||
|
@ -142,9 +140,13 @@ class mail_group(osv.Model):
|
|||
return mail_group_id
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
groups = self.browse(cr, uid, ids, context=context)
|
||||
# Cascade-delete mail aliases as well, as they should not exist without the mail group.
|
||||
mail_alias = self.pool.get('mail.alias')
|
||||
alias_ids = [group.alias_id.id for group in self.browse(cr, uid, ids, context=context) if group.alias_id]
|
||||
alias_ids = [group.alias_id.id for group in groups if group.alias_id]
|
||||
# Cascade-delete menu entries as well
|
||||
self.pool.get('ir.ui.menu').unlink(cr, uid, [group.menu_id.id for group in groups if group.menu_id], context=context)
|
||||
# Delete mail_group
|
||||
res = super(mail_group, self).unlink(cr, uid, ids, context=context)
|
||||
mail_alias.unlink(cr, uid, alias_ids, context=context)
|
||||
return res
|
||||
|
|
|
@ -30,6 +30,7 @@ from tools.translate import _
|
|||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class mail_mail(osv.Model):
|
||||
""" Model holding RFC2822 email messages to send. This model also provides
|
||||
facilities to queue and send new email messages. """
|
||||
|
@ -58,8 +59,8 @@ class mail_mail(osv.Model):
|
|||
'body_html': fields.text('Rich-text Contents', help="Rich-text/HTML message"),
|
||||
|
||||
# Auto-detected based on create() - if 'mail_message_id' was passed then this mail is a notification
|
||||
# and during unlink() we will cascade delete the parent and its attachments
|
||||
'notification': fields.boolean('Is Notification')
|
||||
# and during unlink() we will not cascade delete the parent and its attachments
|
||||
'notification': fields.boolean('Is Notification')
|
||||
}
|
||||
|
||||
def _get_default_from(self, cr, uid, context=None):
|
||||
|
@ -76,21 +77,21 @@ class mail_mail(osv.Model):
|
|||
def create(self, cr, uid, values, context=None):
|
||||
if 'notification' not in values and values.get('mail_message_id'):
|
||||
values['notification'] = True
|
||||
return super(mail_mail,self).create(cr, uid, values, context=context)
|
||||
return super(mail_mail, self).create(cr, uid, values, context=context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
# cascade-delete the parent message for all mails that are not created for a notification
|
||||
ids_to_cascade = self.search(cr, uid, [('notification','=',False),('id','in',ids)])
|
||||
ids_to_cascade = self.search(cr, uid, [('notification', '=', False), ('id', 'in', ids)])
|
||||
parent_msg_ids = [m.mail_message_id.id for m in self.browse(cr, uid, ids_to_cascade, context=context)]
|
||||
res = super(mail_mail,self).unlink(cr, uid, ids, context=context)
|
||||
res = super(mail_mail, self).unlink(cr, uid, ids, context=context)
|
||||
self.pool.get('mail.message').unlink(cr, uid, parent_msg_ids, context=context)
|
||||
return res
|
||||
|
||||
def mark_outgoing(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state':'outgoing'}, context=context)
|
||||
return self.write(cr, uid, ids, {'state': 'outgoing'}, context=context)
|
||||
|
||||
def cancel(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state':'cancel'}, context=context)
|
||||
return self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
|
||||
|
||||
def process_email_queue(self, cr, uid, ids=None, context=None):
|
||||
"""Send immediately queued messages, committing after each
|
||||
|
@ -127,7 +128,7 @@ class mail_mail(osv.Model):
|
|||
"""Perform any post-processing necessary after sending ``mail``
|
||||
successfully, including deleting it completely along with its
|
||||
attachment if the ``auto_delete`` flag of the mail was set.
|
||||
Overridden by subclasses for extra post-processing behaviors.
|
||||
Overridden by subclasses for extra post-processing behaviors.
|
||||
|
||||
:param browse_record mail: the mail that was just sent
|
||||
:return: True
|
||||
|
@ -136,14 +137,46 @@ class mail_mail(osv.Model):
|
|||
mail.unlink()
|
||||
return True
|
||||
|
||||
def _send_get_mail_subject(self, cr, uid, mail, force=False, context=None):
|
||||
""" if void and related document: '<Author> posted on <Resource>'
|
||||
:param mail: mail.mail browse_record """
|
||||
def send_get_mail_subject(self, cr, uid, mail, force=False, partner=None, context=None):
|
||||
""" If subject is void and record_name defined: '<Author> posted on <Resource>'
|
||||
|
||||
:param boolean force: force the subject replacement
|
||||
:param browse_record mail: mail.mail browse_record
|
||||
:param browse_record partner: specific recipient partner
|
||||
"""
|
||||
if force or (not mail.subject and mail.model and mail.res_id):
|
||||
return '%s posted on %s' % (mail.author_id.name, mail.record_name)
|
||||
return mail.subject
|
||||
|
||||
def send(self, cr, uid, ids, auto_commit=False, context=None):
|
||||
def send_get_mail_body(self, cr, uid, mail, partner=None, context=None):
|
||||
""" Return a specific ir_email body. The main purpose of this method
|
||||
is to be inherited by Portal, to add a link for signing in, in
|
||||
each notification email a partner receives.
|
||||
|
||||
:param browse_record mail: mail.mail browse_record
|
||||
:param browse_record partner: specific recipient partner
|
||||
"""
|
||||
return mail.body_html
|
||||
|
||||
def send_get_email_dict(self, cr, uid, mail, partner=None, context=None):
|
||||
""" Return a dictionary for specific email values, depending on a
|
||||
partner, or generic to the whole recipients given by mail.email_to.
|
||||
|
||||
:param browse_record mail: mail.mail browse_record
|
||||
:param browse_record partner: specific recipient partner
|
||||
"""
|
||||
body = self.send_get_mail_body(cr, uid, mail, partner=partner, context=context)
|
||||
subject = self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context)
|
||||
body_alternative = tools.html2plaintext(body)
|
||||
email_to = [partner.email] if partner else tools.email_split(mail.email_to)
|
||||
return {
|
||||
'body': body,
|
||||
'body_alternative': body_alternative,
|
||||
'subject': subject,
|
||||
'email_to': email_to,
|
||||
}
|
||||
|
||||
def send(self, cr, uid, ids, auto_commit=False, recipient_ids=None, context=None):
|
||||
""" Sends the selected emails immediately, ignoring their current
|
||||
state (mails that have already been sent should not be passed
|
||||
unless they should actually be re-sent).
|
||||
|
@ -154,50 +187,55 @@ class mail_mail(osv.Model):
|
|||
:param bool auto_commit: whether to force a commit of the mail status
|
||||
after sending each mail (meant only for scheduler processing);
|
||||
should never be True during normal transactions (default: False)
|
||||
:param list recipient_ids: specific list of res.partner recipients.
|
||||
If set, one email is sent to each partner. Its is possible to
|
||||
tune the sent email through ``send_get_mail_body`` and ``send_get_mail_subject``.
|
||||
If not specified, one email is sent to mail_mail.email_to.
|
||||
:return: True
|
||||
"""
|
||||
ir_mail_server = self.pool.get('ir.mail_server')
|
||||
for mail in self.browse(cr, uid, ids, context=context):
|
||||
try:
|
||||
body = mail.body_html
|
||||
subject = self._send_get_mail_subject(cr, uid, mail, context=context)
|
||||
|
||||
# handle attachments
|
||||
attachments = []
|
||||
for attach in mail.attachment_ids:
|
||||
attachments.append((attach.datas_fname, base64.b64decode(attach.datas)))
|
||||
|
||||
# use only sanitized html and set its plaintexted version as alternative
|
||||
body_alternative = tools.html2plaintext(body)
|
||||
content_subtype_alternative = 'plain'
|
||||
# specific behavior to customize the send email for notified partners
|
||||
email_list = []
|
||||
if recipient_ids:
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, recipient_ids, context=context):
|
||||
email_list.append(self.send_get_email_dict(cr, uid, mail, partner=partner, context=context))
|
||||
else:
|
||||
email_list.append(self.send_get_email_dict(cr, uid, mail, context=context))
|
||||
|
||||
# build an RFC2822 email.message.Message object and send it without queuing
|
||||
msg = ir_mail_server.build_email(
|
||||
email_from = mail.email_from,
|
||||
email_to = tools.email_split(mail.email_to),
|
||||
subject = subject,
|
||||
body = body,
|
||||
body_alternative = body_alternative,
|
||||
email_cc = tools.email_split(mail.email_cc),
|
||||
reply_to = mail.reply_to,
|
||||
attachments = attachments,
|
||||
message_id = mail.message_id,
|
||||
references = mail.references,
|
||||
object_id = mail.res_id and ('%s-%s' % (mail.res_id, mail.model)),
|
||||
subtype = 'html',
|
||||
subtype_alternative = content_subtype_alternative)
|
||||
res = ir_mail_server.send_email(cr, uid, msg,
|
||||
mail_server_id=mail.mail_server_id.id, context=context)
|
||||
for email in email_list:
|
||||
msg = ir_mail_server.build_email(
|
||||
email_from = mail.email_from,
|
||||
email_to = email.get('email_to'),
|
||||
subject = email.get('subject'),
|
||||
body = email.get('body'),
|
||||
body_alternative = email.get('body_alternative'),
|
||||
email_cc = tools.email_split(mail.email_cc),
|
||||
reply_to = mail.reply_to,
|
||||
attachments = attachments,
|
||||
message_id = mail.message_id,
|
||||
references = mail.references,
|
||||
object_id = mail.res_id and ('%s-%s' % (mail.res_id, mail.model)),
|
||||
subtype = 'html',
|
||||
subtype_alternative = 'plain')
|
||||
res = ir_mail_server.send_email(cr, uid, msg,
|
||||
mail_server_id=mail.mail_server_id.id, context=context)
|
||||
if res:
|
||||
mail.write({'state':'sent', 'message_id': res})
|
||||
mail.write({'state': 'sent', 'message_id': res})
|
||||
else:
|
||||
mail.write({'state':'exception'})
|
||||
mail.write({'state': 'exception'})
|
||||
mail.refresh()
|
||||
if mail.state == 'sent':
|
||||
self._postprocess_sent_message(cr, uid, mail, context=context)
|
||||
except Exception:
|
||||
_logger.exception('failed sending mail.mail %s', mail.id)
|
||||
mail.write({'state':'exception'})
|
||||
mail.write({'state': 'exception'})
|
||||
|
||||
if auto_commit == True:
|
||||
cr.commit()
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
##############################################################################
|
||||
|
||||
import logging
|
||||
import openerp
|
||||
import tools
|
||||
|
||||
from email.header import decode_header
|
||||
from operator import itemgetter
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -35,6 +37,7 @@ def decode(text):
|
|||
text = decode_header(text.replace('\r', ''))
|
||||
return ''.join([tools.ustr(x[0], x[1]) for x in text])
|
||||
|
||||
|
||||
class mail_message(osv.Model):
|
||||
""" Messages model: system notification (replacing res.log notifications),
|
||||
comments (OpenChatter discussion) and incoming emails. """
|
||||
|
@ -57,7 +60,10 @@ class mail_message(osv.Model):
|
|||
for message in self.browse(cr, uid, ids, context=context):
|
||||
if not message.model or not message.res_id:
|
||||
continue
|
||||
result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
|
||||
try:
|
||||
result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
|
||||
except openerp.exceptions.AccessDenied, e:
|
||||
pass
|
||||
return result
|
||||
|
||||
def _get_unread(self, cr, uid, ids, name, arg, context=None):
|
||||
|
@ -147,7 +153,7 @@ class mail_message(osv.Model):
|
|||
|
||||
def _message_dict_get(self, cr, uid, msg, context=None):
|
||||
""" Return a dict representation of the message browse record. """
|
||||
attachment_ids = self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)
|
||||
attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)]
|
||||
author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0]
|
||||
author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0]
|
||||
partner_ids = self.pool.get('res.partner').name_get(cr, uid, [x.id for x in msg.partner_ids], context=context)
|
||||
|
@ -306,15 +312,15 @@ class mail_message(osv.Model):
|
|||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
# cascade-delete attachments that are directly attached to the message (should only happen
|
||||
# for mail.messages that act as parent for a standalone mail.mail record.
|
||||
# for mail.messages that act as parent for a standalone mail.mail record).
|
||||
attachments_to_delete = []
|
||||
for mail in self.browse(cr, uid, ids, context=context):
|
||||
for attach in mail.attachment_ids:
|
||||
if attach.res_model == 'mail.message' and attach.res_id == mail.id:
|
||||
for message in self.browse(cr, uid, ids, context=context):
|
||||
for attach in message.attachment_ids:
|
||||
if attach.res_model == self._name and attach.res_id == message.id:
|
||||
attachments_to_delete.append(attach.id)
|
||||
if attachments_to_delete:
|
||||
self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context)
|
||||
return super(mail_message,self).unlink(cr, uid, ids, context=context)
|
||||
return super(mail_message, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
def notify(self, cr, uid, newid, context=None):
|
||||
""" Add the related record followers to the destination partner_ids.
|
||||
|
@ -341,3 +347,25 @@ class mail_message(osv.Model):
|
|||
default = {}
|
||||
default.update(message_id=False, headers=False)
|
||||
return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Tools
|
||||
#------------------------------------------------------
|
||||
|
||||
def check_partners_email(self, cr, uid, partner_ids, context=None):
|
||||
""" Verify that selected partner_ids have an email_address defined.
|
||||
Otherwise throw a warning. """
|
||||
partner_wo_email_lst = []
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
if not partner.email:
|
||||
partner_wo_email_lst.append(partner)
|
||||
if not partner_wo_email_lst:
|
||||
return {}
|
||||
warning_msg = _('The following partners chosen as recipients for the email have no email address linked :')
|
||||
for partner in partner_wo_email_lst:
|
||||
warning_msg += '\n- %s' % (partner.name)
|
||||
return {'warning': {
|
||||
'title': _('Partners email addresses not found'),
|
||||
'message': warning_msg,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -623,14 +623,8 @@ class mail_thread(osv.AbstractModel):
|
|||
return self.message_subscribe(cr, uid, ids, partner_ids, context=context)
|
||||
|
||||
def message_subscribe(self, cr, uid, ids, partner_ids, context=None):
|
||||
""" Add partners to the records followers.
|
||||
:param partner_ids: a list of partner_ids to subscribe
|
||||
:param return: new value of followers if read_back key in context
|
||||
"""
|
||||
self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
|
||||
if context and context.get('read_back'):
|
||||
return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
|
||||
return []
|
||||
""" Add partners to the records followers. """
|
||||
return self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
|
||||
|
||||
def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None):
|
||||
""" Wrapper on message_subscribe, using users. If user_ids is not
|
||||
|
@ -640,14 +634,8 @@ class mail_thread(osv.AbstractModel):
|
|||
return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
|
||||
|
||||
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
|
||||
""" Remove partners from the records followers.
|
||||
:param partner_ids: a list of partner_ids to unsubscribe
|
||||
:param return: new value of followers if read_back key in context
|
||||
"""
|
||||
self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
|
||||
if context and context.get('read_back'):
|
||||
return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
|
||||
return []
|
||||
""" Remove partners from the records followers. """
|
||||
return self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Thread state
|
||||
|
|
|
@ -72,6 +72,9 @@ class res_users(osv.Model):
|
|||
|
||||
def create(self, cr, uid, data, context=None):
|
||||
# create default alias same as the login
|
||||
if not data.get('login', False):
|
||||
raise osv.except_osv(_('Invalid Action!'), _('You may not create a user.'))
|
||||
|
||||
mail_alias = self.pool.get('mail.alias')
|
||||
alias_id = mail_alias.create_unique_alias(cr, uid, {'alias_name': data['login']}, model_name=self._name, context=context)
|
||||
data['alias_id'] = alias_id
|
||||
|
|
|
@ -96,10 +96,6 @@
|
|||
width: 120px;
|
||||
}
|
||||
|
||||
.openerp button.oe_mail_button_followers {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.openerp button.oe_mail_button_mouseout {
|
||||
color: white;
|
||||
background-color: #8a89ba;
|
||||
|
@ -230,6 +226,10 @@
|
|||
clear: both;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_content a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.openerp img.oe_mail_icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
|
@ -307,6 +307,29 @@
|
|||
padding: 1px;
|
||||
}
|
||||
|
||||
/* attachment button: override of openerp values */
|
||||
.openerp .oe_mail_msg_content .oe_mail_compose_message_icons div.oe_hidden_input_file {
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin: 2px;
|
||||
}
|
||||
.openerp .oe_mail_msg_content .oe_mail_compose_message_icons div.oe_hidden_input_file button {
|
||||
margin: 0px;
|
||||
}
|
||||
.openerp .oe_mail_msg_content .oe_mail_compose_message_icons input.oe_form_binary_file {
|
||||
bottom: 0px;
|
||||
top: auto;
|
||||
left: auto;
|
||||
right: 28px;
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
min-width: 22px;
|
||||
font-size: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Messages layout
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -322,31 +345,20 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_footer {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_footer li {
|
||||
float: left;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_body {
|
||||
.openerp .oe_mail_msg .oe_mail_msg_body {
|
||||
margin-bottom: .5em;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_record_body pre {
|
||||
.openerp .oe_mail_msg .oe_mail_msg_body pre {
|
||||
font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_body span.oe_mail_msg_tail {
|
||||
white-space: pre-wrap;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* Read more/less link */
|
||||
.openerp .oe_mail_msg_content .oe_mail_reduce {
|
||||
.openerp .oe_mail_msg span.oe_mail_reduce {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
@ -364,16 +376,23 @@
|
|||
border-top: 4px solid #404040;
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_footer li:after {
|
||||
/* Message footer */
|
||||
.openerp .oe_mail_msg .oe_mail_msg_footer {
|
||||
color: #888;
|
||||
}
|
||||
.openerp .oe_mail_msg .oe_mail_msg_footer li {
|
||||
float: left;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.openerp .oe_mail_msg .oe_mail_msg_footer li:after {
|
||||
content: " · ";
|
||||
}
|
||||
|
||||
.openerp .oe_mail_msg_footer li:last-child:after {
|
||||
.openerp .oe_mail_msg .oe_mail_msg_footer li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Attachments list */
|
||||
.openerp ul.oe_mail_msg_attachments {
|
||||
.openerp .oe_mail_msg_content ul.oe_mail_msg_attachments {
|
||||
display: none;
|
||||
width: 100%;
|
||||
border-top: 1px solid #CCC;
|
||||
|
@ -381,7 +400,7 @@
|
|||
padding: .5em 0;
|
||||
list-style-position: inside;
|
||||
}
|
||||
.openerp ul.oe_mail_msg_attachments li {
|
||||
.openerp .oe_mail_msg_content ul.oe_mail_msg_attachments li {
|
||||
float: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
min-height: 0px;
|
||||
max-height: none;
|
||||
padding: 0px 18px;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
/* Resize footer width */
|
||||
|
|
|
@ -17,19 +17,13 @@ openerp.mail = function(session) {
|
|||
*/
|
||||
|
||||
session.web.FormView = session.web.FormView.extend({
|
||||
// TDE FIXME TODO: CHECK WITH NEW BRANCH
|
||||
do_action: function(action, on_close) {
|
||||
if (action.res_model == 'mail.compose.message' &&
|
||||
this.fields && this.fields.message_ids &&
|
||||
this.fields.message_ids.view.get("actual_mode") != 'create') {
|
||||
// debug
|
||||
console.groupCollapsed('FormView do_action on mail.compose.message');
|
||||
console.log('message_ids field:', this.fields.message_ids);
|
||||
console.groupEnd();
|
||||
var record_thread = this.fields.message_ids;
|
||||
var thread = record_thread.thread;
|
||||
thread.instantiate_composition_form('comment', true, false, 0, action.context);
|
||||
return false;
|
||||
action.context && action.context.redirect == true &&
|
||||
this.fields && this.fields.message_ids && this.fields.message_ids.view.get("actual_mode") != 'create') {
|
||||
var thread = this.fields.message_ids.thread;
|
||||
thread.refresh_composition_form(action.context);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return this._super(action, on_close);
|
||||
|
@ -37,35 +31,32 @@ openerp.mail = function(session) {
|
|||
},
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------
|
||||
* ChatterUtils
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* This class holds a few tools method that will be used by
|
||||
* the various Chatter widgets.
|
||||
*
|
||||
* This class holds a few tools method for Chatter.
|
||||
* Some regular expressions not used anymore, kept because I want to
|
||||
* - (^|\s)@((\w|@|\.)*): @login@log.log
|
||||
* 1. '(void)'
|
||||
* 2. login@log.log
|
||||
* - (^|\s)\[(\w+).(\w+),(\d)\|*((\w|[@ .,])*)\]: [ir.attachment,3|My Label],
|
||||
* for internal links
|
||||
* 1. '(void)'
|
||||
* 2. 'ir'
|
||||
* 3. 'attachment'
|
||||
* 4. '3'
|
||||
* 5. 'My Label'
|
||||
*/
|
||||
|
||||
mail.ChatterUtils = {
|
||||
|
||||
/** get an image in /web/binary/image?... */
|
||||
get_image: function(session_prefix, session_id, model, field, id) {
|
||||
return session_prefix + '/web/binary/image?session_id=' + session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
|
||||
/** Get an image in /web/binary/image?... */
|
||||
get_image: function(session, model, field, id) {
|
||||
return session.prefix + '/web/binary/image?session_id=' + session.session_id + '&model=' + model + '&field=' + field + '&id=' + (id || '');
|
||||
},
|
||||
|
||||
/** check if the current user is the message author */
|
||||
/** Get the url of an attachment {'id': id} */
|
||||
get_attachment_url: function (session, attachment) {
|
||||
return session.origin + '/web/binary/saveas?session_id=' + session.session_id + '&model=ir.attachment&field=datas&filename_field=datas_fname&id=' + attachment['id'];
|
||||
},
|
||||
|
||||
/** Check if the current user is the message author */
|
||||
is_author: function (widget, message_user_id) {
|
||||
return (widget.session && widget.session.uid != 0 && widget.session.uid == message_user_id);
|
||||
},
|
||||
|
@ -111,21 +102,19 @@ openerp.mail = function(session) {
|
|||
init: function (parent, options) {
|
||||
var self = this;
|
||||
this._super(parent);
|
||||
this.attachment_ids = [];
|
||||
// options
|
||||
this.options = options || {};
|
||||
this.options.context = options.context || {};
|
||||
this.options.form_xml_id = options.form_xml_id || 'email_compose_message_wizard_form_chatter';
|
||||
this.options.form_view_id = options.form_view_id || false;
|
||||
// debug
|
||||
// console.groupCollapsed('New ComposeMessage: model', this.options.context.default_res_model, ', id', this.options.context.default_res_id);
|
||||
// console.log('context:', this.options.context);
|
||||
// console.groupEnd();
|
||||
this.show_attachment_delete = true;
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this._super.apply(this, arguments);
|
||||
// customize display: add avatar, clean previous content
|
||||
var user_avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'image_small', this.session.uid);
|
||||
var user_avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid);
|
||||
this.$el.find('img.oe_mail_icon').attr('src', user_avatar);
|
||||
this.$el.find('div.oe_mail_msg_content').empty();
|
||||
// create a context for the dataset and default_get of the wizard
|
||||
|
@ -156,10 +145,52 @@ openerp.mail = function(session) {
|
|||
});
|
||||
// add the form, bind events, activate the form
|
||||
var msg_node = this.$el.find('div.oe_mail_msg_content');
|
||||
return $.when(this.form_view.appendTo(msg_node)).pipe(function() {
|
||||
self.bind_events();
|
||||
self.form_view.do_show();
|
||||
});
|
||||
return $.when(this.form_view.appendTo(msg_node)).pipe(this.proxy('postprocess_create_form_view'));
|
||||
},
|
||||
|
||||
postprocess_create_form_view: function () {
|
||||
// handle attachment button
|
||||
this.fileupload_id = _.uniqueId('oe_fileupload');
|
||||
var button_attach = this.$el.find('button.oe_mail_compose_message_attachment');
|
||||
var rendered = session.web.qweb.render('mail.compose_message.add_attachment', {'widget': this});
|
||||
$(rendered).insertBefore(button_attach);
|
||||
// move the button inside div.oe_hidden_input_file
|
||||
var input_node = this.$el.find('input[name=ufile]');
|
||||
button_attach.detach().insertAfter(input_node);
|
||||
// set the function called when attachments are added
|
||||
this.$el.find('input.oe_form_binary_file').change(this.on_attachment_change);
|
||||
this.bind_events();
|
||||
this.form_view.do_show();
|
||||
},
|
||||
|
||||
on_attachment_change: function (event) {
|
||||
var $target = $(event.target);
|
||||
if ($target.val() !== '') {
|
||||
this.$el.find('form.oe_form_binary_form').submit();
|
||||
session.web.blockUI();
|
||||
}
|
||||
},
|
||||
|
||||
on_attachment_delete: function (event) {
|
||||
if (event.target.dataset && event.target.dataset.id) {
|
||||
var attachment_id = parseInt(event.target.dataset.id);
|
||||
var idx = _.pluck(this.attachment_ids, 'id').indexOf(attachment_id);
|
||||
if (idx == -1) return false;
|
||||
new session.web.DataSetSearch(this, 'ir.attachment').unlink(attachment_id);
|
||||
this.attachment_ids.splice(idx, 1);
|
||||
this.display_attachments();
|
||||
}
|
||||
},
|
||||
|
||||
display_attachments: function () {
|
||||
var attach_node = this.$el.find('div.oe_mail_compose_message_attachments');
|
||||
var rendered = session.web.qweb.render('mail.thread.message.attachments', {'record': this});
|
||||
attach_node.empty();
|
||||
$(rendered).appendTo(attach_node);
|
||||
this.$el.find('.oe_mail_msg_attachments').show();
|
||||
var composer_attachment_ids = _.pluck(this.attachment_ids, 'id');
|
||||
var onchange_like = {'value': {'attachment_ids': composer_attachment_ids}}
|
||||
this.form_view.on_processed_onchange(onchange_like, []);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -170,13 +201,18 @@ openerp.mail = function(session) {
|
|||
refresh: function (new_context) {
|
||||
if (! this.form_view) return;
|
||||
var self = this;
|
||||
this.attachments = [];
|
||||
this.options.context = _.extend(this.options.context, new_context || {});
|
||||
this.ds_compose.context = _.extend(this.ds_compose.context, this.options.context);
|
||||
return this.ds_compose.call('default_get', [
|
||||
['subject', 'body_text', 'body', 'attachment_ids', 'partner_ids', 'composition_mode',
|
||||
'model', 'res_id', 'parent_id', 'content_subtype'],
|
||||
['subject', 'body_text', 'body', 'partner_ids', 'composition_mode',
|
||||
'use_template', 'template_id', 'model', 'res_id', 'parent_id', 'content_subtype'],
|
||||
this.ds_compose.get_context(),
|
||||
]).then( function (result) { self.form_view.on_processed_onchange({'value': result}, []); });
|
||||
]).then( function (result) {
|
||||
self.form_view.on_processed_onchange({'value': result}, []);
|
||||
self.attachment_ids = [];
|
||||
self.display_attachments();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -184,11 +220,17 @@ openerp.mail = function(session) {
|
|||
* in the function. */
|
||||
bind_events: function() {
|
||||
var self = this;
|
||||
// event: click on 'Attachment' icon-link that opens the dialog to
|
||||
// add an attachment.
|
||||
this.$el.on('click', 'button.oe_mail_compose_message_attachment', function (event) {
|
||||
event.stopImmediatePropagation();
|
||||
// event: add a new attachment
|
||||
$(window).on(this.fileupload_id, function() {
|
||||
var args = [].slice.call(arguments).slice(1);
|
||||
var attachment = args[0];
|
||||
attachment['url'] = mail.ChatterUtils.get_attachment_url(self.session, attachment);
|
||||
self.attachment_ids.push(attachment);
|
||||
self.display_attachments();
|
||||
session.web.unblockUI();
|
||||
});
|
||||
// event: delete an attachment
|
||||
this.$el.on('click', '.oe_mail_attachment_delete', self.on_attachment_delete);
|
||||
},
|
||||
}),
|
||||
|
||||
|
@ -210,47 +252,48 @@ openerp.mail = function(session) {
|
|||
|
||||
/**
|
||||
* @param {Object} parent parent
|
||||
* @param {Object} [options]
|
||||
* @param {Object} [options.context] context of the thread. It should
|
||||
* @param {Array} [domain]
|
||||
* @param {Object} [context] context of the thread. It should
|
||||
contain at least default_model, default_res_id. Please refer to
|
||||
the ComposeMessage widget for more information about it.
|
||||
* @param {Number} [options.thread_level=0] number of thread levels
|
||||
* @param {Object} [options]
|
||||
* @param {Number} [options.message_ids=null] ids for message_fetch
|
||||
* @param {Number} [options.message_data=null] already formatted message
|
||||
data, for subthreads getting data from their parent
|
||||
* @param {Boolean} [options.composer] use the advanced composer, or
|
||||
* @param {Number} [options.thread_level=0] number of thread levels
|
||||
* @param {Boolean} [options.use_composer] use the advanced composer, or
|
||||
the default basic textarea if not set
|
||||
* @param {Number} [options.truncate_limit=250] number of character to
|
||||
* display before having a "show more" link; note that the text
|
||||
* will not be truncated if it does not have 110% of the parameter
|
||||
*/
|
||||
init: function(parent, options) {
|
||||
init: function(parent, domain, context, options) {
|
||||
this._super(parent);
|
||||
// options
|
||||
this.options = options || {};
|
||||
this.options.domain = options.domain || [];
|
||||
this.options.context = _.extend({
|
||||
this.domain = domain || [];
|
||||
this.context = _.extend({
|
||||
default_model: 'mail.thread',
|
||||
default_res_id: 0,
|
||||
default_parent_id: false }, options.context || {});
|
||||
this.options.thread_level = options.thread_level || 0;
|
||||
this.options.composer = options.composer || false;
|
||||
this.options.message_ids = options.message_ids || null;
|
||||
this.options.message_data = options.message_data || null;
|
||||
default_parent_id: false }, context || {});
|
||||
// options
|
||||
this.options = {
|
||||
message_ids: options.message_ids || null,
|
||||
message_data: options.message_data || null,
|
||||
thread_level: options.thread_level || 0,
|
||||
use_composer: options.use_composer || false,
|
||||
show_header_compose: options.show_header_compose != undefined ? options.show_header_compose: true,
|
||||
show_record_name: options.show_record_name != undefined ? options.show_record_name: true,
|
||||
show_reply: options.show_reply || false,
|
||||
show_reply_by_email: options.show_reply_by_email || false,
|
||||
show_dd_reply_by_email:options.show_dd_reply_by_email != undefined ? options.show_dd_reply_by_email: true,
|
||||
show_dd_delete: options.show_dd_delete || false,
|
||||
show_dd_hide: options.show_dd_hide || false,
|
||||
show_more: options.show_more || false,
|
||||
truncate_limit: options.truncate_limit || 250,
|
||||
}
|
||||
// datasets and internal vars
|
||||
this.ds_thread = new session.web.DataSetSearch(this, this.options.context.default_model);
|
||||
this.ds_thread = new session.web.DataSetSearch(this, this.context.default_model);
|
||||
this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification');
|
||||
this.ds_message = new session.web.DataSetSearch(this, 'mail.message');
|
||||
// display customization vars
|
||||
this.display = {
|
||||
truncate_limit: options.truncate_limit || 250,
|
||||
show_header_compose: options.show_header_compose || false,
|
||||
show_reply: options.show_reply || false,
|
||||
show_delete: options.show_delete || false,
|
||||
show_hide: options.show_hide || false,
|
||||
show_reply_by_email: options.show_reply_by_email || false,
|
||||
show_more: options.show_more || false,
|
||||
}
|
||||
},
|
||||
|
||||
start: function() {
|
||||
|
@ -260,7 +303,7 @@ openerp.mail = function(session) {
|
|||
// fetch and display message, using message_ids if set
|
||||
var display_done = $.when(this.message_fetch(true, [], {})).then(this.proxy('do_customize_display'));
|
||||
// add message composition form view
|
||||
if (this.display.show_header_compose && this.options.composer) {
|
||||
if (this.options.show_header_compose && this.options.use_composer) {
|
||||
var compose_done = this.instantiate_composition_form();
|
||||
}
|
||||
return display_done && compose_done;
|
||||
|
@ -270,7 +313,9 @@ openerp.mail = function(session) {
|
|||
* - show_header_compose: show the composition form in the header */
|
||||
do_customize_display: function() {
|
||||
this.display_user_avatar();
|
||||
if (this.display.show_header_compose) { this.$el.find('div.oe_mail_thread_action').eq(0).show(); }
|
||||
if (this.options.show_header_compose) {
|
||||
this.$el.find('div.oe_mail_thread_action').eq(0).show();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -278,10 +323,8 @@ openerp.mail = function(session) {
|
|||
* in the function. */
|
||||
bind_events: function() {
|
||||
var self = this;
|
||||
// event: click on 'more' at bottom of thread
|
||||
this.$el.find('button.oe_mail_button_more').click(function () {
|
||||
self.do_message_fetch();
|
||||
});
|
||||
// event: click on 'More' at bottom of thread
|
||||
this.$el.on('click', 'button.oe_mail_button_more', this.do_message_fetch_more);
|
||||
// event: writing in basic textarea of composition form (quick reply)
|
||||
this.$el.find('textarea.oe_mail_compose_textarea').keyup(function (event) {
|
||||
var charCode = (event.which) ? event.which : window.event.keyCode;
|
||||
|
@ -290,41 +333,21 @@ openerp.mail = function(session) {
|
|||
});
|
||||
// event: click on 'Reply' in msg
|
||||
this.$el.on('click', 'a.oe_mail_msg_reply', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var act_dom = $(this).parents('li.oe_mail_thread_msg').eq(0).find('div.oe_mail_thread_action:first');
|
||||
act_dom.toggle();
|
||||
});
|
||||
// event: click on 'attachment(s)' in msg
|
||||
// event: click on 'Attachment(s)' in msg
|
||||
this.$el.on('click', 'a.oe_mail_msg_view_attachments', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var act_dom = $(this).parent().parent().parent().find('.oe_mail_msg_attachments');
|
||||
act_dom.toggle();
|
||||
});
|
||||
// event: click on 'Delete' in msg side menu
|
||||
this.$el.on('click', 'a.oe_mail_msg_delete', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (! confirm(_t("Do you really want to delete this message?"))) { return false; }
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).remove();
|
||||
return self.ds_msg.unlink([parseInt(msg_id)]);
|
||||
});
|
||||
this.$el.on('click', 'a.oe_mail_msg_delete', this.on_message_delete);
|
||||
// event: click on 'Hide' in msg side menu
|
||||
this.$el.on('click', 'a.oe_mail_msg_hide', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).remove();
|
||||
return self.ds_notif.call('set_message_read', [parseInt(msg_id)]);
|
||||
});
|
||||
// event: click on "Reply by email" in msg side menu (email style)
|
||||
this.$el.on('click', 'a.oe_mail_msg_hide', this.on_message_read);
|
||||
// event: click on 'Reply by email' in msg side menu
|
||||
this.$el.on('click', 'a.oe_mail_msg_reply_by_email', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (! self.compose_message_widget) return true;
|
||||
var msg_id = event.srcElement.dataset.msg_id;
|
||||
if (! msg_id) return false;
|
||||
self.compose_message_widget.refresh({
|
||||
|
@ -334,20 +357,37 @@ openerp.mail = function(session) {
|
|||
});
|
||||
},
|
||||
|
||||
on_message_delete: function (event) {
|
||||
if (! confirm(_t("Do you really want to delete this message?"))) { return false; }
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).remove();
|
||||
return this.ds_message.unlink([parseInt(msg_id)]);
|
||||
},
|
||||
|
||||
on_message_read: function (event) {
|
||||
//TDE: TODO
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).remove();
|
||||
return this.ds_notification.call('set_message_read', [parseInt(msg_id)]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Override-hack of do_action: automatically reload the chatter.
|
||||
* Normally it should be called only when clicking on 'Post/Send'
|
||||
* in the composition form. */
|
||||
do_action: function(action, on_close) {
|
||||
//TDE: TODO: instead of reloading, push the message ?
|
||||
this.message_clean();
|
||||
this.message_fetch();
|
||||
if (this.compose_message_widget) {
|
||||
this.compose_message_widget.refresh({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_parent_id': this.options.default_parent_id,
|
||||
'default_parent_id': this.context.default_parent_id,
|
||||
'default_content_subtype': 'plain'} );
|
||||
}
|
||||
return this._super(action, on_close);
|
||||
// return this._super(action, on_close);
|
||||
},
|
||||
|
||||
/** Instantiate the composition form, with every parameters in context
|
||||
|
@ -357,7 +397,7 @@ openerp.mail = function(session) {
|
|||
this.compose_message_widget.destroy();
|
||||
}
|
||||
this.compose_message_widget = new mail.ComposeMessage(this, {
|
||||
'context': _.extend(context || {}, this.options.context),
|
||||
'context': _.extend(context || {}, this.context),
|
||||
});
|
||||
var composition_node = this.$el.find('div.oe_mail_thread_action');
|
||||
composition_node.empty();
|
||||
|
@ -365,6 +405,11 @@ openerp.mail = function(session) {
|
|||
return compose_done;
|
||||
},
|
||||
|
||||
refresh_composition_form: function (context) {
|
||||
if (! this.compose_message_widget) return;
|
||||
return this.compose_message_widget.refresh(context);
|
||||
},
|
||||
|
||||
/** Clean the thread */
|
||||
message_clean: function() {
|
||||
this.$el.find('div.oe_mail_thread_display').empty();
|
||||
|
@ -374,20 +419,20 @@ openerp.mail = function(session) {
|
|||
* @param {Bool} initial_mode: initial mode: try to use message_data or
|
||||
* message_ids, if nothing available perform a message_read; otherwise
|
||||
* directly perform a message_read
|
||||
* @param {Array} additional_domain: added to options.domain
|
||||
* @param {Object} additional_context: added to options.context
|
||||
* @param {Array} additional_domain: added to this.domain
|
||||
* @param {Object} additional_context: added to this.context
|
||||
*/
|
||||
message_fetch: function (initial_mode, additional_domain, additional_context) {
|
||||
var self = this;
|
||||
// domain and context: options + additional
|
||||
fetch_domain = _.flatten([this.options.domain, additional_domain || []], true)
|
||||
fetch_context = _.extend(this.options.context, additional_context || {})
|
||||
// if message_ids is set: try to use it
|
||||
fetch_domain = _.flatten([this.domain, additional_domain || []], true)
|
||||
fetch_context = _.extend(this.context, additional_context || {})
|
||||
// initial mode: try to use message_data or message_ids
|
||||
if (initial_mode && this.options.message_data) {
|
||||
return this.message_display(this.options.message_data);
|
||||
}
|
||||
return this.ds_message.call('message_read',
|
||||
[(initial_mode && this.options.message_ids) || false, fetch_domain, this.options.thread_level, undefined, fetch_context]
|
||||
message_ids = initial_mode && this.options.message_ids != null && this.options.message_ids || false;
|
||||
return this.ds_message.call('message_read', [message_ids, fetch_domain, this.options.thread_level, undefined, fetch_context]
|
||||
).then(this.proxy('message_display'));
|
||||
},
|
||||
|
||||
|
@ -407,19 +452,19 @@ openerp.mail = function(session) {
|
|||
}
|
||||
else {
|
||||
self.display_record(record);
|
||||
// if (self.options.thread_level >= 0) {
|
||||
self.thread = new mail.Thread(self, {
|
||||
'context': {
|
||||
'default_model': record.model,
|
||||
self.thread = new mail.Thread(self, self.domain,
|
||||
{ 'default_model': record.model,
|
||||
'default_res_id': record.res_id,
|
||||
'default_parent_id': record.id },
|
||||
'message_data': record.child_ids, 'thread_level': self.options.thread_level-1,
|
||||
'show_header_compose': false, 'show_reply': self.options.thread_level > 1,
|
||||
'show_hide': self.display.show_hide, 'show_delete': self.display.show_delete,
|
||||
});
|
||||
{ 'message_data': record.child_ids,
|
||||
'thread_level': self.options.thread_level - 1,
|
||||
'show_header_compose': false,
|
||||
'show_reply': self.options.show_reply && self.options.thread_level > 1,
|
||||
'show_reply_by_email': self.options.show_reply_by_email,
|
||||
'show_dd_hide': self.options.show_dd_hide,
|
||||
'show_dd_delete': self.options.show_dd_delete });
|
||||
self.$el.find('li.oe_mail_thread_msg:last').append('<div class="oe_mail_thread_subthread"/>');
|
||||
self.thread.appendTo(self.$el.find('div.oe_mail_thread_subthread:last'));
|
||||
// }
|
||||
}
|
||||
});
|
||||
if (! _expendable) {
|
||||
|
@ -431,7 +476,7 @@ openerp.mail = function(session) {
|
|||
* - record.date: formatting according to the user timezone
|
||||
* - record.timerelative: relative time givein by timeago lib
|
||||
* - record.avatar: image url
|
||||
* - record.attachments[].url: url of each attachment
|
||||
* - record.attachment_ids[].url: url of each attachment
|
||||
* - record.is_author: is the current user the author of the record */
|
||||
display_record: function (record) {
|
||||
// formatting and additional fields
|
||||
|
@ -440,21 +485,18 @@ openerp.mail = function(session) {
|
|||
if (record.type == 'email') {
|
||||
record.avatar = ('/mail/static/src/img/email_icon.png');
|
||||
} else {
|
||||
record.avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.partner', 'image_small', record.author_id[0]);
|
||||
record.avatar = mail.ChatterUtils.get_image(this.session, 'res.partner', 'image_small', record.author_id[0]);
|
||||
}
|
||||
//TDE: FIX
|
||||
if (record.attachments) {
|
||||
for (var l in record.attachments) {
|
||||
var url = self.session.origin + '/web/binary/saveas?session_id=' + self.session.session_id + '&model=ir.attachment&field=datas&filename_field=datas_fname&id='+records[k].attachments[l].id;
|
||||
record.attachments[l].url = url;
|
||||
}
|
||||
for (var l in record.attachment_ids) {
|
||||
var attach = record.attachment_ids[l];
|
||||
attach['url'] = mail.ChatterUtils.get_attachment_url(this.session, attach);
|
||||
}
|
||||
record.is_author = mail.ChatterUtils.is_author(this, record.author_user_id[0]);
|
||||
// render, add the expand feature
|
||||
var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'params': this.options, 'display': this.display});
|
||||
var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'options': this.options});
|
||||
$(rendered).appendTo(this.$el.children('div.oe_mail_thread_display:first'));
|
||||
this.$el.find('div.oe_mail_msg_record_body').expander({
|
||||
slicePoint: this.options.msg_more_limit,
|
||||
this.$el.find('div.oe_mail_msg_body').expander({
|
||||
slicePoint: this.options.truncate_limit,
|
||||
expandText: 'read more',
|
||||
userCollapseText: '[^]',
|
||||
detailClass: 'oe_mail_msg_tail',
|
||||
|
@ -473,7 +515,7 @@ openerp.mail = function(session) {
|
|||
},
|
||||
|
||||
display_user_avatar: function () {
|
||||
var avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'image_small', this.session.uid);
|
||||
var avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid);
|
||||
return this.$el.find('img.oe_mail_icon').attr('src', avatar);
|
||||
},
|
||||
|
||||
|
@ -485,12 +527,12 @@ openerp.mail = function(session) {
|
|||
comment_node.val('');
|
||||
}
|
||||
return this.ds_thread.call('message_post', [
|
||||
[this.options.context.default_res_id], body, false, 'comment', this.options.context.default_parent_id, undefined]
|
||||
[this.context.default_res_id], body, false, 'comment', this.context.default_parent_id, undefined]
|
||||
).then(self.message_fetch());
|
||||
},
|
||||
|
||||
/** Action: 'shows more' to fetch new messages */
|
||||
do_message_fetch: function () {
|
||||
do_message_fetch_more: function () {
|
||||
return this.message_fetch(false, this.fetch_more_domain, this.fetch_more_context);
|
||||
},
|
||||
|
||||
|
@ -533,13 +575,11 @@ openerp.mail = function(session) {
|
|||
* mail_thread Widget
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* This widget handles the display of the Chatter on documents.
|
||||
* This widget handles the display of messages on a document. Its main
|
||||
* use is to receive a context and a domain, and to delegate the message
|
||||
* fetching and displaying to the Thread widget.
|
||||
*/
|
||||
|
||||
/* Add mail_thread widget to registry */
|
||||
session.web.form.widgets.add('mail_thread', 'openerp.mail.RecordThread');
|
||||
|
||||
/** mail_thread widget: thread of comments */
|
||||
mail.RecordThread = session.web.form.AbstractField.extend({
|
||||
template: 'mail.record_thread',
|
||||
|
||||
|
@ -548,13 +588,11 @@ openerp.mail = function(session) {
|
|||
this.options.domain = this.options.domain || [];
|
||||
this.options.context = {'default_model': 'mail.thread', 'default_res_id': false};
|
||||
this.options.thread_level = this.options.thread_level || 0;
|
||||
this.thread_list = [];
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
// NB: all the widget should be modified to check the actual_mode property on view, not use
|
||||
// any other method to know if the view is in create mode anymore
|
||||
// NB: check the actual_mode property on view to know if the view is in create mode anymore
|
||||
this.view.on("change:actual_mode", this, this._check_visibility);
|
||||
this._check_visibility();
|
||||
},
|
||||
|
@ -563,11 +601,6 @@ openerp.mail = function(session) {
|
|||
this.$el.toggle(this.view.get("actual_mode") !== "create");
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
for (var i in this.thread_list) { this.thread_list[i].destroy(); }
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
set_value: function() {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -579,15 +612,15 @@ openerp.mail = function(session) {
|
|||
_.extend(this.options.context, {
|
||||
default_res_id: this.view.datarecord.id,
|
||||
default_model: this.view.model });
|
||||
// update domain
|
||||
var domain = this.options.domain.concat([['model', '=', this.view.model], ['res_id', '=', this.view.datarecord.id]]);
|
||||
// create and render Thread widget
|
||||
this.$el.find('div.oe_mail_recthread_main').empty();
|
||||
for (var i in this.thread_list) { this.thread_list[i].destroy(); }
|
||||
var thread = new mail.Thread(self, {
|
||||
'context': this.options.context,
|
||||
'thread_level': this.options.thread_level, 'show_header_compose': true,
|
||||
'message_ids': this.get_value(),
|
||||
'show_delete': true, 'composer': true });
|
||||
this.thread_list.push(thread);
|
||||
var thread = new mail.Thread(self, domain, this.options.context,
|
||||
{ 'thread_level': this.options.thread_level,
|
||||
'use_composer': true,
|
||||
'show_dd_delete': true,
|
||||
'show_reply_by_email': true });
|
||||
return thread.appendTo(this.$el.find('div.oe_mail_recthread_main'));
|
||||
},
|
||||
});
|
||||
|
@ -598,22 +631,22 @@ openerp.mail = function(session) {
|
|||
* Wall Widget
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* This widget handles the display of the Chatter on the Wall.
|
||||
* This widget handles the display of messages on a Wall. Its main
|
||||
* use is to receive a context and a domain, and to delegate the message
|
||||
* fetching and displaying to the Thread widget.
|
||||
*/
|
||||
|
||||
/* Add WallView widget to registry */
|
||||
session.web.client_actions.add('mail.wall', 'session.mail.Wall');
|
||||
|
||||
/* WallView widget: a wall of messages */
|
||||
mail.Wall = session.web.Widget.extend({
|
||||
template: 'mail.wall',
|
||||
|
||||
/**
|
||||
* @param {Object} parent parent
|
||||
* @param {Object} [options]
|
||||
* @param {Number} [options.domain] domain on the Wall, is an array.
|
||||
* @param {Number} [options.domain] context, is an object. It should
|
||||
* @param {Array} [options.domain] domain on the Wall
|
||||
* @param {Object} [options.context] context, is an object. It should
|
||||
* contain default_model, default_res_id, to give it to the threads.
|
||||
* @param {Number} [options.thread_level] number of thread levels to display
|
||||
* 0 being flat.
|
||||
*/
|
||||
init: function (parent, options) {
|
||||
this._super(parent);
|
||||
|
@ -621,23 +654,15 @@ openerp.mail = function(session) {
|
|||
this.options.domain = options.domain || [];
|
||||
this.options.context = options.context || {};
|
||||
this.options.thread_level = options.thread_level || 1;
|
||||
this.thread_list = [];
|
||||
this.ds_msg = new session.web.DataSetSearch(this, 'mail.message');
|
||||
// for search view
|
||||
this.search = {'domain': [], 'context': {}, 'groupby': {}}
|
||||
this.search_results = {'domain': [], 'context': {}, 'groupby': {}}
|
||||
this.ds_msg = new session.web.DataSetSearch(this, 'mail.message');
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this._super.apply(this, arguments);
|
||||
var search_view_ready = this.load_search_view({}, false);
|
||||
var thread_displayed = this.message_display();
|
||||
return (search_view_ready && thread_displayed);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
for (var i in this.thread_list) { this.thread_list[i].destroy(); }
|
||||
this._super.apply(this, arguments);
|
||||
var searchview_ready = this.load_searchview({}, false);
|
||||
var thread_displayed = this.message_render();
|
||||
return (searchview_ready && thread_displayed);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -645,7 +670,7 @@ openerp.mail = function(session) {
|
|||
* @param {Object} defaults ??
|
||||
* @param {Boolean} hidden some kind of trick we do not care here
|
||||
*/
|
||||
load_search_view: function (defaults, hidden) {
|
||||
load_searchview: function (defaults, hidden) {
|
||||
var self = this;
|
||||
this.searchview = new session.web.SearchView(this, this.ds_msg, false, defaults || {}, hidden || false);
|
||||
return this.searchview.appendTo(this.$el.find('.oe_view_manager_view_search')).then(function () {
|
||||
|
@ -654,9 +679,8 @@ openerp.mail = function(session) {
|
|||
},
|
||||
|
||||
/**
|
||||
* Aggregate the domains, contexts and groupbys in parameter
|
||||
* with those from search form, and then calls fetch_comments
|
||||
* to actually fetch comments
|
||||
* Get the domains, contexts and groupbys in parameter from search
|
||||
* view, then render the filtered threads.
|
||||
* @param {Array} domains
|
||||
* @param {Array} contexts
|
||||
* @param {Array} groupbys
|
||||
|
@ -671,30 +695,24 @@ openerp.mail = function(session) {
|
|||
self.search_results['context'] = results.context;
|
||||
self.search_results['domain'] = results.domain;
|
||||
self.search_results['groupby'] = results.group_by;
|
||||
self.message_clean();
|
||||
return self.message_display();
|
||||
return self.message_render();
|
||||
});
|
||||
},
|
||||
|
||||
/** Clean the wall */
|
||||
message_clean: function() {
|
||||
/** Clean and display the threads */
|
||||
message_render: function () {
|
||||
this.$el.find('ul.oe_mail_wall_threads').empty();
|
||||
},
|
||||
|
||||
/** Display the Wall threads */
|
||||
message_display: function () {
|
||||
var domain = this.options.domain.concat(this.search_results['domain']);
|
||||
var render_res = session.web.qweb.render('mail.wall_thread_container', {});
|
||||
$('<li class="oe_mail_wall_thread">').html(render_res).appendTo(this.$el.find('ul.oe_mail_wall_threads'));
|
||||
var thread = new mail.Thread(this, {
|
||||
'domain': this.options.domain, 'context': this.options.context,
|
||||
'thread_level': this.options.thread_level, 'composer': true,
|
||||
// display options
|
||||
'show_header_compose': true, 'show_reply': this.options.thread_level > 0,
|
||||
'show_hide': true, 'show_reply_by_email': true,
|
||||
$(render_res).appendTo(this.$el.find('ul.oe_mail_wall_threads'));
|
||||
var thread = new mail.Thread(this, domain, this.options.context,
|
||||
{ 'thread_level': this.options.thread_level,
|
||||
'use_composer': true,
|
||||
'show_reply': this.options.thread_level > 0,
|
||||
'show_dd_hide': true,
|
||||
}
|
||||
);
|
||||
thread.appendTo(this.$el.find('li.oe_mail_wall_thread:last'));
|
||||
this.thread_list.push(thread);
|
||||
return thread.appendTo(this.$el.find('li.oe_mail_wall_thread:last'));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -31,33 +31,52 @@ openerp_mail_followers = function(session, mail) {
|
|||
},
|
||||
|
||||
start: function() {
|
||||
var self = this;
|
||||
// NB: all the widget should be modified to check the actual_mode property on view, not use
|
||||
// any other method to know if the view is in create mode anymore
|
||||
// use actual_mode property on view to know if the view is in create mode anymore
|
||||
this.view.on("change:actual_mode", this, this._check_visibility);
|
||||
this._check_visibility();
|
||||
this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); })
|
||||
.mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
|
||||
.mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
|
||||
this.$el.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); })
|
||||
.mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
|
||||
.mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
|
||||
this.reinit();
|
||||
this.bind_events();
|
||||
},
|
||||
|
||||
_check_visibility: function() {
|
||||
this.$el.toggle(this.view.get("actual_mode") !== "create");
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
reinit: function() {
|
||||
this.$el.find('button.oe_mail_button_follow').hide();
|
||||
this.$el.find('button.oe_mail_button_unfollow').hide();
|
||||
},
|
||||
|
||||
bind_events: function() {
|
||||
var self = this;
|
||||
this.$('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); })
|
||||
.mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
|
||||
.mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
|
||||
this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); });
|
||||
this.$el.on('click', 'button.oe_mail_button_invite', function(event) {
|
||||
action = {
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'mail.wizard.invite',
|
||||
view_mode: 'form',
|
||||
view_type: 'form',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: {
|
||||
'default_res_model': self.view.dataset.model,
|
||||
'default_res_id': self.view.datarecord.id
|
||||
},
|
||||
}
|
||||
self.do_action(action, function() { self.read_value(); });
|
||||
});
|
||||
},
|
||||
|
||||
read_value: function() {
|
||||
var self = this;
|
||||
return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).pipe(function (results) {
|
||||
return results[0].message_follower_ids;
|
||||
}).pipe(this.proxy('set_value'));
|
||||
},
|
||||
|
||||
set_value: function(value_) {
|
||||
this.reinit();
|
||||
if (! this.view.datarecord.id ||
|
||||
|
@ -65,11 +84,11 @@ openerp_mail_followers = function(session, mail) {
|
|||
this.$el.find('div.oe_mail_recthread_aside').hide();
|
||||
return;
|
||||
}
|
||||
return this.fetch_followers(value_);
|
||||
return this.fetch_followers(value_ || this.get_value());
|
||||
},
|
||||
|
||||
fetch_followers: function (value_) {
|
||||
return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers'));
|
||||
return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers'));
|
||||
},
|
||||
|
||||
/** Display the followers, evaluate is_follower directly */
|
||||
|
@ -79,7 +98,7 @@ openerp_mail_followers = function(session, mail) {
|
|||
var node_user_list = this.$el.find('ul.oe_mail_followers_display').empty();
|
||||
this.$el.find('div.oe_mail_recthread_followers h4').html(this.options.title + ' (' + records.length + ')');
|
||||
_(records).each(function (record) {
|
||||
record.avatar_url = mail.ChatterUtils.get_image(self.session.prefix, self.session.session_id, 'res.partner', 'image_small', record.id);
|
||||
record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id);
|
||||
$(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list);
|
||||
});
|
||||
if (this.message_is_follower) {
|
||||
|
@ -91,13 +110,13 @@ openerp_mail_followers = function(session, mail) {
|
|||
},
|
||||
|
||||
do_follow: function () {
|
||||
var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
|
||||
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
|
||||
var context = new session.web.CompoundContext(this.build_context(), {});
|
||||
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value'));
|
||||
},
|
||||
|
||||
do_unfollow: function () {
|
||||
var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
|
||||
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
|
||||
var context = new session.web.CompoundContext(this.build_context(), {});
|
||||
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value'));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
wall_thread_container template for the wall
|
||||
Each discussion thread is contained inside this template
|
||||
-->
|
||||
<t t-name="mail.wall_thread_container">
|
||||
</t>
|
||||
<li t-name="mail.wall_thread_container" class="oe_mail_wall_thread">
|
||||
</li>
|
||||
|
||||
<!--
|
||||
record_thread main template
|
||||
|
@ -73,6 +73,20 @@
|
|||
</div>
|
||||
</t>
|
||||
|
||||
<!--
|
||||
mail.compose_message.add_attachment template
|
||||
Small template to be inserted in the composition form to add attachments
|
||||
-->
|
||||
<t t-name="mail.compose_message.add_attachment">
|
||||
<t t-call="HiddenInputFile">
|
||||
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
|
||||
<t t-set="fileupload_action">/web/binary/upload_attachment</t>
|
||||
<input type="hidden" name="model" t-att-value="widget.form_view.model"/>
|
||||
<input type="hidden" name="id" t-att-value="widget.form_view.datarecord.id || 0"/>
|
||||
<input type="hidden" name="session_id" t-att-value="widget.session.session_id"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<!--
|
||||
thread template
|
||||
This template holds a thread of comments. It begins with an actions
|
||||
|
@ -100,16 +114,14 @@
|
|||
<!-- dropdown menu with message options and actions -->
|
||||
<span class="oe_dropdown_toggle oe_dropdown_arrow">
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="record.is_author">
|
||||
<li t-if="display['show_delete']"><a href="#" class="oe_mail_msg_delete" t-attf-data-id='{record.id}'>Delete</a></li>
|
||||
</t>
|
||||
<li t-if="display['show_hide']"><a href="#" class="oe_mail_msg_hide" t-attf-data-id='{record.id}'>Remove notification</a></li>
|
||||
<li t-if="record.is_author and options.show_dd_delete"><a class="oe_mail_msg_delete" t-attf-data-id='{record.id}'>Delete</a></li>
|
||||
<li t-if="options.show_dd_hide"><a class="oe_mail_msg_hide" t-attf-data-id='{record.id}'>Remove notification</a></li>
|
||||
<!-- Uncomment when adding subtype hiding
|
||||
<li t-if="display['show_hide']">
|
||||
<a href="#" class="oe_mail_msg_hide_type" t-attf-data-subtype='{record.subtype}'>Hide '<t t-esc="record.subtype"/>' for this document</a>
|
||||
</li> -->
|
||||
<li><a href="#" t-attf-data-msg_id="{record.id}" class="oe_mail_msg_reply_by_email">Quote and reply</a></li>
|
||||
<li t-if="record.type == 'email'"><a t-attf-href="#model=mail.message&id=#{record.id}" class="oe_mail_msg_details">Details</a></li>
|
||||
<li t-if="options.show_dd_reply_by_email"><a class="oe_mail_msg_reply_by_email" t-attf-data-msg_id="{record.id}">Quote and reply</a></li>
|
||||
<li t-if="record.type == 'email'"><a class="oe_mail_msg_details" t-attf-href="#model=mail.message&id=#{record.id}" >Details</a></li>
|
||||
</ul>
|
||||
</span>
|
||||
<!-- message itself -->
|
||||
|
@ -118,38 +130,54 @@
|
|||
<t t-raw="record.subject"/>
|
||||
</h1>
|
||||
<div class="oe_mail_msg_body">
|
||||
<div class="oe_mail_msg_record_body">
|
||||
<a t-attf-href="#model=#{record.model}&id=#{record.res_id}" t-if="(params.thread_level > 0) & (!record.subject)"><t t-raw="record.record_name"/></a>
|
||||
<t t-raw="record.body"/>
|
||||
</div>
|
||||
<t t-if="options.show_record_name and record.record_name and (!record.subject) and (options.thread_level > 0)">
|
||||
<a t-attf-href="#model=#{record.model}&id=#{record.res_id}"><t t-raw="record.record_name"/></a>
|
||||
</t>
|
||||
<t t-raw="record.body"/>
|
||||
</div>
|
||||
<div class="oe_clear"/>
|
||||
<ul class="oe_mail_msg_footer">
|
||||
<li t-if="record.subject & params.thread_level > 0"><a t-attf-href="#model=#{record.model}&id=#{record.res_id}"><t t-raw="record.record_name"/></a></li>
|
||||
<li><a t-attf-href="#model=res.partner&id=#{record.author_id[0]}"><t t-raw="record.author_id[1]"/></a></li>
|
||||
<li><span t-att-title="record.date"><t t-raw="record.timerelative"/></span></li>
|
||||
<li t-if="display['show_reply']"><a href="#" class="oe_mail_msg_reply">Reply</a></li>
|
||||
<!-- uncomment when merging vote
|
||||
<li><a href="#">Like</a></li>
|
||||
-->
|
||||
<li t-if="record.attachment_ids.length > 0">
|
||||
<a href="#" class="oe_mail_msg_view_attachments">
|
||||
<t t-if="record.attachment_ids.length == 1">1 Attachment</t>
|
||||
<t t-if="record.attachment_ids.length > 1"><t t-raw="record.attachment_ids.length"/> Attachments</t>
|
||||
</a>
|
||||
</li>
|
||||
<li t-if="options.show_record_name and record.record_name and record.subject and options.thread_level > 0">
|
||||
<a t-attf-href="#model=#{record.model}&id=#{record.res_id}"><t t-raw="record.record_name"/></a>
|
||||
</li>
|
||||
<li><a t-attf-href="#model=res.partner&id=#{record.author_id[0]}"><t t-raw="record.author_id[1]"/></a></li>
|
||||
<li><span t-att-title="record.date"><t t-raw="record.timerelative"/></span></li>
|
||||
<li t-if="options.show_reply"><a class="oe_mail_msg_reply">Reply</a></li>
|
||||
<li t-if="options.show_reply_by_email"><a class="oe_mail_msg_reply_by_email" t-attf-data-msg_id="{record.id}">Reply</a></li>
|
||||
<!-- uncomment when merging vote
|
||||
<li><a href="#">Like</a></li>
|
||||
-->
|
||||
<li t-if="record.attachment_ids.length > 0">
|
||||
<a class="oe_mail_msg_view_attachments">
|
||||
<t t-if="record.attachment_ids.length == 1">1 Attachment</t>
|
||||
<t t-if="record.attachment_ids.length > 1"><t t-raw="record.attachment_ids.length"/> Attachments</t>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<t t-if="record.attachment_ids.length > 0">
|
||||
<div class="oe_clear"></div>
|
||||
<ul class="oe_mail_msg_attachments">
|
||||
<t t-foreach="record.attachments" t-as="attachment">
|
||||
<li> <a t-att-href="attachment.url"><t t-raw="attachment.name"/></a> </li>
|
||||
</t>
|
||||
</ul>
|
||||
<t t-call="mail.thread.message.attachments"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!--
|
||||
mail.thread.message.attachments template
|
||||
Template used to display attachments in a mail.message
|
||||
-->
|
||||
<t t-name="mail.thread.message.attachments">
|
||||
<ul class="oe_mail_msg_attachments">
|
||||
<t t-foreach="record.attachment_ids" t-as="attachment">
|
||||
<li>
|
||||
<a t-att-href="attachment.url"><t t-raw="attachment.name || attachment.filename"/></a>
|
||||
<t t-if="record.show_attachment_delete">
|
||||
<a class="oe_right oe_mail_attachment_delete" title="Delete this attachmentt" t-attf-data-id="{attachment.id}">x</a>
|
||||
</t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
</template>
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
-->
|
||||
<div t-name="mail.followers" class="oe_mail_recthread_aside oe_semantic_html_override">
|
||||
<div class="oe_mail_recthread_actions">
|
||||
<button type="button" class="oe_mail_button_follow oe_mail_button_mouseout">Not following</button>
|
||||
<button type="button" class="oe_mail_button_invite">Invite</button>
|
||||
<button type="button" class="oe_mail_button_follow">Follow</button>
|
||||
<button type="button" class="oe_mail_button_unfollow oe_mail_button_mouseout">Following</button>
|
||||
</div>
|
||||
<div class="oe_mail_recthread_followers">
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import tools
|
||||
|
||||
from openerp.tests import common
|
||||
from openerp.tools.html_sanitize import html_sanitize
|
||||
|
||||
|
@ -29,7 +31,7 @@ Received: by mail1.openerp.com (Postfix, from userid 10002)
|
|||
From: Sylvie Lelitre <sylvie.lelitre@agrolait.com>
|
||||
Subject: {subject}
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="----=_Part_4200734_24778174.1344608186754"
|
||||
Date: Fri, 10 Aug 2012 14:16:26 +0000
|
||||
Message-ID: <1198923581.41972151344608186760.JavaMail@agrolait.com>
|
||||
|
@ -52,9 +54,9 @@ Content-Transfer-Encoding: quoted-printable
|
|||
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
|
||||
</head>=20
|
||||
<body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20
|
||||
|
||||
|
||||
<p>Please call me as soon as possible this afternoon!</p>
|
||||
|
||||
|
||||
<p>--<br/>
|
||||
Sylvie
|
||||
<p>
|
||||
|
@ -82,15 +84,42 @@ Sylvie
|
|||
"""
|
||||
|
||||
|
||||
class test_mail(common.TransactionCase):
|
||||
class TestMailMockups(common.TransactionCase):
|
||||
|
||||
def _mock_smtp_gateway(self, *args, **kwargs):
|
||||
return True
|
||||
|
||||
def _init_mock_build_email(self):
|
||||
self._build_email_args_list = []
|
||||
self._build_email_kwargs_list = []
|
||||
|
||||
def _mock_build_email(self, *args, **kwargs):
|
||||
self._build_email_args = args
|
||||
self._build_email_kwargs = kwargs
|
||||
return self.build_email_real(*args, **kwargs)
|
||||
self._build_email_args_list.append(args)
|
||||
self._build_email_kwargs_list.append(kwargs)
|
||||
return self._build_email(*args, **kwargs)
|
||||
|
||||
def setUp(self):
|
||||
super(TestMailMockups, self).setUp()
|
||||
# Install mock SMTP gateway
|
||||
self._init_mock_build_email()
|
||||
self._build_email = self.registry('ir.mail_server').build_email
|
||||
self.registry('ir.mail_server').build_email = self._mock_build_email
|
||||
self._send_email = self.registry('ir.mail_server').send_email
|
||||
self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
|
||||
|
||||
def tearDown(self):
|
||||
# Remove mocks
|
||||
self.registry('ir.mail_server').build_email = self._build_email
|
||||
self.registry('ir.mail_server').send_email = self._send_email
|
||||
super(TestMailMockups, self).tearDown()
|
||||
|
||||
|
||||
class test_mail(TestMailMockups):
|
||||
|
||||
def _mock_send_get_mail_body(self, *args, **kwargs):
|
||||
# def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None)
|
||||
body = tools.append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner')
|
||||
return body
|
||||
|
||||
def setUp(self):
|
||||
super(test_mail, self).setUp()
|
||||
|
@ -105,10 +134,9 @@ class test_mail(common.TransactionCase):
|
|||
self.res_users = self.registry('res.users')
|
||||
self.res_partner = self.registry('res.partner')
|
||||
|
||||
# Install mock SMTP gateway
|
||||
self.build_email_real = self.registry('ir.mail_server').build_email
|
||||
self.registry('ir.mail_server').build_email = self._mock_build_email
|
||||
self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
|
||||
# Mock send_get_mail_body to test its functionality without other addons override
|
||||
self._send_get_mail_body = self.registry('mail.mail').send_get_mail_body
|
||||
self.registry('mail.mail').send_get_mail_body = self._mock_send_get_mail_body
|
||||
|
||||
# groups@.. will cause the creation of new mail groups
|
||||
self.mail_group_model_id = self.ir_model.search(self.cr, self.uid, [('model', '=', 'mail.group')])[0]
|
||||
|
@ -118,6 +146,11 @@ class test_mail(common.TransactionCase):
|
|||
self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
|
||||
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
|
||||
|
||||
def tearDown(self):
|
||||
# Remove mocks
|
||||
self.registry('mail.mail').send_get_mail_body = self._send_get_mail_body
|
||||
super(test_mail, self).tearDown()
|
||||
|
||||
def test_00_message_process(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
# Incoming mail creates a new mail_group "frogs"
|
||||
|
@ -153,7 +186,7 @@ class test_mail(common.TransactionCase):
|
|||
test_msg_id = '<deadcafe.1337@smtp.agrolait.com>'
|
||||
mail_text = MAIL_TEMPLATE_PLAINTEXT.format(to='groups@example.com', subject='frogs', extra='', msg_id=test_msg_id)
|
||||
self.mail_thread.message_process(cr, uid, None, mail_text)
|
||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id','=',test_msg_id)])[0])
|
||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
|
||||
self.assertEqual(new_mail.body, '\n<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>\n',
|
||||
'plaintext mail incorrectly parsed')
|
||||
|
||||
|
@ -274,18 +307,20 @@ class test_mail(common.TransactionCase):
|
|||
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
|
||||
|
||||
# CASE1: post comment, body and subject specified
|
||||
self._init_mock_build_email()
|
||||
msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment')
|
||||
message = self.mail_message.browse(cr, uid, msg_id)
|
||||
sent_email = self._build_email_kwargs
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
# Test: notifications have been deleted
|
||||
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id)]), 'mail.mail notifications should have been auto-deleted!')
|
||||
# Test: mail_message: subject is _subject, body is _body1 (no formatting done)
|
||||
self.assertEqual(message.subject, _subject, 'mail.message subject incorrect')
|
||||
self.assertEqual(message.body, _body1, 'mail.message body incorrect')
|
||||
# Test: sent_email: email send by server: correct subject, body; body_alternative
|
||||
self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
|
||||
self.assertEqual(sent_email['body'], _mail_body1, 'sent_email body incorrect')
|
||||
self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1, 'sent_email body_alternative is incorrect')
|
||||
# Test: sent_email: email send by server: correct subject, body, body_alternative
|
||||
for sent_email in sent_emails:
|
||||
self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
|
||||
self.assertEqual(sent_email['body'], _mail_body1 + '\n<pre>Bert Tartopoils</pre>\n', 'sent_email body incorrect')
|
||||
self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils', 'sent_email body_alternative is incorrect')
|
||||
# Test: mail_message: partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.partner_ids])
|
||||
test_pids = set([p_a_id, p_b_id, p_c_id])
|
||||
|
@ -295,14 +330,16 @@ class test_mail(common.TransactionCase):
|
|||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
||||
# Test: sent_email: email_to should contain b@b, not c@c (pref email), not a@a (writer)
|
||||
self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
|
||||
for sent_email in sent_emails:
|
||||
self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
|
||||
|
||||
# CASE2: post an email with attachments, parent_id, partner_ids
|
||||
# TESTS: automatic subject, signature in body_html, attachments propagation
|
||||
self._init_mock_build_email()
|
||||
msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email',
|
||||
partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments)
|
||||
message = self.mail_message.browse(cr, uid, msg_id2)
|
||||
sent_email = self._build_email_kwargs
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id2)]), 'mail.mail notifications should have been auto-deleted!')
|
||||
|
||||
# Test: mail_message: subject is False, body is _body2 (no formatting done), parent_id is msg_id
|
||||
|
@ -310,9 +347,11 @@ class test_mail(common.TransactionCase):
|
|||
self.assertEqual(message.body, html_sanitize(_body2), 'mail.message body incorrect')
|
||||
self.assertEqual(message.parent_id.id, msg_id, 'mail.message parent_id incorrect')
|
||||
# Test: sent_email: email send by server: correct subject, body, body_alternative
|
||||
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
|
||||
self.assertEqual(sent_email['body'], _mail_body2, 'sent_email body incorrect')
|
||||
self.assertEqual(sent_email['body_alternative'], _mail_bodyalt2, 'sent_email body_alternative incorrect')
|
||||
self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
|
||||
for sent_email in sent_emails:
|
||||
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
|
||||
self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect')
|
||||
self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect')
|
||||
# Test: mail_message: partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.partner_ids])
|
||||
test_pids = set([p_a_id, p_b_id, p_c_id, p_d_id])
|
||||
|
@ -322,7 +361,8 @@ class test_mail(common.TransactionCase):
|
|||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
||||
# Test: sent_email: email_to should contain b@b, c@c, not a@a (writer)
|
||||
self.assertEqual(set(sent_email['email_to']), set(['b@b', 'c@c']), 'sent_email email_to incorrect')
|
||||
for sent_email in sent_emails:
|
||||
self.assertTrue(set(sent_email['email_to']).issubset(set(['b@b', 'c@c'])), 'sent_email email_to incorrect')
|
||||
# Test: attachments
|
||||
for attach in message.attachment_ids:
|
||||
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
|
||||
|
@ -409,12 +449,14 @@ class test_mail(common.TransactionCase):
|
|||
self.assertEqual(compose.content_subtype, 'html', 'mail.compose.message incorrect content_subtype')
|
||||
|
||||
# 2. Post the comment, get created message
|
||||
parent_id = message.id
|
||||
mail_compose.send_mail(cr, uid, [compose_id])
|
||||
group_pigs.refresh()
|
||||
message = group_pigs.message_ids[0]
|
||||
# Test: mail.message: subject as Re:.., body in html
|
||||
# Test: mail.message: subject as Re:.., body in html, parent_id
|
||||
self.assertEqual(message.subject, _msg_reply, 'mail.message incorrect subject')
|
||||
self.assertIn('Administrator wrote:<blockquote><pre>Pigs rules</pre></blockquote></div>', message.body, 'mail.message body is incorrect')
|
||||
self.assertEqual(message.parent_id and message.parent_id.id, parent_id, 'mail.message parent_id incorrect')
|
||||
# Test: mail.message: attachments
|
||||
for attach in message.attachment_ids:
|
||||
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
|
||||
|
@ -458,6 +500,7 @@ class test_mail(common.TransactionCase):
|
|||
# It will be updated as soon as we have fixed specs !
|
||||
cr, uid = self.cr, self.uid
|
||||
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
||||
|
||||
def _compare_structures(struct1, struct2, n=0):
|
||||
# print '%scompare structure' % ('\t' * n)
|
||||
self.assertEqual(len(struct1), len(struct2), 'message_read structure number of childs incorrect')
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import invite
|
||||
import mail_compose_message
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2012-Today OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv
|
||||
from osv import fields
|
||||
from tools.translate import _
|
||||
|
||||
|
||||
class invite_wizard(osv.osv_memory):
|
||||
""" Wizard to invite partners and make them followers. """
|
||||
_name = 'mail.wizard.invite'
|
||||
_description = 'Invite wizard'
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
result = super(invite_wizard, self).default_get(cr, uid, fields, context=context)
|
||||
if 'message' in fields and result.get('res_model') and result.get('res_id'):
|
||||
document_name = self.pool.get(result.get('res_model')).name_get(cr, uid, [result.get('res_id')], context=context)[0][1]
|
||||
message = _('<div>You have been invited to follow %s.</div>' % document_name)
|
||||
result['message'] = message
|
||||
elif 'message' in fields:
|
||||
result['message'] = _('<div>You have been invited to follow a new document.</div>')
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'res_model': fields.char('Related Document Model', size=128,
|
||||
required=True, select=1,
|
||||
help='Model of the followed resource'),
|
||||
'res_id': fields.integer('Related Document ID', select=1,
|
||||
help='Id of the followed resource'),
|
||||
'partner_ids': fields.many2many('res.partner', string='Partners'),
|
||||
'message': fields.html('Message'),
|
||||
}
|
||||
|
||||
def onchange_partner_ids(self, cr, uid, ids, value, context=None):
|
||||
""" onchange_partner_ids (value format: [[6, 0, [3, 4]]]). The
|
||||
basic purpose of this method is to check that destination partners
|
||||
effectively have email addresses. Otherwise a warning is thrown.
|
||||
"""
|
||||
res = {'value': {}}
|
||||
if not value or not value[0] or not value[0][0] == 6:
|
||||
return
|
||||
res.update(self.pool.get('mail.message').check_partners_email(cr, uid, value[0][2], context=context))
|
||||
return res
|
||||
|
||||
def add_followers(self, cr, uid, ids, context=None):
|
||||
for wizard in self.browse(cr, uid, ids, context=context):
|
||||
model_obj = self.pool.get(wizard.res_model)
|
||||
document = model_obj.browse(cr, uid, wizard.res_id, context=context)
|
||||
|
||||
# filter partner_ids to get the new followers, to avoid sending email to already following partners
|
||||
new_follower_ids = [p.id for p in wizard.partner_ids if p.id not in document.message_follower_ids]
|
||||
model_obj.message_subscribe(cr, uid, [wizard.res_id], new_follower_ids, context=context)
|
||||
|
||||
# send an email
|
||||
if wizard.message:
|
||||
for follower_id in new_follower_ids:
|
||||
mail_mail = self.pool.get('mail.mail')
|
||||
mail_id = mail_mail.create(cr, uid, {
|
||||
'subject': 'Invitation to follow %s' % document.name_get()[0][1],
|
||||
'body_html': '%s' % wizard.message,
|
||||
'auto_delete': True,
|
||||
}, context=context)
|
||||
mail_mail.send(cr, uid, [mail_id], recipient_ids=[follower_id], context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- wizard view -->
|
||||
<record model="ir.ui.view" id="mail_wizard_invite_form">
|
||||
<field name="name">Add Followers</field>
|
||||
<field name="model">mail.wizard.invite</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Add Followers" version="7.0">
|
||||
<group>
|
||||
<field name="res_model" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<field name="partner_ids" widget="many2many_tags"
|
||||
on_change="onchange_partner_ids(partner_ids)" />
|
||||
<field name="message"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Add Followers"
|
||||
name="add_followers" type="object" class="oe_highlight" />
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -31,6 +31,7 @@ from tools.translate import _
|
|||
# main mako-like expression pattern
|
||||
EXPRESSION_PATTERN = re.compile('(\$\{.+?\})')
|
||||
|
||||
|
||||
class mail_compose_message(osv.TransientModel):
|
||||
""" Generic message composition wizard. You may inherit from this wizard
|
||||
at model and view levels to provide specific features.
|
||||
|
@ -117,6 +118,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
'body_text': lambda self, cr, uid, ctx={}: False,
|
||||
'body': lambda self, cr, uid, ctx={}: '',
|
||||
'subject': lambda self, cr, uid, ctx={}: False,
|
||||
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
||||
}
|
||||
|
||||
def notify(self, cr, uid, newid, context=None):
|
||||
|
@ -152,7 +154,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
# create subject
|
||||
re_prefix = _('Re:')
|
||||
reply_subject = tools.ustr(message_data.subject or '')
|
||||
if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)):
|
||||
if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)) and message_data.subject:
|
||||
reply_subject = "%s %s" % (re_prefix, reply_subject)
|
||||
# create the reply in the body
|
||||
reply_body = _('<div>On %(date)s, %(sender_name)s wrote:<blockquote>%(body)s</blockquote></div>') % {
|
||||
|
@ -176,8 +178,8 @@ class mail_compose_message(osv.TransientModel):
|
|||
return result
|
||||
|
||||
def toggle_content_subtype(self, cr, uid, ids, context=None):
|
||||
""" hit toggle formatting mode button: calls onchange_formatting to
|
||||
emulate an on_change, then writes the value to update the form. """
|
||||
""" toggle content_subtype: calls onchange_formatting to emulate an
|
||||
on_change, then writes the value to update the form. """
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
content_st_new_value = 'plain' if record.content_subtype == 'html' else 'html'
|
||||
onchange_res = self.onchange_content_subtype(cr, uid, ids, content_st_new_value, record.model, record.res_id, context=context)
|
||||
|
@ -185,48 +187,23 @@ class mail_compose_message(osv.TransientModel):
|
|||
return True
|
||||
|
||||
def onchange_content_subtype(self, cr, uid, ids, value, model, res_id, context=None):
|
||||
""" onchange_content_subtype (values: 'plain' or 'html'). This onchange
|
||||
on the subtype allows to have some specific behavior when switching
|
||||
between text or html mode.
|
||||
This method can be overridden for models that want to have their
|
||||
specific behavior. """
|
||||
""" This onchange allows to have some specific behavior when switching
|
||||
between text or html mode. This method can be overridden.
|
||||
:param values: 'plain' or 'html'
|
||||
"""
|
||||
return {'value': {'content_subtype': value}}
|
||||
|
||||
def _verify_partner_email(self, cr, uid, partner_ids, context=None):
|
||||
""" Verify that selected partner_ids have an email_address defined.
|
||||
Otherwise throw a warning. """
|
||||
partner_wo_email_lst = []
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
if not partner.email:
|
||||
partner_wo_email_lst.append(partner)
|
||||
if not partner_wo_email_lst:
|
||||
return {}
|
||||
warning_msg = _('The following partners chosen as recipients for the email have no email address linked :')
|
||||
for partner in partner_wo_email_lst:
|
||||
warning_msg += '\n- %s' % (partner.name)
|
||||
return {'warning': {
|
||||
'title': _('Partners email addresses not found'),
|
||||
'message': warning_msg,
|
||||
}
|
||||
}
|
||||
|
||||
def onchange_partner_ids(self, cr, uid, ids, value, context=None):
|
||||
""" onchange_partner_ids (value format: [[6, 0, [3, 4]]]). The
|
||||
basic purpose of this method is to check that destination partners
|
||||
""" The basic purpose of this method is to check that destination partners
|
||||
effectively have email addresses. Otherwise a warning is thrown.
|
||||
:param value: value format: [[6, 0, [3, 4]]]
|
||||
"""
|
||||
res = {'value': {}}
|
||||
if not value or not value[0] or not value[0][0] == 6:
|
||||
return
|
||||
res.update(self._verify_partner_email(cr, uid, value[0][2], context=context))
|
||||
res.update(self.check_partners_email(cr, uid, value[0][2], context=context))
|
||||
return res
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
# Cascade delete all attachments, as they are owned by the composition wizard
|
||||
for wizard in self.read(cr, uid, ids, ['attachment_ids'], context=context):
|
||||
self.pool.get('ir.attachment').unlink(cr, uid, wizard['attachment_ids'], context=context)
|
||||
return super(mail_compose_message, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
def dummy(self, cr, uid, ids, context=None):
|
||||
""" TDE: defined to have buttons that do basically nothing. It is
|
||||
currently impossible to have buttons that do nothing special
|
||||
|
@ -255,6 +232,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
post_values = {
|
||||
'subject': wizard.subject if wizard.content_subtype == 'html' else False,
|
||||
'body': wizard.body if wizard.content_subtype == 'html' else '<pre>%s</pre>' % tools.ustr(wizard.body_text),
|
||||
'parent_id': wizard.parent_id and wizard.parent_id.id,
|
||||
'partner_ids': [(4, partner.id) for partner in wizard.partner_ids],
|
||||
'attachments': [(attach.datas_fname or attach.name, base64.b64decode(attach.datas)) for attach in wizard.attachment_ids],
|
||||
}
|
||||
|
@ -268,6 +246,8 @@ class mail_compose_message(osv.TransientModel):
|
|||
post_values.update(email_dict)
|
||||
# post the message
|
||||
active_model_pool.message_post(cr, uid, [res_id], type='comment', context=context, **post_values)
|
||||
# post process: update attachments, because id is not necessarily known when adding attachments in Chatter
|
||||
self.pool.get('ir.attachment').write(cr, uid, [attach.id for attach in wizard.attachment_ids], {'res_id': wizard.id}, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
@ -296,6 +276,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
def merge(match):
|
||||
exp = str(match.group()[2:-1]).strip()
|
||||
result = eval(exp, {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<group>
|
||||
<field name="subject" placeholder="Subject..."/>
|
||||
<field name="partner_ids" widget="many2many_tags" placeholder="Add contacts to notify..."
|
||||
context="{'force_create':True}"
|
||||
context="{'force_email':True}"
|
||||
on_change="onchange_partner_ids(partner_ids)"/>
|
||||
</group>
|
||||
<notebook>
|
||||
|
@ -65,7 +65,7 @@
|
|||
class="oe_mail_compose_message_body_html"
|
||||
attrs="{'invisible':[('content_subtype', '=', 'plain')]}"/>
|
||||
<field name="partner_ids" colspan="2" nolabel="1" widget="many2many_tags" placeholder="Add contacts to notify..."
|
||||
context="{'force_create':True}"
|
||||
context="{'force_email':True}"
|
||||
on_change="onchange_partner_ids(partner_ids)"
|
||||
class="oe_mail_compose_message_partner_ids"/>
|
||||
<field name="attachment_ids" colspan="2" nolabel="1" widget="many2many_tags"
|
||||
|
|
|
@ -25,14 +25,14 @@ class marketing_config_settings(osv.osv_memory):
|
|||
_name = 'marketing.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
_columns = {
|
||||
'module_marketing_campaign': fields.boolean('Marketing Campaigns',
|
||||
'module_marketing_campaign': fields.boolean('Marketing campaigns',
|
||||
help="""Provides leads automation through marketing campaigns.
|
||||
Campaigns can in fact be defined on any resource, not just CRM leads.
|
||||
This installs the module marketing_campaign."""),
|
||||
'module_marketing_campaign_crm_demo': fields.boolean('Demo Data for Marketing Campaigns',
|
||||
'module_marketing_campaign_crm_demo': fields.boolean('Demo data for marketing campaigns',
|
||||
help="""Installs demo data like leads, campaigns and segments for Marketing Campaigns.
|
||||
This installs the module marketing_campaign_crm_demo."""),
|
||||
'module_crm_profiling': fields.boolean('Track Customer Profile to Focus your Campaigns',
|
||||
'module_crm_profiling': fields.boolean('Track customer profile to focus your campaigns',
|
||||
help="""Allows users to perform segmentation within partners.
|
||||
This installs the module crm_profiling."""),
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -48,7 +48,7 @@ msgstr "إستعمال مراكز العمل"
|
|||
#. module: mrp
|
||||
#: model:product.template,name:mrp.product_sugar_product_template
|
||||
msgid "Sugar"
|
||||
msgstr ""
|
||||
msgstr "سكر"
|
||||
|
||||
#. module: mrp
|
||||
#: report:mrp.production.order:0
|
||||
|
@ -63,7 +63,7 @@ msgstr "عدد الدورات"
|
|||
#. module: mrp
|
||||
#: model:product.uom.categ,name:mrp.product_uom_categ_fluid
|
||||
msgid "Fluid"
|
||||
msgstr ""
|
||||
msgstr "سائل"
|
||||
|
||||
#. module: mrp
|
||||
#: model:process.transition,note:mrp.process_transition_minimumstockprocure0
|
||||
|
@ -145,7 +145,7 @@ msgstr "منتجات منتهية"
|
|||
#. module: mrp
|
||||
#: view:mrp.production:0
|
||||
msgid "Manufacturing Orders which are currently in production."
|
||||
msgstr ""
|
||||
msgstr "تصنيع الطلبيات التي هي حاليا في الإنتاج."
|
||||
|
||||
#. module: mrp
|
||||
#: model:process.transition,name:mrp.process_transition_servicerfq0
|
||||
|
@ -218,17 +218,14 @@ msgstr "امليء المنتج لتتعقب بسهولة تكاليف الان
|
|||
msgid "For purchased material"
|
||||
msgstr "للمواد المشتراه"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "مراجعة"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
"Create a product form for everything you buy or sell. Specify a supplier if "
|
||||
"the product can be purchased."
|
||||
msgstr ""
|
||||
"إنشاء نموذج المنتج على كل شيء قمت بالشراءه أو بيعه. حدد المورد إذا كان من "
|
||||
"الممكن شراء المنتج."
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.ui.menu,name:mrp.next_id_77
|
||||
|
@ -264,7 +261,7 @@ msgstr "معلومات عن القدرة"
|
|||
#. module: mrp
|
||||
#: field:mrp.production,move_created_ids2:0
|
||||
msgid "Produced Products"
|
||||
msgstr ""
|
||||
msgstr "إنتاج المنتجات"
|
||||
|
||||
#. module: mrp
|
||||
#: report:mrp.production.order:0
|
||||
|
@ -319,7 +316,7 @@ msgstr "انت تحاول تخصيص الكثير من ما هو دون المن
|
|||
#. module: mrp
|
||||
#: model:product.template,name:mrp.product_cloth_product_template
|
||||
msgid "Cloth"
|
||||
msgstr ""
|
||||
msgstr "ثوب"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_product_produce
|
||||
|
@ -334,7 +331,7 @@ msgstr ""
|
|||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_routing_workcenter
|
||||
msgid "Work Center Usage"
|
||||
msgstr ""
|
||||
msgstr "استخدام عمل المركز"
|
||||
|
||||
#. module: mrp
|
||||
#: model:process.transition,name:mrp.process_transition_procurestockableproduct0
|
||||
|
@ -396,6 +393,11 @@ msgid ""
|
|||
"sales person creates a sales order, he can relate it to several properties "
|
||||
"and OpenERP will automatically select the BoM to use according the needs."
|
||||
msgstr ""
|
||||
"وتستخدم الخصائص في OpenERP لتحديد مواد المشروع المناسبة لتصنيع منتج عندما "
|
||||
"يكون لديك طرق مختلفة لبناء نفس المنتج. يمكنك تعيين العديد من الخصائص على كل "
|
||||
"فاتورة مواد. عندما يقوم مندوب المبيعات بإنشاء طلبات مبيعات، وكما يمكنه ربطها "
|
||||
"بالعديد من الخصائص وOpenERP سوف تختار تلقائيا فاتورة المواد لاستخدامها وفقا "
|
||||
"للاحتياجات."
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,picking_id:0
|
||||
|
@ -473,7 +475,7 @@ msgstr ""
|
|||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle:0
|
||||
msgid "Specify Cost of Work Center per cycle."
|
||||
msgstr ""
|
||||
msgstr "حدد تكلفة العمل المركزية دورة"
|
||||
|
||||
#. module: mrp
|
||||
#: model:process.transition,name:mrp.process_transition_bom0
|
||||
|
@ -485,11 +487,6 @@ msgstr "تعطب التصنيع"
|
|||
msgid "For Services."
|
||||
msgstr "للخدمات."
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "تاريخ التعديل."
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -525,7 +522,7 @@ msgstr "خطأ: كود إين غير صالح"
|
|||
#. module: mrp
|
||||
#: field:mrp.production,move_created_ids:0
|
||||
msgid "Products to Produce"
|
||||
msgstr ""
|
||||
msgstr "لإنتاج منتجات"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing:0
|
||||
|
@ -541,18 +538,13 @@ msgstr "كمية التغيير"
|
|||
#. module: mrp
|
||||
#: model:ir.actions.act_window,name:mrp.action_configure_workcenter
|
||||
msgid "Configure your work centers"
|
||||
msgstr ""
|
||||
msgstr "اضبط مراكز عملك"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.production:0
|
||||
msgid "Force Reservation"
|
||||
msgstr "فرض الحجز"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "المؤلف"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -669,7 +661,7 @@ msgstr "جاهز"
|
|||
#. module: mrp
|
||||
#: model:product.template,name:mrp.product_buttons_product_template
|
||||
msgid "Shirt Buttons"
|
||||
msgstr ""
|
||||
msgstr "أزرار القميص"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,routing_id:0
|
||||
|
@ -806,7 +798,7 @@ msgstr "عاجل"
|
|||
#. module: mrp
|
||||
#: view:mrp.production:0
|
||||
msgid "Manufacturing Orders which are waiting for raw materials."
|
||||
msgstr ""
|
||||
msgstr "تصنيع الطلبيات التي تنتظر المواد الخام."
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.mrp_workcenter_action
|
||||
|
@ -839,11 +831,6 @@ msgstr "الدورات الكلية"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "جاهز للانتاج"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "إسم التصنيف"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -903,7 +890,7 @@ msgstr "الحد الادنى من المخزون"
|
|||
#: code:addons/mrp/mrp.py:503
|
||||
#, python-format
|
||||
msgid "Cannot delete a manufacturing order in state '%s'"
|
||||
msgstr ""
|
||||
msgstr "لا يمكن حذف نظام التصنيع في ولاية %s"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.ui.menu,name:mrp.menus_dash_mrp
|
||||
|
@ -915,7 +902,7 @@ msgstr "اللوحة الرئيسية"
|
|||
#: code:addons/mrp/report/price.py:211
|
||||
#, python-format
|
||||
msgid "Total Cost of %s %s"
|
||||
msgstr ""
|
||||
msgstr "التكلفة الكلية لـ%s %s"
|
||||
|
||||
#. module: mrp
|
||||
#: model:process.node,name:mrp.process_node_stockproduct0
|
||||
|
@ -1423,11 +1410,6 @@ msgstr "شراء المنتجات"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "تحميلات مركز العمل"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "فمراجعة فاتورة المواد"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1958,12 +1940,6 @@ msgstr "الوقت بالساعات للإعداد."
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "فاتورة المواد"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1981,17 +1957,6 @@ msgstr "تخصيص من المخزون."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "انتظار السلع"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "اخر مؤشر"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "مراجعات فاتورة المواد"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2179,19 +2144,6 @@ msgstr "غير الكمية"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "غير كمية المنتج"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "الوصف"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2312,6 +2264,9 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ msgid "Day"
|
||||
#~ msgstr "يوم"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "مراجعة"
|
||||
|
||||
#~ msgid "title"
|
||||
#~ msgstr "الاسم"
|
||||
|
||||
|
@ -2324,6 +2279,9 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ msgid "October"
|
||||
#~ msgstr "أكتوبر"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "المؤلف"
|
||||
|
||||
#~ msgid "March"
|
||||
#~ msgstr "مارس"
|
||||
|
||||
|
@ -2394,6 +2352,9 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ "following addons."
|
||||
#~ msgstr "اضف وظائف اكثر لجوهر تطبيق الصناعة بالملحقات التالية."
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "إسم التصنيف"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Time in hours for this work center to achieve the operation of the specified "
|
||||
#~ "routing."
|
||||
|
@ -2497,6 +2458,15 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ "performance."
|
||||
#~ msgstr "يسمح لك هذا التقرير بتحليل انشطة التصنيع الخاصة بك و الاداء."
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "فاتورة المواد"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "مراجعات فاتورة المواد"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "اخر مؤشر"
|
||||
|
||||
#~ msgid "Draft"
|
||||
#~ msgstr "مسوّدة"
|
||||
|
||||
|
@ -2527,6 +2497,9 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ msgid "Work Cost of "
|
||||
#~ msgstr "تكلفة العمل لـ "
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "فمراجعة فاتورة المواد"
|
||||
|
||||
#~ msgid "Manufacturing Operations"
|
||||
#~ msgstr "عمليات التصنيع"
|
||||
|
||||
|
@ -2535,6 +2508,9 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ "this work center."
|
||||
#~ msgstr "وصف مركز العمل. يبين هنا ماهي الدورة وفقًا لمركز العمل هذا."
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "الوصف"
|
||||
|
||||
#~ msgid "May"
|
||||
#~ msgstr "مايو"
|
||||
|
||||
|
@ -2644,3 +2620,6 @@ msgstr "منتجات للاستهلاك"
|
|||
#~ "الخصائص على كل فاتورة من المواد. عندما ينشأ البائع ترتيب مبيعات، يمكنه ربطها "
|
||||
#~ "بالعديد من الخصائص و ستحدد OpenERP تلقائيا فاتورة المواد لاستخدمها طبقًا "
|
||||
#~ "للاحتياجات."
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "تاريخ التعديل."
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -223,11 +223,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "За закупени суровини"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Версия"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -494,11 +489,6 @@ msgstr "Разлагане на производство"
|
|||
msgid "For Services."
|
||||
msgstr "За услуги."
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Дата на промяна"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -560,11 +550,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr "Мощност за резервация"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Автор"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -845,11 +830,6 @@ msgstr "Общо цикли"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Готов за производство"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Име на промяна"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1410,11 +1390,6 @@ msgstr "Снабдяване с продукти"
|
|||
msgid "Work Center Loads"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1918,12 +1893,6 @@ msgstr ""
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1941,17 +1910,6 @@ msgstr ""
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Чакащи стоки"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2137,19 +2095,6 @@ msgstr ""
|
|||
msgid "Change Product Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Описание"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2320,6 +2265,15 @@ msgstr ""
|
|||
#~ msgid "products"
|
||||
#~ msgstr "продукти"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Автор"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Дата на промяна"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Име на промяна"
|
||||
|
||||
#~ msgid "Stockable Production Order"
|
||||
#~ msgstr "Скадируема поръчка за производство"
|
||||
|
||||
|
@ -2332,6 +2286,9 @@ msgstr ""
|
|||
#~ msgid "Day"
|
||||
#~ msgstr "Ден"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Версия"
|
||||
|
||||
#~ msgid "title"
|
||||
#~ msgstr "заглавие"
|
||||
|
||||
|
@ -2435,6 +2392,9 @@ msgstr ""
|
|||
#~ msgid "January"
|
||||
#~ msgstr "Януари"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Описание"
|
||||
|
||||
#~ msgid "May"
|
||||
#~ msgstr "Май"
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -210,11 +210,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -469,11 +464,6 @@ msgstr ""
|
|||
msgid "For Services."
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -531,11 +521,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -816,11 +801,6 @@ msgstr ""
|
|||
msgid "Ready to Produce"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1381,11 +1361,6 @@ msgstr ""
|
|||
msgid "Work Center Loads"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1889,12 +1864,6 @@ msgstr ""
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1912,17 +1881,6 @@ msgstr ""
|
|||
msgid "Waiting Goods"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2108,19 +2066,6 @@ msgstr ""
|
|||
msgid "Change Product Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -225,11 +225,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Per material comprat"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisió"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -499,11 +494,6 @@ msgstr "Descomposició fabricació"
|
|||
msgid "For Services."
|
||||
msgstr "Per serveis"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Data modificació"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -565,11 +555,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr "Força reserves"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -862,11 +847,6 @@ msgstr "Total cicles"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Llest per produir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nom de modificació"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1460,11 +1440,6 @@ msgstr "Proveir products"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Càrregues centre de producció"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisió de la llista de materials"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2007,12 +1982,6 @@ msgstr "Temps en hores per la configuració."
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Llista de materials (LdM)"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2030,17 +1999,6 @@ msgstr "Assignació des d'estoc."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperant mercaderia"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Últim índex"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisions llista de materials"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2229,19 +2187,6 @@ msgstr "Canvia la quantitat"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Canvia Qtat. producte"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Descripció"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2378,6 +2323,9 @@ msgstr "Productes a consumir"
|
|||
#~ "virtual menor que 0. Probablement no hauria d'utilitzar aquesta opció, "
|
||||
#~ "suggerim utilitzar una configuració de MTO en productes."
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisió"
|
||||
|
||||
#~ msgid "Exceptions Procurements"
|
||||
#~ msgstr "Excepcions de proveïments"
|
||||
|
||||
|
@ -2544,6 +2492,9 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "Make Procurement"
|
||||
#~ msgstr "Realitza proveïment"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Data modificació"
|
||||
|
||||
#~ msgid "If Procure method is Make to order and supply method is produce"
|
||||
#~ msgstr ""
|
||||
#~ "Si mètode de proveïment és obtenir sota comanda i mètode de subministre és "
|
||||
|
@ -2552,6 +2503,9 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "Purchase Lead Time"
|
||||
#~ msgstr "Termini de temps de compra"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Stockable Product Stock"
|
||||
#~ msgstr "Estoc de producte estocable"
|
||||
|
||||
|
@ -2644,6 +2598,9 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Dies de seguretat"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nom de modificació"
|
||||
|
||||
#~ msgid "Exception"
|
||||
#~ msgstr "Excepció"
|
||||
|
||||
|
@ -2995,6 +2952,9 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "plus"
|
||||
#~ msgstr "més"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Llista de materials (LdM)"
|
||||
|
||||
#~ msgid "Stockable Product Process"
|
||||
#~ msgstr "Procés producte estocable"
|
||||
|
||||
|
@ -3004,6 +2964,12 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "A Request for Quotation is created and sent to the supplier."
|
||||
#~ msgstr "Una sol·licitud de pressupost és creada i enviada al proveïdor."
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Últim índex"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisions llista de materials"
|
||||
|
||||
#~ msgid "Retry"
|
||||
#~ msgstr "Torna a intentar"
|
||||
|
||||
|
@ -3061,6 +3027,9 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "Close Move at end"
|
||||
#~ msgstr "Moviment de tancament al final"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Descripció"
|
||||
|
||||
#~ msgid "Running"
|
||||
#~ msgstr "En procés"
|
||||
|
||||
|
@ -3303,6 +3272,9 @@ msgstr "Productes a consumir"
|
|||
#~ msgid "Configure"
|
||||
#~ msgstr "Configura"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisió de la llista de materials"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Routing indicates all the workcenters used, for how long and/or cycles.If "
|
||||
#~ "Routing is indicated then,the third tab of a production order (workcenters) "
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: mrp
|
||||
|
@ -211,11 +211,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Pro nakoupený materiál"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revize"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -477,11 +472,6 @@ msgstr "Rozložení výroby"
|
|||
msgid "For Services."
|
||||
msgstr "Pro služby."
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Datum úpravy"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -539,11 +529,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr "Vynutit rezervaci"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -828,11 +813,6 @@ msgstr "Celkem cyklů"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Připraveno k výrobě"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Jméno úpravy"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1396,11 +1376,6 @@ msgstr "Pořídit výrobek"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Vytížení výrobních center"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revize Soupisky materiálu"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1912,12 +1887,6 @@ msgstr "Čas v hodinách na sestavení"
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "BoM"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1935,17 +1904,6 @@ msgstr "Přiřazení ze skladu."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Čekající zboží"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "poslední ukazatel"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revize BoM"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2131,19 +2089,6 @@ msgstr "Změnit množství"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Změnit množ. výrobků"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Popis"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2298,6 +2243,9 @@ msgstr "Výrobků ke spotřebě"
|
|||
#~ msgid "Raw Material Location"
|
||||
#~ msgstr "Umístění surového materiálu"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revize"
|
||||
|
||||
#~ msgid "title"
|
||||
#~ msgstr "nadpis"
|
||||
|
||||
|
@ -2323,6 +2271,12 @@ msgstr "Výrobků ke spotřebě"
|
|||
#~ msgid "Advanced Routes"
|
||||
#~ msgstr "Pokročilé trasy"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Datum úpravy"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "March"
|
||||
#~ msgstr "Březen"
|
||||
|
||||
|
@ -2355,6 +2309,9 @@ msgstr "Výrobků ke spotřebě"
|
|||
#~ "Čas v hodinách pro toto pracovní centrum k dosažení operace zadaného "
|
||||
#~ "směrování."
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Jméno úpravy"
|
||||
|
||||
#~ msgid "Extended Filters..."
|
||||
#~ msgstr "Rozšířené filtry..."
|
||||
|
||||
|
@ -2433,6 +2390,15 @@ msgstr "Výrobků ke spotřebě"
|
|||
#~ msgid "Image"
|
||||
#~ msgstr "Obrázek"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "BoM"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "poslední ukazatel"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revize BoM"
|
||||
|
||||
#~ msgid "Draft"
|
||||
#~ msgstr "Koncept"
|
||||
|
||||
|
@ -2451,6 +2417,9 @@ msgstr "Výrobků ke spotřebě"
|
|||
#~ "will be automatically pre-completed."
|
||||
#~ msgstr "poslední ukazatel"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revize Soupisky materiálu"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Work Cost of "
|
||||
#~ msgstr "Cena práce "
|
||||
|
@ -2468,6 +2437,9 @@ msgstr "Výrobků ke spotřebě"
|
|||
#~ msgid "MRP Applications Configuration"
|
||||
#~ msgstr "Nastavení aplikace MRP"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Popis"
|
||||
|
||||
#~ msgid "May"
|
||||
#~ msgstr "Květen"
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -211,11 +211,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -470,11 +465,6 @@ msgstr ""
|
|||
msgid "For Services."
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -532,11 +522,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -817,11 +802,6 @@ msgstr ""
|
|||
msgid "Ready to Produce"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1382,11 +1362,6 @@ msgstr ""
|
|||
msgid "Work Center Loads"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1890,12 +1865,6 @@ msgstr ""
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1913,17 +1882,6 @@ msgstr ""
|
|||
msgid "Waiting Goods"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2109,19 +2067,6 @@ msgstr ""
|
|||
msgid "Change Product Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -225,11 +225,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Für eingekauftes Material"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revision"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -509,11 +504,6 @@ msgstr "Fertigungsreste"
|
|||
msgid "For Services."
|
||||
msgstr "Für Dienstleistungsprodukte."
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Änderung am"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -575,11 +565,6 @@ msgstr "Konfigurieren Sie Ihre Arbeitsplätze"
|
|||
msgid "Force Reservation"
|
||||
msgstr "Erzwinge Reservierung"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Mitarbeiter"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -880,11 +865,6 @@ msgstr "Gesamt Zyklen"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Startbereit für Fertigung"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Bezeichnung geändert"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1483,11 +1463,6 @@ msgstr "Beschaffung Produkte"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Arbeitsplatz Auslastungen"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Stückliste Revision"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2032,12 +2007,6 @@ msgstr "Vorbereitungszeit"
|
|||
msgid "Orange Juice"
|
||||
msgstr "Orangensaft"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Stückliste"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2055,17 +2024,6 @@ msgstr "Zuweisung vom Lager."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Erwartet Material"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Letzter Index"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Stücklisten Revision"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2257,19 +2215,6 @@ msgstr "Ändere Anzahl"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Ändere Produkt Menge"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2409,6 +2354,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ "virtuellem Lager unter \"0\". Idealerweise arbeitet man allerdings mit "
|
||||
#~ "Lagerbestandsregeln."
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revision"
|
||||
|
||||
#~ msgid "Compute Stock Minimum Rules Only"
|
||||
#~ msgstr "Regelbasierte Beschaffungsvorschläge"
|
||||
|
||||
|
@ -2582,6 +2530,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "Make Procurement"
|
||||
#~ msgstr "Erzeuge Beschaffung"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Änderung am"
|
||||
|
||||
#~ msgid "If Procure method is Make to order and supply method is produce"
|
||||
#~ msgstr ""
|
||||
#~ "Falls Beschaffungsmethode 'aus Auftrag' und Einkaufsmethode 'Produktion'"
|
||||
|
@ -2684,6 +2635,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Sicherheitspuffer (Tage)"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Bezeichnung geändert"
|
||||
|
||||
#~ msgid "Exception"
|
||||
#~ msgstr "Fehlerliste"
|
||||
|
||||
|
@ -3033,6 +2987,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "plus"
|
||||
#~ msgstr "Plus"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Stückliste"
|
||||
|
||||
#~ msgid "Stockable Product Process"
|
||||
#~ msgstr "Lagerfähiges Produkt Prozess"
|
||||
|
||||
|
@ -3042,6 +2999,12 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "A Request for Quotation is created and sent to the supplier."
|
||||
#~ msgstr "Eine Angebotsanfrage wurde erzeugt und an den Lieferanten versendet."
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Letzter Index"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Stücklisten Revision"
|
||||
|
||||
#~ msgid "Retry"
|
||||
#~ msgstr "Wiederhole"
|
||||
|
||||
|
@ -3100,6 +3063,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "Close Move at end"
|
||||
#~ msgstr "Beende Warenfluss (Ende)"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Beschreibung"
|
||||
|
||||
#~ msgid "Running"
|
||||
#~ msgstr "In Weiterbearbeitung"
|
||||
|
||||
|
@ -3238,6 +3204,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "January"
|
||||
#~ msgstr "Januar"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Stückliste Revision"
|
||||
|
||||
#~ msgid "February"
|
||||
#~ msgstr "Februar"
|
||||
|
||||
|
@ -3263,6 +3232,9 @@ msgstr "Benötigte Produkte"
|
|||
#~ msgid "Advanced Routes"
|
||||
#~ msgstr "Lieferketten"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Mitarbeiter"
|
||||
|
||||
#~ msgid "Workcenter Usage"
|
||||
#~ msgstr "Fertigungsstelle Auslastung"
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
"X-Poedit-Country: GREECE\n"
|
||||
"X-Poedit-Language: Greek\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
|
@ -213,11 +213,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Αναθεώρηση"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -476,11 +471,6 @@ msgstr ""
|
|||
msgid "For Services."
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Ημερ/νία Τροποποίησης"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -540,11 +530,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr "Κράτηση Τώρα"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Δημιουργός"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -825,11 +810,6 @@ msgstr "Σύννολο Κύκλων"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Έτοιμο για Παραγωγή"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Όνομα τροποποίησης"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1390,11 +1370,6 @@ msgstr "Προμήθεια Προϊόντων"
|
|||
msgid "Work Center Loads"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1899,12 +1874,6 @@ msgstr "Χρόνος εγκατάστασης σε ώρες"
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Κ.Υ."
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1922,17 +1891,6 @@ msgstr ""
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Σε αναμονή υλικών"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "last indice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Αναθεωρήσεις ΚΥ"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2118,19 +2076,6 @@ msgstr ""
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Αλλαγή Ποσ. Προϊόντος"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Περιγραφή"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2296,6 +2241,9 @@ msgstr ""
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Ημέρες Ασφαλείας"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Όνομα τροποποίησης"
|
||||
|
||||
#~ msgid "From minimum stock rules, it goes for procure product."
|
||||
#~ msgstr "From minimum stock rules, it goes for procure product."
|
||||
|
||||
|
@ -2331,6 +2279,9 @@ msgstr ""
|
|||
#~ msgid "Manufacturing Resource Planning"
|
||||
#~ msgstr "Σχεδίαση Πηγών Βιομηχανικής Παραγωγής (MRP)"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Αναθεώρηση"
|
||||
|
||||
#~ msgid "Routing Workcenters"
|
||||
#~ msgstr "Κέντρα Εργασίας Γραμμής Παραγωγής"
|
||||
|
||||
|
@ -2468,12 +2419,18 @@ msgstr ""
|
|||
#~ msgid "Print product price"
|
||||
#~ msgstr "Εκτύπωση τιμής Προϊόντος"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Ημερ/νία Τροποποίησης"
|
||||
|
||||
#~ msgid "If Procure method is Make to order and supply method is produce"
|
||||
#~ msgstr "If Procure method is Make to order and supply method is produce"
|
||||
|
||||
#~ msgid "Purchase Lead Time"
|
||||
#~ msgstr "Χρόνος Παράδοσης Παραγγελίας"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Δημιουργός"
|
||||
|
||||
#~ msgid "Stockable Product Stock"
|
||||
#~ msgstr "Απόθεμα Αποθηκεύσιμου Προϊόντος"
|
||||
|
||||
|
@ -2888,6 +2845,9 @@ msgstr ""
|
|||
#~ msgid "plus"
|
||||
#~ msgstr "plus"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Κ.Υ."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The list of operations (list of workcenters) to produce the finished "
|
||||
#~ "product. The routing is mainly used to compute workcenter costs during "
|
||||
|
@ -2908,6 +2868,12 @@ msgstr ""
|
|||
#~ msgid "A Request for Quotation is created and sent to the supplier."
|
||||
#~ msgstr "Η Αίτηση για Προσφορά δημιουργήθηκε και εστάλει στον προμηθευτή."
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "last indice"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Αναθεωρήσεις ΚΥ"
|
||||
|
||||
#~ msgid "Retry"
|
||||
#~ msgstr "Νέα προσπάθεια"
|
||||
|
||||
|
@ -2962,6 +2928,9 @@ msgstr ""
|
|||
#~ msgid "Close Move at end"
|
||||
#~ msgstr "Close Move at end"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Περιγραφή"
|
||||
|
||||
#~ msgid "Running"
|
||||
#~ msgstr "Σε εξέλιξη"
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -225,11 +225,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Para material comprado"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -507,11 +502,6 @@ msgstr "Descomposición fabricación"
|
|||
msgid "For Services."
|
||||
msgstr "Para servicios"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Fecha de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -573,11 +563,6 @@ msgstr "Configure sus centros de producción"
|
|||
msgid "Force Reservation"
|
||||
msgstr "Forzar reservas"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -880,11 +865,6 @@ msgstr "Total ciclos"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Listo para producir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nombre de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1481,11 +1461,6 @@ msgstr "Abastecer productos"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Cargas centro de producción"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisión de lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2032,12 +2007,6 @@ msgstr "Tiempo en horas para la configuración."
|
|||
msgid "Orange Juice"
|
||||
msgstr "Zumo de naranja"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2055,17 +2024,6 @@ msgstr "Asignación desde stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperando mercancía"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Último índice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisiones lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2256,19 +2214,6 @@ msgstr "Cambiar cantidad"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Cambiar Ctd. producto"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2405,6 +2350,9 @@ msgstr "Productos a consumir"
|
|||
#~ "stock virtual menor que 0. Probablemente no debería utilizar esta opción, "
|
||||
#~ "sugerimos utilizar una configuración de MTO en productos."
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisión"
|
||||
|
||||
#~ msgid "Compute Stock Minimum Rules Only"
|
||||
#~ msgstr "Calcular sólo reglas de stock mínimo"
|
||||
|
||||
|
@ -2591,6 +2539,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Purchase Lead Time"
|
||||
#~ msgstr "Plazo de tiempo de compra"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Stockable Product Stock"
|
||||
#~ msgstr "Stock de producto almacenable"
|
||||
|
||||
|
@ -2688,6 +2639,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Días de seguridad"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nombre de modificación"
|
||||
|
||||
#~ msgid "Exception"
|
||||
#~ msgstr "Excepción"
|
||||
|
||||
|
@ -3044,6 +2998,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "plus"
|
||||
#~ msgstr "más"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#~ msgid "Stockable Product Process"
|
||||
#~ msgstr "Proceso producto almacenable"
|
||||
|
||||
|
@ -3053,6 +3010,12 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "A Request for Quotation is created and sent to the supplier."
|
||||
#~ msgstr "Una solicitud de presupuesto es creada y enviada al proveedor."
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Último índice"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisiones lista de materiales"
|
||||
|
||||
#~ msgid "Retry"
|
||||
#~ msgstr "Volver a intentar"
|
||||
|
||||
|
@ -3111,6 +3074,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Close Move at end"
|
||||
#~ msgstr "Movimiento de cierre al final"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Descripción"
|
||||
|
||||
#~ msgid "Running"
|
||||
#~ msgstr "En proceso"
|
||||
|
||||
|
@ -3239,6 +3205,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Image"
|
||||
#~ msgstr "Imagen"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisión de lista de materiales"
|
||||
|
||||
#~ msgid "January"
|
||||
#~ msgstr "Enero"
|
||||
|
||||
|
@ -3532,3 +3501,6 @@ msgstr "Productos a consumir"
|
|||
#~ " *Gráfico de carga del centro de trabajo\n"
|
||||
#~ " *Lista de órdenes de fabricación con excepciones\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Fecha de modificación"
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -225,11 +225,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Para material comprado"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -497,11 +492,6 @@ msgstr "Descomposición de la fabricación"
|
|||
msgid "For Services."
|
||||
msgstr "Para servicios"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Fecha de Modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -561,11 +551,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -851,11 +836,6 @@ msgstr "Ciclos totales"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Listo para producir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nombre de la modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1431,11 +1411,6 @@ msgstr ""
|
|||
msgid "Work Center Loads"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisión de lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1955,12 +1930,6 @@ msgstr "Tiempo en horas para la configuración."
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "LdM"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1978,17 +1947,6 @@ msgstr "Asignación desde stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperando mercandería"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Último índice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisiones de LdM"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2177,19 +2135,6 @@ msgstr ""
|
|||
msgid "Change Product Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2320,6 +2265,9 @@ msgstr ""
|
|||
#~ msgid "MRP Subproducts"
|
||||
#~ msgstr "Subproductos MRP"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisión"
|
||||
|
||||
#~ msgid "title"
|
||||
#~ msgstr "título"
|
||||
|
||||
|
@ -2349,6 +2297,12 @@ msgstr ""
|
|||
#~ "Activa garantía y gestión de reparaciones (y su impacto sobre stocks y "
|
||||
#~ "facturación)"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Fecha de Modificación"
|
||||
|
||||
#~ msgid "March"
|
||||
#~ msgstr "Marzo"
|
||||
|
||||
|
@ -2384,6 +2338,9 @@ msgstr ""
|
|||
#~ msgid "Extended Filters..."
|
||||
#~ msgstr "Filtros extendidos..."
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nombre de la modificación"
|
||||
|
||||
#~ msgid "Just In Time Scheduling"
|
||||
#~ msgstr "Planificación 'Just in Time'"
|
||||
|
||||
|
@ -2478,6 +2435,9 @@ msgstr ""
|
|||
#~ "Estos informes le permiten analizar sus actividades productivas y "
|
||||
#~ "rendimiento."
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "LdM"
|
||||
|
||||
#~ msgid "December"
|
||||
#~ msgstr "Diciembre"
|
||||
|
||||
|
@ -2490,6 +2450,12 @@ msgstr ""
|
|||
#~ msgid "Configuration Progress"
|
||||
#~ msgstr "Progreso de la configuración"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisiones de LdM"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Último índice"
|
||||
|
||||
#~ msgid "Draft"
|
||||
#~ msgstr "Borrador"
|
||||
|
||||
|
@ -2512,6 +2478,9 @@ msgstr ""
|
|||
#~ msgid "Manufacturing Operations"
|
||||
#~ msgstr "Operaciones de fabricación"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisión de lista de materiales"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Description of the work center. Explain here what's a cycle according to "
|
||||
#~ "this work center."
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -225,11 +225,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Para material comprado"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -508,11 +503,6 @@ msgstr "Descomposición fabricación"
|
|||
msgid "For Services."
|
||||
msgstr "Para servicios"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Fecha modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -574,11 +564,6 @@ msgstr "Configure sus centros de trabajo"
|
|||
msgid "Force Reservation"
|
||||
msgstr "Forzar reservas"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -881,11 +866,6 @@ msgstr "Total ciclos"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Listo para producir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nombre de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1483,11 +1463,6 @@ msgstr "Abastecer productos"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Cargas centro de producción"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisión de lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2034,12 +2009,6 @@ msgstr "Tiempo en horas para la configuración."
|
|||
msgid "Orange Juice"
|
||||
msgstr "Jugo de Naranja"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2057,17 +2026,6 @@ msgstr "Asignación desde stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperando mercancía"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Último índice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisiones lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2258,19 +2216,6 @@ msgstr "Cambiar cantidad"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Cambiar Ctd. producto"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2414,6 +2359,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "MRP Subproducts"
|
||||
#~ msgstr "Subproductos MRP"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisión"
|
||||
|
||||
#~ msgid "title"
|
||||
#~ msgstr "título"
|
||||
|
||||
|
@ -2442,6 +2390,12 @@ msgstr "Productos a consumir"
|
|||
#~ "Activa la garantía y la gestión de reparaciones (y su impacto sobre stocks y "
|
||||
#~ "facturación)"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Fecha modificación"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "March"
|
||||
#~ msgstr "Marzo"
|
||||
|
||||
|
@ -2481,6 +2435,9 @@ msgstr "Productos a consumir"
|
|||
#~ "Tiempo en horas para este centro de producción para realizar la operación de "
|
||||
#~ "la ruta indicada."
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nombre de modificación"
|
||||
|
||||
#~ msgid "Extended Filters..."
|
||||
#~ msgstr "Filtros extendidos..."
|
||||
|
||||
|
@ -2620,6 +2577,15 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Image"
|
||||
#~ msgstr "Imagen"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Último índice"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisiones lista de materiales"
|
||||
|
||||
#~ msgid "Draft"
|
||||
#~ msgstr "Borrador"
|
||||
|
||||
|
@ -2641,6 +2607,9 @@ msgstr "Productos a consumir"
|
|||
#~ "y/o ciclos. Si se indica la ruta, entonces la tercera pestaña de una orden "
|
||||
#~ "de producción (centros de producción) será automáticamente pre-completada."
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisión de lista de materiales"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Work Cost of "
|
||||
#~ msgstr "Coste trabajo de "
|
||||
|
@ -2673,6 +2642,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "MRP Applications Configuration"
|
||||
#~ msgstr "Configuración de las aplicaciónes MRP"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Descripción"
|
||||
|
||||
#~ msgid "May"
|
||||
#~ msgstr "Mayo"
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
"Language: \n"
|
||||
|
||||
#. module: mrp
|
||||
|
@ -226,11 +226,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Para material comprado"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -508,11 +503,6 @@ msgstr "Descomposición fabricación"
|
|||
msgid "For Services."
|
||||
msgstr "Para servicios"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Fecha de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -574,11 +564,6 @@ msgstr "Configure sus centros de producción"
|
|||
msgid "Force Reservation"
|
||||
msgstr "Forzar reservas"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -880,11 +865,6 @@ msgstr "Total ciclos"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Listo para producir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nombre de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1481,11 +1461,6 @@ msgstr "Abastecer productos"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Cargas centro de producción"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisión de lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2032,12 +2007,6 @@ msgstr "Tiempo en horas para la configuración."
|
|||
msgid "Orange Juice"
|
||||
msgstr "Zumo de naranja"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2055,17 +2024,6 @@ msgstr "Asignación desde stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperando mercancía"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Último índice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisiones lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2256,19 +2214,6 @@ msgstr "Cambiar cantidad"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Cambiar Ctd. producto"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2390,6 +2335,33 @@ msgstr ""
|
|||
msgid "Products to Consume"
|
||||
msgstr "Productos a consumir"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisión"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Fecha de modificación"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nombre de modificación"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisión de lista de materiales"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Último índice"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisiones lista de materiales"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Descripción"
|
||||
|
||||
#~ msgid "-"
|
||||
#~ msgstr "-"
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -225,11 +225,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Para material comprado"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -497,11 +492,6 @@ msgstr "Descomposición fabricación"
|
|||
msgid "For Services."
|
||||
msgstr "Para servicios"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Fecha modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -563,11 +553,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr "Forzar reservas"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -861,11 +846,6 @@ msgstr "Total ciclos"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Listo para producir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nombre de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1453,11 +1433,6 @@ msgstr "Abastecer productos"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Cargas centro de producción"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisión de lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2000,12 +1975,6 @@ msgstr "Tiempo en horas para la configuración."
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2023,17 +1992,6 @@ msgstr "Asignación desde stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperando mercancía"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Último índice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisiones lista de materiales"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2222,19 +2180,6 @@ msgstr "Cambiar cantidad"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Cambiar Ctd. producto"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2374,6 +2319,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Invalid model name in the action definition."
|
||||
#~ msgstr "Nombre de modelo no válido en la definición de acción."
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisión"
|
||||
|
||||
#~ msgid "Compute Stock Minimum Rules Only"
|
||||
#~ msgstr "Calcular sólo reglas de stock mínimo"
|
||||
|
||||
|
@ -2521,6 +2469,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Make Procurement"
|
||||
#~ msgstr "Realizar abastecimiento"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Fecha modificación"
|
||||
|
||||
#~ msgid "If Procure method is Make to order and supply method is produce"
|
||||
#~ msgstr ""
|
||||
#~ "si método de abastecimiento es obtener bajo pedido y método de suministro es "
|
||||
|
@ -2529,6 +2480,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Purchase Lead Time"
|
||||
#~ msgstr "Plazo de tiempo de compra"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Stockable Product Stock"
|
||||
#~ msgstr "Stock de producto almacenable"
|
||||
|
||||
|
@ -2620,6 +2574,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Días de seguridad"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nombre de modificación"
|
||||
|
||||
#~ msgid "Exception"
|
||||
#~ msgstr "Excepción"
|
||||
|
||||
|
@ -2960,6 +2917,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "plus"
|
||||
#~ msgstr "más"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Lista de materiales (LdM)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The list of operations (list of workcenters) to produce the finished "
|
||||
#~ "product. The routing is mainly used to compute workcenter costs during "
|
||||
|
@ -2981,6 +2941,12 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "A Request for Quotation is created and sent to the supplier."
|
||||
#~ msgstr "Una solicitud de presupuesto es creada y enviada al proveedor."
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Último índice"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisiones lista de materiales"
|
||||
|
||||
#~ msgid "Retry"
|
||||
#~ msgstr "Volver a intentar"
|
||||
|
||||
|
@ -3031,6 +2997,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Close Move at end"
|
||||
#~ msgstr "Movimiento de cierre al final"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Descripción"
|
||||
|
||||
#~ msgid "Running"
|
||||
#~ msgstr "En proceso"
|
||||
|
||||
|
@ -3352,6 +3321,9 @@ msgstr "Productos a consumir"
|
|||
#~ msgid "Image"
|
||||
#~ msgstr "Imágen"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisión de lista de materiales"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Routing indicates all the workcenters used, for how long and/or cycles.If "
|
||||
#~ "Routing is indicated then,the third tab of a production order (workcenters) "
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -210,11 +210,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisjon"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -469,11 +464,6 @@ msgstr ""
|
|||
msgid "For Services."
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Muutmise Kuupäev"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -531,11 +521,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -816,11 +801,6 @@ msgstr "Kokku tsükkleid"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Valmis tootmiseks"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Modifikatsiooni nimi"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1381,11 +1361,6 @@ msgstr "Hangi tooted"
|
|||
msgid "Work Center Loads"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1889,12 +1864,6 @@ msgstr ""
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1912,17 +1881,6 @@ msgstr ""
|
|||
msgid "Waiting Goods"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2108,19 +2066,6 @@ msgstr ""
|
|||
msgid "Change Product Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2232,6 +2177,9 @@ msgstr ""
|
|||
#~ msgid "Moves Created"
|
||||
#~ msgstr "Liikumised loodud"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisjon"
|
||||
|
||||
#~ msgid "Compute Stock Minimum Rules Only"
|
||||
#~ msgstr "Arvuta ainult lao miinimum reeglid"
|
||||
|
||||
|
@ -2325,6 +2273,12 @@ msgstr ""
|
|||
#~ msgid "Print product price"
|
||||
#~ msgstr "Prindi toote hind"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Muutmise Kuupäev"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Latest error"
|
||||
#~ msgstr "Viimane viga"
|
||||
|
||||
|
@ -2353,6 +2307,9 @@ msgstr ""
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Turvalised Päevad"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Modifikatsiooni nimi"
|
||||
|
||||
#~ msgid "Exception"
|
||||
#~ msgstr "Erand"
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:58+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -224,11 +224,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Ostettaville materiaaleille"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisio"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -496,11 +491,6 @@ msgstr "Valmistusrakenteen purkaminen"
|
|||
msgid "For Services."
|
||||
msgstr "Palveluille"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Muokkauspäivä"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -560,11 +550,6 @@ msgstr "Määrittele työpisteesi"
|
|||
msgid "Force Reservation"
|
||||
msgstr "Pakota varaus"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Tekijä"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -849,11 +834,6 @@ msgstr "Kierrot yhteensä"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Valmis tuotantoon"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Muutoksen nimi"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1428,11 +1408,6 @@ msgstr "Hanki tuotteita"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Työpisteen kuormitus"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Osaluettelon versio"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1947,12 +1922,6 @@ msgstr "Asetuksiin kuluva aika tunneissa."
|
|||
msgid "Orange Juice"
|
||||
msgstr "Appelssiinimehu"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Osaluettelo"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -1970,17 +1939,6 @@ msgstr "Varastosta otto"
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Odottaa tuotteita"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Viimeinen järjestys"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Osaluettelon revisiot"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2171,19 +2129,6 @@ msgstr "Muuta määrää"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Muuta tuotteen määrää"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Kuvaus"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2338,6 +2283,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "Make Procurement"
|
||||
#~ msgstr "Tee hankinta"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Tekijä"
|
||||
|
||||
#~ msgid "Latest error"
|
||||
#~ msgstr "Viimeisin virhe"
|
||||
|
||||
|
@ -2416,6 +2364,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "Service Product"
|
||||
#~ msgstr "Palvelutuote"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisio"
|
||||
|
||||
#~ msgid "Invalid model name in the action definition."
|
||||
#~ msgstr "Virheellinen mallin nimi toiminnon määrittelyssä."
|
||||
|
||||
|
@ -2554,6 +2505,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "Purchase Lead Time"
|
||||
#~ msgstr "Oston läpimenoaika"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Muokkauspäivä"
|
||||
|
||||
#~ msgid "Routing workcenter usage"
|
||||
#~ msgstr "Reititys työpisteiden käyttö"
|
||||
|
||||
|
@ -2647,6 +2601,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "Serivce Stockable Order"
|
||||
#~ msgstr "Huolto varastoitava tilaus"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Muutoksen nimi"
|
||||
|
||||
#~ msgid "Production done"
|
||||
#~ msgstr "Tuotanto valmis"
|
||||
|
||||
|
@ -2884,9 +2841,15 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "Canceled"
|
||||
#~ msgstr "Peruttu"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Osaluettelo"
|
||||
|
||||
#~ msgid "New Production Order"
|
||||
#~ msgstr "Uusi tuotantotilaus"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Viimeinen järjestys"
|
||||
|
||||
#~ msgid "plus"
|
||||
#~ msgstr "plus"
|
||||
|
||||
|
@ -2912,6 +2875,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "The normal working time of the workcenter."
|
||||
#~ msgstr "Työpisteen normaali työaika."
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Osaluettelon revisiot"
|
||||
|
||||
#~ msgid "Procurement Reason"
|
||||
#~ msgstr "Hankinnan syy"
|
||||
|
||||
|
@ -2944,6 +2910,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "TOTAL"
|
||||
#~ msgstr "Yhteensä"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Kuvaus"
|
||||
|
||||
#~ msgid "Close Move at end"
|
||||
#~ msgstr "Sulje siirto lopussa"
|
||||
|
||||
|
@ -3142,6 +3111,9 @@ msgstr "Käytettävät tuotteet"
|
|||
#~ msgid "Image"
|
||||
#~ msgstr "Kuva"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Osaluettelon versio"
|
||||
|
||||
#~ msgid "Manufacturing Operations"
|
||||
#~ msgstr "Valmistuksen vaiheet"
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,product_uom:0
|
||||
|
@ -242,11 +242,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Pour un produit acheté"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Révision"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -523,11 +518,6 @@ msgstr "Décomposition de la fabrication"
|
|||
msgid "For Services."
|
||||
msgstr "Pour les services."
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Date de modification"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -589,11 +579,6 @@ msgstr "Configurer les centres de travails"
|
|||
msgid "Force Reservation"
|
||||
msgstr "Forcer la réservation"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Auteur"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -886,11 +871,6 @@ msgstr "Cycles Totaux"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Prêt à Produire"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nom de la Modification"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1486,11 +1466,6 @@ msgstr "Approvisionner les produits"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Occupation des postes de charge"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Révision des nomenclatures"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -2028,12 +2003,6 @@ msgstr "Temps en Heures pour la mise en place"
|
|||
msgid "Orange Juice"
|
||||
msgstr "Jus d'orange"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Nomenclature"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2051,17 +2020,6 @@ msgstr "Affectation à partir du stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "En attente de marchandises"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Dernier Indice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Révisions des Nomenclatures"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2250,19 +2208,6 @@ msgstr "Changer la quantité"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Changer la Qté de Produits"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2409,6 +2354,9 @@ msgstr "Produits à consommer"
|
|||
#~ msgid "Moves Created"
|
||||
#~ msgstr "Mouvements créés"
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Révision"
|
||||
|
||||
#~ msgid "Packing list"
|
||||
#~ msgstr "Liste des Colisages"
|
||||
|
||||
|
@ -2457,6 +2405,12 @@ msgstr "Produits à consommer"
|
|||
#~ msgid "Print product price"
|
||||
#~ msgstr "Imprimer le prix du produit"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Date de modification"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Auteur"
|
||||
|
||||
#~ msgid "Latest error"
|
||||
#~ msgstr "Dernière Erreur"
|
||||
|
||||
|
@ -2487,6 +2441,9 @@ msgstr "Produits à consommer"
|
|||
#~ msgid "Security Days"
|
||||
#~ msgstr "Jours de sécurité"
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nom de la Modification"
|
||||
|
||||
#~ msgid "Exception"
|
||||
#~ msgstr "Exception"
|
||||
|
||||
|
@ -2601,9 +2558,18 @@ msgstr "Produits à consommer"
|
|||
#~ msgid "plus"
|
||||
#~ msgstr "plus"
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Nomenclature"
|
||||
|
||||
#~ msgid "New Production Order"
|
||||
#~ msgstr "Nouvel Ordre de Production"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Dernier Indice"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Révisions des Nomenclatures"
|
||||
|
||||
#~ msgid "Retry"
|
||||
#~ msgstr "Réessayez"
|
||||
|
||||
|
@ -2616,6 +2582,9 @@ msgstr "Produits à consommer"
|
|||
#~ msgid "Warehouse"
|
||||
#~ msgstr "Entrepôt"
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Description"
|
||||
|
||||
#~ msgid "Running"
|
||||
#~ msgstr "En cours"
|
||||
|
||||
|
@ -3272,6 +3241,9 @@ msgstr "Produits à consommer"
|
|||
#~ msgid "Total Cost of "
|
||||
#~ msgstr "Coût total "
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Révision des nomenclatures"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Work Cost of "
|
||||
#~ msgstr "Coût de fabrication de "
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-08-28 05:59+0000\n"
|
||||
"X-Generator: Launchpad (build 15864)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-13 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 15944)\n"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.routing.workcenter:0
|
||||
|
@ -226,11 +226,6 @@ msgstr ""
|
|||
msgid "For purchased material"
|
||||
msgstr "Para material mercado"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,indice:0
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.actions.act_window,help:mrp.product_form_config_action
|
||||
msgid ""
|
||||
|
@ -498,11 +493,6 @@ msgstr "Descomposición fabricación"
|
|||
msgid "For Services."
|
||||
msgstr "Para servizos"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,date:0
|
||||
msgid "Modification Date"
|
||||
msgstr "Data de modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.workcenter,costs_cycle_account_id:0
|
||||
#: help:mrp.workcenter,costs_hour_account_id:0
|
||||
|
@ -564,11 +554,6 @@ msgstr ""
|
|||
msgid "Force Reservation"
|
||||
msgstr "Forzar reservas"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,author_id:0
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,value:0
|
||||
msgid "Stock value"
|
||||
|
@ -859,11 +844,6 @@ msgstr "Ciclos totais"
|
|||
msgid "Ready to Produce"
|
||||
msgstr "Listo para producir"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,name:0
|
||||
msgid "Modification name"
|
||||
msgstr "Nome da modificación"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom:0
|
||||
#: view:mrp.production:0
|
||||
|
@ -1450,11 +1430,6 @@ msgstr "Abastecer produtos"
|
|||
msgid "Work Center Loads"
|
||||
msgstr "Cargas centro de produción"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_mrp_bom_revision
|
||||
msgid "Bill of Material Revision"
|
||||
msgstr "Revisión da lista de materiais"
|
||||
|
||||
#. module: mrp
|
||||
#: help:mrp.production,origin:0
|
||||
msgid ""
|
||||
|
@ -1990,12 +1965,6 @@ msgstr "Tempo en horas para a configuración."
|
|||
msgid "Orange Juice"
|
||||
msgstr ""
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,bom_id:0
|
||||
#: field:procurement.order,bom_id:0
|
||||
msgid "BoM"
|
||||
msgstr "Lista de materiais"
|
||||
|
||||
#. module: mrp
|
||||
#: model:ir.model,name:mrp.model_report_mrp_inout
|
||||
#: view:report.mrp.inout:0
|
||||
|
@ -2013,17 +1982,6 @@ msgstr "Asignación desde stock."
|
|||
msgid "Waiting Goods"
|
||||
msgstr "Esperando mercancía"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom.revision,last_indice:0
|
||||
msgid "last indice"
|
||||
msgstr "Último índice"
|
||||
|
||||
#. module: mrp
|
||||
#: field:mrp.bom,revision_ids:0
|
||||
#: view:mrp.bom.revision:0
|
||||
msgid "BoM Revisions"
|
||||
msgstr "Revisións lista de materiais"
|
||||
|
||||
#. module: mrp
|
||||
#: field:report.mrp.inout,date:0
|
||||
#: field:report.workcenter.load,name:0
|
||||
|
@ -2212,19 +2170,6 @@ msgstr "Cambiar cantidade"
|
|||
msgid "Change Product Qty"
|
||||
msgstr "Cambiar Ctde producto"
|
||||
|
||||
#. module: mrp
|
||||
#: view:mrp.bom.revision:0
|
||||
#: field:mrp.bom.revision,description:0
|
||||
#: view:mrp.property:0
|
||||
#: view:mrp.property.group:0
|
||||
#: field:mrp.routing,note:0
|
||||
#: view:mrp.routing.workcenter:0
|
||||
#: field:mrp.routing.workcenter,note:0
|
||||
#: view:mrp.workcenter:0
|
||||
#: field:mrp.workcenter,note:0
|
||||
msgid "Description"
|
||||
msgstr "Descrición"
|
||||
|
||||
#. module: mrp
|
||||
#: view:board.board:0
|
||||
msgid "Manufacturing board"
|
||||
|
@ -2368,6 +2313,9 @@ msgstr "Produtos a consumir"
|
|||
#~ "Mellora as ordes de produción cos estados de preparación, así como a data de "
|
||||
#~ "inicio e final da execución da orde."
|
||||
|
||||
#~ msgid "Revision"
|
||||
#~ msgstr "Revisión"
|
||||
|
||||
#~ msgid "title"
|
||||
#~ msgstr "título"
|
||||
|
||||
|
@ -2400,6 +2348,12 @@ msgstr "Produtos a consumir"
|
|||
#~ "Activa a garantía e a xestión das reparacións (e o seu impacto sobre os "
|
||||
#~ "stocks e a facturación)"
|
||||
|
||||
#~ msgid "Author"
|
||||
#~ msgstr "Autor"
|
||||
|
||||
#~ msgid "Modification Date"
|
||||
#~ msgstr "Data de modificación"
|
||||
|
||||
#~ msgid "March"
|
||||
#~ msgstr "Marzo"
|
||||
|
||||
|
@ -2442,6 +2396,9 @@ msgstr "Produtos a consumir"
|
|||
#~ msgid "Extended Filters..."
|
||||
#~ msgstr "Filtros extendidos..."
|
||||
|
||||
#~ msgid "Modification name"
|
||||
#~ msgstr "Nome da modificación"
|
||||
|
||||
#~ msgid "Just In Time Scheduling"
|
||||
#~ msgstr "Planificación 'Just in Time'"
|
||||
|
||||
|
@ -2622,6 +2579,9 @@ msgstr "Produtos a consumir"
|
|||
#~ "Estes informes permítenlle analizar as súas actividades productivas e o seu "
|
||||
#~ "rendemento."
|
||||
|
||||
#~ msgid "BoM"
|
||||
#~ msgstr "Lista de materiais"
|
||||
|
||||
#~ msgid "December"
|
||||
#~ msgstr "Decembro"
|
||||
|
||||
|
@ -2634,6 +2594,12 @@ msgstr "Produtos a consumir"
|
|||
#~ msgid "Configuration Progress"
|
||||
#~ msgstr "Progreso da configuración"
|
||||
|
||||
#~ msgid "BoM Revisions"
|
||||
#~ msgstr "Revisións lista de materiais"
|
||||
|
||||
#~ msgid "last indice"
|
||||
#~ msgstr "Último índice"
|
||||
|
||||
#~ msgid "Draft"
|
||||
#~ msgstr "Proxecto"
|
||||
|
||||
|
@ -2652,6 +2618,9 @@ msgstr "Produtos a consumir"
|
|||
#~ msgid "January"
|
||||
#~ msgstr "Xaneiro"
|
||||
|
||||
#~ msgid "Bill of Material Revision"
|
||||
#~ msgstr "Revisión da lista de materiais"
|
||||
|
||||
#~ msgid "Manufacturing Operations"
|
||||
#~ msgstr "Operacións de produción"
|
||||
|
||||
|
@ -2680,6 +2649,9 @@ msgstr "Produtos a consumir"
|
|||
#~ msgid "Work Cost of "
|
||||
#~ msgstr "Custo do traballo de "
|
||||
|
||||
#~ msgid "Description"
|
||||
#~ msgstr "Descrición"
|
||||
|
||||
#~ msgid "May"
|
||||
#~ msgstr "Maio"
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue