Merge remote-tracking branch 'odoo/master' into master-sass-in-bundles-fme

This commit is contained in:
Fabien Meghazi 2014-06-27 19:40:02 +02:00
commit 9fa77980d7
641 changed files with 9354 additions and 27178 deletions

View File

@ -5,6 +5,6 @@ Contributing to Odoo
TL;DR TL;DR
* Use the [template structure](https://raw.githubusercontent.com/odoo/odoo/master/doc/_templates/issue_template.md) * Use this [template](https://raw.githubusercontent.com/odoo/odoo/master/doc/_templates/issue_template.md) when reporting issues, and please search for duplicates first!
* Pull requests made against the [correct version](https://github.com/odoo/odoo/wiki/Contributing#against-which-version-should-i-submit-a-patch) * Pull requests must be made against the [correct version](https://github.com/odoo/odoo/wiki/Contributing#against-which-version-should-i-submit-a-patch)
* Read the restrictions for [changes in stable](https://github.com/odoo/odoo/wiki/Contributing#what-does-stable-mean) * There are restrictions on the kind of [changes allowed in stable series](https://github.com/odoo/odoo/wiki/Contributing#what-does-stable-mean)

View File

@ -59,7 +59,7 @@ class account_payment_term(osv.osv):
_name = "account.payment.term" _name = "account.payment.term"
_description = "Payment Term" _description = "Payment Term"
_columns = { _columns = {
'name': fields.char('Payment Term', size=64, translate=True, required=True), 'name': fields.char('Payment Term', translate=True, required=True),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the payment term without removing it."), 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the payment term without removing it."),
'note': fields.text('Description', translate=True), 'note': fields.text('Description', translate=True),
'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'), 'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'),
@ -180,7 +180,7 @@ class account_account_type(osv.osv):
return obj_financial_report.write(cr, uid, [financial_report_ref[field_value].id], {'account_type_ids': [(4, account_type_id)]}) return obj_financial_report.write(cr, uid, [financial_report_ref[field_value].id], {'account_type_ids': [(4, account_type_id)]})
_columns = { _columns = {
'name': fields.char('Account Type', size=64, required=True, translate=True), 'name': fields.char('Account Type', required=True, translate=True),
'code': fields.char('Code', size=32, required=True, select=True), 'code': fields.char('Code', size=32, required=True, select=True),
'close_method': fields.selection([('none', 'None'), ('balance', 'Balance'), ('detail', 'Detail'), ('unreconciled', 'Unreconciled')], 'Deferral Method', required=True, help="""Set here the method that will be used to generate the end of year journal entries for all the accounts of this type. 'close_method': fields.selection([('none', 'None'), ('balance', 'Balance'), ('detail', 'Detail'), ('unreconciled', 'Unreconciled')], 'Deferral Method', required=True, help="""Set here the method that will be used to generate the end of year journal entries for all the accounts of this type.
@ -444,7 +444,7 @@ class account_account(osv.osv):
return True return True
_columns = { _columns = {
'name': fields.char('Name', size=256, required=True, select=True), 'name': fields.char('Name', required=True, select=True),
'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."), 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
'code': fields.char('Code', size=64, required=True, select=1), 'code': fields.char('Code', size=64, required=True, select=1),
'type': fields.selection([ 'type': fields.selection([
@ -715,7 +715,7 @@ class account_journal(osv.osv):
_description = "Journal" _description = "Journal"
_columns = { _columns = {
'with_last_closing_balance' : fields.boolean('Opening With Last Closing Balance'), 'with_last_closing_balance' : fields.boolean('Opening With Last Closing Balance'),
'name': fields.char('Journal Name', size=64, required=True), 'name': fields.char('Journal Name', required=True),
'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."), 'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."),
'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Checks'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True, 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Checks'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True,
help="Select 'Sale' for customer invoices journals."\ help="Select 'Sale' for customer invoices journals."\
@ -859,7 +859,7 @@ class account_fiscalyear(osv.osv):
_name = "account.fiscalyear" _name = "account.fiscalyear"
_description = "Fiscal Year" _description = "Fiscal Year"
_columns = { _columns = {
'name': fields.char('Fiscal Year', size=64, required=True), 'name': fields.char('Fiscal Year', required=True),
'code': fields.char('Code', size=6, required=True), 'code': fields.char('Code', size=6, required=True),
'company_id': fields.many2one('res.company', 'Company', required=True), 'company_id': fields.many2one('res.company', 'Company', required=True),
'date_start': fields.date('Start Date', required=True), 'date_start': fields.date('Start Date', required=True),
@ -952,10 +952,9 @@ class account_period(osv.osv):
_name = "account.period" _name = "account.period"
_description = "Account period" _description = "Account period"
_columns = { _columns = {
'name': fields.char('Period Name', size=64, required=True), 'name': fields.char('Period Name', required=True),
'code': fields.char('Code', size=12), 'code': fields.char('Code', size=12),
'special': fields.boolean('Opening/Closing Period', size=12, 'special': fields.boolean('Opening/Closing Period',help="These periods can overlap."),
help="These periods can overlap."),
'date_start': fields.date('Start of Period', required=True, states={'done':[('readonly',True)]}), 'date_start': fields.date('Start of Period', required=True, states={'done':[('readonly',True)]}),
'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}), 'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}),
'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True), 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
@ -1092,10 +1091,10 @@ class account_journal_period(osv.osv):
return result return result
_columns = { _columns = {
'name': fields.char('Journal-Period Name', size=64, required=True), 'name': fields.char('Journal-Period Name', required=True),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"),
'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"), 'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"),
'icon': fields.function(_icon_get, string='Icon', type='char', size=32), 'icon': fields.function(_icon_get, string='Icon', type='char'),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the journal period without removing it."), 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the journal period without removing it."),
'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'Status', required=True, readonly=True, 'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'Status', required=True, readonly=True,
help='When journal period is created. The status is \'Draft\'. If a report is printed it comes to \'Printed\' status. When all transactions are done, it comes in \'Done\' status.'), help='When journal period is created. The status is \'Draft\'. If a report is printed it comes to \'Printed\' status. When all transactions are done, it comes in \'Done\' status.'),
@ -1235,8 +1234,8 @@ class account_move(osv.osv):
return [line.move_id.id for line in line_obj.browse(cr, uid, ids, context=context)] return [line.move_id.id for line in line_obj.browse(cr, uid, ids, context=context)]
_columns = { _columns = {
'name': fields.char('Number', size=64, required=True), 'name': fields.char('Number', required=True),
'ref': fields.char('Reference', size=64), 'ref': fields.char('Reference'),
'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}), 'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'Status', required=True, readonly=True, 'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'Status', required=True, readonly=True,
@ -1629,8 +1628,8 @@ class account_move_reconcile(osv.osv):
_name = "account.move.reconcile" _name = "account.move.reconcile"
_description = "Account Reconciliation" _description = "Account Reconciliation"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'type': fields.char('Type', size=16, required=True), 'type': fields.char('Type', required=True),
'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry Lines'), 'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry Lines'),
'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'), 'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'),
'create_date': fields.date('Creation date', readonly=True), 'create_date': fields.date('Creation date', readonly=True),
@ -1787,7 +1786,7 @@ class account_tax_code(osv.osv):
_description = 'Tax Code' _description = 'Tax Code'
_rec_name = 'code' _rec_name = 'code'
_columns = { _columns = {
'name': fields.char('Tax Case Name', size=64, required=True, translate=True), 'name': fields.char('Tax Case Name', required=True, translate=True),
'code': fields.char('Case Code', size=64), 'code': fields.char('Case Code', size=64),
'info': fields.text('Description'), 'info': fields.text('Description'),
'sum': fields.function(_sum_year, string="Year Sum"), 'sum': fields.function(_sum_year, string="Year Sum"),
@ -1876,7 +1875,7 @@ class account_tax(osv.osv):
_name = 'account.tax' _name = 'account.tax'
_description = 'Tax' _description = 'Tax'
_columns = { _columns = {
'name': fields.char('Tax Name', size=64, required=True, translate=True, help="This name will be displayed on reports"), 'name': fields.char('Tax Name', required=True, translate=True, help="This name will be displayed on reports"),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the tax lines from the lowest sequences to the higher ones. The order is important if you have a tax with several tax children. In this case, the evaluation order is important."), 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the tax lines from the lowest sequences to the higher ones. The order is important if you have a tax with several tax children. In this case, the evaluation order is important."),
'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For taxes of type percentage, enter % ratio between 0-1."), 'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For taxes of type percentage, enter % ratio between 0-1."),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the tax without removing it."), 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the tax without removing it."),
@ -1884,7 +1883,7 @@ class account_tax(osv.osv):
help="The computation method for the tax amount."), help="The computation method for the tax amount."),
'applicable_type': fields.selection( [('true','Always'), ('code','Given by Python Code')], 'Applicability', required=True, 'applicable_type': fields.selection( [('true','Always'), ('code','Given by Python Code')], 'Applicability', required=True,
help="If not applicable (computed through a Python code), the tax won't appear on the invoice."), help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."), 'domain':fields.char('Domain', help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account', help="Set the account that will be set by default on invoice tax lines for invoices. Leave empty to use the expense account."), 'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account', help="Set the account that will be set by default on invoice tax lines for invoices. Leave empty to use the expense account."),
'account_paid_id':fields.many2one('account.account', 'Refund Tax Account', help="Set the account that will be set by default on invoice tax lines for refunds. Leave empty to use the expense account."), 'account_paid_id':fields.many2one('account.account', 'Refund Tax Account', help="Set the account that will be set by default on invoice tax lines for refunds. Leave empty to use the expense account."),
'account_analytic_collected_id':fields.many2one('account.analytic.account', 'Invoice Tax Analytic Account', help="Set the analytic account that will be used by default on the invoice tax lines for invoices. Leave empty if you don't want to use an analytic account on the invoice tax lines by default."), 'account_analytic_collected_id':fields.many2one('account.analytic.account', 'Invoice Tax Analytic Account', help="Set the analytic account that will be used by default on the invoice tax lines for invoices. Leave empty if you don't want to use an analytic account on the invoice tax lines by default."),
@ -2267,7 +2266,7 @@ class account_model(osv.osv):
_name = "account.model" _name = "account.model"
_description = "Account Model" _description = "Account Model"
_columns = { _columns = {
'name': fields.char('Model Name', size=64, required=True, help="This is a model for recurring accounting entries"), 'name': fields.char('Model Name', required=True, help="This is a model for recurring accounting entries"),
'journal_id': fields.many2one('account.journal', 'Journal', required=True), 'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries'), 'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries'),
@ -2374,7 +2373,7 @@ class account_model_line(osv.osv):
_name = "account.model.line" _name = "account.model.line"
_description = "Account Model Entries" _description = "Account Model Entries"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones."), 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones."),
'quantity': fields.float('Quantity', digits_compute=dp.get_precision('Account'), help="The optional quantity on entries."), 'quantity': fields.float('Quantity', digits_compute=dp.get_precision('Account'), help="The optional quantity on entries."),
'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')), 'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')),
@ -2402,8 +2401,8 @@ class account_subscription(osv.osv):
_name = "account.subscription" _name = "account.subscription"
_description = "Account Subscription" _description = "Account Subscription"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'ref': fields.char('Reference', size=16), 'ref': fields.char('Reference'),
'model_id': fields.many2one('account.model', 'Model', required=True), 'model_id': fields.many2one('account.model', 'Model', required=True),
'date_start': fields.date('Start Date', required=True), 'date_start': fields.date('Start Date', required=True),
'period_total': fields.integer('Number of Periods', required=True), 'period_total': fields.integer('Number of Periods', required=True),
@ -2507,7 +2506,7 @@ class account_account_template(osv.osv):
_description ='Templates for Accounts' _description ='Templates for Accounts'
_columns = { _columns = {
'name': fields.char('Name', size=256, required=True, select=True), 'name': fields.char('Name', required=True, select=True),
'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."), 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
'code': fields.char('Code', size=64, required=True, select=1), 'code': fields.char('Code', size=64, required=True, select=1),
'type': fields.selection([ 'type': fields.selection([
@ -2688,7 +2687,7 @@ class account_tax_code_template(osv.osv):
_order = 'code' _order = 'code'
_rec_name = 'code' _rec_name = 'code'
_columns = { _columns = {
'name': fields.char('Tax Case Name', size=64, required=True), 'name': fields.char('Tax Case Name', required=True),
'code': fields.char('Case Code', size=64), 'code': fields.char('Case Code', size=64),
'info': fields.text('Description'), 'info': fields.text('Description'),
'parent_id': fields.many2one('account.tax.code.template', 'Parent Code', select=True), 'parent_id': fields.many2one('account.tax.code.template', 'Parent Code', select=True),
@ -2758,7 +2757,7 @@ class account_chart_template(osv.osv):
_description= "Templates for Account Chart" _description= "Templates for Account Chart"
_columns={ _columns={
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'parent_id': fields.many2one('account.chart.template', 'Parent Chart Template'), 'parent_id': fields.many2one('account.chart.template', 'Parent Chart Template'),
'code_digits': fields.integer('# of Digits', required=True, help="No. of Digits to use for account code"), 'code_digits': fields.integer('# of Digits', required=True, help="No. of Digits to use for account code"),
'visible': fields.boolean('Can be Visible?', help="Set this to False if you don't want this template to be used actively in the wizard that generate Chart of Accounts from templates, this is useful when you want to generate accounts of this template only when loading its child template."), 'visible': fields.boolean('Can be Visible?', help="Set this to False if you don't want this template to be used actively in the wizard that generate Chart of Accounts from templates, this is useful when you want to generate accounts of this template only when loading its child template."),
@ -2792,12 +2791,12 @@ class account_tax_template(osv.osv):
_columns = { _columns = {
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True), 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
'name': fields.char('Tax Name', size=64, required=True), 'name': fields.char('Tax Name', required=True),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the taxes lines from lower sequences to higher ones. The order is important if you have a tax that has several tax children. In this case, the evaluation order is important."), 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the taxes lines from lower sequences to higher ones. The order is important if you have a tax that has several tax children. In this case, the evaluation order is important."),
'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For Tax Type percent enter % ratio between 0-1."), 'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For Tax Type percent enter % ratio between 0-1."),
'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True), 'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True),
'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True, help="If not applicable (computed through a Python code), the tax won't appear on the invoice."), 'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True, help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."), 'domain':fields.char('Domain', help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'), 'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'),
'account_paid_id':fields.many2one('account.account.template', 'Refund Tax Account'), 'account_paid_id':fields.many2one('account.account.template', 'Refund Tax Account'),
'parent_id':fields.many2one('account.tax.template', 'Parent Tax Account', select=True), 'parent_id':fields.many2one('account.tax.template', 'Parent Tax Account', select=True),
@ -2921,7 +2920,7 @@ class account_fiscal_position_template(osv.osv):
_description = 'Template for Fiscal Position' _description = 'Template for Fiscal Position'
_columns = { _columns = {
'name': fields.char('Fiscal Position Template', size=64, required=True), 'name': fields.char('Fiscal Position Template', required=True),
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True), 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
'account_ids': fields.one2many('account.fiscal.position.account.template', 'position_id', 'Account Mapping'), 'account_ids': fields.one2many('account.fiscal.position.account.template', 'position_id', 'Account Mapping'),
'tax_ids': fields.one2many('account.fiscal.position.tax.template', 'position_id', 'Tax Mapping'), 'tax_ids': fields.one2many('account.fiscal.position.tax.template', 'position_id', 'Tax Mapping'),
@ -3553,10 +3552,10 @@ class account_bank_accounts_wizard(osv.osv_memory):
_name='account.bank.accounts.wizard' _name='account.bank.accounts.wizard'
_columns = { _columns = {
'acc_name': fields.char('Account Name.', size=64, required=True), 'acc_name': fields.char('Account Name.', required=True),
'bank_account_id': fields.many2one('wizard.multi.charts.accounts', 'Bank Account', required=True, ondelete='cascade'), 'bank_account_id': fields.many2one('wizard.multi.charts.accounts', 'Bank Account', required=True, ondelete='cascade'),
'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."), 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
'account_type': fields.selection([('cash','Cash'), ('check','Check'), ('bank','Bank')], 'Account Type', size=32), 'account_type': fields.selection([('cash','Cash'), ('check','Check'), ('bank','Bank')], 'Account Type'),
} }

View File

@ -33,7 +33,7 @@ class account_analytic_line(osv.osv):
'move_id': fields.many2one('account.move.line', 'Move Line', ondelete='cascade', select=True), 'move_id': fields.many2one('account.move.line', 'Move Line', ondelete='cascade', select=True),
'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal', required=True, ondelete='restrict', select=True), 'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal', required=True, ondelete='restrict', select=True),
'code': fields.char('Code', size=8), 'code': fields.char('Code', size=8),
'ref': fields.char('Ref.', size=64), 'ref': fields.char('Ref.'),
'currency_id': fields.related('move_id', 'currency_id', type='many2one', relation='res.currency', string='Account Currency', store=True, help="The related account currency if not equal to the company one.", readonly=True), 'currency_id': fields.related('move_id', 'currency_id', type='many2one', relation='res.currency', string='Account Currency', store=True, help="The related account currency if not equal to the company one.", readonly=True),
'amount_currency': fields.related('move_id', 'amount_currency', type='float', string='Amount Currency', store=True, help="The amount expressed in the related account currency if not equal to the company one.", readonly=True), 'amount_currency': fields.related('move_id', 'amount_currency', type='float', string='Amount Currency', store=True, help="The amount expressed in the related account currency if not equal to the company one.", readonly=True),
} }

View File

@ -114,7 +114,7 @@ class account_bank_statement(osv.osv):
_description = "Bank Statement" _description = "Bank Statement"
_inherit = ['mail.thread'] _inherit = ['mail.thread']
_columns = { _columns = {
'name': fields.char('Reference', size=64, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement 'name': fields.char('Reference', states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True), 'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, 'journal_id': fields.many2one('account.journal', 'Journal', required=True,
readonly=True, states={'draft':[('readonly',False)]}), readonly=True, states={'draft':[('readonly',False)]}),
@ -448,15 +448,31 @@ class account_bank_statement_line(osv.osv):
""" Used to instanciate a batch of reconciliations in a single request """ """ Used to instanciate a batch of reconciliations in a single request """
# Build a list of reconciliations data # Build a list of reconciliations data
ret = [] ret = []
statement_line_done = {}
mv_line_ids_selected = [] mv_line_ids_selected = []
for st_line in self.browse(cr, uid, ids, context=context):
# look for structured communication first
exact_match_id = self.search_structured_com(cr, uid, st_line, context=context)
if exact_match_id:
reconciliation_data = {
'st_line': self.get_statement_line_for_reconciliation(cr, uid, st_line.id, context),
'reconciliation_proposition': self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], context=context)
}
for mv_line in reconciliation_data['reconciliation_proposition']:
mv_line_ids_selected.append(mv_line['id'])
statement_line_done[st_line.id] = reconciliation_data
for st_line_id in ids: for st_line_id in ids:
reconciliation_data = { if statement_line_done.get(st_line_id):
'st_line': self.get_statement_line_for_reconciliation(cr, uid, st_line_id, context), ret.append(statement_line_done.get(st_line_id))
'reconciliation_proposition': self.get_reconciliation_proposition(cr, uid, st_line_id, mv_line_ids_selected, context) else:
} reconciliation_data = {
for mv_line in reconciliation_data['reconciliation_proposition']: 'st_line': self.get_statement_line_for_reconciliation(cr, uid, st_line_id, context),
mv_line_ids_selected.append(mv_line['id']) 'reconciliation_proposition': self.get_reconciliation_proposition(cr, uid, st_line_id, mv_line_ids_selected, context)
ret.append(reconciliation_data) }
for mv_line in reconciliation_data['reconciliation_proposition']:
mv_line_ids_selected.append(mv_line['id'])
ret.append(reconciliation_data)
# Check if, now that 'candidate' move lines were selected, there are moves left for statement lines # Check if, now that 'candidate' move lines were selected, there are moves left for statement lines
#for reconciliation_data in ret: #for reconciliation_data in ret:
@ -529,23 +545,19 @@ class account_bank_statement_line(osv.osv):
if st_line.amount < 0: if st_line.amount < 0:
sign = -1 sign = -1
# look for structured communication
exact_match_id = self.search_structured_com(cr, uid, st_line, context=context)
if exact_match_id:
return self.make_counter_part_lines(cr, uid, st_line, [exact_match_id], count=False, context=context)
#we don't propose anything if there is no partner detected #we don't propose anything if there is no partner detected
if not st_line.partner_id.id: if not st_line.partner_id.id:
return [] return []
# look for exact match # look for exact match
exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=1, additional_domain=[(amount_field, '=', (sign * st_line.amount))]) exact_match_id = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, additional_domain=[(amount_field, '=', (sign * st_line.amount))])
if exact_match_id: if exact_match_id:
return exact_match_id return exact_match_id[0]
# select oldest move lines # select oldest move lines
if sign == -1: if sign == -1:
mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field, '<', 0)]) mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, additional_domain=[(amount_field, '<', 0)])
else: else:
mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, limit=50, additional_domain=[(amount_field, '>', 0)]) mv_lines = self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids=excluded_ids, additional_domain=[(amount_field, '>', 0)])
ret = [] ret = []
total = 0 total = 0
# get_move_lines_counterparts inverts debit and credit # get_move_lines_counterparts inverts debit and credit
@ -558,11 +570,11 @@ class account_bank_statement_line(osv.osv):
break break
return ret return ret
def get_move_lines_counterparts_id(self, cr, uid, st_line_id, excluded_ids=[], filter_str="", offset=0, limit=None, count=False, additional_domain=[], context=None): def get_move_lines_counterparts_id(self, cr, uid, st_line_id, excluded_ids=[], additional_domain=[], count=False, context=None):
st_line = self.browse(cr, uid, st_line_id, context=context) st_line = self.browse(cr, uid, st_line_id, context=context)
return self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids, filter_str, offset, limit, count, additional_domain, context=context) return self.get_move_lines_counterparts(cr, uid, st_line, excluded_ids, additional_domain, count, context=context)
def get_move_lines_counterparts(self, cr, uid, st_line, excluded_ids=[], filter_str="", offset=0, limit=None, count=False, additional_domain=[], context=None): def get_move_lines_counterparts(self, cr, uid, st_line, excluded_ids=[], additional_domain=[], count=False, context=None):
""" Find the move lines that could be used to reconcile a statement line and returns the counterpart that could be created to reconcile them """ Find the move lines that could be used to reconcile a statement line and returns the counterpart that could be created to reconcile them
If count is true, only returns the count. If count is true, only returns the count.
@ -576,10 +588,7 @@ class account_bank_statement_line(osv.osv):
""" """
mv_line_pool = self.pool.get('account.move.line') mv_line_pool = self.pool.get('account.move.line')
domain = additional_domain + [ domain = additional_domain + [('reconcile_id', '=', False),('state', '=', 'valid')]
('reconcile_id', '=', False),
('state', '=', 'valid'),
]
if st_line.partner_id.id: if st_line.partner_id.id:
domain += [('partner_id', '=', st_line.partner_id.id), domain += [('partner_id', '=', st_line.partner_id.id),
'|', ('account_id.type', '=', 'receivable'), '|', ('account_id.type', '=', 'receivable'),
@ -589,11 +598,7 @@ class account_bank_statement_line(osv.osv):
#domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')] #domain += [('account_id.reconcile', '=', True), ('account_id.type', '=', 'other')]
if excluded_ids: if excluded_ids:
domain.append(('id', 'not in', excluded_ids)) domain.append(('id', 'not in', excluded_ids))
if filter_str: line_ids = mv_line_pool.search(cr, uid, domain, order="date_maturity asc, id asc", context=context)
if not st_line.partner_id:
domain += [ '|', ('partner_id.name', 'ilike', filter_str)]
domain += ['|', ('move_id.name', 'ilike', filter_str), ('move_id.ref', 'ilike', filter_str)]
line_ids = mv_line_pool.search(cr, uid, domain, offset=offset, limit=limit, order="date_maturity asc, id asc", context=context)
return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context) return self.make_counter_part_lines(cr, uid, st_line, line_ids, count=count, context=context)
def make_counter_part_lines(self, cr, uid, st_line, line_ids, count=False, context=None): def make_counter_part_lines(self, cr, uid, st_line, line_ids, count=False, context=None):

View File

@ -97,7 +97,7 @@ class account_financial_report(osv.osv):
return res return res
_columns = { _columns = {
'name': fields.char('Report Name', size=128, required=True, translate=True), 'name': fields.char('Report Name', required=True, translate=True),
'parent_id': fields.many2one('account.financial.report', 'Parent'), 'parent_id': fields.many2one('account.financial.report', 'Parent'),
'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'), 'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'),
'sequence': fields.integer('Sequence'), 'sequence': fields.integer('Sequence'),

View File

@ -24,7 +24,7 @@ from lxml import etree
import openerp.addons.decimal_precision as dp import openerp.addons.decimal_precision as dp
import openerp.exceptions import openerp.exceptions
from openerp.osv import fields, osv, orm from openerp.osv import fields, osv
from openerp.tools.translate import _ from openerp.tools.translate import _
class account_invoice(osv.osv): class account_invoice(osv.osv):
@ -226,8 +226,8 @@ class account_invoice(osv.osv):
}, },
} }
_columns = { _columns = {
'name': fields.char('Reference/Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}), 'name': fields.char('Reference/Description', select=True, readonly=True, states={'draft':[('readonly',False)]}),
'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}), 'origin': fields.char('Source Document', help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}),
'supplier_invoice_number': fields.char('Supplier Invoice Number', size=64, help="The reference of this invoice as provided by the supplier.", readonly=True, states={'draft':[('readonly',False)]}), 'supplier_invoice_number': fields.char('Supplier Invoice Number', size=64, help="The reference of this invoice as provided by the supplier.", readonly=True, states={'draft':[('readonly',False)]}),
'type': fields.selection([ 'type': fields.selection([
('out_invoice','Customer Invoice'), ('out_invoice','Customer Invoice'),
@ -237,8 +237,8 @@ class account_invoice(osv.osv):
],'Type', readonly=True, select=True, change_default=True, track_visibility='always'), ],'Type', readonly=True, select=True, change_default=True, track_visibility='always'),
'number': fields.related('move_id','name', type='char', readonly=True, size=64, relation='account.move', store=True, string='Number'), 'number': fields.related('move_id','name', type='char', readonly=True, size=64, relation='account.move', store=True, string='Number'),
'internal_number': fields.char('Invoice Number', size=32, readonly=True, help="Unique number of the invoice, computed automatically when the invoice is created."), 'internal_number': fields.char('Invoice Number', readonly=True, help="Unique number of the invoice, computed automatically when the invoice is created."),
'reference': fields.char('Invoice Reference', size=64, help="The partner reference of this invoice."), 'reference': fields.char('Invoice Reference', help="The partner reference of this invoice."),
'reference_type': fields.selection(_get_reference_type, 'Payment Reference', 'reference_type': fields.selection(_get_reference_type, 'Payment Reference',
required=True, readonly=True, states={'draft':[('readonly',False)]}), required=True, readonly=True, states={'draft':[('readonly',False)]}),
'comment': fields.text('Additional Information'), 'comment': fields.text('Additional Information'),
@ -318,7 +318,7 @@ class account_invoice(osv.osv):
}, },
help="Remaining amount due."), help="Remaining amount due."),
'payment_ids': fields.function(_compute_lines, relation='account.move.line', type="many2many", string='Payments'), 'payment_ids': fields.function(_compute_lines, relation='account.move.line', type="many2many", string='Payments'),
'move_name': fields.char('Journal Entry', size=64, readonly=True, states={'draft':[('readonly',False)]}), 'move_name': fields.char('Journal Entry', readonly=True, states={'draft':[('readonly',False)]}),
'user_id': fields.many2one('res.users', 'Salesperson', readonly=True, track_visibility='onchange', states={'draft':[('readonly',False)]}), 'user_id': fields.many2one('res.users', 'Salesperson', readonly=True, track_visibility='onchange', states={'draft':[('readonly',False)]}),
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]}), 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]}),
'commercial_partner_id': fields.related('partner_id', 'commercial_partner_id', string='Commercial Entity', type='many2one', 'commercial_partner_id': fields.related('partner_id', 'commercial_partner_id', string='Commercial Entity', type='many2one',
@ -903,6 +903,7 @@ class account_invoice(osv.osv):
move_obj = self.pool.get('account.move') move_obj = self.pool.get('account.move')
if context is None: if context is None:
context = {} context = {}
inv_date = {}
for inv in self.browse(cr, uid, ids, context=context): for inv in self.browse(cr, uid, ids, context=context):
if not inv.journal_id.sequence_id: if not inv.journal_id.sequence_id:
raise osv.except_osv(_('Error!'), _('Please define sequence on the journal related to this invoice.')) raise osv.except_osv(_('Error!'), _('Please define sequence on the journal related to this invoice.'))
@ -913,8 +914,8 @@ class account_invoice(osv.osv):
ctx = context.copy() ctx = context.copy()
ctx.update({'lang': inv.partner_id.lang}) ctx.update({'lang': inv.partner_id.lang})
if not inv.date_invoice: date_invoice = inv.date_invoice or fields.date.context_today(self,cr,uid,context=context)
self.write(cr, uid, [inv.id], {'date_invoice': fields.date.context_today(self,cr,uid,context=context)}, context=ctx) inv_date = {'date_invoice': date_invoice}
company_currency = self.pool['res.company'].browse(cr, uid, inv.company_id.id).currency_id.id company_currency = self.pool['res.company'].browse(cr, uid, inv.company_id.id).currency_id.id
# create the analytical lines # create the analytical lines
# one move line per invoice line # one move line per invoice line
@ -944,17 +945,10 @@ class account_invoice(osv.osv):
# one move line per tax line # one move line per tax line
iml += ait_obj.move_line_get(cr, uid, inv.id) iml += ait_obj.move_line_get(cr, uid, inv.id)
entry_type = ''
if inv.type in ('in_invoice', 'in_refund'): if inv.type in ('in_invoice', 'in_refund'):
ref = inv.reference ref = inv.reference
entry_type = 'journal_pur_voucher'
if inv.type == 'in_refund':
entry_type = 'cont_voucher'
else: else:
ref = self._convert_ref(cr, uid, inv.number) ref = self._convert_ref(cr, uid, inv.number)
entry_type = 'journal_sale_vou'
if inv.type == 'out_refund':
entry_type = 'cont_voucher'
diff_currency_p = inv.currency_id.id <> company_currency diff_currency_p = inv.currency_id.id <> company_currency
# create one move line for the total and possibly adjust the other lines amount # create one move line for the total and possibly adjust the other lines amount
@ -967,11 +961,11 @@ class account_invoice(osv.osv):
totlines = False totlines = False
if inv.payment_term: if inv.payment_term:
totlines = payment_term_obj.compute(cr, totlines = payment_term_obj.compute(cr,
uid, inv.payment_term.id, total, inv.date_invoice or False, context=ctx) uid, inv.payment_term.id, total, date_invoice or False, context=ctx)
if totlines: if totlines:
res_amount_currency = total_currency res_amount_currency = total_currency
i = 0 i = 0
ctx.update({'date': inv.date_invoice}) ctx.update({'date': date_invoice})
for t in totlines: for t in totlines:
if inv.currency_id.id != company_currency: if inv.currency_id.id != company_currency:
amount_currency = cur_obj.compute(cr, uid, company_currency, inv.currency_id.id, t[1], context=ctx) amount_currency = cur_obj.compute(cr, uid, company_currency, inv.currency_id.id, t[1], context=ctx)
@ -1010,7 +1004,7 @@ class account_invoice(osv.osv):
'ref': ref 'ref': ref
}) })
date = inv.date_invoice or time.strftime('%Y-%m-%d') date = date_invoice or time.strftime('%Y-%m-%d')
part = self.pool.get("res.partner")._find_accounting_partner(inv.partner_id) part = self.pool.get("res.partner")._find_accounting_partner(inv.partner_id)
@ -1037,7 +1031,7 @@ class account_invoice(osv.osv):
period_id = inv.period_id and inv.period_id.id or False period_id = inv.period_id and inv.period_id.id or False
ctx.update(company_id=inv.company_id.id) ctx.update(company_id=inv.company_id.id)
if not period_id: if not period_id:
period_ids = period_obj.find(cr, uid, inv.date_invoice, context=ctx) period_ids = period_obj.find(cr, uid, date_invoice, context=ctx)
period_id = period_ids and period_ids[0] or False period_id = period_ids and period_ids[0] or False
if period_id: if period_id:
move['period_id'] = period_id move['period_id'] = period_id
@ -1048,7 +1042,9 @@ class account_invoice(osv.osv):
move_id = move_obj.create(cr, uid, move, context=ctx) move_id = move_obj.create(cr, uid, move, context=ctx)
new_move_name = move_obj.browse(cr, uid, move_id, context=ctx).name new_move_name = move_obj.browse(cr, uid, move_id, context=ctx).name
# make the invoice point to that move # make the invoice point to that move
self.write(cr, uid, [inv.id], {'move_id': move_id,'period_id':period_id, 'move_name':new_move_name}, context=ctx) vals = inv_date
vals.update(move_id=move_id, period_id=period_id, move_name=new_move_name)
self.write(cr, uid, [inv.id], vals, context=ctx)
# Pass invoice in context in method post: used if you want to get the same # Pass invoice in context in method post: used if you want to get the same
# account move reference when creating the same invoice after a cancelled one: # account move reference when creating the same invoice after a cancelled one:
move_obj.post(cr, uid, [move_id], context=ctx) move_obj.post(cr, uid, [move_id], context=ctx)
@ -1299,14 +1295,6 @@ class account_invoice(osv.osv):
amount_currency = False amount_currency = False
currency_id = False currency_id = False
pay_journal = self.pool.get('account.journal').read(cr, uid, pay_journal_id, ['type'], context=context)
if invoice.type in ('in_invoice', 'out_invoice'):
if pay_journal['type'] == 'bank':
entry_type = 'bank_pay_voucher' # Bank payment
else:
entry_type = 'pay_voucher' # Cash payment
else:
entry_type = 'cont_voucher'
if invoice.type in ('in_invoice', 'in_refund'): if invoice.type in ('in_invoice', 'in_refund'):
ref = invoice.reference ref = invoice.reference
else: else:
@ -1414,7 +1402,7 @@ class account_invoice_line(osv.osv):
_order = "invoice_id,sequence,id" _order = "invoice_id,sequence,id"
_columns = { _columns = {
'name': fields.text('Description', required=True), 'name': fields.text('Description', required=True),
'origin': fields.char('Source Document', size=256, help="Reference of the document that produced this invoice."), 'origin': fields.char('Source Document', help="Reference of the document that produced this invoice."),
'sequence': fields.integer('Sequence', help="Gives the sequence of this line when displaying the invoice."), 'sequence': fields.integer('Sequence', help="Gives the sequence of this line when displaying the invoice."),
'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='cascade', select=True), 'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='cascade', select=True),
'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null', select=True), 'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null', select=True),
@ -1535,7 +1523,6 @@ class account_invoice_line(osv.osv):
res_final['value']['price_unit'] = new_price res_final['value']['price_unit'] = new_price
if result['uos_id'] and result['uos_id'] != res.uom_id.id: if result['uos_id'] and result['uos_id'] != res.uom_id.id:
selected_uom = self.pool.get('product.uom').browse(cr, uid, result['uos_id'], context=context)
new_price = self.pool.get('product.uom')._compute_price(cr, uid, res.uom_id.id, res_final['value']['price_unit'], result['uos_id']) new_price = self.pool.get('product.uom')._compute_price(cr, uid, res.uom_id.id, res_final['value']['price_unit'], result['uos_id'])
res_final['value']['price_unit'] = new_price res_final['value']['price_unit'] = new_price
return res_final return res_final
@ -1659,7 +1646,7 @@ class account_invoice_tax(osv.osv):
_columns = { _columns = {
'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True), 'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True),
'name': fields.char('Tax Description', size=64, required=True), 'name': fields.char('Tax Description', required=True),
'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]), 'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'), 'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
'base': fields.float('Base', digits_compute=dp.get_precision('Account')), 'base': fields.float('Base', digits_compute=dp.get_precision('Account')),

View File

@ -445,7 +445,7 @@ class account_move_line(osv.osv):
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity expressed by this line, eg: number of product sold. The quantity is not a legal requirement but is very useful for some reports."), 'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity expressed by this line, eg: number of product sold. The quantity is not a legal requirement but is very useful for some reports."),
'product_uom_id': fields.many2one('product.uom', 'Unit of Measure'), 'product_uom_id': fields.many2one('product.uom', 'Unit of Measure'),
'product_id': fields.many2one('product.product', 'Product'), 'product_id': fields.many2one('product.product', 'Product'),
@ -454,7 +454,7 @@ class account_move_line(osv.osv):
'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2), 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2),
'move_id': fields.many2one('account.move', 'Journal Entry', ondelete="cascade", help="The move of this entry line.", select=2, required=True), 'move_id': fields.many2one('account.move', 'Journal Entry', ondelete="cascade", help="The move of this entry line.", select=2, required=True),
'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Internal Note'), 'narration': fields.related('move_id','narration', type='text', relation='account.move', string='Internal Note'),
'ref': fields.related('move_id', 'ref', string='Reference', type='char', size=64, store=True), 'ref': fields.related('move_id', 'ref', string='Reference', type='char', store=True),
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1), 'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1),
'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2), 'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2), 'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2),

View File

@ -28,7 +28,7 @@ class account_fiscal_position(osv.osv):
_name = 'account.fiscal.position' _name = 'account.fiscal.position'
_description = 'Fiscal Position' _description = 'Fiscal Position'
_columns = { _columns = {
'name': fields.char('Fiscal Position', size=64, required=True), 'name': fields.char('Fiscal Position', required=True),
'active': fields.boolean('Active', help="By unchecking the active field, you may hide a fiscal position without deleting it."), 'active': fields.boolean('Active', help="By unchecking the active field, you may hide a fiscal position without deleting it."),
'company_id': fields.many2one('res.company', 'Company'), 'company_id': fields.many2one('res.company', 'Company'),
'account_ids': fields.one2many('account.fiscal.position.account', 'position_id', 'Account Mapping'), 'account_ids': fields.one2many('account.fiscal.position.account', 'position_id', 'Account Mapping'),

View File

@ -25,10 +25,10 @@ class account_analytic_journal(osv.osv):
_name = 'account.analytic.journal' _name = 'account.analytic.journal'
_description = 'Analytic Journal' _description = 'Analytic Journal'
_columns = { _columns = {
'name': fields.char('Journal Name', size=64, required=True), 'name': fields.char('Journal Name', required=True),
'code': fields.char('Journal Code', size=8), 'code': fields.char('Journal Code', size=8),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the analytic journal without removing it."), 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the analytic journal without removing it."),
'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True, help="Gives the type of the analytic journal. When it needs for a document (eg: an invoice) to create analytic entries, OpenERP will look for a matching journal of the same type."), 'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', required=True, help="Gives the type of the analytic journal. When it needs for a document (eg: an invoice) to create analytic entries, OpenERP will look for a matching journal of the same type."),
'line_ids': fields.one2many('account.analytic.line', 'journal_id', 'Lines'), 'line_ids': fields.one2many('account.analytic.line', 'journal_id', 'Lines'),
'company_id': fields.many2one('res.company', 'Company', required=True), 'company_id': fields.many2one('res.company', 'Company', required=True),
} }

View File

@ -32,7 +32,7 @@ class account_entries_report(osv.osv):
'date': fields.date('Effective Date', readonly=True), 'date': fields.date('Effective Date', readonly=True),
'date_created': fields.date('Date Created', readonly=True), 'date_created': fields.date('Date Created', readonly=True),
'date_maturity': fields.date('Date Maturity', readonly=True), 'date_maturity': fields.date('Date Maturity', readonly=True),
'ref': fields.char('Reference', size=64, readonly=True), 'ref': fields.char('Reference', readonly=True),
'nbr': fields.integer('# of Items', readonly=True), 'nbr': fields.integer('# of Items', readonly=True),
'debit': fields.float('Debit', readonly=True), 'debit': fields.float('Debit', readonly=True),
'credit': fields.float('Credit', readonly=True), 'credit': fields.float('Credit', readonly=True),

View File

@ -73,7 +73,7 @@ class temp_range(osv.osv):
_description = 'A Temporary table used for Dashboard view' _description = 'A Temporary table used for Dashboard view'
_columns = { _columns = {
'name': fields.char('Range',size=64) 'name': fields.char('Range')
} }
@ -112,7 +112,7 @@ class report_aged_receivable(osv.osv):
return res return res
_columns = { _columns = {
'name': fields.char('Month Range', size=7, readonly=True), 'name': fields.char('Month Range', size=24, readonly=True),
'balance': fields.function(_calc_bal, string='Balance', readonly=True), 'balance': fields.function(_calc_bal, string='Balance', readonly=True),
} }
@ -151,14 +151,14 @@ class report_invoice_created(osv.osv):
_description = "Report of Invoices Created within Last 15 days" _description = "Report of Invoices Created within Last 15 days"
_auto = False _auto = False
_columns = { _columns = {
'name': fields.char('Description', size=64, readonly=True), 'name': fields.char('Description', readonly=True),
'type': fields.selection([ 'type': fields.selection([
('out_invoice','Customer Invoice'), ('out_invoice','Customer Invoice'),
('in_invoice','Supplier Invoice'), ('in_invoice','Supplier Invoice'),
('out_refund','Customer Refund'), ('out_refund','Customer Refund'),
('in_refund','Supplier Refund'), ('in_refund','Supplier Refund'),
],'Type', readonly=True), ],'Type', readonly=True),
'number': fields.char('Invoice Number', size=32, readonly=True), 'number': fields.char('Invoice Number', readonly=True),
'partner_id': fields.many2one('res.partner', 'Partner', readonly=True), 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
'amount_untaxed': fields.float('Untaxed', readonly=True), 'amount_untaxed': fields.float('Untaxed', readonly=True),
'amount_total': fields.float('Total', readonly=True), 'amount_total': fields.float('Total', readonly=True),
@ -174,7 +174,7 @@ class report_invoice_created(osv.osv):
('paid','Done'), ('paid','Done'),
('cancel','Cancelled') ('cancel','Cancelled')
],'Status', readonly=True), ],'Status', readonly=True),
'origin': fields.char('Source Document', size=64, readonly=True, help="Reference of the document that generated this invoice report."), 'origin': fields.char('Source Document', readonly=True, help="Reference of the document that generated this invoice report."),
'create_date': fields.datetime('Create Date', readonly=True) 'create_date': fields.datetime('Create Date', readonly=True)
} }
_order = 'create_date' _order = 'create_date'
@ -203,7 +203,7 @@ class report_account_type_sales(osv.osv):
_description = "Report of the Sales by Account Type" _description = "Report of the Sales by Account Type"
_auto = False _auto = False
_columns = { _columns = {
'name': fields.char('Year', size=64, required=False, readonly=True), 'name': fields.char('Year', required=False, readonly=True),
'period_id': fields.many2one('account.period', 'Force Period', readonly=True), 'period_id': fields.many2one('account.period', 'Force Period', readonly=True),
'product_id': fields.many2one('product.product', 'Product', readonly=True), 'product_id': fields.many2one('product.product', 'Product', readonly=True),
'quantity': fields.float('Quantity', readonly=True), 'quantity': fields.float('Quantity', readonly=True),
@ -244,7 +244,7 @@ class report_account_sales(osv.osv):
_description = "Report of the Sales by Account" _description = "Report of the Sales by Account"
_auto = False _auto = False
_columns = { _columns = {
'name': fields.char('Year', size=64, required=False, readonly=True, select=True), 'name': fields.char('Year', required=False, readonly=True, select=True),
'period_id': fields.many2one('account.period', 'Force Period', readonly=True), 'period_id': fields.many2one('account.period', 'Force Period', readonly=True),
'product_id': fields.many2one('product.product', 'Product', readonly=True), 'product_id': fields.many2one('product.product', 'Product', readonly=True),
'quantity': fields.float('Quantity', readonly=True), 'quantity': fields.float('Quantity', readonly=True),

View File

@ -139,6 +139,13 @@
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field> <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record> </record>
<record id="account_subscription_line_comp_rule" model="ir.rule">
<field name="name">Account subscription line company rule</field>
<field name="model_id" ref="model_account_subscription_line"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('subscription_id.model_id.company_id','=',False),('subscription_id.model_id.company_id','child_of',[user.company_id.id])]</field>
</record>
<record model="ir.rule" id="account_invoice_line_comp_rule"> <record model="ir.rule" id="account_invoice_line_comp_rule">
<field name="name">Invoice Line company rule</field> <field name="name">Invoice Line company rule</field>
<field name="model_id" ref="model_account_invoice_line"/> <field name="model_id" ref="model_account_invoice_line"/>

View File

@ -37,7 +37,7 @@ openerp.account = function (instance) {
// We'll need to get the code of an account selected in a many2one (whose value is the id) // We'll need to get the code of an account selected in a many2one (whose value is the id)
this.map_account_id_code = {}; this.map_account_id_code = {};
// The same move line cannot be selected for multiple resolutions // The same move line cannot be selected for multiple resolutions
this.excluded_move_lines_ids = {}; this.excluded_move_lines_ids = [];
// Description of the fields to initialize in the "create new line" form // Description of the fields to initialize in the "create new line" form
// NB : for presets to work correctly, a field id must be the same string as a preset field // NB : for presets to work correctly, a field id must be the same string as a preset field
this.create_form_fields = { this.create_form_fields = {
@ -253,59 +253,34 @@ openerp.account = function (instance) {
}); });
} }
}, },
// Adds move line ids to the list of move lines not to fetch for a given partner excludeMoveLines: function(line_ids) {
// This is required because the same move line cannot be selected for multiple reconciliation
excludeMoveLines: function(source_child, partner_id, line_ids) {
var self = this; var self = this;
var excluded_ids = this.excluded_move_lines_ids[partner_id];
var excluded_move_lines_changed = false;
_.each(line_ids, function(line_id){ _.each(line_ids, function(line_id){
if (excluded_ids.indexOf(line_id) === -1) { line_id = parseInt(line_id);
excluded_ids.push(line_id); if (self.excluded_move_lines_ids.indexOf(line_id) === -1) {
excluded_move_lines_changed = true; self.excluded_move_lines_ids.push(line_id);
} }
}); });
if (! excluded_move_lines_changed) //update all children view
return;
// Function that finds if an array of line objects contains at least a line identified by its id
var contains_lines = function(lines_array, line_ids) {
for (var i = 0; i < lines_array.length; i++)
for (var j = 0; j < line_ids.length; j++)
if (lines_array[i].id === line_ids[j])
return true;
return false;
};
// Update children if needed
_.each(self.getChildren(), function(child){ _.each(self.getChildren(), function(child){
if (child.partner_id === partner_id && child !== source_child) { child.render();
if (contains_lines(child.get("mv_lines_selected"), line_ids)) {
child.set("mv_lines_selected", _.filter(child.get("mv_lines_selected"), function(o){ return line_ids.indexOf(o.id) === -1 }));
} else if (contains_lines(child.mv_lines_deselected, line_ids)) {
child.mv_lines_deselected = _.filter(child.mv_lines_deselected, function(o){ return line_ids.indexOf(o.id) === -1 });
child.updateMatches();
} else if (contains_lines(child.get("mv_lines"), line_ids)) {
child.updateMatches();
}
}
}); });
}, },
unexcludeMoveLines: function(source_child, partner_id, line_ids) { unexcludeMoveLines: function(line_ids) {
var self = this; var self = this;
var index = -1;
var initial_excluded_lines_num = this.excluded_move_lines_ids[partner_id].length; _.each(line_ids, function(line_id){
this.excluded_move_lines_ids[partner_id] = _.difference(this.excluded_move_lines_ids[partner_id], line_ids); line_id = parseInt(line_id);
if (this.excluded_move_lines_ids[partner_id].length === initial_excluded_lines_num) index = self.excluded_move_lines_ids.indexOf(line_id);
return; if (index > -1) {
self.excluded_move_lines_ids.splice(index,1);
// Update children if needed }
});
//update all children view
_.each(self.getChildren(), function(child){ _.each(self.getChildren(), function(child){
if (child.partner_id === partner_id && child !== source_child && (child.get("mode") === "match" || child.$el.hasClass("no_match"))) child.render();
child.updateMatches();
}); });
}, },
@ -490,9 +465,7 @@ openerp.account = function (instance) {
// Exclude selected move lines // Exclude selected move lines
var selected_line_ids = _(context.reconciliation_proposition).map(function(o){ return o.id }); var selected_line_ids = _(context.reconciliation_proposition).map(function(o){ return o.id });
if (this.getParent().excluded_move_lines_ids[this.partner_id] === undefined) this.getParent().excludeMoveLines(selected_line_ids);
this.getParent().excluded_move_lines_ids[this.partner_id] = [];
this.getParent().excludeMoveLines(this, this.partner_id, selected_line_ids);
} else { } else {
this.set("mv_lines_selected", []); this.set("mv_lines_selected", []);
this.st_line = undefined; this.st_line = undefined;
@ -513,7 +486,6 @@ openerp.account = function (instance) {
this.presets = this.getParent().presets; this.presets = this.getParent().presets;
this.is_valid = true; this.is_valid = true;
this.is_consistent = true; // Used to prevent bad server requests this.is_consistent = true; // Used to prevent bad server requests
this.total_move_lines_num = undefined; // Used for pagers
this.filter = ""; this.filter = "";
this.set("balance", undefined); // Debit is +, credit is - this.set("balance", undefined); // Debit is +, credit is -
@ -525,12 +497,14 @@ openerp.account = function (instance) {
// NB : mv_lines represent the counterpart that will be created to reconcile existing move lines, so debit and credit are inverted // NB : mv_lines represent the counterpart that will be created to reconcile existing move lines, so debit and credit are inverted
this.set("mv_lines", []); this.set("mv_lines", []);
this.on("change:mv_lines", this, this.mvLinesChanged); this.on("change:mv_lines", this, this.mvLinesChanged);
this.mv_lines_deselected = []; // deselected lines are displayed on top of the match table
this.on("change:mv_lines_selected", this, this.mvLinesSelectedChanged); this.on("change:mv_lines_selected", this, this.mvLinesSelectedChanged);
this.set("lines_created", []); this.set("lines_created", []);
this.set("line_created_being_edited", [{'id': 0}]); this.set("line_created_being_edited", [{'id': 0}]);
this.on("change:lines_created", this, this.createdLinesChanged); this.on("change:lines_created", this, this.createdLinesChanged);
this.on("change:line_created_being_edited", this, this.createdLinesChanged); this.on("change:line_created_being_edited", this, this.createdLinesChanged);
//all lines associated to current reconciliation
this.propositions_lines = undefined;
}, },
start: function() { start: function() {
@ -553,9 +527,6 @@ openerp.account = function (instance) {
self.st_line = data; self.st_line = data;
self.decorateStatementLine(self.st_line); self.decorateStatementLine(self.st_line);
self.partner_id = data.partner_id; self.partner_id = data.partner_id;
if (self.getParent().excluded_move_lines_ids[self.partner_id] === undefined)
self.getParent().excluded_move_lines_ids[self.partner_id] = [];
// load and display move lines
$.when(self.loadReconciliationProposition()).then(function(){ $.when(self.loadReconciliationProposition()).then(function(){
deferred_fetch_data.resolve(); deferred_fetch_data.resolve();
}); });
@ -566,6 +537,15 @@ openerp.account = function (instance) {
// Display the widget // Display the widget
return $.when(deferred_fetch_data).then(function(){ return $.when(deferred_fetch_data).then(function(){
//load all lines that can be usefull for counterparts
var deferred_total_move_lines_num = self.model_bank_statement_line
.call("get_move_lines_counterparts_id", [self.st_line.id, []])
.then(function(lines){
_(lines).each(self.decorateMoveLine.bind(self));
self.propositions_lines = lines;
});
return deferred_total_move_lines_num;
}).then(function(){
// Render template // Render template
var presets_array = []; var presets_array = [];
for (var id in self.presets) for (var id in self.presets)
@ -577,10 +557,9 @@ openerp.account = function (instance) {
self.$(".match").slideUp(0); self.$(".match").slideUp(0);
self.$(".create").slideUp(0); self.$(".create").slideUp(0);
if (self.st_line.no_match) self.$el.addClass("no_match"); if (self.st_line.no_match) self.$el.addClass("no_match");
if (self.context.mode !== "match") self.updateMatches(); if (self.context.mode !== "match") self.render();
self.bindPopoverTo(self.$(".line_info_button")); self.bindPopoverTo(self.$(".line_info_button"));
self.createFormWidgets(); self.createFormWidgets();
// Special case hack : no identified partner // Special case hack : no identified partner
if (self.st_line.has_no_partner) { if (self.st_line.has_no_partner) {
self.$el.css("opacity", "0"); self.$el.css("opacity", "0");
@ -623,7 +602,7 @@ openerp.account = function (instance) {
_.each(self.getChildren(), function(o){ o.destroy() }); _.each(self.getChildren(), function(o){ o.destroy() });
self.is_consistent = false; self.is_consistent = false;
return $.when(self.$el.animate({opacity: 0}, self.animation_speed)).then(function() { return $.when(self.$el.animate({opacity: 0}, self.animation_speed)).then(function() {
self.getParent().unexcludeMoveLines(self, self.partner_id, _.map(self.get("mv_lines_selected"), function(o){ return o.id })); self.getParent().unexcludeMoveLines(_.map(self.get("mv_lines_selected"), function(o){ return o.id }));
$.each(self.$(".bootstrap_popover"), function(){ $(this).popover('destroy') }); $.each(self.$(".bootstrap_popover"), function(){ $(this).popover('destroy') });
self.$el.empty(); self.$el.empty();
self.$el.removeClass("no_partner"); self.$el.removeClass("no_partner");
@ -637,7 +616,6 @@ openerp.account = function (instance) {
self.set("pager_index", 0, {silent: true}); self.set("pager_index", 0, {silent: true});
self.set("mv_lines", [], {silent: true}); self.set("mv_lines", [], {silent: true});
self.set("mv_lines_selected", [], {silent: true}); self.set("mv_lines_selected", [], {silent: true});
self.mv_lines_deselected = [];
self.set("lines_created", [], {silent: true}); self.set("lines_created", [], {silent: true});
self.set("line_created_being_edited", [{'id': 0}], {silent: true}); self.set("line_created_being_edited", [{'id': 0}], {silent: true});
// Rebirth // Rebirth
@ -836,68 +814,35 @@ openerp.account = function (instance) {
if (e.currentTarget.dataset.selected === "true") self.deselectMoveLine(e.currentTarget); if (e.currentTarget.dataset.selected === "true") self.deselectMoveLine(e.currentTarget);
else self.selectMoveLine(e.currentTarget); else self.selectMoveLine(e.currentTarget);
}, },
// Takes a move line from the match view and adds it to the mv_lines_selected array
selectMoveLine: function(mv_line) { selectMoveLine: function(mv_line) {
var self = this; var self = this;
var line_id = mv_line.dataset.lineid; var line_id = mv_line.dataset.lineid;
var line = _.find(self.propositions_lines, function(o){ return o.id == line_id});
// find the line in mv_lines or mv_lines_deselected $(mv_line).attr('data-selected','true');
var line = _.find(self.get("mv_lines"), function(o){ return o.id == line_id }); self.getParent().excludeMoveLines([line_id]);
if (! line) {
line = _.find(self.mv_lines_deselected, function(o){ return o.id == line_id });
self.mv_lines_deselected = _.filter(self.mv_lines_deselected, function(o) { return o.id != line_id });
}
// If no line found, the view is probably not up to date to the model (asynchronous fun)
if (! line) return;
// Warn the user if he's selecting lines from both a payable and a receivable account
var last_selected_line = _.last(self.get("mv_lines_selected"));
if (last_selected_line && last_selected_line.account_type != line.account_type) {
// TODO : web client API
alert(_.str.sprintf(_t("You are selecting transactions from both a payable and a receivable account.\n\nIn order to proceed, you first need to deselect the %s transactions."), last_selected_line.account_type));
return;
}
self.set("mv_lines_selected", self.get("mv_lines_selected").concat(line)); self.set("mv_lines_selected", self.get("mv_lines_selected").concat(line));
}, },
// Removes a move line from the mv_lines_selected array
deselectMoveLine: function(mv_line) { deselectMoveLine: function(mv_line) {
var self = this; var self = this;
var line_id = mv_line.dataset.lineid; var line_id = mv_line.dataset.lineid;
var line = _.find(self.get("mv_lines_selected"), function(o) { return o.id == line_id }); var line = _.find(self.propositions_lines, function(o){ return o.id == line_id});
// If no line found, the view is probably not up to date to the model (asynchronous fun) $(mv_line).attr('data-selected','false');
if (! line) return; self.getParent().unexcludeMoveLines([line_id]);
self.set("mv_lines_selected",_.filter(self.get("mv_lines_selected"), function(o) { return o.id != line_id }));
// add the line to mv_lines_deselected and remove it from mv_lines_selected
self.mv_lines_deselected.unshift(line);
var mv_lines_selected = _.filter(self.get("mv_lines_selected"), function(o) { return o.id != line_id });
// remove partial reconciliation stuff if necessary
if (line.partial_reconcile === true) self.unpartialReconcileLine(line);
if (line.propose_partial_reconcile === true) line.propose_partial_reconcile = false;
self.$el.removeClass("no_match");
self.set("mode", "match");
self.set("mv_lines_selected", mv_lines_selected);
}, },
/** Matches pagination */ /** Matches pagination */
pagerControlLeftHandler: function() { pagerControlLeftHandler: function() {
var self = this; var self = this;
if (self.$(".pager_control_left").hasClass("disabled")) { return; /* shouldn't happen, anyway*/ }
if (self.total_move_lines_num < 0) { return; }
self.set("pager_index", self.get("pager_index")-1 ); self.set("pager_index", self.get("pager_index")-1 );
}, },
pagerControlRightHandler: function() { pagerControlRightHandler: function() {
var self = this; var self = this;
var new_index = self.get("pager_index")+1; var new_index = self.get("pager_index")+1;
if (self.$(".pager_control_right").hasClass("disabled")) { return; /* shouldn't happen, anyway*/ }
if ((new_index * self.max_move_lines_displayed) >= self.total_move_lines_num) { return; }
self.set("pager_index", new_index ); self.set("pager_index", new_index );
}, },
@ -905,11 +850,9 @@ openerp.account = function (instance) {
var self = this; var self = this;
self.set("pager_index", 0); self.set("pager_index", 0);
self.filter = self.$(".filter").val(); self.filter = self.$(".filter").val();
window.clearTimeout(self.apply_filter_timeout); self.render();
self.apply_filter_timeout = window.setTimeout(self.proxy('updateMatches'), 200);
}, },
/** Creating */ /** Creating */
initializeCreateForm: function() { initializeCreateForm: function() {
@ -1041,20 +984,16 @@ openerp.account = function (instance) {
table.empty(); table.empty();
var slice_start = self.get("pager_index") * self.max_move_lines_displayed; var slice_start = self.get("pager_index") * self.max_move_lines_displayed;
var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed; var slice_end = (self.get("pager_index")+1) * self.max_move_lines_displayed;
_( _.filter(self.mv_lines_deselected, function(o){
return o.q_label.indexOf(self.filter) !== -1 || (o.ref && o.ref.indexOf(self.filter) !== -1) var visible = 0
})
.slice(slice_start, slice_end)).each(function(line){
var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false}));
self.bindPopoverTo($line.find(".line_info_button"));
table.append($line);
nothing_displayed = false;
});
_(self.get("mv_lines")).each(function(line){ _(self.get("mv_lines")).each(function(line){
var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false})); if (visible >= slice_start && visible < slice_end) {
self.bindPopoverTo($line.find(".line_info_button")); var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: false}));
table.append($line); self.bindPopoverTo($line.find(".line_info_button"));
nothing_displayed = false; table.append($line);
nothing_displayed = false;
}
visible = visible + 1;
}); });
if (nothing_displayed) if (nothing_displayed)
table.append(QWeb.render("filter_no_match", {filter_str: self.filter})); table.append(QWeb.render("filter_no_match", {filter_str: self.filter}));
@ -1066,7 +1005,7 @@ openerp.account = function (instance) {
self.$(".pager_control_left").addClass("disabled"); self.$(".pager_control_left").addClass("disabled");
else else
self.$(".pager_control_left").removeClass("disabled"); self.$(".pager_control_left").removeClass("disabled");
if (self.total_move_lines_num <= ((self.get("pager_index")+1) * self.max_move_lines_displayed)) if (self.get('mv_lines').length <= ((self.get("pager_index")+1) * self.max_move_lines_displayed))
self.$(".pager_control_right").addClass("disabled"); self.$(".pager_control_right").addClass("disabled");
else else
self.$(".pager_control_right").removeClass("disabled"); self.$(".pager_control_right").removeClass("disabled");
@ -1136,7 +1075,7 @@ openerp.account = function (instance) {
self.el.dataset.mode = "inactive"; self.el.dataset.mode = "inactive";
} else if (self.get("mode") === "match") { } else if (self.get("mode") === "match") {
return $.when(self.updateMatches()).then(function() { return $.when(self.render()).then(function() {
if (self.$el.hasClass("no_match")) { if (self.$el.hasClass("no_match")) {
self.set("mode", "inactive"); self.set("mode", "inactive");
return; return;
@ -1156,18 +1095,14 @@ openerp.account = function (instance) {
pagerChanged: function() { pagerChanged: function() {
var self = this; var self = this;
self.updateMatches(); self.render();
}, },
mvLinesChanged: function() { mvLinesChanged: function() {
var self = this; var self = this;
// If pager_index is out of range, set it to display the last page
if (self.get("pager_index") !== 0 && self.total_move_lines_num <= (self.get("pager_index") * self.max_move_lines_displayed)) {
self.set("pager_index", Math.ceil(self.total_move_lines_num/self.max_move_lines_displayed)-1);
}
// If there is no match to display, disable match view and pass in mode inactive // If there is no match to display, disable match view and pass in mode inactive
if (self.total_move_lines_num + self.mv_lines_deselected.length === 0 && self.filter === "") { if (self.get("mv_lines").length === 0 && self.filter === "") {
self.$el.addClass("no_match"); self.$el.addClass("no_match");
if (self.get("mode") === "match") { if (self.get("mode") === "match") {
self.set("mode", "inactive"); self.set("mode", "inactive");
@ -1186,13 +1121,11 @@ openerp.account = function (instance) {
var added_lines_ids = _.map(_.difference(val.newValue, val.oldValue), function(o){ return o.id }); var added_lines_ids = _.map(_.difference(val.newValue, val.oldValue), function(o){ return o.id });
var removed_lines_ids = _.map(_.difference(val.oldValue, val.newValue), function(o){ return o.id }); var removed_lines_ids = _.map(_.difference(val.oldValue, val.newValue), function(o){ return o.id });
self.getParent().excludeMoveLines(self, self.partner_id, added_lines_ids); self.getParent().excludeMoveLines(added_lines_ids);
self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines_ids); self.getParent().unexcludeMoveLines(removed_lines_ids);
$.when(self.updateMatches()).then(function(){ self.updateAccountingViewMatchedLines();
self.updateAccountingViewMatchedLines(); self.updateBalance();
self.updateBalance();
});
}, },
// Generic function for updating the line_created_being_edited // Generic function for updating the line_created_being_edited
@ -1339,47 +1272,23 @@ openerp.account = function (instance) {
loadReconciliationProposition: function() { loadReconciliationProposition: function() {
var self = this; var self = this;
return self.model_bank_statement_line return self.model_bank_statement_line
.call("get_reconciliation_proposition", [self.st_line.id, self.getParent().excluded_move_lines_ids[self.partner_id]]) .call("get_reconciliation_proposition", [self.st_line.id, self.getParent().excluded_move_lines_ids])
.then(function (lines) { .then(function (lines) {
_(lines).each(self.decorateMoveLine.bind(self)); _(lines).each(self.decorateMoveLine.bind(self));
self.set("mv_lines_selected", self.get("mv_lines_selected").concat(lines)); self.set("mv_lines_selected", self.get("mv_lines_selected").concat(lines));
}); });
}, },
// Loads move lines according to the widget's state render: function() {
updateMatches: function() {
var self = this; var self = this;
var deselected_lines_num = self.mv_lines_deselected.length; var lines_to_show = [];
var move_lines = {}; _.each(self.propositions_lines, function(line){
var move_lines_num = 0; var filter = (line.q_label.toLowerCase().indexOf(self.filter.toLowerCase()) > -1 || line.account_code.toLowerCase().indexOf(self.filter.toLowerCase()) > -1);
var offset = self.get("pager_index") * self.max_move_lines_displayed - deselected_lines_num; if (self.getParent().excluded_move_lines_ids.indexOf(line.id) === -1 && filter) {
if (offset < 0) offset = 0; lines_to_show.push(line);
var limit = (self.get("pager_index")+1) * self.max_move_lines_displayed - deselected_lines_num; }
if (limit > self.max_move_lines_displayed) limit = self.max_move_lines_displayed;
var excluded_ids = _.collect(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o){ return o.id });
excluded_ids = excluded_ids.concat(self.getParent().excluded_move_lines_ids[self.partner_id]);
var deferred_move_lines;
if (limit > 0) {
// Load move lines
deferred_move_lines = self.model_bank_statement_line
.call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, offset, limit])
.then(function (lines) {
_(lines).each(self.decorateMoveLine.bind(self));
move_lines = lines;
});
}
// Fetch the number of move lines corresponding to this statement line and this filter
var deferred_total_move_lines_num = self.model_bank_statement_line
.call("get_move_lines_counterparts_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true])
.then(function(num){
move_lines_num = num;
});
return $.when(deferred_move_lines, deferred_total_move_lines_num).then(function(){
self.total_move_lines_num = move_lines_num + deselected_lines_num;
self.set("mv_lines", move_lines);
}); });
self.set("mv_lines", lines_to_show);
}, },
// Changes the partner_id of the statement_line in the DB and reloads the widget // Changes the partner_id of the statement_line in the DB and reloads the widget
@ -1439,8 +1348,6 @@ openerp.account = function (instance) {
var self = this; var self = this;
if (! self.is_consistent) return; if (! self.is_consistent) return;
self.getParent().unexcludeMoveLines(self, self.partner_id, _.map(self.get("mv_lines_selected"), function(o){ return o.id }));
// Prepare data // Prepare data
var mv_line_dicts = []; var mv_line_dicts = [];
_.each(self.get("mv_lines_selected"), function(o) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(o)) }); _.each(self.get("mv_lines_selected"), function(o) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(o)) });

View File

@ -128,7 +128,7 @@
<td><span class="glyphicon glyphicon-add-remove"></span></td> <td><span class="glyphicon glyphicon-add-remove"></span></td>
<td><t t-esc="line.account_code"/></td> <td><t t-esc="line.account_code"/></td>
<td><t t-esc="line.q_due_date"/></td> <td><t t-esc="line.q_due_date"/></td>
<td><t t-esc="line.q_label"/></td> <td class="js_qlabel"><t t-esc="line.q_label"/></td>
<td><t t-if="line.debit !== 0"> <td><t t-if="line.debit !== 0">
<t t-if="line.propose_partial_reconcile" t-call="icon_do_partial_reconciliation"></t> <t t-if="line.propose_partial_reconcile" t-call="icon_do_partial_reconciliation"></t>

View File

@ -30,7 +30,7 @@ class accounting_report(osv.osv_memory):
_columns = { _columns = {
'enable_filter': fields.boolean('Enable Comparison'), 'enable_filter': fields.boolean('Enable Comparison'),
'account_report_id': fields.many2one('account.financial.report', 'Account Reports', required=True), 'account_report_id': fields.many2one('account.financial.report', 'Account Reports', required=True),
'label_filter': fields.char('Column Label', size=32, help="This label will be displayed on report to show the balance computed for the given comparison filter."), 'label_filter': fields.char('Column Label', help="This label will be displayed on report to show the balance computed for the given comparison filter."),
'fiscalyear_id_cmp': fields.many2one('account.fiscalyear', 'Fiscal Year', help='Keep empty for all open fiscal year'), 'fiscalyear_id_cmp': fields.many2one('account.fiscalyear', 'Fiscal Year', help='Keep empty for all open fiscal year'),
'filter_cmp': fields.selection([('filter_no', 'No Filters'), ('filter_date', 'Date'), ('filter_period', 'Periods')], "Filter by", required=True), 'filter_cmp': fields.selection([('filter_no', 'No Filters'), ('filter_date', 'Date'), ('filter_period', 'Periods')], "Filter by", required=True),
'period_from_cmp': fields.many2one('account.period', 'Start Period'), 'period_from_cmp': fields.many2one('account.period', 'Start Period'),

View File

@ -35,7 +35,7 @@ class account_fiscalyear_close(osv.osv_memory):
'New Fiscal Year', required=True), 'New Fiscal Year', required=True),
'journal_id': fields.many2one('account.journal', 'Opening Entries Journal', domain="[('type','=','situation')]", required=True, help='The best practice here is to use a journal dedicated to contain the opening entries of all fiscal years. Note that you should define it with default debit/credit accounts, of type \'situation\' and with a centralized counterpart.'), 'journal_id': fields.many2one('account.journal', 'Opening Entries Journal', domain="[('type','=','situation')]", required=True, help='The best practice here is to use a journal dedicated to contain the opening entries of all fiscal years. Note that you should define it with default debit/credit accounts, of type \'situation\' and with a centralized counterpart.'),
'period_id': fields.many2one('account.period', 'Opening Entries Period', required=True), 'period_id': fields.many2one('account.period', 'Opening Entries Period', required=True),
'report_name': fields.char('Name of new entries',size=64, required=True, help="Give name of the new entries"), 'report_name': fields.char('Name of new entries', required=True, help="Give name of the new entries"),
} }
_defaults = { _defaults = {
'report_name': lambda self, cr, uid, context: _('End of Fiscal Year Entry'), 'report_name': lambda self, cr, uid, context: _('End of Fiscal Year Entry'),

View File

@ -34,7 +34,7 @@ class account_invoice_refund(osv.osv_memory):
'date': fields.date('Date', help='This date will be used as the invoice date for credit note and period will be chosen accordingly!'), 'date': fields.date('Date', help='This date will be used as the invoice date for credit note and period will be chosen accordingly!'),
'period': fields.many2one('account.period', 'Force period'), 'period': fields.many2one('account.period', 'Force period'),
'journal_id': fields.many2one('account.journal', 'Refund Journal', help='You can select here the journal to use for the credit note that will be created. If you leave that field empty, it will use the same journal as the current invoice.'), 'journal_id': fields.many2one('account.journal', 'Refund Journal', help='You can select here the journal to use for the credit note that will be created. If you leave that field empty, it will use the same journal as the current invoice.'),
'description': fields.char('Reason', size=128, required=True), 'description': fields.char('Reason', required=True),
'filter_refund': fields.selection([('refund', 'Create a draft refund'), ('cancel', 'Cancel: create refund and reconcile'),('modify', 'Modify: create refund, reconcile and create a new draft invoice')], "Refund Method", required=True, help='Refund base on this type. You can not Modify and Cancel if the invoice is already reconciled'), 'filter_refund': fields.selection([('refund', 'Create a draft refund'), ('cancel', 'Cancel: create refund and reconcile'),('modify', 'Modify: create refund, reconcile and create a new draft invoice')], "Refund Method", required=True, help='Refund base on this type. You can not Modify and Cancel if the invoice is already reconciled'),
} }

View File

@ -107,7 +107,7 @@ class account_move_line_reconcile_writeoff(osv.osv_memory):
'journal_id': fields.many2one('account.journal','Write-Off Journal', required=True), 'journal_id': fields.many2one('account.journal','Write-Off Journal', required=True),
'writeoff_acc_id': fields.many2one('account.account','Write-Off account', required=True), 'writeoff_acc_id': fields.many2one('account.account','Write-Off account', required=True),
'date_p': fields.date('Date'), 'date_p': fields.date('Date'),
'comment': fields.char('Comment', size= 64, required=True), 'comment': fields.char('Comment', required=True),
'analytic_id': fields.many2one('account.analytic.account', 'Analytic Account', domain=[('parent_id', '!=', False)]), 'analytic_id': fields.many2one('account.analytic.account', 'Analytic Account', domain=[('parent_id', '!=', False)]),
} }
_defaults = { _defaults = {

View File

@ -36,11 +36,11 @@ class account_subscription_generate(osv.osv_memory):
def action_generate(self, cr, uid, ids, context=None): def action_generate(self, cr, uid, ids, context=None):
mod_obj = self.pool.get('ir.model.data') mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window') act_obj = self.pool.get('ir.actions.act_window')
sub_line_obj = self.pool.get('account.subscription.line')
moves_created=[] moves_created=[]
for data in self.read(cr, uid, ids, context=context): for data in self.read(cr, uid, ids, context=context):
cr.execute('select id from account_subscription_line where date<%s and move_id is null', (data['date'],)) line_ids = sub_line_obj.search(cr, uid, [('date', '<', data['date']), ('move_id', '=', False)], context=context)
line_ids = map(lambda x: x[0], cr.fetchall()) moves = sub_line_obj.move_create(cr, uid, line_ids, context=context)
moves = self.pool.get('account.subscription.line').move_create(cr, uid, line_ids, context=context)
moves_created.extend(moves) moves_created.extend(moves)
result = mod_obj.get_object_reference(cr, uid, 'account', 'action_move_line_form') result = mod_obj.get_object_reference(cr, uid, 'account', 'action_move_line_form')
id = result and result[1] or False id = result and result[1] or False

View File

@ -5,7 +5,7 @@ from openerp.tools.translate import _
class CashBox(osv.osv_memory): class CashBox(osv.osv_memory):
_register = False _register = False
_columns = { _columns = {
'name' : fields.char('Reason', size=64, required=True), 'name' : fields.char('Reason', required=True),
# Attention, we don't set a domain, because there is a journal_type key # Attention, we don't set a domain, because there is a journal_type key
# in the context of the action # in the context of the action
'amount' : fields.float('Amount', 'amount' : fields.float('Amount',
@ -49,7 +49,7 @@ class CashBoxIn(CashBox):
_columns = CashBox._columns.copy() _columns = CashBox._columns.copy()
_columns.update({ _columns.update({
'ref' : fields.char('Reference', size=32), 'ref' : fields.char('Reference'),
}) })
def _compute_values_for_statement_line(self, cr, uid, box, record, context=None): def _compute_values_for_statement_line(self, cr, uid, box, record, context=None):

View File

@ -70,7 +70,7 @@ class account_analytic_plan(osv.osv):
_name = "account.analytic.plan" _name = "account.analytic.plan"
_description = "Analytic Plan" _description = "Analytic Plan"
_columns = { _columns = {
'name': fields.char('Analytic Plan', size=64, required=True, select=True), 'name': fields.char('Analytic Plan', required=True, select=True),
'plan_ids': fields.one2many('account.analytic.plan.line', 'plan_id', 'Analytic Plans'), 'plan_ids': fields.one2many('account.analytic.plan.line', 'plan_id', 'Analytic Plans'),
} }
@ -81,7 +81,7 @@ class account_analytic_plan_line(osv.osv):
_order = "sequence, id" _order = "sequence, id"
_columns = { _columns = {
'plan_id': fields.many2one('account.analytic.plan','Analytic Plan',required=True), 'plan_id': fields.many2one('account.analytic.plan','Analytic Plan',required=True),
'name': fields.char('Axis Name', size=64, required=True, select=True), 'name': fields.char('Axis Name', required=True, select=True),
'sequence': fields.integer('Sequence'), 'sequence': fields.integer('Sequence'),
'root_analytic_id': fields.many2one('account.analytic.account', 'Root Account', help="Root account of this plan.", required=False), 'root_analytic_id': fields.many2one('account.analytic.account', 'Root Account', help="Root account of this plan.", required=False),
'min_required': fields.float('Minimum Allowed (%)'), 'min_required': fields.float('Minimum Allowed (%)'),
@ -97,7 +97,7 @@ class account_analytic_plan_instance(osv.osv):
_name = "account.analytic.plan.instance" _name = "account.analytic.plan.instance"
_description = "Analytic Plan Instance" _description = "Analytic Plan Instance"
_columns = { _columns = {
'name': fields.char('Analytic Distribution', size=64), 'name': fields.char('Analytic Distribution'),
'code': fields.char('Distribution Code', size=16), 'code': fields.char('Distribution Code', size=16),
'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal' ), 'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal' ),
'account_ids': fields.one2many('account.analytic.plan.instance.line', 'plan_id', 'Account Id'), 'account_ids': fields.one2many('account.analytic.plan.instance.line', 'plan_id', 'Account Id'),

View File

@ -32,7 +32,7 @@ class account_asset_category(osv.osv):
_description = 'Asset category' _description = 'Asset category'
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, select=1), 'name': fields.char('Name', required=True, select=1),
'note': fields.text('Note'), 'note': fields.text('Note'),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'), 'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True, domain=[('type','=','other')]), 'account_asset_id': fields.many2one('account.account', 'Asset Account', required=True, domain=[('type','=','other')]),
@ -246,7 +246,7 @@ class account_asset_asset(osv.osv):
_columns = { _columns = {
'account_move_line_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}), 'account_move_line_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
'entry_count': fields.function(_entry_count, string='# Asset Entries', type='integer'), 'entry_count': fields.function(_entry_count, string='# Asset Entries', type='integer'),
'name': fields.char('Asset Name', size=64, required=True, readonly=True, states={'draft':[('readonly',False)]}), 'name': fields.char('Asset Name', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'code': fields.char('Reference', size=32, readonly=True, states={'draft':[('readonly',False)]}), 'code': fields.char('Reference', size=32, readonly=True, states={'draft':[('readonly',False)]}),
'purchase_value': fields.float('Gross Value', required=True, readonly=True, states={'draft':[('readonly',False)]}), 'purchase_value': fields.float('Gross Value', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'currency_id': fields.many2one('res.currency','Currency',required=True, readonly=True, states={'draft':[('readonly',False)]}), 'currency_id': fields.many2one('res.currency','Currency',required=True, readonly=True, states={'draft':[('readonly',False)]}),
@ -379,7 +379,7 @@ class account_asset_depreciation_line(osv.osv):
return res return res
_columns = { _columns = {
'name': fields.char('Depreciation Name', size=64, required=True, select=1), 'name': fields.char('Depreciation Name', required=True, select=1),
'sequence': fields.integer('Sequence', required=True), 'sequence': fields.integer('Sequence', required=True),
'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True, ondelete='cascade'), 'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True, ondelete='cascade'),
'parent_state': fields.related('asset_id', 'state', type='char', string='State of Asset'), 'parent_state': fields.related('asset_id', 'state', type='char', string='State of Asset'),
@ -474,7 +474,7 @@ class account_asset_history(osv.osv):
_name = 'account.asset.history' _name = 'account.asset.history'
_description = 'Asset history' _description = 'Asset history'
_columns = { _columns = {
'name': fields.char('History name', size=64, select=1), 'name': fields.char('History name', select=1),
'user_id': fields.many2one('res.users', 'User', required=True), 'user_id': fields.many2one('res.users', 'User', required=True),
'date': fields.date('Date', required=True), 'date': fields.date('Date', required=True),
'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True), 'asset_id': fields.many2one('account.asset.asset', 'Asset', required=True),

View File

@ -27,7 +27,7 @@ class asset_asset_report(osv.osv):
_description = "Assets Analysis" _description = "Assets Analysis"
_auto = False _auto = False
_columns = { _columns = {
'name': fields.char('Year', size=16, required=False, readonly=True), 'name': fields.char('Year', required=False, readonly=True),
'purchase_date': fields.date('Purchase Date', readonly=True), 'purchase_date': fields.date('Purchase Date', readonly=True),
'depreciation_date': fields.date('Depreciation Date', readonly=True), 'depreciation_date': fields.date('Depreciation Date', readonly=True),
'asset_id': fields.many2one('account.asset.asset', string='Asset', readonly=True), 'asset_id': fields.many2one('account.asset.asset', string='Asset', readonly=True),

View File

@ -28,7 +28,7 @@ class asset_modify(osv.osv_memory):
_description = 'Modify Asset' _description = 'Modify Asset'
_columns = { _columns = {
'name': fields.char('Reason', size=64, required=True), 'name': fields.char('Reason', required=True),
'method_number': fields.integer('Number of Depreciations', required=True), 'method_number': fields.integer('Number of Depreciations', required=True),
'method_period': fields.integer('Period Length'), 'method_period': fields.integer('Period Length'),
'method_end': fields.date('Ending date'), 'method_end': fields.date('Ending date'),

View File

@ -62,7 +62,7 @@ class account_bank_statement_line_global(osv.osv):
_description = 'Batch Payment Info' _description = 'Batch Payment Info'
_columns = { _columns = {
'name': fields.char('OBI', size=128, required=True, help="Originator to Beneficiary Information"), 'name': fields.char('OBI', required=True, help="Originator to Beneficiary Information"),
'code': fields.char('Code', size=64, required=True), 'code': fields.char('Code', size=64, required=True),
'parent_id': fields.many2one('account.bank.statement.line.global', 'Parent Code', ondelete='cascade'), 'parent_id': fields.many2one('account.bank.statement.line.global', 'Parent Code', ondelete='cascade'),
'child_ids': fields.one2many('account.bank.statement.line.global', 'parent_id', 'Child Codes'), 'child_ids': fields.one2many('account.bank.statement.line.global', 'parent_id', 'Child Codes'),

View File

@ -39,7 +39,7 @@ class account_budget_post(osv.osv):
_description = "Budgetary Position" _description = "Budgetary Position"
_columns = { _columns = {
'code': fields.char('Code', size=64, required=True), 'code': fields.char('Code', size=64, required=True),
'name': fields.char('Name', size=256, required=True), 'name': fields.char('Name', required=True),
'account_ids': fields.many2many('account.account', 'account_budget_rel', 'budget_id', 'account_id', 'Accounts'), 'account_ids': fields.many2many('account.account', 'account_budget_rel', 'budget_id', 'account_id', 'Accounts'),
'crossovered_budget_line': fields.one2many('crossovered.budget.lines', 'general_budget_id', 'Budget Lines'), 'crossovered_budget_line': fields.one2many('crossovered.budget.lines', 'general_budget_id', 'Budget Lines'),
'company_id': fields.many2one('res.company', 'Company', required=True), 'company_id': fields.many2one('res.company', 'Company', required=True),
@ -56,7 +56,7 @@ class crossovered_budget(osv.osv):
_description = "Budget" _description = "Budget"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, states={'done':[('readonly',True)]}), 'name': fields.char('Name', required=True, states={'done':[('readonly',True)]}),
'code': fields.char('Code', size=16, required=True, states={'done':[('readonly',True)]}), 'code': fields.char('Code', size=16, required=True, states={'done':[('readonly',True)]}),
'creating_user_id': fields.many2one('res.users', 'Responsible User'), 'creating_user_id': fields.many2one('res.users', 'Responsible User'),
'validating_user_id': fields.many2one('res.users', 'Validate User', readonly=True), 'validating_user_id': fields.many2one('res.users', 'Validate User', readonly=True),

View File

@ -36,9 +36,9 @@ class account_voucher(osv.osv):
return journal_pool.search(cr, uid, [('type', '=', ttype)], limit=1) return journal_pool.search(cr, uid, [('type', '=', ttype)], limit=1)
_columns = { _columns = {
'amount_in_word' : fields.char("Amount in Word" , size=128, readonly=True, states={'draft':[('readonly',False)]}), 'amount_in_word' : fields.char("Amount in Word", readonly=True, states={'draft':[('readonly',False)]}),
'allow_check' : fields.related('journal_id', 'allow_check_writing', type='boolean', string='Allow Check Writing'), 'allow_check' : fields.related('journal_id', 'allow_check_writing', type='boolean', string='Allow Check Writing'),
'number': fields.char('Number', size=32), 'number': fields.char('Number'),
} }
def _amount_to_text(self, cr, uid, amount, currency_id, context=None): def _amount_to_text(self, cr, uid, amount, currency_id, context=None):

View File

@ -49,7 +49,7 @@ class followup_line(osv.osv):
_name = 'account_followup.followup.line' _name = 'account_followup.followup.line'
_description = 'Follow-up Criteria' _description = 'Follow-up Criteria'
_columns = { _columns = {
'name': fields.char('Follow-Up Action', size=64, required=True), 'name': fields.char('Follow-Up Action', required=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of follow-up lines."), 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of follow-up lines."),
'delay': fields.integer('Due Days', help="The number of days after the due date of the invoice to wait before sending the reminder. Could be negative if you want to send a polite alert beforehand.", required=True), 'delay': fields.integer('Due Days', help="The number of days after the due date of the invoice to wait before sending the reminder. Could be negative if you want to send a polite alert beforehand.", required=True),
'followup_id': fields.many2one('account_followup.followup', 'Follow Ups', required=True, ondelete="cascade"), 'followup_id': fields.many2one('account_followup.followup', 'Follow Ups', required=True, ondelete="cascade"),

View File

@ -30,7 +30,7 @@ class payment_mode(osv.osv):
_name= 'payment.mode' _name= 'payment.mode'
_description= 'Payment Mode' _description= 'Payment Mode'
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, help='Mode of Payment'), 'name': fields.char('Name', required=True, help='Mode of Payment'),
'bank_id': fields.many2one('res.partner.bank', "Bank account", 'bank_id': fields.many2one('res.partner.bank', "Bank account",
required=True,help='Bank Account for the Payment Mode'), required=True,help='Bank Account for the Payment Mode'),
'journal': fields.many2one('account.journal', 'Journal', required=True, 'journal': fields.many2one('account.journal', 'Journal', required=True,
@ -87,7 +87,7 @@ class payment_order(osv.osv):
_columns = { _columns = {
'date_scheduled': fields.date('Scheduled Date', states={'done':[('readonly', True)]}, help='Select a date if you have chosen Preferred Date to be fixed.'), 'date_scheduled': fields.date('Scheduled Date', states={'done':[('readonly', True)]}, help='Select a date if you have chosen Preferred Date to be fixed.'),
'reference': fields.char('Reference', size=128, required=1, states={'done': [('readonly', True)]}), 'reference': fields.char('Reference', required=1, states={'done': [('readonly', True)]}),
'mode': fields.many2one('payment.mode', 'Payment Mode', select=True, required=1, states={'done': [('readonly', True)]}, help='Select the Payment Mode to be applied.'), 'mode': fields.many2one('payment.mode', 'Payment Mode', select=True, required=1, states={'done': [('readonly', True)]}, help='Select the Payment Mode to be applied.'),
'state': fields.selection([ 'state': fields.selection([
('draft', 'Draft'), ('draft', 'Draft'),
@ -303,9 +303,9 @@ class payment_line(osv.osv):
return res return res
_columns = { _columns = {
'name': fields.char('Your Reference', size=64, required=True), 'name': fields.char('Your Reference', required=True),
'communication': fields.char('Communication', size=64, required=True, help="Used as the message between ordering customer and current company. Depicts 'What do you want to say to the recipient about this order ?'"), 'communication': fields.char('Communication', required=True, help="Used as the message between ordering customer and current company. Depicts 'What do you want to say to the recipient about this order ?'"),
'communication2': fields.char('Communication 2', size=64, help='The successor message of Communication.'), 'communication2': fields.char('Communication 2', help='The successor message of Communication.'),
'move_line_id': fields.many2one('account.move.line', 'Entry line', domain=[('reconcile_id', '=', False), ('account_id.type', '=', 'payable')], help='This Entry Line will be referred for the information of the ordering customer.'), 'move_line_id': fields.many2one('account.move.line', 'Entry line', domain=[('reconcile_id', '=', False), ('account_id.type', '=', 'payable')], help='This Entry Line will be referred for the information of the ordering customer.'),
'amount_currency': fields.float('Amount in Partner Currency', digits=(16, 2), 'amount_currency': fields.float('Amount in Partner Currency', digits=(16, 2),
required=True, help='Payment amount in the partner currency'), required=True, help='Payment amount in the partner currency'),

View File

@ -26,7 +26,7 @@ class account_move(osv.osv):
_inherit = 'account.move' _inherit = 'account.move'
_columns = { _columns = {
'internal_sequence_number': fields.char('Internal Number', size=64, readonly=True, help='Internal Sequence Number'), 'internal_sequence_number': fields.char('Internal Number', readonly=True, help='Internal Sequence Number'),
} }
def post(self, cr, uid, ids, context=None): def post(self, cr, uid, ids, context=None):

View File

@ -26,9 +26,9 @@ class account_sequence_installer(osv.osv_memory):
_inherit = 'res.config.installer' _inherit = 'res.config.installer'
_columns = { _columns = {
'name': fields.char('Name',size=64, required=True), 'name': fields.char('Name', required=True),
'prefix': fields.char('Prefix',size=64, help="Prefix value of the record for the sequence"), 'prefix': fields.char('Prefix', size=64, help="Prefix value of the record for the sequence"),
'suffix': fields.char('Suffix',size=64, help="Suffix value of the record for the sequence"), 'suffix': fields.char('Suffix', size=64, help="Suffix value of the record for the sequence"),
'number_next': fields.integer('Next Number', required=True, help="Next number of this sequence"), 'number_next': fields.integer('Next Number', required=True, help="Next number of this sequence"),
'number_increment': fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"), 'number_increment': fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"),
'padding' : fields.integer('Number padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."), 'padding' : fields.integer('Number padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."),

View File

@ -43,7 +43,7 @@ class accounting_assert_test(osv.osv):
_order = "sequence" _order = "sequence"
_columns = { _columns = {
'name': fields.char('Test Name', size=256, required=True, select=True, translate=True), 'name': fields.char('Test Name', required=True, select=True, translate=True),
'desc': fields.text('Test Description', select=True, translate=True), 'desc': fields.text('Test Description', select=True, translate=True),
'code_exec': fields.text('Python code', required=True), 'code_exec': fields.text('Python code', required=True),
'active': fields.boolean('Active'), 'active': fields.boolean('Active'),

View File

@ -333,7 +333,7 @@ class account_voucher(osv.osv):
('payment','Payment'), ('payment','Payment'),
('receipt','Receipt'), ('receipt','Receipt'),
],'Default Type', readonly=True, states={'draft':[('readonly',False)]}), ],'Default Type', readonly=True, states={'draft':[('readonly',False)]}),
'name':fields.char('Memo', size=256, readonly=True, states={'draft':[('readonly',False)]}), 'name':fields.char('Memo', readonly=True, states={'draft':[('readonly',False)]}),
'date':fields.date('Date', readonly=True, select=True, states={'draft':[('readonly',False)]}, help="Effective date for accounting entries"), 'date':fields.date('Date', readonly=True, select=True, states={'draft':[('readonly',False)]}, help="Effective date for accounting entries"),
'journal_id':fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}), 'journal_id':fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'account_id':fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}), 'account_id':fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}),
@ -351,15 +351,15 @@ class account_voucher(osv.osv):
('cancel','Cancelled'), ('cancel','Cancelled'),
('proforma','Pro-forma'), ('proforma','Pro-forma'),
('posted','Posted') ('posted','Posted')
], 'Status', readonly=True, size=32, track_visibility='onchange', ], 'Status', readonly=True, track_visibility='onchange',
help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed Voucher. \ help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed Voucher. \
\n* The \'Pro-forma\' when voucher is in Pro-forma status,voucher does not have an voucher number. \ \n* The \'Pro-forma\' when voucher is in Pro-forma status,voucher does not have an voucher number. \
\n* The \'Posted\' status is used when user create voucher,a voucher number is generated and voucher entries are created in account \ \n* The \'Posted\' status is used when user create voucher,a voucher number is generated and voucher entries are created in account \
\n* The \'Cancelled\' status is used when user cancel voucher.'), \n* The \'Cancelled\' status is used when user cancel voucher.'),
'amount': fields.float('Total', digits_compute=dp.get_precision('Account'), required=True, readonly=True, states={'draft':[('readonly',False)]}), 'amount': fields.float('Total', digits_compute=dp.get_precision('Account'), required=True, readonly=True, states={'draft':[('readonly',False)]}),
'tax_amount':fields.float('Tax Amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}), 'tax_amount':fields.float('Tax Amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}),
'reference': fields.char('Ref #', size=64, readonly=True, states={'draft':[('readonly',False)]}, help="Transaction reference number."), 'reference': fields.char('Ref #', readonly=True, states={'draft':[('readonly',False)]}, help="Transaction reference number."),
'number': fields.char('Number', size=32, readonly=True,), 'number': fields.char('Number', readonly=True,),
'move_id':fields.many2one('account.move', 'Account Entry'), 'move_id':fields.many2one('account.move', 'Account Entry'),
'move_ids': fields.related('move_id','line_id', type='one2many', relation='account.move.line', string='Journal Items', readonly=True), 'move_ids': fields.related('move_id','line_id', type='one2many', relation='account.move.line', string='Journal Items', readonly=True),
'partner_id':fields.many2one('res.partner', 'Partner', change_default=1, readonly=True, states={'draft':[('readonly',False)]}), 'partner_id':fields.many2one('res.partner', 'Partner', change_default=1, readonly=True, states={'draft':[('readonly',False)]}),
@ -377,7 +377,7 @@ class account_voucher(osv.osv):
('with_writeoff', 'Reconcile Payment Balance'), ('with_writeoff', 'Reconcile Payment Balance'),
], 'Payment Difference', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="This field helps you to choose what you want to do with the eventual difference between the paid amount and the sum of allocated amounts. You can either choose to keep open this difference on the partner's account, or reconcile it with the payment(s)"), ], 'Payment Difference', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="This field helps you to choose what you want to do with the eventual difference between the paid amount and the sum of allocated amounts. You can either choose to keep open this difference on the partner's account, or reconcile it with the payment(s)"),
'writeoff_acc_id': fields.many2one('account.account', 'Counterpart Account', readonly=True, states={'draft': [('readonly', False)]}), 'writeoff_acc_id': fields.many2one('account.account', 'Counterpart Account', readonly=True, states={'draft': [('readonly', False)]}),
'comment': fields.char('Counterpart Comment', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}), 'comment': fields.char('Counterpart Comment', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'analytic_id': fields.many2one('account.analytic.account','Write-Off Analytic Account', readonly=True, states={'draft': [('readonly', False)]}), 'analytic_id': fields.many2one('account.analytic.account','Write-Off Analytic Account', readonly=True, states={'draft': [('readonly', False)]}),
'writeoff_amount': fields.function(_get_writeoff_amount, string='Difference Amount', type='float', readonly=True, help="Computed as the difference between the amount stated in the voucher and the sum of allocation on the voucher lines."), 'writeoff_amount': fields.function(_get_writeoff_amount, string='Difference Amount', type='float', readonly=True, help="Computed as the difference between the amount stated in the voucher and the sum of allocation on the voucher lines."),
'payment_rate_currency_id': fields.many2one('res.currency', 'Payment Rate Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}), 'payment_rate_currency_id': fields.many2one('res.currency', 'Payment Rate Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
@ -1482,7 +1482,7 @@ class account_voucher_line(osv.osv):
_columns = { _columns = {
'voucher_id':fields.many2one('account.voucher', 'Voucher', required=1, ondelete='cascade'), 'voucher_id':fields.many2one('account.voucher', 'Voucher', required=1, ondelete='cascade'),
'name':fields.char('Description', size=256), 'name':fields.char('Description',),
'account_id':fields.many2one('account.account','Account', required=True), 'account_id':fields.many2one('account.account','Account', required=True),
'partner_id':fields.related('voucher_id', 'partner_id', type='many2one', relation='res.partner', string='Partner'), 'partner_id':fields.related('voucher_id', 'partner_id', type='many2one', relation='res.partner', string='Partner'),
'untax_amount':fields.float('Untax Amount'), 'untax_amount':fields.float('Untax Amount'),

View File

@ -171,7 +171,7 @@ class account_analytic_account(osv.osv):
return result return result
_columns = { _columns = {
'name': fields.char('Account/Contract Name', size=128, required=True, track_visibility='onchange'), 'name': fields.char('Account/Contract Name', required=True, track_visibility='onchange'),
'complete_name': fields.function(_get_full_name, type='char', string='Full Name'), 'complete_name': fields.function(_get_full_name, type='char', string='Full Name'),
'code': fields.char('Reference', select=True, track_visibility='onchange'), 'code': fields.char('Reference', select=True, track_visibility='onchange'),
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Contract')], 'Type of Account', required=True, 'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Contract')], 'Type of Account', required=True,
@ -314,7 +314,7 @@ class account_analytic_line(osv.osv):
_description = 'Analytic Line' _description = 'Analytic Line'
_columns = { _columns = {
'name': fields.char('Description', size=256, required=True), 'name': fields.char('Description', required=True),
'date': fields.date('Date', required=True, select=True), 'date': fields.date('Date', required=True, select=True),
'amount': fields.float('Amount', required=True, help='Calculated by multiplying the quantity and the price given in the Product\'s cost price. Always expressed in the company main currency.', digits_compute=dp.get_precision('Account')), 'amount': fields.float('Amount', required=True, help='Calculated by multiplying the quantity and the price given in the Product\'s cost price. Always expressed in the company main currency.', digits_compute=dp.get_precision('Account')),
'unit_amount': fields.float('Quantity', help='Specifies the amount of quantity to count.'), 'unit_amount': fields.float('Quantity', help='Specifies the amount of quantity to count.'),

View File

@ -54,9 +54,9 @@ class ir_model_fields_anonymization(osv.osv):
_rec_name = 'field_id' _rec_name = 'field_id'
_columns = { _columns = {
'model_name': fields.char('Object Name', size=128, required=True), 'model_name': fields.char('Object Name', required=True),
'model_id': fields.many2one('ir.model', 'Object', ondelete='set null'), 'model_id': fields.many2one('ir.model', 'Object', ondelete='set null'),
'field_name': fields.char('Field Name', size=128, required=True), 'field_name': fields.char('Field Name', required=True),
'field_id': fields.many2one('ir.model.fields', 'Field', ondelete='set null'), 'field_id': fields.many2one('ir.model.fields', 'Field', ondelete='set null'),
'state': fields.selection(selection=FIELD_STATES, String='Status', required=True, readonly=True), 'state': fields.selection(selection=FIELD_STATES, String='Status', required=True, readonly=True),
} }
@ -226,9 +226,9 @@ class ir_model_fields_anonymization_history(osv.osv):
'date': fields.datetime('Date', required=True, readonly=True), 'date': fields.datetime('Date', required=True, readonly=True),
'field_ids': fields.many2many('ir.model.fields.anonymization', 'anonymized_field_to_history_rel', 'field_id', 'history_id', 'Fields', readonly=True), 'field_ids': fields.many2many('ir.model.fields.anonymization', 'anonymized_field_to_history_rel', 'field_id', 'history_id', 'Fields', readonly=True),
'state': fields.selection(selection=ANONYMIZATION_HISTORY_STATE, string='Status', required=True, readonly=True), 'state': fields.selection(selection=ANONYMIZATION_HISTORY_STATE, string='Status', required=True, readonly=True),
'direction': fields.selection(selection=ANONYMIZATION_DIRECTION, string='Direction', required=True, readonly=True), 'direction': fields.selection(selection=ANONYMIZATION_DIRECTION, string='Direction', size=20, required=True, readonly=True),
'msg': fields.text('Message', readonly=True), 'msg': fields.text('Message', readonly=True),
'filepath': fields.char(string='File path', size=256, readonly=True), 'filepath': fields.char(string='File path', readonly=True),
} }
@ -253,7 +253,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
return res return res
_columns = { _columns = {
'name': fields.char(size=64, string='File Name'), 'name': fields.char(string='File Name'),
'summary': fields.function(_get_summary, type='text', string='Summary'), 'summary': fields.function(_get_summary, type='text', string='Summary'),
'file_export': fields.binary(string='Export'), 'file_export': fields.binary(string='Export'),
'file_import': fields.binary(string='Import', help="This is the file created by the anonymization process. It should have the '.pickle' extention."), 'file_import': fields.binary(string='Import', help="This is the file created by the anonymization process. It should have the '.pickle' extention."),

View File

@ -205,16 +205,16 @@ class CompanyLDAP(osv.osv):
'sequence': fields.integer('Sequence'), 'sequence': fields.integer('Sequence'),
'company': fields.many2one('res.company', 'Company', required=True, 'company': fields.many2one('res.company', 'Company', required=True,
ondelete='cascade'), ondelete='cascade'),
'ldap_server': fields.char('LDAP Server address', size=64, required=True), 'ldap_server': fields.char('LDAP Server address', required=True),
'ldap_server_port': fields.integer('LDAP Server port', required=True), 'ldap_server_port': fields.integer('LDAP Server port', required=True),
'ldap_binddn': fields.char('LDAP binddn', size=64, 'ldap_binddn': fields.char('LDAP binddn',
help=("The user account on the LDAP server that is used to query " help=("The user account on the LDAP server that is used to query "
"the directory. Leave empty to connect anonymously.")), "the directory. Leave empty to connect anonymously.")),
'ldap_password': fields.char('LDAP password', size=64, 'ldap_password': fields.char('LDAP password',
help=("The password of the user account on the LDAP server that is " help=("The password of the user account on the LDAP server that is "
"used to query the directory.")), "used to query the directory.")),
'ldap_filter': fields.char('LDAP filter', size=256, required=True), 'ldap_filter': fields.char('LDAP filter', required=True),
'ldap_base': fields.char('LDAP base', size=64, required=True), 'ldap_base': fields.char('LDAP base', required=True),
'user': fields.many2one('res.users', 'Template User', 'user': fields.many2one('res.users', 'Template User',
help="User to copy when creating new users"), help="User to copy when creating new users"),
'create_user': fields.boolean('Create user', 'create_user': fields.boolean('Create user',

View File

@ -54,7 +54,7 @@ class base_action_rule(osv.osv):
_order = 'sequence' _order = 'sequence'
_columns = { _columns = {
'name': fields.char('Rule Name', size=64, required=True), 'name': fields.char('Rule Name', required=True),
'model_id': fields.many2one('ir.model', 'Related Document Model', 'model_id': fields.many2one('ir.model', 'Related Document Model',
required=True, domain=[('osv_memory', '=', False)]), required=True, domain=[('osv_memory', '=', False)]),
'model': fields.related('model_id', 'model', type="char", size=256, string='Model'), 'model': fields.related('model_id', 'model', type="char", size=256, string='Model'),
@ -156,13 +156,13 @@ class base_action_rule(osv.osv):
""" Return a wrapper around `old_create` calling both `old_create` and """ Return a wrapper around `old_create` calling both `old_create` and
`_process`, in that order. `_process`, in that order.
""" """
def create(cr, uid, vals, context=None): def create(cr, uid, vals, context=None, **kwargs):
# avoid loops or cascading actions # avoid loops or cascading actions
if context and context.get('action'): if context and context.get('action'):
return old_create(cr, uid, vals, context=context) return old_create(cr, uid, vals, context=context)
context = dict(context or {}, action=True) context = dict(context or {}, action=True)
new_id = old_create(cr, uid, vals, context=context) new_id = old_create(cr, uid, vals, context=context, **kwargs)
# retrieve the action rules to run on creation # retrieve the action rules to run on creation
action_dom = [('model', '=', model), ('kind', 'in', ['on_create', 'on_create_or_write'])] action_dom = [('model', '=', model), ('kind', 'in', ['on_create', 'on_create_or_write'])]
@ -180,10 +180,10 @@ class base_action_rule(osv.osv):
""" Return a wrapper around `old_write` calling both `old_write` and """ Return a wrapper around `old_write` calling both `old_write` and
`_process`, in that order. `_process`, in that order.
""" """
def write(cr, uid, ids, vals, context=None): def write(cr, uid, ids, vals, context=None, **kwargs):
# avoid loops or cascading actions # avoid loops or cascading actions
if context and context.get('action'): if context and context.get('action'):
return old_write(cr, uid, ids, vals, context=context) return old_write(cr, uid, ids, vals, context=context, **kwargs)
context = dict(context or {}, action=True) context = dict(context or {}, action=True)
ids = [ids] if isinstance(ids, (int, long, str)) else ids ids = [ids] if isinstance(ids, (int, long, str)) else ids
@ -199,7 +199,7 @@ class base_action_rule(osv.osv):
pre_ids[action] = self._filter(cr, uid, action, action.filter_pre_id, ids, context=context) pre_ids[action] = self._filter(cr, uid, action, action.filter_pre_id, ids, context=context)
# execute write # execute write
old_write(cr, uid, ids, vals, context=context) old_write(cr, uid, ids, vals, context=context, **kwargs)
# check postconditions, and execute actions on the records that satisfy them # check postconditions, and execute actions on the records that satisfy them
for action in actions: for action in actions:

View File

@ -12,7 +12,7 @@ class lead_test(osv.Model):
_name = "base.action.rule.lead.test" _name = "base.action.rule.lead.test"
_columns = { _columns = {
'name': fields.char('Subject', size=64, required=True, select=1), 'name': fields.char('Subject', required=True, select=1),
'user_id': fields.many2one('res.users', 'Responsible'), 'user_id': fields.many2one('res.users', 'Responsible'),
'state': fields.selection(AVAILABLE_STATES, string="Status", readonly=True), 'state': fields.selection(AVAILABLE_STATES, string="Status", readonly=True),
'active': fields.boolean('Active', required=False), 'active': fields.boolean('Active', required=False),

View File

@ -1,22 +1,53 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import openerp import openerp
from openerp import SUPERUSER_ID
from openerp.addons.web import http from openerp.addons.web import http
from openerp.addons.web.http import request from openerp.addons.web.http import request
from werkzeug.wrappers import BaseResponse as Response
import json import json
class website_gengo(http.Controller): class website_gengo(http.Controller):
def get_gengo_key(self, cr):
icp = request.registry['ir.config_parameter']
return icp.get_param(cr, SUPERUSER_ID, request.registry['base.gengo.translations'].GENGO_KEY, default="")
@http.route('/website/gengo_callback', type='http', auth='none') @http.route('/website/gengo_callback', type='http', auth='none')
def gengo_callback(self,**post): def gengo_callback(self, **post):
cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context cr, uid, context = request.cr, openerp.SUPERUSER_ID, request.context
translation_pool = request.registry['ir.translation'] translation_pool = request.registry['ir.translation']
if post and post.get('job'): if post and post.get('job') and post.get('pgk'):
job = json.loads(post['job']) if post.get('pgk') != self.get_gengo_key(cr):
return Response("Bad authentication - 403/412", status=412)
job = json.loads(post['job'], 'utf-8')
tid = job.get('custom_data', False) tid = job.get('custom_data', False)
if (job.get('status') == 'approved') and tid: if (job.get('status') == 'approved') and tid:
term = translation_pool.browse(cr, uid, int(tid), context=context) term = translation_pool.browse(cr, uid, int(tid), context=context)
if term.job_id <> job.get('job_id'): if term.src != job.get('body_src'):
raise 'Error' return Response("Text Altered - Not saved", status=100)
vals = {'state': 'translated', 'value': job.get('body_tgt')} domain = [
translation_pool.write(cr, uid, [int(tid)], vals, context=context) '|',
('id', "=", int(tid)),
'&', '&', '&', '&', '&',
('state', '=', term.state),
('gengo_translation', '=', term.gengo_translation),
('src', "=", term.src),
('type', "=", term.type),
('name', "=", term.name),
('lang', "=", term.lang),
#('order_id', "=", term.order_id),
]
all_ir_tanslations = translation_pool.search(cr, uid, domain, context=context or {})
if all_ir_tanslations:
vals = {'state': 'translated', 'value': job.get('body_tgt')}
translation_pool.write(cr, uid, all_ir_tanslations, vals, context=context)
return Response("OK", status=200)
else:
return Response("No terms found", status=104)
return Response("Not saved", status=100)

View File

@ -8,6 +8,7 @@
<field name="interval_number">6</field> <field name="interval_number">6</field>
<field name="interval_type">hours</field> <field name="interval_type">hours</field>
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field name="doall">0</field>
<field eval="'base.gengo.translations'" name="model"></field> <field eval="'base.gengo.translations'" name="model"></field>
<field eval="'_sync_response'" name="function"/> <field eval="'_sync_response'" name="function"/>
<field eval="'(20,)'" name="args"/> <field eval="'(20,)'" name="args"/>
@ -20,6 +21,7 @@
<field name="interval_number">6</field> <field name="interval_number">6</field>
<field name="interval_type">hours</field> <field name="interval_type">hours</field>
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field name="doall">0</field>
<field eval="'base.gengo.translations'" name="model"></field> <field eval="'base.gengo.translations'" name="model"></field>
<field eval="'_sync_request'" name="function"/> <field eval="'_sync_request'" name="function"/>
<field eval="'(20,)'" name="args"/> <field eval="'(20,)'" name="args"/>

View File

@ -56,16 +56,18 @@ LANG_CODE_MAPPING = {
'fi_FI': ('fi', 'Finnish') 'fi_FI': ('fi', 'Finnish')
} }
class ir_translation(osv.Model): class ir_translation(osv.Model):
_name = "ir.translation" _name = "ir.translation"
_inherit = "ir.translation" _inherit = "ir.translation"
_columns = { _columns = {
'gengo_comment': fields.text("Comments & Activity Linked to Gengo"), 'gengo_comment': fields.text("Comments & Activity Linked to Gengo"),
'job_id': fields.char('Gengo Job ID', size=32), 'order_id': fields.char('Gengo Order ID', size=32),
"gengo_translation": fields.selection([('machine', 'Translation By Machine'), "gengo_translation": fields.selection([('machine', 'Translation By Machine'),
('standard', 'Standard'), ('standard', 'Standard'),
('pro', 'Pro'), ('pro', 'Pro'),
('ultra', 'Ultra')], "Gengo Translation Service Level", help='You can select here the service level you want for an automatic translation using Gengo.'), ('ultra', 'Ultra')], "Gengo Translation Service Level", help='You can select here the service level you want for an automatic translation using Gengo.'),
} }
def _get_all_supported_languages(self, cr, uid, context=None): def _get_all_supported_languages(self, cr, uid, context=None):
@ -83,3 +85,19 @@ class ir_translation(osv.Model):
def _get_gengo_corresponding_language(cr, lang): def _get_gengo_corresponding_language(cr, lang):
return lang in LANG_CODE_MAPPING and LANG_CODE_MAPPING[lang][0] or lang return lang in LANG_CODE_MAPPING and LANG_CODE_MAPPING[lang][0] or lang
def _get_source_query(self, cr, uid, name, types, lang, source, res_id):
query, params = super(ir_translation, self)._get_source_query(cr, uid, name, types, lang, source, res_id)
query += """
ORDER BY
CASE
WHEN gengo_translation=%s then 10
WHEN gengo_translation=%s then 20
WHEN gengo_translation=%s then 30
WHEN gengo_translation=%s then 40
ELSE 0
END DESC
"""
params += ('machine', 'standard', 'ultra', 'pro',)
return (query, params)

View File

@ -19,12 +19,13 @@
# #
############################################################################## ##############################################################################
import uuid
import logging import logging
import re import re
import time import time
from openerp.osv import osv, fields from openerp.osv import osv, fields
from openerp import tools from openerp import tools, SUPERUSER_ID
from openerp.tools.translate import _ from openerp.tools.translate import _
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -36,7 +37,9 @@ except ImportError:
GENGO_DEFAULT_LIMIT = 20 GENGO_DEFAULT_LIMIT = 20
class base_gengo_translations(osv.osv_memory): class base_gengo_translations(osv.osv_memory):
GENGO_KEY = "Gengo.UUID"
_name = 'base.gengo.translations' _name = 'base.gengo.translations'
_columns = { _columns = {
@ -46,9 +49,20 @@ class base_gengo_translations(osv.osv_memory):
'lang_id': fields.many2one('res.lang', 'Language', required=True), 'lang_id': fields.many2one('res.lang', 'Language', required=True),
'sync_limit': fields.integer("No. of terms to sync"), 'sync_limit': fields.integer("No. of terms to sync"),
} }
_defaults = {'sync_type' : 'both', _defaults = {
'sync_limit' : 20 'sync_type': 'both',
} 'sync_limit': 20
}
def init(self, cr):
icp = self.pool['ir.config_parameter']
if not icp.get_param(cr, SUPERUSER_ID, self.GENGO_KEY, default=None):
icp.set_param(cr, SUPERUSER_ID, self.GENGO_KEY, str(uuid.uuid4()), groups=['base.group_website_designer', 'base.group_website_publisher'])
def get_gengo_key(self, cr):
icp = self.pool['ir.config_parameter']
return icp.get_param(cr, SUPERUSER_ID, self.GENGO_KEY, default="Undefined")
def gengo_authentication(self, cr, uid, context=None): def gengo_authentication(self, cr, uid, context=None):
''' '''
This method tries to open a connection with Gengo. For that, it uses the Public and Private This method tries to open a connection with Gengo. For that, it uses the Public and Private
@ -113,48 +127,68 @@ class base_gengo_translations(osv.osv_memory):
_logger.warning("%s", gengo) _logger.warning("%s", gengo)
else: else:
offset = 0 offset = 0
all_translation_ids = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('job_id', "!=", False)], context=context) all_translation_ids = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('order_id', "!=", False)], context=context)
while True: while True:
translation_ids = all_translation_ids[offset:offset + limit] translation_ids = all_translation_ids[offset:offset + limit]
offset += limit offset += limit
if not translation_ids: if not translation_ids:
break break
terms_progress = {
'gengo_order_ids': set(),
'ir_translation_ids': set(),
}
translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context) translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context)
gengo_job_id = [term.job_id for term in translation_terms] for term in translation_terms:
if gengo_job_id: terms_progress['gengo_order_ids'].add(term.order_id)
gengo_ids = ','.join(gengo_job_id) terms_progress['ir_translation_ids'].add(tools.ustr(term.id))
for order_id in terms_progress['gengo_order_ids']:
order_response = gengo.getTranslationOrderJobs(id=order_id)
jobs_approved = order_response.get('response', []).get('order', []).get('jobs_approved', [])
gengo_ids = ','.join(jobs_approved)
if gengo_ids: # Need to check, because getTranslationJobBatch don't catch this case and so call the getTranslationJobs because no ids in url
try: try:
job_response = gengo.getTranslationJobBatch(id=gengo_ids) job_response = gengo.getTranslationJobBatch(id=gengo_ids)
except: except:
continue continue
if job_response['opstat'] == 'ok': if job_response['opstat'] == 'ok':
for job in job_response['response'].get('jobs', []): for job in job_response['response'].get('jobs', []):
self._update_terms_job(cr, uid, job, context=context) if job.get('custom_data') in terms_progress['ir_translation_ids']:
self._update_terms_job(cr, uid, job, context=context)
return True return True
def _update_terms_job(self, cr, uid, job, context=None): def _update_terms_job(self, cr, uid, job, context=None):
translation_pool = self.pool.get('ir.translation') translation_pool = self.pool.get('ir.translation')
tid = int(job['custom_data']) tid = int(job['custom_data'])
vals = {} vals = {}
if job.get('job_id', False): if job.get('status', False) in ('queued', 'available', 'pending', 'reviewable'):
vals['job_id'] = job['job_id']
vals['state'] = 'inprogress' vals['state'] = 'inprogress'
if job.get('status', False) in ('queued','available','pending','reviewable'): if job.get('body_tgt', False) and job.get('status', False) == 'approved':
vals['state'] = 'inprogress'
if job.get('body_tgt', False) and job.get('status', False)=='approved':
vals['value'] = job['body_tgt'] vals['value'] = job['body_tgt']
if job.get('status', False) in ('approved', 'canceled'): if job.get('status', False) in ('approved', 'canceled'):
vals['state'] = 'translated' vals['state'] = 'translated'
if vals: if vals:
translation_pool.write(cr, uid, [tid], vals, context=context) translation_pool.write(cr, uid, [tid], vals, context=context)
def _update_terms(self, cr, uid, response, context=None): def _update_terms(self, cr, uid, response, term_ids, context=None):
""" """
Update the terms after their translation were requested to Gengo Update the terms after their translation were requested to Gengo
""" """
for jobs in response.get('jobs', []): translation_pool = self.pool.get('ir.translation')
vals = {
'order_id': response.get('order_id', ''),
'state': 'inprogress'
}
translation_pool.write(cr, uid, term_ids, vals, context=context)
jobs = response.get('jobs', [])
if jobs:
for t_id, res in jobs.items(): for t_id, res in jobs.items():
self._update_terms_job(cr, uid, res, context=context) self._update_terms_job(cr, uid, res, context=context)
return return
def pack_jobs_request(self, cr, uid, term_ids, context=None): def pack_jobs_request(self, cr, uid, term_ids, context=None):
@ -164,7 +198,7 @@ class base_gengo_translations(osv.osv_memory):
'term2.id': {...} 'term2.id': {...}
} }
}''' }'''
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
translation_pool = self.pool.get('ir.translation') translation_pool = self.pool.get('ir.translation')
jobs = {} jobs = {}
user = self.pool.get('res.users').browse(cr, uid, uid, context=context) user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
@ -173,7 +207,7 @@ class base_gengo_translations(osv.osv_memory):
if re.search(r"\w", term.src or ""): if re.search(r"\w", term.src or ""):
comment = user.company_id.gengo_comment or '' comment = user.company_id.gengo_comment or ''
if term.gengo_comment: if term.gengo_comment:
comment+='\n' + term.gengo_comment comment += '\n' + term.gengo_comment
jobs[time.strftime('%Y%m%d%H%M%S') + '-' + str(term.id)] = { jobs[time.strftime('%Y%m%d%H%M%S') + '-' + str(term.id)] = {
'type': 'text', 'type': 'text',
'slug': 'Single :: English to ' + term.lang, 'slug': 'Single :: English to ' + term.lang,
@ -184,10 +218,9 @@ class base_gengo_translations(osv.osv_memory):
'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang), 'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang),
'auto_approve': auto_approve, 'auto_approve': auto_approve,
'comment': comment, 'comment': comment,
'callback_url': self.pool.get('ir.config_parameter').get_param(cr, uid,'web.base.url') + '/website/gengo_callback' 'callback_url': "%s/website/gengo_callback?pgk=%s&db=%s" % (base_url, self.get_gengo_key(cr), cr.dbname)
} }
return {'jobs': jobs, 'as_group': 1} return {'jobs': jobs, 'as_group': 0}
def _send_translation_terms(self, cr, uid, term_ids, context=None): def _send_translation_terms(self, cr, uid, term_ids, context=None):
""" """
@ -200,7 +233,7 @@ class base_gengo_translations(osv.osv_memory):
if request['jobs']: if request['jobs']:
result = gengo.postTranslationJobs(jobs=request) result = gengo.postTranslationJobs(jobs=request)
if result['opstat'] == 'ok': if result['opstat'] == 'ok':
self._update_terms(cr, uid, result['response'], context=context) self._update_terms(cr, uid, result['response'], term_ids, context=context)
else: else:
_logger.error(gengo) _logger.error(gengo)
return True return True
@ -218,10 +251,10 @@ class base_gengo_translations(osv.osv_memory):
context = {} context = {}
language_pool = self.pool.get('res.lang') language_pool = self.pool.get('res.lang')
translation_pool = self.pool.get('ir.translation') translation_pool = self.pool.get('ir.translation')
domain = [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('job_id', "=", False)] domain = [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('order_id', "=", False)]
if context.get('gengo_language', False): if context.get('gengo_language', False):
lc = language_pool.browse(cr, uid, context['gengo_language'], context=context).code lc = language_pool.browse(cr, uid, context['gengo_language'], context=context).code
domain.append( ('lang', '=', lc) ) domain.append(('lang', '=', lc))
all_term_ids = translation_pool.search(cr, uid, domain, context=context) all_term_ids = translation_pool.search(cr, uid, domain, context=context)
try: try:

View File

@ -22,11 +22,11 @@ class ir_import(orm.TransientModel):
_transient_max_hours = 12.0 _transient_max_hours = 12.0
_columns = { _columns = {
'res_model': fields.char('Model', size=64), 'res_model': fields.char('Model'),
'file': fields.binary( 'file': fields.binary(
'File', help="File to check and/or import, raw binary (not base64)"), 'File', help="File to check and/or import, raw binary (not base64)"),
'file_name': fields.char('File Name', size=None), 'file_name': fields.char('File Name'),
'file_type': fields.char('File Type', size=None), 'file_type': fields.char('File Type'),
} }
def get_fields(self, cr, uid, model, context=None, def get_fields(self, cr, uid, model, context=None,

View File

@ -6,42 +6,42 @@ class char(orm.Model):
_name = name('char') _name = name('char')
_columns = { _columns = {
'value': fields.char('unknown', size=None) 'value': fields.char('unknown')
} }
class char_required(orm.Model): class char_required(orm.Model):
_name = name('char.required') _name = name('char.required')
_columns = { _columns = {
'value': fields.char('unknown', size=None, required=True) 'value': fields.char('unknown', required=True)
} }
class char_readonly(orm.Model): class char_readonly(orm.Model):
_name = name('char.readonly') _name = name('char.readonly')
_columns = { _columns = {
'value': fields.char('unknown', size=None, readonly=True) 'value': fields.char('unknown', readonly=True)
} }
class char_states(orm.Model): class char_states(orm.Model):
_name = name('char.states') _name = name('char.states')
_columns = { _columns = {
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('readonly', False)]}) 'value': fields.char('unknown', readonly=True, states={'draft': [('readonly', False)]})
} }
class char_noreadonly(orm.Model): class char_noreadonly(orm.Model):
_name = name('char.noreadonly') _name = name('char.noreadonly')
_columns = { _columns = {
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('invisible', True)]}) 'value': fields.char('unknown', readonly=True, states={'draft': [('invisible', True)]})
} }
class char_stillreadonly(orm.Model): class char_stillreadonly(orm.Model):
_name = name('char.stillreadonly') _name = name('char.stillreadonly')
_columns = { _columns = {
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('readonly', True)]}) 'value': fields.char('unknown', readonly=True, states={'draft': [('readonly', True)]})
} }
# TODO: complex field (m2m, o2m, m2o) # TODO: complex field (m2m, o2m, m2o)
@ -95,7 +95,7 @@ class preview_model(orm.Model):
_name = name('preview') _name = name('preview')
_columns = { _columns = {
'name': fields.char('Name', size=None), 'name': fields.char('Name'),
'somevalue': fields.integer('Some Value', required=True), 'somevalue': fields.integer('Some Value', required=True),
'othervalue': fields.integer('Other Variable'), 'othervalue': fields.integer('Other Variable'),
} }

View File

@ -35,8 +35,8 @@ class base_report_designer_installer(osv.osv_memory):
return data return data
_columns = { _columns = {
'name':fields.char('File name', size=34), 'name':fields.char('File name'),
'plugin_file':fields.char('OpenObject Report Designer Plug-in', size=256, readonly=True, help="OpenObject Report Designer plug-in file. Save as this file and install this plug-in in OpenOffice."), 'plugin_file':fields.char('OpenObject Report Designer Plug-in', readonly=True, help="OpenObject Report Designer plug-in file. Save as this file and install this plug-in in OpenOffice."),
'description':fields.text('Description', readonly=True) 'description':fields.text('Description', readonly=True)
} }

View File

@ -81,8 +81,7 @@ class base_config_settings(osv.osv_memory):
return self.pool.get("res.font").font_scan(cr, uid, context=context) return self.pool.get("res.font").font_scan(cr, uid, context=context)
# Preferences wizard for Sales & CRM. # Preferences wizard for Sales & CRM.
# It is defined here because it is inherited independently in modules sale, crm, # It is defined here because it is inherited independently in modules sale, crm.
# plugin_outlook and plugin_thunderbird.
class sale_config_settings(osv.osv_memory): class sale_config_settings(osv.osv_memory):
_name = 'sale.config.settings' _name = 'sale.config.settings'
_inherit = 'res.config.settings' _inherit = 'res.config.settings'
@ -91,18 +90,6 @@ class sale_config_settings(osv.osv_memory):
help="""When you create a new contact (person or company), you will be able to load all the data from LinkedIn (photos, address, etc)."""), 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_crm': fields.boolean('CRM'),
'module_sale' : fields.boolean('SALE'), 'module_sale' : fields.boolean('SALE'),
'module_plugin_thunderbird': fields.boolean('Enable Thunderbird plug-in',
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.\n'
'-This installs the module plugin_thunderbird.'),
'module_plugin_outlook': fields.boolean('Enable Outlook plug-in',
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 email into an OpenERP mail message with attachments.\n'
'-This installs the module plugin_outlook.'),
'module_mass_mailing': fields.boolean( 'module_mass_mailing': fields.boolean(
'Manage mass mailing campaigns', 'Manage mass mailing campaigns',
help='Get access to statistics with your mass mailing, manage campaigns.'), help='Get access to statistics with your mass mailing, manage campaigns.'),

View File

@ -159,26 +159,13 @@
<div name="config_sale"> <div name="config_sale">
<field name="module_crm" invisible="1"/> <field name="module_crm" invisible="1"/>
<separator string="Emails Integration" attrs="{'invisible': [('module_crm','=',False)]}"/> <separator string="Emails Integration" attrs="{'invisible': [('module_crm','=',False)]}"/>
<p attrs="{'invisible': [('module_crm','=',False)]}"> <p name="config_email_integration" attrs="{'invisible': [('module_crm','=',False)]}">
OpenERP allows to automatically create leads (or others documents) OpenERP allows to automatically create leads (or others documents)
from incoming emails. You can automatically synchronize emails with OpenERP from incoming emails. You can automatically synchronize emails with OpenERP
using regular POP/IMAP accounts, using a direct email integration script for your using regular POP/IMAP accounts, using a direct email integration script for your
email server, or by manually pushing emails to OpenERP using specific email server, or by manually pushing emails to OpenERP using specific
plugins for your preferred email application. plugins for your preferred email application.
</p> </p>
<group name="On Mail Client" attrs="{'invisible': [('module_crm','=',False)]}">
<label for="id" string="On Mail Client"/>
<div>
<div name="module_plugin_thunderbird" attrs="{'invisible': [('module_crm','=',False)]}" class="oe_inline">
<field name="module_plugin_thunderbird"/>
<label for="module_plugin_thunderbird"/>
</div>
<div name="module_plugin_outlook" attrs="{'invisible': [('module_crm','=',False)]}">
<field name="module_plugin_outlook" class="oe_inline"/>
<label for="module_plugin_outlook"/>
</div>
</div>
</group>
</div> </div>
<div name="config_other"/> <div name="config_other"/>
</form> </form>

View File

@ -168,7 +168,7 @@ class board_create(osv.osv_memory):
_description = "Board Creation" _description = "Board Creation"
_columns = { _columns = {
'name': fields.char('Board Name', size=64, required=True), 'name': fields.char('Board Name', required=True),
'menu_parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True), 'menu_parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
} }

View File

@ -43,7 +43,6 @@ If you need to manage your meetings, you should install the CRM module.
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'security/calendar_security.xml', 'security/calendar_security.xml',
'calendar_view.xml', 'calendar_view.xml',
'contacts_view.xml',
'calendar_data.xml', 'calendar_data.xml',
'views/calendar.xml', 'views/calendar.xml',
], ],

View File

@ -762,7 +762,6 @@ class calendar_event(osv.Model):
res[meeting_id][field] = meeting.start_date if meeting.allday else meeting.start_datetime res[meeting_id][field] = meeting.start_date if meeting.allday else meeting.start_datetime
elif field == 'stop': elif field == 'stop':
res[meeting_id][field] = meeting.stop_date if meeting.allday else meeting.stop_datetime res[meeting_id][field] = meeting.stop_date if meeting.allday else meeting.stop_datetime
return res return res
def _get_rulestring(self, cr, uid, ids, name, arg, context=None): def _get_rulestring(self, cr, uid, ids, name, arg, context=None):

View File

@ -1,31 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="view_calendar_contacts" model="ir.ui.view">
<field name="name">My Coworkers</field>
<field name="model">calendar.contacts</field>
<field name="arch" type="xml">
<tree string="contacts" editable="bottom">
<field name="partner_id"/>
</tree>
</field>
</record>
<record id="action_calendar_contacts" model="ir.actions.act_window">
<field name="name">Calendar Contacts</field>
<field name="res_model">calendar.contacts</field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="domain">[('user_id','=',uid)]</field>
<field name="view_id" ref="view_calendar_contacts" />
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click on "<b>create</b>" to select colleagues you want to see meetings.
</p><p>
Your colleagues will appear in the right list to see them in the calendar view. You will easily manage collaboration and meeting with them.
</p>
</field>
</record>
</data>
</openerp>

View File

@ -72,3 +72,13 @@ span.no-wrap {
.cal_tab { .cal_tab {
margin: 20 0 20 0; margin: 20 0 20 0;
} }
.openerp .oe_remove_follower {
cursor: pointer;
position: absolute;
right: 0px;
line-height: 20px;
color: #D3D3D3;
}
.openerp .oe_add_input_box > div > input{
width: 200px;
}

View File

@ -1,9 +1,136 @@
openerp.calendar = function(instance) { openerp.calendar = function(instance) {
var _t = instance.web._t; var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb; var QWeb = instance.web.qweb;
instance.calendar = {}; instance.calendar = {};
function reload_favorite_list(result) {
var self = current = result;
if (result.view) {
self = result.view;
}
new instance.web.Model("res.users").query(["partner_id"]).filter([["id", "=",self.dataset.context.uid]]).first()
.done(
function(result) {
var sidebar_items = {};
var filter_value = result.partner_id[0];
var filter_item = {
value: filter_value,
label: result.partner_id[1] + _lt(" [Me]"),
color: self.get_color(filter_value),
avatar_model: self.avatar_model,
is_checked: true,
is_remove: false,
};
sidebar_items[0] = filter_item ;
filter_item = {
value: -1,
label: _lt("Everybody's calendars"),
color: self.get_color(-1),
avatar_model: self.avatar_model,
is_checked: false
};
sidebar_items[-1] = filter_item ;
//Get my coworkers/contacts
new instance.web.Model("calendar.contacts").query(["partner_id"]).filter([["user_id", "=",self.dataset.context.uid]]).all().then(function(result) {
_.each(result, function(item) {
filter_value = item.partner_id[0];
filter_item = {
value: filter_value,
label: item.partner_id[1],
color: self.get_color(filter_value),
avatar_model: self.avatar_model,
is_checked: true
};
sidebar_items[filter_value] = filter_item ;
});
self.all_filters = sidebar_items;
self.now_filter_ids = $.map(self.all_filters, function(o) { return o.value; });
self.sidebar.filter.events_loaded(self.all_filters);
self.sidebar.filter.set_filters();
self.sidebar.filter.set_distroy_filters();
self.sidebar.filter.addInputBox();
self.sidebar.filter.destroy_filter();
}).done(function () {
self.$calendar.fullCalendar('refetchEvents');
if (current.ir_model_m2o) {
current.ir_model_m2o.set_value(false);
}
});
});
}
instance.web_calendar.CalendarView.include({
extraSideBar: function(){
this._super();
if (this.useContacts){
new reload_favorite_list(this);
}
}
});
instance.web_calendar.SidebarFilter.include({
set_distroy_filters: function() {
var self = this;
// When mouse-enter the favorite list it will show the 'X' for removing partner from the favorite list.
if (self.view.useContacts){
self.$('.oe_calendar_all_responsibles').on('mouseenter mouseleave', function(e) {
self.$('.oe_remove_follower').toggleClass('hidden', e.type == 'mouseleave');
});
}
},
addInputBox: function() {
var self = this;
if (this.dfm)
return;
this.dfm = new instance.web.form.DefaultFieldManager(self);
this.dfm.extend_field_desc({
partner_id: {
relation: "res.partner",
},
});
this.ir_model_m2o = new instance.web.form.FieldMany2One(self.dfm, {
attrs: {
class: 'oe_add_input_box',
name: "partner_id",
type: "many2one",
options: '{"no_open": True}',
placeholder: _t("Select Favorite Calendar"),
},
});
this.ir_model_m2o.insertAfter($('div.oe_calendar_filter'));
this.ir_model_m2o.on('change:value', self, function() {
self.add_filter();
});
},
add_filter: function() {
var self = this;
new instance.web.Model("res.users").query(["partner_id"]).filter([["id", "=",this.view.dataset.context.uid]]).first().done(function(result){
$.map(self.ir_model_m2o.display_value, function(element,index) {
if (result.partner_id[0] != index){
self.ds_message = new instance.web.DataSetSearch(self, 'calendar.contacts');
self.ds_message.call("create", [{'partner_id': index}]);
}
});
});
new reload_favorite_list(this);
},
destroy_filter: function(e) {
var self= this;
this.$(".oe_remove_follower").on('click', function(e) {
self.ds_message = new instance.web.DataSetSearch(self, 'calendar.contacts');
if (! confirm(_t("Do you really want to delete this filter from favorite?"))) { return false; }
var id = $(e.currentTarget)[0].dataset.id;
self.ds_message.call('search', [[['partner_id', '=', parseInt(id)]]]).then(function(record){
return self.ds_message.unlink(record);
}).done(function() {
new reload_favorite_list(self);
});
});
},
});
instance.web.WebClient = instance.web.WebClient.extend({ instance.web.WebClient = instance.web.WebClient.extend({

View File

@ -73,4 +73,13 @@
</div> </div>
</div> </div>
</t> </t>
<t t-extend="CalendarView.sidebar.responsible">
<t t-jquery="span#color_filter" t-operation="after">
<t t-if="(filters_value.value != -1) &amp;&amp; (filters_value.is_remove != false)">
<span class="oe_remove_follower oe_e hidden" title="Remove this favorite from the list" t-att-data-id="filters_value.value">X</span>
</t>
</t>
</t>
</template> </template>

View File

@ -40,7 +40,7 @@ class crm_case_channel(osv.osv):
_description = "Channels" _description = "Channels"
_order = 'name' _order = 'name'
_columns = { _columns = {
'name': fields.char('Channel Name', size=64, required=True), 'name': fields.char('Channel Name', required=True),
'active': fields.boolean('Active'), 'active': fields.boolean('Active'),
} }
_defaults = { _defaults = {
@ -59,7 +59,7 @@ class crm_case_stage(osv.osv):
_order = "sequence" _order = "sequence"
_columns = { _columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True), 'name': fields.char('Stage Name', required=True, translate=True),
'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."), 'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."),
'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"), 'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"),
'on_change': fields.boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity."), 'on_change': fields.boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity."),
@ -74,7 +74,7 @@ class crm_case_stage(osv.osv):
'type': fields.selection([('lead', 'Lead'), 'type': fields.selection([('lead', 'Lead'),
('opportunity', 'Opportunity'), ('opportunity', 'Opportunity'),
('both', 'Both')], ('both', 'Both')],
string='Type', size=16, required=True, string='Type', required=True,
help="This field is used to distinguish stages related to Leads from stages related to Opportunities, or to specify stages available for both types."), help="This field is used to distinguish stages related to Leads from stages related to Opportunities, or to specify stages available for both types."),
} }
@ -87,13 +87,12 @@ class crm_case_stage(osv.osv):
'case_default': True, 'case_default': True,
} }
class crm_case_categ(osv.osv): class crm_case_categ(osv.osv):
""" Category of Case """ """ Category of Case """
_name = "crm.case.categ" _name = "crm.case.categ"
_description = "Category of Case" _description = "Category of Case"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, translate=True), 'name': fields.char('Name', required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'), 'object_id': fields.many2one('ir.model', 'Object Name'),
} }
@ -113,7 +112,7 @@ class crm_case_resource_type(osv.osv):
_description = "Campaign" _description = "Campaign"
_rec_name = "name" _rec_name = "name"
_columns = { _columns = {
'name': fields.char('Campaign Name', size=64, required=True, translate=True), 'name': fields.char('Campaign Name', required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'section_id': fields.many2one('crm.case.section', 'Sales Team'),
} }
@ -122,7 +121,7 @@ class crm_payment_mode(osv.osv):
_name = "crm.payment.mode" _name = "crm.payment.mode"
_description = "CRM Payment Mode" _description = "CRM Payment Mode"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'section_id': fields.many2one('crm.case.section', 'Sales Team'),
} }

View File

@ -201,7 +201,7 @@ class crm_lead(format_address, osv.osv):
select=True, help="Linked partner (optional). Usually created when converting the lead."), select=True, help="Linked partner (optional). Usually created when converting the lead."),
'id': fields.integer('ID', readonly=True), 'id': fields.integer('ID', readonly=True),
'name': fields.char('Subject', size=64, required=True, select=1), 'name': fields.char('Subject', required=True, select=1),
'active': fields.boolean('Active', required=False), 'active': fields.boolean('Active', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1), 'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1), 'date_action_next': fields.datetime('Next Action', readonly=1),
@ -228,7 +228,7 @@ class crm_lead(format_address, osv.osv):
'stage_id': fields.many2one('crm.case.stage', 'Stage', track_visibility='onchange', select=True, 'stage_id': fields.many2one('crm.case.stage', 'Stage', track_visibility='onchange', select=True,
domain="['&', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"), domain="['&', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"),
'user_id': fields.many2one('res.users', 'Salesperson', select=True, track_visibility='onchange'), 'user_id': fields.many2one('res.users', 'Salesperson', select=True, track_visibility='onchange'),
'referred': fields.char('Referred By', size=64), 'referred': fields.char('Referred By'),
'date_open': fields.datetime('Assigned', readonly=True), 'date_open': fields.datetime('Assigned', readonly=True),
'day_open': fields.function(_compute_day, string='Days to Open', \ 'day_open': fields.function(_compute_day, string='Days to Open', \
multi='day_open', type="float", store=True), multi='day_open', type="float", store=True),
@ -246,7 +246,7 @@ class crm_lead(format_address, osv.osv):
'phone': fields.char("Phone", size=64), 'phone': fields.char("Phone", size=64),
'date_deadline': fields.date('Expected Closing', help="Estimate of the date on which the opportunity will be won."), 'date_deadline': fields.date('Expected Closing', help="Estimate of the date on which the opportunity will be won."),
'date_action': fields.date('Next Action Date', select=True), 'date_action': fields.date('Next Action Date', select=True),
'title_action': fields.char('Next Action', size=64), 'title_action': fields.char('Next Action'),
'color': fields.integer('Color Index'), 'color': fields.integer('Color Index'),
'partner_address_name': fields.related('partner_id', 'name', type='char', string='Partner Contact Name', readonly=True), 'partner_address_name': fields.related('partner_id', 'name', type='char', string='Partner Contact Name', readonly=True),
'partner_address_email': fields.related('partner_id', 'email', type='char', string='Partner Contact Email', readonly=True), 'partner_address_email': fields.related('partner_id', 'email', type='char', string='Partner Contact Email', readonly=True),
@ -255,16 +255,16 @@ class crm_lead(format_address, osv.osv):
'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True), 'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True),
# Fields for address, due to separation from crm and res.partner # Fields for address, due to separation from crm and res.partner
'street': fields.char('Street', size=128), 'street': fields.char('Street'),
'street2': fields.char('Street2', size=128), 'street2': fields.char('Street2'),
'zip': fields.char('Zip', change_default=True, size=24), 'zip': fields.char('Zip', change_default=True, size=24),
'city': fields.char('City', size=128), 'city': fields.char('City'),
'state_id': fields.many2one("res.country.state", 'State'), 'state_id': fields.many2one("res.country.state", 'State'),
'country_id': fields.many2one('res.country', 'Country'), 'country_id': fields.many2one('res.country', 'Country'),
'phone': fields.char('Phone', size=64), 'phone': fields.char('Phone'),
'fax': fields.char('Fax', size=64), 'fax': fields.char('Fax'),
'mobile': fields.char('Mobile', size=64), 'mobile': fields.char('Mobile'),
'function': fields.char('Function', size=128), 'function': fields.char('Function'),
'title': fields.many2one('res.partner.title', 'Title'), 'title': fields.many2one('res.partner.title', 'Title'),
'company_id': fields.many2one('res.company', 'Company', select=1), 'company_id': fields.many2one('res.company', 'Company', select=1),
'payment_mode': fields.many2one('crm.payment.mode', 'Payment Mode', \ 'payment_mode': fields.many2one('crm.payment.mode', 'Payment Mode', \
@ -935,8 +935,10 @@ class crm_lead(format_address, osv.osv):
def message_get_reply_to(self, cr, uid, ids, context=None): def message_get_reply_to(self, cr, uid, ids, context=None):
""" Override to get the reply_to of the parent project. """ """ Override to get the reply_to of the parent project. """
return [lead.section_id.message_get_reply_to()[0] if lead.section_id else False leads = self.browse(cr, SUPERUSER_ID, ids, context=context)
for lead in self.browse(cr, SUPERUSER_ID, ids, context=context)] section_ids = set([lead.section_id.id for lead in leads if lead.section_id])
aliases = self.pool['crm.case.section'].message_get_reply_to(cr, uid, list(section_ids), context=context)
return dict((lead.id, aliases.get(lead.section_id and lead.section_id.id or 0, False)) for lead in leads)
def get_formview_id(self, cr, uid, id, context=None): def get_formview_id(self, cr, uid, id, context=None):
obj = self.browse(cr, uid, id, context=context) obj = self.browse(cr, uid, id, context=context)

View File

@ -54,14 +54,14 @@ class crm_phonecall(osv.osv):
'email_from': fields.char('Email', size=128, help="These people will receive email."), 'email_from': fields.char('Email', size=128, help="These people will receive email."),
'date_open': fields.datetime('Opened', readonly=True), 'date_open': fields.datetime('Opened', readonly=True),
# phonecall fields # phonecall fields
'name': fields.char('Call Summary', size=64, required=True), 'name': fields.char('Call Summary', required=True),
'active': fields.boolean('Active', required=False), 'active': fields.boolean('Active', required=False),
'duration': fields.float('Duration', help='Duration in minutes and seconds.'), 'duration': fields.float('Duration', help='Duration in minutes and seconds.'),
'categ_id': fields.many2one('crm.case.categ', 'Category', \ 'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="['|',('section_id','=',section_id),('section_id','=',False),\ domain="['|',('section_id','=',section_id),('section_id','=',False),\
('object_id.model', '=', 'crm.phonecall')]"), ('object_id.model', '=', 'crm.phonecall')]"),
'partner_phone': fields.char('Phone', size=32), 'partner_phone': fields.char('Phone'),
'partner_mobile': fields.char('Mobile', size=32), 'partner_mobile': fields.char('Mobile'),
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'), 'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'),
'date_closed': fields.datetime('Closed', readonly=True), 'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'), 'date': fields.datetime('Date'),

View File

@ -30,7 +30,7 @@ class crm_segmentation(osv.osv):
_description = "Partner Segmentation" _description = "Partner Segmentation"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, help='The name of the segmentation.'), 'name': fields.char('Name', required=True, help='The name of the segmentation.'),
'description': fields.text('Description'), 'description': fields.text('Description'),
'categ_id': fields.many2one('res.partner.category', 'Partner Category',\ 'categ_id': fields.many2one('res.partner.category', 'Partner Category',\
required=True, help='The partner category that will be \ required=True, help='The partner category that will be \
@ -115,10 +115,10 @@ class crm_segmentation_line(osv.osv):
_description = "Segmentation line" _description = "Segmentation line"
_columns = { _columns = {
'name': fields.char('Rule Name', size=64, required=True), 'name': fields.char('Rule Name', required=True),
'segmentation_id': fields.many2one('crm.segmentation', 'Segmentation'), 'segmentation_id': fields.many2one('crm.segmentation', 'Segmentation'),
'expr_name': fields.selection([('sale','Sale Amount'), 'expr_name': fields.selection([('sale','Sale Amount'),
('purchase','Purchase Amount')], 'Control Variable', size=64, required=True), ('purchase','Purchase Amount')], 'Control Variable', required=True),
'expr_operator': fields.selection([('<','<'),('=','='),('>','>')], 'Operator', required=True), 'expr_operator': fields.selection([('<','<'),('=','='),('>','>')], 'Operator', required=True),
'expr_value': fields.float('Value', required=True), 'expr_value': fields.float('Value', required=True),
'operator': fields.selection([('and','Mandatory Expression'),\ 'operator': fields.selection([('and','Mandatory Expression'),\

View File

@ -46,7 +46,7 @@ class crm_lead_report(osv.osv):
_rec_name = 'date_deadline' _rec_name = 'date_deadline'
_columns = { _columns = {
'date_deadline': fields.date('Exp. Closing', size=10, readonly=True, help="Expected Closing"), 'date_deadline': fields.date('Exp. Closing', readonly=True, help="Expected Closing"),
'create_date': fields.datetime('Creation Date', readonly=True), 'create_date': fields.datetime('Creation Date', readonly=True),
'opening_date': fields.date('Assignation Date', readonly=True), 'opening_date': fields.date('Assignation Date', readonly=True),
'date_closed': fields.date('Close Date', readonly=True), 'date_closed': fields.date('Close Date', readonly=True),

View File

@ -44,7 +44,7 @@ class crm_phonecall_report(osv.osv):
'section_id':fields.many2one('crm.case.section', 'Section', readonly=True), 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'), 'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'),
'nbr': fields.integer('# of Cases', readonly=True), 'nbr': fields.integer('# of Cases', readonly=True),
'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True), 'state': fields.selection(AVAILABLE_STATES, 'Status', readonly=True),
'create_date': fields.datetime('Create Date', readonly=True, select=True), 'create_date': fields.datetime('Create Date', readonly=True, select=True),
'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"), 'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'duration': fields.float('Duration', digits=(16,2),readonly=True, group_operator="avg"), 'duration': fields.float('Duration', digits=(16,2),readonly=True, group_operator="avg"),

View File

@ -33,7 +33,7 @@
</div> </div>
</group> </group>
</div> </div>
<xpath expr="//group[@name='On Mail Client']" position="before"> <xpath expr="//p[@name='config_email_integration']" position="after">
<group name="default_alias"> <group name="default_alias">
<label for="id" string="Leads Email Alias"/> <label for="id" string="Leads Email Alias"/>
<div attrs="{'invisible': [('alias_domain', '=', False)]}"> <div attrs="{'invisible': [('alias_domain', '=', False)]}">

View File

@ -29,10 +29,10 @@ class crm_phonecall2phonecall(osv.osv_memory):
_description = 'Phonecall To Phonecall' _description = 'Phonecall To Phonecall'
_columns = { _columns = {
'name' : fields.char('Call summary', size=64, required=True, select=1), 'name' : fields.char('Call summary', required=True, select=1),
'user_id' : fields.many2one('res.users',"Assign To"), 'user_id' : fields.many2one('res.users',"Assign To"),
'contact_name':fields.char('Contact', size=64), 'contact_name':fields.char('Contact'),
'phone':fields.char('Phone', size=64), 'phone':fields.char('Phone'),
'categ_id': fields.many2one('crm.case.categ', 'Category', \ 'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="['|',('section_id','=',False),('section_id','=',section_id),\ domain="['|',('section_id','=',False),('section_id','=',section_id),\
('object_id.model', '=', 'crm.phonecall')]"), ('object_id.model', '=', 'crm.phonecall')]"),

View File

@ -39,7 +39,7 @@ class crm_claim_stage(osv.osv):
_order = "sequence" _order = "sequence"
_columns = { _columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True), 'name': fields.char('Stage Name', required=True, translate=True),
'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."), 'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."),
'section_ids':fields.many2many('crm.case.section', 'section_claim_stage_rel', 'stage_id', 'section_id', string='Sections', 'section_ids':fields.many2many('crm.case.section', 'section_claim_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."), help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
@ -70,9 +70,9 @@ class crm_claim(osv.osv):
_columns = { _columns = {
'id': fields.integer('ID', readonly=True), 'id': fields.integer('ID', readonly=True),
'name': fields.char('Claim Subject', size=128, required=True), 'name': fields.char('Claim Subject', required=True),
'active': fields.boolean('Active'), 'active': fields.boolean('Active'),
'action_next': fields.char('Next Action', size=200), 'action_next': fields.char('Next Action'),
'date_action_next': fields.datetime('Next Action Date'), 'date_action_next': fields.datetime('Next Action Date'),
'description': fields.text('Description'), 'description': fields.text('Description'),
'resolution': fields.text('Resolution'), 'resolution': fields.text('Resolution'),
@ -87,8 +87,8 @@ class crm_claim(osv.osv):
('object_id.model', '=', 'crm.claim')]"), ('object_id.model', '=', 'crm.claim')]"),
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'), 'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'),
'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'), 'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'),
'user_id': fields.many2one('res.users', 'Responsible'), 'user_id': fields.many2one('res.users', 'Responsible', track_visibility='always'),
'user_fault': fields.char('Trouble Responsible', size=64), 'user_fault': fields.char('Trouble Responsible'),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \ 'section_id': fields.many2one('crm.case.section', 'Sales Team', \
select=True, help="Responsible sales team."\ select=True, help="Responsible sales team."\
" Define Responsible user and Email account for"\ " Define Responsible user and Email account for"\
@ -97,7 +97,7 @@ class crm_claim(osv.osv):
'partner_id': fields.many2one('res.partner', 'Partner'), 'partner_id': fields.many2one('res.partner', 'Partner'),
'email_cc': fields.text('Watchers Emails', size=252, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"), 'email_cc': fields.text('Watchers Emails', size=252, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
'email_from': fields.char('Email', size=128, help="Destination email for email gateway."), 'email_from': fields.char('Email', size=128, help="Destination email for email gateway."),
'partner_phone': fields.char('Phone', size=32), 'partner_phone': fields.char('Phone'),
'stage_id': fields.many2one ('crm.claim.stage', 'Stage', track_visibility='onchange', 'stage_id': fields.many2one ('crm.claim.stage', 'Stage', track_visibility='onchange',
domain="['|', ('section_ids', '=', section_id), ('case_default', '=', True)]"), domain="['|', ('section_ids', '=', section_id), ('case_default', '=', True)]"),
'cause': fields.text('Root Cause'), 'cause': fields.text('Root Cause'),
@ -161,6 +161,13 @@ class crm_claim(osv.osv):
# context: no_log, because subtype already handle this # context: no_log, because subtype already handle this
return super(crm_claim, self).create(cr, uid, vals, context=context) return super(crm_claim, self).create(cr, uid, vals, context=context)
def copy(self, cr, uid, id, default=None, context=None):
claim = self.browse(cr, uid, id, context=context)
default = dict(default or {},
stage_id = self._get_default_stage_id(cr, uid, context=context),
name = _('%s (copy)') % claim.name)
return super(crm_claim, self).copy(cr, uid, id, default, context=context)
# ------------------------------------------------------- # -------------------------------------------------------
# Mail gateway # Mail gateway
# ------------------------------------------------------- # -------------------------------------------------------

View File

@ -37,7 +37,7 @@ class crm_claim_report(osv.osv):
_description = "CRM Claim Report" _description = "CRM Claim Report"
_columns = { _columns = {
'name': fields.char('Year', size=64, required=False, readonly=True), 'name': fields.char('Year', required=False, readonly=True),
'user_id':fields.many2one('res.users', 'User', readonly=True), 'user_id':fields.many2one('res.users', 'User', readonly=True),
'section_id':fields.many2one('crm.case.section', 'Section', readonly=True), 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
'nbr': fields.integer('# of Cases', readonly=True), 'nbr': fields.integer('# of Cases', readonly=True),

View File

@ -37,7 +37,7 @@ class crm_helpdesk(osv.osv):
_columns = { _columns = {
'id': fields.integer('ID', readonly=True), 'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True), 'name': fields.char('Name', required=True),
'active': fields.boolean('Active', required=False), 'active': fields.boolean('Active', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1), 'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1), 'date_action_next': fields.datetime('Next Action', readonly=1),
@ -70,7 +70,7 @@ class crm_helpdesk(osv.osv):
('open', 'In Progress'), ('open', 'In Progress'),
('pending', 'Pending'), ('pending', 'Pending'),
('done', 'Closed'), ('done', 'Closed'),
('cancel', 'Cancelled')], 'Status', size=16, readonly=True, track_visibility='onchange', ('cancel', 'Cancelled')], 'Status', readonly=True, track_visibility='onchange',
help='The status is set to \'Draft\', when a case is created.\ help='The status is set to \'Draft\', when a case is created.\
\nIf the case is in progress the status is set to \'Open\'.\ \nIf the case is in progress the status is set to \'Open\'.\
\nWhen the case is over, the status is set to \'Done\'.\ \nWhen the case is over, the status is set to \'Done\'.\

View File

@ -39,11 +39,11 @@ class crm_helpdesk_report(osv.osv):
_auto = False _auto = False
_columns = { _columns = {
'name': fields.char('Year', size=64, required=False, readonly=True), 'name': fields.char('Year', required=False, readonly=True),
'user_id':fields.many2one('res.users', 'User', readonly=True), 'user_id':fields.many2one('res.users', 'User', readonly=True),
'section_id':fields.many2one('crm.case.section', 'Section', readonly=True), 'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
'nbr': fields.integer('# of Cases', readonly=True), 'nbr': fields.integer('# of Cases', readonly=True),
'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True), 'state': fields.selection(AVAILABLE_STATES, 'Status', readonly=True),
'month':fields.selection([('01', 'January'), ('02', 'February'), \ 'month':fields.selection([('01', 'January'), ('02', 'February'), \
('03', 'March'), ('04', 'April'),\ ('03', 'March'), ('04', 'April'),\
('05', 'May'), ('06', 'June'), \ ('05', 'May'), ('06', 'June'), \

View File

@ -32,7 +32,7 @@ class res_partner_grade(osv.osv):
_columns = { _columns = {
'sequence': fields.integer('Sequence'), 'sequence': fields.integer('Sequence'),
'active': fields.boolean('Active'), 'active': fields.boolean('Active'),
'name': fields.char('Grade Name', size=32), 'name': fields.char('Grade Name'),
'partner_weight': fields.integer('Grade Weight', 'partner_weight': fields.integer('Grade Weight',
help="Gives the probability to assign a lead to this partner. (0 means no assignation.)"), help="Gives the probability to assign a lead to this partner. (0 means no assignation.)"),
} }
@ -47,7 +47,7 @@ class res_partner_activation(osv.osv):
_columns = { _columns = {
'sequence' : fields.integer('Sequence'), 'sequence' : fields.integer('Sequence'),
'name' : fields.char('Name', size=32, required=True), 'name' : fields.char('Name', required=True),
} }

View File

@ -48,7 +48,7 @@
<p>Thanks,</p> <p>Thanks,</p>
<pre> <pre>
${ctx['partner_id'].user_id and ctx['partner_id'].user_id.signature or ''} ${ctx['partner_id'].user_id and ctx['partner_id'].user_id.signature | safe or ''}
</pre> </pre>
% if not ctx['partner_id'].user_id: % if not ctx['partner_id'].user_id:
PS: It looks like you do not have an account manager assigned to you, please contact us. PS: It looks like you do not have an account manager assigned to you, please contact us.

View File

@ -55,7 +55,7 @@ class crm_lead_report_assign(osv.osv):
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'), 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
'type':fields.selection([ 'type':fields.selection([
('lead','Lead'), ('lead','Lead'),
('opportunity','Opportunity'), ('opportunity','Opportunity')
],'Type', help="Type is used to separate Leads and Opportunities"), ],'Type', help="Type is used to separate Leads and Opportunities"),
} }
def init(self, cr): def init(self, cr):

View File

@ -146,7 +146,7 @@ class question(osv.osv):
_description= "Question" _description= "Question"
_columns={ _columns={
'name': fields.char("Question",size=128, required=True), 'name': fields.char("Question", required=True),
'answers_ids': fields.one2many("crm_profiling.answer","question_id","Avalaible Answers",), 'answers_ids': fields.one2many("crm_profiling.answer","question_id","Avalaible Answers",),
} }
@ -159,7 +159,7 @@ class questionnaire(osv.osv):
_description= "Questionnaire" _description= "Questionnaire"
_columns = { _columns = {
'name': fields.char("Questionnaire",size=128, required=True), 'name': fields.char("Questionnaire", required=True),
'description':fields.text("Description", required=True), 'description':fields.text("Description", required=True),
'questions_ids': fields.many2many('crm_profiling.question','profile_questionnaire_quest_rel',\ 'questions_ids': fields.many2many('crm_profiling.question','profile_questionnaire_quest_rel',\
'questionnaire', 'question', "Questions"), 'questionnaire', 'question', "Questions"),
@ -171,7 +171,7 @@ class answer(osv.osv):
_name="crm_profiling.answer" _name="crm_profiling.answer"
_description="Answer" _description="Answer"
_columns={ _columns={
"name": fields.char("Answer",size=128, required=True), "name": fields.char("Answer", required=True),
"question_id": fields.many2one('crm_profiling.question',"Question"), "question_id": fields.many2one('crm_profiling.question',"Question"),
} }

View File

@ -28,7 +28,7 @@ from openerp.modules.registry import RegistryManager
class decimal_precision(orm.Model): class decimal_precision(orm.Model):
_name = 'decimal.precision' _name = 'decimal.precision'
_columns = { _columns = {
'name': fields.char('Usage', size=50, select=True, required=True), 'name': fields.char('Usage', select=True, required=True),
'digits': fields.integer('Digits', required=True), 'digits': fields.integer('Digits', required=True),
} }
_defaults = { _defaults = {

View File

@ -62,7 +62,7 @@ class delivery_carrier(osv.osv):
return res return res
_columns = { _columns = {
'name': fields.char('Delivery Method', size=64, required=True), 'name': fields.char('Delivery Method', required=True),
'partner_id': fields.many2one('res.partner', 'Transport Company', required=True, help="The partner that is doing the delivery service."), 'partner_id': fields.many2one('res.partner', 'Transport Company', required=True, help="The partner that is doing the delivery service."),
'product_id': fields.many2one('product.product', 'Delivery Product', required=True), 'product_id': fields.many2one('product.product', 'Delivery Product', required=True),
'grids_id': fields.one2many('delivery.grid', 'carrier_id', 'Delivery Grids'), 'grids_id': fields.one2many('delivery.grid', 'carrier_id', 'Delivery Grids'),
@ -171,8 +171,8 @@ class delivery_grid(osv.osv):
_name = "delivery.grid" _name = "delivery.grid"
_description = "Delivery Grid" _description = "Delivery Grid"
_columns = { _columns = {
'name': fields.char('Grid Name', size=64, required=True), 'name': fields.char('Grid Name', required=True),
'sequence': fields.integer('Sequence', size=64, required=True, help="Gives the sequence order when displaying a list of delivery grid."), 'sequence': fields.integer('Sequence', required=True, help="Gives the sequence order when displaying a list of delivery grid."),
'carrier_id': fields.many2one('delivery.carrier', 'Carrier', required=True, ondelete='cascade'), 'carrier_id': fields.many2one('delivery.carrier', 'Carrier', required=True, ondelete='cascade'),
'country_ids': fields.many2many('res.country', 'delivery_grid_country_rel', 'grid_id', 'country_id', 'Countries'), 'country_ids': fields.many2many('res.country', 'delivery_grid_country_rel', 'grid_id', 'country_id', 'Countries'),
'state_ids': fields.many2many('res.country.state', 'delivery_grid_state_rel', 'grid_id', 'state_id', 'States'), 'state_ids': fields.many2many('res.country.state', 'delivery_grid_state_rel', 'grid_id', 'state_id', 'States'),
@ -229,8 +229,8 @@ class delivery_grid_line(osv.osv):
_name = "delivery.grid.line" _name = "delivery.grid.line"
_description = "Delivery Grid Line" _description = "Delivery Grid Line"
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True), 'name': fields.char('Name', required=True),
'sequence': fields.integer('Sequence', size=64, required=True, help="Gives the sequence order when calculating delivery grid."), 'sequence': fields.integer('Sequence', required=True, help="Gives the sequence order when calculating delivery grid."),
'grid_id': fields.many2one('delivery.grid', 'Grid',required=True, ondelete='cascade'), 'grid_id': fields.many2one('delivery.grid', 'Grid',required=True, ondelete='cascade'),
'type': fields.selection([('weight','Weight'),('volume','Volume'),\ 'type': fields.selection([('weight','Weight'),('volume','Volume'),\
('wv','Weight * Volume'), ('price','Price'), ('quantity','Quantity')],\ ('wv','Weight * Volume'), ('price','Price'), ('quantity','Quantity')],\

View File

@ -64,7 +64,7 @@ class stock_picking(osv.osv):
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20), 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20), 'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
}), }),
'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32), 'carrier_tracking_ref': fields.char('Carrier Tracking Ref'),
'number_of_packages': fields.integer('Number of Packages'), 'number_of_packages': fields.integer('Number of Packages'),
'weight_uom_id': fields.many2one('product.uom', 'Unit of Measure', required=True,readonly="1",help="Unit of measurement for Weight",), 'weight_uom_id': fields.many2one('product.uom', 'Unit of Measure', required=True,readonly="1",help="Unit of measurement for Weight",),
} }

View File

@ -158,7 +158,7 @@ class document_directory(osv.osv):
_description = 'Directory' _description = 'Directory'
_order = 'name' _order = 'name'
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, select=1), 'name': fields.char('Name', required=True, select=1),
'write_date': fields.datetime('Date Modified', readonly=True), 'write_date': fields.datetime('Date Modified', readonly=True),
'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True), 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
'create_date': fields.datetime('Date Created', readonly=True), 'create_date': fields.datetime('Date Created', readonly=True),
@ -172,7 +172,7 @@ class document_directory(osv.osv):
'type': fields.selection([ ('directory','Static Directory'), ('ressource','Folders per resource'), ], 'type': fields.selection([ ('directory','Static Directory'), ('ressource','Folders per resource'), ],
'Type', required=True, select=1, change_default=True, 'Type', required=True, select=1, change_default=True,
help="Each directory can either have the type Static or be linked to another resource. A static directory, as with Operating Systems, is the classic directory that can contain a set of files. The directories linked to systems resources automatically possess sub-directories for each of resource types defined in the parent directory."), help="Each directory can either have the type Static or be linked to another resource. A static directory, as with Operating Systems, is the classic directory that can contain a set of files. The directories linked to systems resources automatically possess sub-directories for each of resource types defined in the parent directory."),
'domain': fields.char('Domain', size=128, help="Use a domain if you want to apply an automatic filter on visible resources."), 'domain': fields.char('Domain', help="Use a domain if you want to apply an automatic filter on visible resources."),
'ressource_type_id': fields.many2one('ir.model', 'Resource model', change_default=True, 'ressource_type_id': fields.many2one('ir.model', 'Resource model', change_default=True,
help="Select an object here and there will be one folder per record of that resource."), help="Select an object here and there will be one folder per record of that resource."),
'resource_field': fields.many2one('ir.model.fields', 'Name field', help='Field to be used as name on resource directories. If empty, the "name" will be used.'), 'resource_field': fields.many2one('ir.model.fields', 'Name field', help='Field to be used as name on resource directories. If empty, the "name" will be used.'),
@ -370,8 +370,8 @@ class document_directory_dctx(osv.osv):
_description = 'Directory Dynamic Context' _description = 'Directory Dynamic Context'
_columns = { _columns = {
'dir_id': fields.many2one('document.directory', 'Directory', required=True, ondelete="cascade"), 'dir_id': fields.many2one('document.directory', 'Directory', required=True, ondelete="cascade"),
'field': fields.char('Field', size=20, required=True, select=1, help="The name of the field."), 'field': fields.char('Field', required=True, select=1, help="The name of the field."),
'expr': fields.char('Expression', size=64, required=True, help="A python expression used to evaluate the field.\n" + \ 'expr': fields.char('Expression', required=True, help="A python expression used to evaluate the field.\n" + \
"You can use 'dir_id' for current dir, 'res_id', 'res_model' as a reference to the current record, in dynamic folders"), "You can use 'dir_id' for current dir, 'res_id', 'res_model' as a reference to the current record, in dynamic folders"),
} }
@ -379,10 +379,10 @@ class document_directory_content_type(osv.osv):
_name = 'document.directory.content.type' _name = 'document.directory.content.type'
_description = 'Directory Content Type' _description = 'Directory Content Type'
_columns = { _columns = {
'name': fields.char('Content Type', size=64, required=True), 'name': fields.char('Content Type', required=True),
'code': fields.char('Extension', size=4), 'code': fields.char('Extension', size=4),
'active': fields.boolean('Active'), 'active': fields.boolean('Active'),
'mimetype': fields.char('Mime Type',size=32) 'mimetype': fields.char('Mime Type')
} }
_defaults = { _defaults = {
'active': lambda *args: 1 'active': lambda *args: 1
@ -399,7 +399,7 @@ class document_directory_content(osv.osv):
return res return res
_columns = { _columns = {
'name': fields.char('Content Name', size=64, required=True), 'name': fields.char('Content Name', required=True),
'sequence': fields.integer('Sequence', size=16), 'sequence': fields.integer('Sequence', size=16),
'prefix': fields.char('Prefix', size=16), 'prefix': fields.char('Prefix', size=16),
'suffix': fields.char('Suffix', size=16), 'suffix': fields.char('Suffix', size=16),

View File

@ -253,14 +253,6 @@
</p> </p>
</field> </field>
</record> </record>
<menuitem name="Documents" id="menu_document_doc" parent="knowledge.menu_document" sequence="0"/>
<menuitem
name="Documents"
action="action_document_file_form"
id="menu_document_files"
parent="menu_document_doc"
sequence="0"
/>
<record model="ir.actions.act_window" id="action_document_file_directory_form"> <record model="ir.actions.act_window" id="action_document_file_directory_form">
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>

View File

@ -71,7 +71,7 @@ class report_document_file(osv.osv):
_columns = { _columns = {
'file_size': fields.integer('File Size', readonly=True), 'file_size': fields.integer('File Size', readonly=True),
'nbr':fields.integer('# of Files', readonly=True), 'nbr':fields.integer('# of Files', readonly=True),
'month': fields.char('Month', size=24,readonly=True), 'month': fields.char('Month', size=24, readonly=True),
} }
_order = "month" _order = "month"
def init(self, cr): def init(self, cr):

View File

@ -216,7 +216,7 @@ class email_template(osv.osv):
'name': fields.char('Name'), 'name': fields.char('Name'),
'model_id': fields.many2one('ir.model', 'Applies to', help="The kind of document with with this template can be used"), 'model_id': fields.many2one('ir.model', 'Applies to', help="The kind of document with with this template can be used"),
'model': fields.related('model_id', 'model', type='char', string='Related Document Model', 'model': fields.related('model_id', 'model', type='char', string='Related Document Model',
size=128, select=True, store=True, readonly=True), select=True, store=True, readonly=True),
'lang': fields.char('Language', 'lang': fields.char('Language',
help="Optional translation language (ISO code) to select when sending out an email. " help="Optional translation language (ISO code) to select when sending out an email. "
"If not set, the english version will be used. " "If not set, the english version will be used. "

View File

@ -237,8 +237,8 @@ class test_message_compose(TestMail):
email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, force_send=True, context=context) email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, force_send=True, context=context)
sent_emails = self._build_email_kwargs_list sent_emails = self._build_email_kwargs_list
email_to_lst = [ email_to_lst = [
['b@b.b', 'c@c.c'], ['Administrator <admin@yourcompany.example.com>'], ['b@b.b', 'c@c.c'], ['"Administrator" <admin@yourcompany.example.com>'],
['Raoul Grosbedon <raoul@raoul.fr>'], ['Bert Tartignole <bert@bert.fr>']] ['"Raoul Grosbedon" <raoul@raoul.fr>'], ['"Bert Tartignole" <bert@bert.fr>']]
self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails') self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails')
for email in sent_emails: for email in sent_emails:
self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients') self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients')

View File

@ -30,8 +30,8 @@ class event_type(osv.osv):
_name = 'event.type' _name = 'event.type'
_description = __doc__ _description = __doc__
_columns = { _columns = {
'name': fields.char('Event Type', size=64, required=True), 'name': fields.char('Event Type', required=True),
'default_reply_to': fields.char('Default Reply-To', size=64,help="The email address of the organizer which is put in the 'Reply-To' of all emails sent automatically at event or registrations confirmation. You can also put your email address of your mail gateway if you use one." ), 'default_reply_to': fields.char('Default Reply-To', size=64, help="The email address of the organizer which is put in the 'Reply-To' of all emails sent automatically at event or registrations confirmation. You can also put your email address of your mail gateway if you use one." ),
'default_email_event': fields.many2one('email.template','Event Confirmation Email', help="It will select this default confirmation event mail value when you choose this event"), 'default_email_event': fields.many2one('email.template','Event Confirmation Email', help="It will select this default confirmation event mail value when you choose this event"),
'default_email_registration': fields.many2one('email.template','Registration Confirmation Email', help="It will select this default confirmation registration mail value when you choose this event"), 'default_email_registration': fields.many2one('email.template','Registration Confirmation Email', help="It will select this default confirmation registration mail value when you choose this event"),
'default_registration_min': fields.integer('Default Minimum Registration', help="It will select this default minimum value when you choose this event"), 'default_registration_min': fields.integer('Default Minimum Registration', help="It will select this default minimum value when you choose this event"),
@ -174,7 +174,7 @@ class event_event(osv.osv):
return [(x, x) for x in pytz.all_timezones] return [(x, x) for x in pytz.all_timezones]
_columns = { _columns = {
'name': fields.char('Event Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}), 'name': fields.char('Event Name', required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}),
'user_id': fields.many2one('res.users', 'Responsible User', readonly=False, states={'done': [('readonly', True)]}), 'user_id': fields.many2one('res.users', 'Responsible User', readonly=False, states={'done': [('readonly', True)]}),
'type': fields.many2one('event.type', 'Type of Event', readonly=False, states={'done': [('readonly', True)]}), 'type': fields.many2one('event.type', 'Type of Event', readonly=False, states={'done': [('readonly', True)]}),
'seats_max': fields.integer('Maximum Avalaible Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )", readonly=True, states={'draft': [('readonly', False)]}), 'seats_max': fields.integer('Maximum Avalaible Seats', oldname='register_max', help="You can for each event define a maximum registration level. If you have too much registrations you are not able to confirm your event. (put 0 to ignore this rule )", readonly=True, states={'draft': [('readonly', False)]}),
@ -299,14 +299,14 @@ class event_registration(osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin'] _inherit = ['mail.thread', 'ir.needaction_mixin']
_columns = { _columns = {
'id': fields.integer('ID'), 'id': fields.integer('ID'),
'origin': fields.char('Source Document', size=124,readonly=True,help="Reference of the sales order which created the registration"), 'origin': fields.char('Source Document', readonly=True,help="Reference of the sales order which created the registration"),
'nb_register': fields.integer('Number of Participants', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'nb_register': fields.integer('Number of Participants', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'event_id': fields.many2one('event.event', 'Event', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'event_id': fields.many2one('event.event', 'Event', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}), 'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
'create_date': fields.datetime('Creation Date' , readonly=True), 'create_date': fields.datetime('Creation Date' , readonly=True),
'date_closed': fields.datetime('Attended Date', readonly=True), 'date_closed': fields.datetime('Attended Date', readonly=True),
'date_open': fields.datetime('Registration Date', readonly=True), 'date_open': fields.datetime('Registration Date', readonly=True),
'reply_to': fields.related('event_id','reply_to',string='Reply-to Email', type='char', size=128, readonly=True,), 'reply_to': fields.related('event_id','reply_to',string='Reply-to Email', type='char', readonly=True,),
'log_ids': fields.one2many('mail.message', 'res_id', 'Logs', domain=[('model','=',_name)]), 'log_ids': fields.one2many('mail.message', 'res_id', 'Logs', domain=[('model','=',_name)]),
'event_end_date': fields.related('event_id','date_end', type='datetime', string="Event End Date", readonly=True), 'event_end_date': fields.related('event_id','date_end', type='datetime', string="Event End Date", readonly=True),
'event_begin_date': fields.related('event_id', 'date_begin', type='datetime', string="Event Start Date", readonly=True), 'event_begin_date': fields.related('event_id', 'date_begin', type='datetime', string="Event Start Date", readonly=True),
@ -316,10 +316,10 @@ class event_registration(osv.osv):
('cancel', 'Cancelled'), ('cancel', 'Cancelled'),
('open', 'Confirmed'), ('open', 'Confirmed'),
('done', 'Attended')], 'Status', ('done', 'Attended')], 'Status',
size=16, readonly=True), readonly=True),
'email': fields.char('Email', size=64), 'email': fields.char('Email', size=64),
'phone': fields.char('Phone', size=64), 'phone': fields.char('Phone', size=64),
'name': fields.char('Name', size=128, select=True), 'name': fields.char('Name', select=True),
} }
_defaults = { _defaults = {
'nb_register': 1, 'nb_register': 1,

View File

@ -208,7 +208,7 @@ class event_ticket(osv.osv):
_columns = { _columns = {
'name': fields.char('Name', size=64, required=True, translate=True), 'name': fields.char('Name', required=True, translate=True),
'event_id': fields.many2one('event.event', "Event", required=True, ondelete='cascade'), 'event_id': fields.many2one('event.event', "Event", required=True, ondelete='cascade'),
'product_id': fields.many2one('product.product', 'Product', required=True, domain=[("event_type_id", "!=", False)]), 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[("event_type_id", "!=", False)]),
'registration_ids': fields.one2many('event.registration', 'event_ticket_id', 'Registrations'), 'registration_ids': fields.one2many('event.registration', 'event_ticket_id', 'Registrations'),

View File

@ -47,13 +47,13 @@ class fetchmail_server(osv.osv):
_order = 'priority' _order = 'priority'
_columns = { _columns = {
'name':fields.char('Name', size=256, required=True, readonly=False), 'name':fields.char('Name', required=True, readonly=False),
'active':fields.boolean('Active', required=False), 'active':fields.boolean('Active', required=False),
'state':fields.selection([ 'state':fields.selection([
('draft', 'Not Confirmed'), ('draft', 'Not Confirmed'),
('done', 'Confirmed'), ('done', 'Confirmed'),
], 'Status', select=True, readonly=True), ], 'Status', select=True, readonly=True),
'server' : fields.char('Server Name', size=256, readonly=True, help="Hostname or IP of the mail server", states={'draft':[('readonly', False)]}), 'server' : fields.char('Server Name', readonly=True, help="Hostname or IP of the mail server", states={'draft':[('readonly', False)]}),
'port' : fields.integer('Port', readonly=True, states={'draft':[('readonly', False)]}), 'port' : fields.integer('Port', readonly=True, states={'draft':[('readonly', False)]}),
'type':fields.selection([ 'type':fields.selection([
('pop', 'POP Server'), ('pop', 'POP Server'),
@ -66,8 +66,8 @@ class fetchmail_server(osv.osv):
'original':fields.boolean('Keep Original', help="Whether a full original copy of each email should be kept for reference" 'original':fields.boolean('Keep Original', help="Whether a full original copy of each email should be kept for reference"
"and attached to each processed message. This will usually double the size of your message database."), "and attached to each processed message. This will usually double the size of your message database."),
'date': fields.datetime('Last Fetch Date', readonly=True), 'date': fields.datetime('Last Fetch Date', readonly=True),
'user' : fields.char('Username', size=256, readonly=True, states={'draft':[('readonly', False)]}), 'user' : fields.char('Username', readonly=True, states={'draft':[('readonly', False)]}),
'password' : fields.char('Password', size=1024, readonly=True, states={'draft':[('readonly', False)]}), 'password' : fields.char('Password', readonly=True, states={'draft':[('readonly', False)]}),
'action_id':fields.many2one('ir.actions.server', 'Server Action', help="Optional custom server action to trigger for each incoming mail, " 'action_id':fields.many2one('ir.actions.server', 'Server Action', help="Optional custom server action to trigger for each incoming mail, "
"on the record that was created or updated by this mail"), "on the record that was created or updated by this mail"),
'object_id': fields.many2one('ir.model', "Create a New Record", help="Process each incoming mail as part of a conversation " 'object_id': fields.many2one('ir.model', "Create a New Record", help="Process each incoming mail as part of a conversation "
@ -78,7 +78,7 @@ class fetchmail_server(osv.osv):
"lower values mean higher priority"), "lower values mean higher priority"),
'message_ids': fields.one2many('mail.mail', 'fetchmail_server_id', 'Messages', readonly=True), 'message_ids': fields.one2many('mail.mail', 'fetchmail_server_id', 'Messages', readonly=True),
'configuration' : fields.text('Configuration', readonly=True), 'configuration' : fields.text('Configuration', readonly=True),
'script' : fields.char('Script', readonly=True, size=64), 'script' : fields.char('Script', readonly=True),
} }
_defaults = { _defaults = {
'state': "draft", 'state': "draft",

View File

@ -145,7 +145,7 @@ class fleet_vehicle_model(osv.Model):
_columns = { _columns = {
'name': fields.function(_model_name_get_fnc, type="char", string='Name', store=True), 'name': fields.function(_model_name_get_fnc, type="char", string='Name', store=True),
'modelname': fields.char('Model name', size=32, required=True), 'modelname': fields.char('Model name', required=True),
'brand_id': fields.many2one('fleet.vehicle.model.brand', 'Model Brand', required=True, help='Brand of the vehicle'), 'brand_id': fields.many2one('fleet.vehicle.model.brand', 'Model Brand', required=True, help='Brand of the vehicle'),
'vendors': fields.many2many('res.partner', 'fleet_vehicle_model_vendors', 'model_id', 'partner_id', string='Vendors'), 'vendors': fields.many2many('res.partner', 'fleet_vehicle_model_vendors', 'model_id', 'partner_id', string='Vendors'),
'image': fields.related('brand_id', 'image', type="binary", string="Logo"), 'image': fields.related('brand_id', 'image', type="binary", string="Logo"),
@ -170,7 +170,7 @@ class fleet_vehicle_model_brand(osv.Model):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
_columns = { _columns = {
'name': fields.char('Brand Name', size=64, required=True), 'name': fields.char('Brand Name', required=True),
'image': fields.binary("Logo", 'image': fields.binary("Logo",
help="This field holds the image used as logo for the brand, limited to 1024x1024px."), help="This field holds the image used as logo for the brand, limited to 1024x1024px."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image, 'image_medium': fields.function(_get_image, fnct_inv=_set_image,
@ -337,8 +337,8 @@ class fleet_vehicle(osv.Model):
_columns = { _columns = {
'name': fields.function(_vehicle_name_get_fnc, type="char", string='Name', store=True), 'name': fields.function(_vehicle_name_get_fnc, type="char", string='Name', store=True),
'company_id': fields.many2one('res.company', 'Company'), 'company_id': fields.many2one('res.company', 'Company'),
'license_plate': fields.char('License Plate', size=32, required=True, help='License plate number of the vehicle (ie: plate number for a car)'), 'license_plate': fields.char('License Plate', required=True, help='License plate number of the vehicle (ie: plate number for a car)'),
'vin_sn': fields.char('Chassis Number', size=32, help='Unique number written on the vehicle motor (VIN/SN number)'), 'vin_sn': fields.char('Chassis Number', help='Unique number written on the vehicle motor (VIN/SN number)'),
'driver_id': fields.many2one('res.partner', 'Driver', help='Driver of the vehicle'), 'driver_id': fields.many2one('res.partner', 'Driver', help='Driver of the vehicle'),
'model_id': fields.many2one('fleet.vehicle.model', 'Model', required=True, help='Model of the vehicle'), 'model_id': fields.many2one('fleet.vehicle.model', 'Model', required=True, help='Model of the vehicle'),
'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'), 'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'),
@ -350,9 +350,9 @@ class fleet_vehicle(osv.Model):
'fuel_logs_count': fields.function(_count_all, type='integer', string='Fuel Logs', multi=True), 'fuel_logs_count': fields.function(_count_all, type='integer', string='Fuel Logs', multi=True),
'odometer_count': fields.function(_count_all, type='integer', string='Odometer', multi=True), 'odometer_count': fields.function(_count_all, type='integer', string='Odometer', multi=True),
'acquisition_date': fields.date('Acquisition Date', required=False, help='Date when the vehicle has been bought'), 'acquisition_date': fields.date('Acquisition Date', required=False, help='Date when the vehicle has been bought'),
'color': fields.char('Color', size=32, help='Color of the vehicle'), 'color': fields.char('Color', help='Color of the vehicle'),
'state_id': fields.many2one('fleet.vehicle.state', 'State', help='Current state of the vehicle', ondelete="set null"), 'state_id': fields.many2one('fleet.vehicle.state', 'State', help='Current state of the vehicle', ondelete="set null"),
'location': fields.char('Location', size=128, help='Location of the vehicle (garage, ...)'), 'location': fields.char('Location', help='Location of the vehicle (garage, ...)'),
'seats': fields.integer('Seats Number', help='Number of seats of the vehicle'), 'seats': fields.integer('Seats Number', help='Number of seats of the vehicle'),
'doors': fields.integer('Doors Number', help='Number of doors of the vehicle'), 'doors': fields.integer('Doors Number', help='Number of doors of the vehicle'),
'tag_ids' :fields.many2many('fleet.vehicle.tag', 'fleet_vehicle_vehicle_tag_rel', 'vehicle_tag_id','tag_id', 'Tags'), 'tag_ids' :fields.many2many('fleet.vehicle.tag', 'fleet_vehicle_vehicle_tag_rel', 'vehicle_tag_id','tag_id', 'Tags'),
@ -607,7 +607,7 @@ class fleet_vehicle_log_services(osv.Model):
_description = 'Services for vehicles' _description = 'Services for vehicles'
_columns = { _columns = {
'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"), 'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"),
'inv_ref': fields.char('Invoice Reference', size=64), 'inv_ref': fields.char('Invoice Reference'),
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"), 'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database 'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
'notes': fields.text('Notes'), 'notes': fields.text('Notes'),
@ -847,5 +847,5 @@ class fleet_contract_state(osv.Model):
_description = 'Contains the different possible status of a leasing contract' _description = 'Contains the different possible status of a leasing contract'
_columns = { _columns = {
'name':fields.char('Contract Status', size=64, required=True), 'name':fields.char('Contract Status', required=True),
} }

View File

@ -280,4 +280,4 @@ class gamification_badge(osv.Model):
'badge_id': res_id, 'badge_id': res_id,
} }
badge_user_obj.create(cr, SUPERUSER_ID, values, context=context) badge_user_obj.create(cr, SUPERUSER_ID, values, context=context)
return True return True

View File

@ -174,10 +174,10 @@ class google_service(osv.osv_memory):
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://www.openerp.com?NoBaseUrl', context=context) return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://www.openerp.com?NoBaseUrl', context=context)
def get_client_id(self, cr, uid, service, context=None): def get_client_id(self, cr, uid, service, context=None):
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_id' % (service,), default=False, context=context) return self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'google_%s_client_id' % (service,), default=False, context=context)
def get_client_secret(self, cr, uid, service, context=None): def get_client_secret(self, cr, uid, service, context=None):
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'google_%s_client_secret' % (service,), default=False, context=context) return self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'google_%s_client_secret' % (service,), default=False, context=context)
def get_uri_oauth(self, a=''): # a = optional action def get_uri_oauth(self, a=''): # a = optional action
return "https://accounts.google.com/o/oauth2/%s" % (a,) return "https://accounts.google.com/o/oauth2/%s" % (a,)

View File

@ -13,8 +13,8 @@ class calendar_config_settings(osv.TransientModel):
def set_calset(self,cr,uid,ids,context=None) : def set_calset(self,cr,uid,ids,context=None) :
params = self.pool['ir.config_parameter'] params = self.pool['ir.config_parameter']
myself = self.browse(cr,uid,ids[0],context=context) myself = self.browse(cr,uid,ids[0],context=context)
params.set_param(cr, uid, 'google_calendar_client_id', myself.cal_client_id or '', context=None) params.set_param(cr, uid, 'google_calendar_client_id', myself.cal_client_id or '', groups=['base.group_system'], context=None)
params.set_param(cr, uid, 'google_calendar_client_secret', myself.cal_client_secret or '', context=None) params.set_param(cr, uid, 'google_calendar_client_secret', myself.cal_client_secret or '', groups=['base.group_system'], context=None)
def get_default_all(self,cr,uid,ids,context=None): def get_default_all(self,cr,uid,ids,context=None):

View File

@ -192,14 +192,14 @@ class config(osv.Model):
return result return result
_columns = { _columns = {
'name': fields.char('Template Name', required=True, size=1024), 'name': fields.char('Template Name', required=True),
'model_id': fields.many2one('ir.model', 'Model', ondelete='set null', required=True), 'model_id': fields.many2one('ir.model', 'Model', ondelete='set null', required=True),
'model': fields.related('model_id', 'model', type='char', string='Model', readonly=True), 'model': fields.related('model_id', 'model', type='char', string='Model', readonly=True),
'filter_id': fields.many2one('ir.filters', 'Filter', domain="[('model_id', '=', model)]"), 'filter_id': fields.many2one('ir.filters', 'Filter', domain="[('model_id', '=', model)]"),
'google_drive_template_url': fields.char('Template URL', required=True, size=1024), 'google_drive_template_url': fields.char('Template URL', required=True, size=1024),
'google_drive_resource_id': fields.function(_resource_get, type="char", string='Resource Id'), 'google_drive_resource_id': fields.function(_resource_get, type="char", string='Resource Id'),
'google_drive_client_id': fields.function(_client_id_get, type="char", string='Google Client '), 'google_drive_client_id': fields.function(_client_id_get, type="char", string='Google Client '),
'name_template': fields.char('Google Drive Name Pattern', size=64, help='Choose how the new google drive will be named, on google side. Eg. gdoc_%(field_name)s', required=True), 'name_template': fields.char('Google Drive Name Pattern', help='Choose how the new google drive will be named, on google side. Eg. gdoc_%(field_name)s', required=True),
'active': fields.boolean('Active'), 'active': fields.boolean('Active'),
} }
@ -235,12 +235,12 @@ class base_config_settings(osv.TransientModel):
_inherit = "base.config.settings" _inherit = "base.config.settings"
_columns = { _columns = {
'google_drive_authorization_code': fields.char('Authorization Code', size=124), 'google_drive_authorization_code': fields.char('Authorization Code'),
'google_drive_uri': fields.char('URI', readonly=True, help="The URL to generate the authorization code from Google"), 'google_drive_uri': fields.char('URI', readonly=True, help="The URL to generate the authorization code from Google"),
} }
_defaults = { _defaults = {
'google_drive_uri': lambda s, cr, uid, c: s.pool['google.service']._get_google_token_uri(cr, uid, 'drive', scope=s.pool['google.drive.config'].get_google_scope(), context=c), 'google_drive_uri': lambda s, cr, uid, c: s.pool['google.service']._get_google_token_uri(cr, uid, 'drive', scope=s.pool['google.drive.config'].get_google_scope(), context=c),
'google_drive_authorization_code': lambda s, cr, uid, c: s.pool['ir.config_parameter'].get_param(cr, uid, 'google_drive_authorization_code', context=c), 'google_drive_authorization_code': lambda s, cr, uid, c: s.pool['ir.config_parameter'].get_param(cr, SUPERUSER_ID, 'google_drive_authorization_code', context=c),
} }
def set_google_authorization_code(self, cr, uid, ids, context=None): def set_google_authorization_code(self, cr, uid, ids, context=None):
@ -249,5 +249,5 @@ class base_config_settings(osv.TransientModel):
auth_code = config.google_drive_authorization_code auth_code = config.google_drive_authorization_code
if auth_code and auth_code != ir_config_param.get_param(cr, uid, 'google_drive_authorization_code', context=context): if auth_code and auth_code != ir_config_param.get_param(cr, uid, 'google_drive_authorization_code', context=context):
refresh_token = self.pool['google.service'].generate_refresh_token(cr, uid, 'drive', config.google_drive_authorization_code, context=context) refresh_token = self.pool['google.service'].generate_refresh_token(cr, uid, 'drive', config.google_drive_authorization_code, context=context)
ir_config_param.set_param(cr, uid, 'google_drive_authorization_code', auth_code) ir_config_param.set_param(cr, uid, 'google_drive_authorization_code', auth_code, groups=['base.group_system'])
ir_config_param.set_param(cr, uid, 'google_drive_refresh_token', refresh_token) ir_config_param.set_param(cr, uid, 'google_drive_refresh_token', refresh_token, groups=['base.group_system'])

View File

@ -5,11 +5,13 @@
<record id="config_google_drive_client_id" model="ir.config_parameter"> <record id="config_google_drive_client_id" model="ir.config_parameter">
<field name="key">google_drive_client_id</field> <field name="key">google_drive_client_id</field>
<field name="value">598905559630.apps.googleusercontent.com</field> <field name="value">598905559630.apps.googleusercontent.com</field>
<field name="group_ids" eval="[(4, ref('base.group_user'))]" />
</record> </record>
<record id="config_google_drive_client_secret" model="ir.config_parameter"> <record id="config_google_drive_client_secret" model="ir.config_parameter">
<field name="key">google_drive_client_secret</field> <field name="key">google_drive_client_secret</field>
<field name="value">vTmou73c-njP-1qCxm7qx7QE</field> <field name="value">vTmou73c-njP-1qCxm7qx7QE</field>
<field name="group_ids" eval="[(4, ref('base.group_system'))]" />
</record> </record>
</data> </data>

View File

@ -51,7 +51,7 @@ class hr_employee_category(osv.Model):
_name = "hr.employee.category" _name = "hr.employee.category"
_description = "Employee Category" _description = "Employee Category"
_columns = { _columns = {
'name': fields.char("Employee Tag", size=64, required=True), 'name': fields.char("Employee Tag", required=True),
'complete_name': fields.function(_name_get_fnc, type="char", string='Name'), 'complete_name': fields.function(_name_get_fnc, type="char", string='Name'),
'parent_id': fields.many2one('hr.employee.category', 'Parent Employee Tag', select=True), 'parent_id': fields.many2one('hr.employee.category', 'Parent Employee Tag', select=True),
'child_ids': fields.one2many('hr.employee.category', 'parent_id', 'Child Categories'), 'child_ids': fields.one2many('hr.employee.category', 'parent_id', 'Child Categories'),
@ -96,7 +96,7 @@ class hr_job(osv.Model):
_description = "Job Position" _description = "Job Position"
_inherit = ['mail.thread', 'ir.needaction_mixin'] _inherit = ['mail.thread', 'ir.needaction_mixin']
_columns = { _columns = {
'name': fields.char('Job Name', size=128, required=True, select=True), 'name': fields.char('Job Name', required=True, select=True),
'expected_employees': fields.function(_get_nbr_employees, string='Total Forecasted Employees', 'expected_employees': fields.function(_get_nbr_employees, string='Total Forecasted Employees',
help='Expected number of employees for this job position after new recruitment.', help='Expected number of employees for this job position after new recruitment.',
store = { store = {
@ -192,20 +192,20 @@ class hr_employee(osv.osv):
'name_related': fields.related('resource_id', 'name', type='char', string='Name', readonly=True, store=True), 'name_related': fields.related('resource_id', 'name', type='char', string='Name', readonly=True, store=True),
'country_id': fields.many2one('res.country', 'Nationality'), 'country_id': fields.many2one('res.country', 'Nationality'),
'birthday': fields.date("Date of Birth"), 'birthday': fields.date("Date of Birth"),
'ssnid': fields.char('SSN No', size=32, help='Social Security Number'), 'ssnid': fields.char('SSN No', help='Social Security Number'),
'sinid': fields.char('SIN No', size=32, help="Social Insurance Number"), 'sinid': fields.char('SIN No', help="Social Insurance Number"),
'identification_id': fields.char('Identification No', size=32), 'identification_id': fields.char('Identification No'),
'otherid': fields.char('Other Id', size=64), 'otherid': fields.char('Other Id'),
'gender': fields.selection([('male', 'Male'), ('female', 'Female')], 'Gender'), 'gender': fields.selection([('male', 'Male'), ('female', 'Female')], 'Gender'),
'marital': fields.selection([('single', 'Single'), ('married', 'Married'), ('widower', 'Widower'), ('divorced', 'Divorced')], 'Marital Status'), 'marital': fields.selection([('single', 'Single'), ('married', 'Married'), ('widower', 'Widower'), ('divorced', 'Divorced')], 'Marital Status'),
'department_id': fields.many2one('hr.department', 'Department'), 'department_id': fields.many2one('hr.department', 'Department'),
'address_id': fields.many2one('res.partner', 'Working Address'), 'address_id': fields.many2one('res.partner', 'Working Address'),
'address_home_id': fields.many2one('res.partner', 'Home Address'), 'address_home_id': fields.many2one('res.partner', 'Home Address'),
'bank_account_id': fields.many2one('res.partner.bank', 'Bank Account Number', domain="[('partner_id','=',address_home_id)]", help="Employee bank salary account"), 'bank_account_id': fields.many2one('res.partner.bank', 'Bank Account Number', domain="[('partner_id','=',address_home_id)]", help="Employee bank salary account"),
'work_phone': fields.char('Work Phone', size=32, readonly=False), 'work_phone': fields.char('Work Phone', readonly=False),
'mobile_phone': fields.char('Work Mobile', size=32, readonly=False), 'mobile_phone': fields.char('Work Mobile', readonly=False),
'work_email': fields.char('Work Email', size=240), 'work_email': fields.char('Work Email', size=240),
'work_location': fields.char('Office Location', size=32), 'work_location': fields.char('Office Location'),
'notes': fields.text('Notes'), 'notes': fields.text('Notes'),
'parent_id': fields.many2one('hr.employee', 'Manager'), 'parent_id': fields.many2one('hr.employee', 'Manager'),
'category_ids': fields.many2many('hr.employee.category', 'employee_category_rel', 'emp_id', 'category_id', 'Tags'), 'category_ids': fields.many2many('hr.employee.category', 'employee_category_rel', 'emp_id', 'category_id', 'Tags'),
@ -232,7 +232,7 @@ class hr_employee(osv.osv):
help="Small-sized photo of the employee. It is automatically "\ help="Small-sized photo of the employee. It is automatically "\
"resized as a 64x64px image, with aspect ratio preserved. "\ "resized as a 64x64px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."), "Use this field anywhere a small image is required."),
'passport_id': fields.char('Passport No', size=64), 'passport_id': fields.char('Passport No'),
'color': fields.integer('Color Index'), 'color': fields.integer('Color Index'),
'city': fields.related('address_id', 'city', type='char', string='City'), 'city': fields.related('address_id', 'city', type='char', string='City'),
'login': fields.related('user_id', 'login', type='char', string='Login', readonly=1), 'login': fields.related('user_id', 'login', type='char', string='Login', readonly=1),
@ -384,7 +384,7 @@ class hr_department(osv.osv):
_name = "hr.department" _name = "hr.department"
_columns = { _columns = {
'name': fields.char('Department Name', size=64, required=True), 'name': fields.char('Department Name', required=True),
'complete_name': fields.function(_dept_name_get_fnc, type="char", string='Name'), 'complete_name': fields.function(_dept_name_get_fnc, type="char", string='Name'),
'company_id': fields.many2one('res.company', 'Company', select=True, required=False), 'company_id': fields.many2one('res.company', 'Company', select=True, required=False),
'parent_id': fields.many2one('hr.department', 'Parent Department', select=True), 'parent_id': fields.many2one('hr.department', 'Parent Department', select=True),

View File

@ -16,8 +16,9 @@
<record model="ir.actions.act_window" id="hr_applicant_resumes"> <record model="ir.actions.act_window" id="hr_applicant_resumes">
<field name="name">Resumes and Letters</field> <field name="name">Resumes and Letters</field>
<field name="res_model">ir.attachment</field> <field name="res_model">ir.attachment</field>
<field name="view_mode">tree,form</field> <field name="view_type">form</field>
<field name="view_id" ref="document.view_document_file_tree"/> <field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="mail.view_document_file_kanban"/>
<field name="domain">[('res_model','=','hr.applicant')]</field> <field name="domain">[('res_model','=','hr.applicant')]</field>
<field name="help" type="html"> <field name="help" type="html">
<p> <p>

View File

@ -30,7 +30,7 @@ class hr_action_reason(osv.osv):
_name = "hr.action.reason" _name = "hr.action.reason"
_description = "Action Reason" _description = "Action Reason"
_columns = { _columns = {
'name': fields.char('Reason', size=64, required=True, help='Specifies the reason for Signing In/Signing Out.'), 'name': fields.char('Reason', required=True, help='Specifies the reason for Signing In/Signing Out.'),
'action_type': fields.selection([('sign_in', 'Sign in'), ('sign_out', 'Sign out')], "Action Type"), 'action_type': fields.selection([('sign_in', 'Sign in'), ('sign_out', 'Sign out')], "Action Type"),
} }
_defaults = { _defaults = {

View File

@ -0,0 +1,3 @@
.oe_systray #oe_attendance_sign_in_out_icon {
font-color: white;
}

View File

@ -1,33 +0,0 @@
.openerp .oe_attendance_status {
height: 32px;
width: 32px;
display: inline-block;
}
.openerp .oe_attendance_signin {
float: right;
height: 32px;
width: 32px;
background: url(/hr_attendance/static/src/img/emp-out32.png);
cursor: pointer;
}
.openerp .oe_attendance_signin:hover {
background: url(/hr_attendance/static/src/img/emp-out-disable32.png);
}
.openerp .oe_attendance_status.oe_attendance_signed .oe_attendance_signin {
display: none;
}
.openerp .oe_attendance_signout {
float:right;
height: 32px;
width: 32px;
background: url(/hr_attendance/static/src/img/emp-in32.png);
cursor: pointer;
}
.openerp .oe_attendance_signout:hover {
background: url(/hr_attendance/static/src/img/emp-in-disable32.png);
}
.openerp .oe_attendance_status.oe_attendance_nosigned .oe_attendance_signout {
display: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -14,15 +14,14 @@ openerp.hr_attendance = function (instance) {
start: function() { start: function() {
var self = this; var self = this;
var tmp = function() { var tmp = function() {
this.$el.toggleClass("oe_attendance_nosigned", ! this.get("signed_in")); var $sign_in_out_icon = this.$('#oe_attendance_sign_in_out_icon');
this.$el.toggleClass("oe_attendance_signed", this.get("signed_in")); $sign_in_out_icon.toggleClass("fa-sign-in", ! this.get("signed_in"));
$sign_in_out_icon.toggleClass("fa-sign-out", this.get("signed_in"));
}; };
this.on("change:signed_in", this, tmp); this.on("change:signed_in", this, tmp);
_.bind(tmp, this)(); _.bind(tmp, this)();
this.$(".oe_attendance_signin").click(function() { this.$(".oe_attendance_sign_in_out").click(function(ev) {
self.do_update_attendance(); ev.preventDefault();
});
this.$(".oe_attendance_signout").click(function() {
self.do_update_attendance(); self.do_update_attendance();
}); });
this.$el.tooltip({ this.$el.tooltip({

View File

@ -1,13 +1,9 @@
<template> <template>
<t t-name="AttendanceSlider"> <t t-name="AttendanceSlider">
<div class="oe_attendance_status oe_attendance_nosigned" data-toggle="tooltip"> <li class="oe_attendance_status" data-toggle="tooltip">
<div class="oe_attendance_signin"></div> <a href="#" class="oe_attendance_sign_in_out">
<div class="oe_attendance_signout"></div> <i id="oe_attendance_sign_in_out_icon" class="fa fa-sign-in"/>
</div> </a>
</li>
</t> </t>
</template> </template>

View File

@ -5,8 +5,8 @@
<data> <data>
<template id="assets_backend" name="hr_attendance assets" inherit_id="web.assets_backend"> <template id="assets_backend" name="hr_attendance assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside"> <xpath expr="." position="inside">
<link rel="stylesheet" href="/hr_attendance/static/src/css/slider.css"/>
<script type="text/javascript" src="/hr_attendance/static/src/js/attendance.js"></script> <script type="text/javascript" src="/hr_attendance/static/src/js/attendance.js"></script>
<link rel="stylesheet" href="/hr_attendance/static/src/css/attendance.css"/>
</xpath> </xpath>
</template> </template>
</data> </data>

Some files were not shown because too many files have changed in this diff Show More