[MERGE] saas-4 report_webkit missing dependency on report
bzr revid: al@openerp.com-20140501152604-4cobh5ui47dt4pem bzr revid: al@openerp.com-20140501155633-gefnc3zqcsr2rhaz bzr revid: al@openerp.com-20140501161156-4wbsvhh8gz4r22h3
This commit is contained in:
commit
7e25b9ae55
|
@ -1944,15 +1944,17 @@ class account_tax(osv.osv):
|
||||||
return super(account_tax, self).write(cr, uid, ids, vals, context=context)
|
return super(account_tax, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
|
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
journal_pool = self.pool.get('account.journal')
|
journal_pool = self.pool.get('account.journal')
|
||||||
|
|
||||||
if context and context.has_key('type'):
|
if context.get('type'):
|
||||||
if context.get('type') in ('out_invoice','out_refund'):
|
if context.get('type') in ('out_invoice','out_refund'):
|
||||||
args += [('type_tax_use','in',['sale','all'])]
|
args += [('type_tax_use','in',['sale','all'])]
|
||||||
elif context.get('type') in ('in_invoice','in_refund'):
|
elif context.get('type') in ('in_invoice','in_refund'):
|
||||||
args += [('type_tax_use','in',['purchase','all'])]
|
args += [('type_tax_use','in',['purchase','all'])]
|
||||||
|
|
||||||
if context and context.has_key('journal_id'):
|
if context.get('journal_id'):
|
||||||
journal = journal_pool.browse(cr, uid, context.get('journal_id'))
|
journal = journal_pool.browse(cr, uid, context.get('journal_id'))
|
||||||
if journal.type in ('sale', 'purchase'):
|
if journal.type in ('sale', 'purchase'):
|
||||||
args += [('type_tax_use','in',[journal.type,'all'])]
|
args += [('type_tax_use','in',[journal.type,'all'])]
|
||||||
|
|
|
@ -409,9 +409,7 @@ class account_invoice(osv.osv):
|
||||||
'''
|
'''
|
||||||
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
|
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
|
||||||
self.write(cr, uid, ids, {'sent': True}, context=context)
|
self.write(cr, uid, ids, {'sent': True}, context=context)
|
||||||
context2 = context.copy()
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_invoice', context=context)
|
||||||
context2['active_ids'] = ids
|
|
||||||
return self.pool['report'].get_action(cr, uid, [], 'account.report_invoice', context=context2)
|
|
||||||
|
|
||||||
def action_invoice_sent(self, cr, uid, ids, context=None):
|
def action_invoice_sent(self, cr, uid, ids, context=None):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -457,7 +457,7 @@
|
||||||
<filter name="invoices" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Proforma/Open/Paid Invoices"/>
|
<filter name="invoices" string="Invoices" domain="[('state','not in',['draft','cancel'])]" help="Proforma/Open/Paid Invoices"/>
|
||||||
<filter name="unpaid" string="Unpaid" domain="[('state','=','open')]" help="Unpaid Invoices"/>
|
<filter name="unpaid" string="Unpaid" domain="[('state','=','open')]" help="Unpaid Invoices"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="user_id" string="Salesperson"/>
|
<field name="user_id" string="Salesperson"/>
|
||||||
<field name="period_id" string="Period"/>
|
<field name="period_id" string="Period"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
|
@ -1034,10 +1034,14 @@ class account_move_line(osv.osv):
|
||||||
part_rec_ids = [rec['reconcile_partial_id'][0] for rec in part_recs]
|
part_rec_ids = [rec['reconcile_partial_id'][0] for rec in part_recs]
|
||||||
unlink_ids += rec_ids
|
unlink_ids += rec_ids
|
||||||
unlink_ids += part_rec_ids
|
unlink_ids += part_rec_ids
|
||||||
|
all_moves = obj_move_line.search(cr, uid, ['|',('reconcile_id', 'in', unlink_ids),('reconcile_partial_id', 'in', unlink_ids)])
|
||||||
|
all_moves = list(set(all_moves) - set(move_ids))
|
||||||
if unlink_ids:
|
if unlink_ids:
|
||||||
if opening_reconciliation:
|
if opening_reconciliation:
|
||||||
obj_move_rec.write(cr, uid, unlink_ids, {'opening_reconciliation': False})
|
obj_move_rec.write(cr, uid, unlink_ids, {'opening_reconciliation': False})
|
||||||
obj_move_rec.unlink(cr, uid, unlink_ids)
|
obj_move_rec.unlink(cr, uid, unlink_ids)
|
||||||
|
if all_moves:
|
||||||
|
obj_move_line.reconcile_partial(cr, uid, all_moves, 'auto',context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, context=None, check=True):
|
def unlink(self, cr, uid, ids, context=None, check=True):
|
||||||
|
|
|
@ -65,7 +65,8 @@
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//div[@name='buttons']" position="inside">
|
<xpath expr="//div[@name='buttons']" position="inside">
|
||||||
<button type="action" string="Invoices"
|
<button type="action" string="Invoices"
|
||||||
name="%(account.action_invoice_tree)d"
|
name="%(account.action_invoice_tree1)d"
|
||||||
|
attrs="{'invisible': [('customer', '=', False)]}"
|
||||||
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}" groups="account.group_account_invoice"/>
|
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}" groups="account.group_account_invoice"/>
|
||||||
<button type="action" string="Journal Items" name="%(account.action_account_moves_all_tree)d" groups="account.group_account_user"/>
|
<button type="action" string="Journal Items" name="%(account.action_account_moves_all_tree)d" groups="account.group_account_user"/>
|
||||||
<button type="action" string="Contracts" name="%(account.action_open_partner_analytic_accounts)d"
|
<button type="action" string="Contracts" name="%(account.action_open_partner_analytic_accounts)d"
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<search string="Analytic Account">
|
<search string="Analytic Account">
|
||||||
<field name="name" filter_domain="['|', ('name','ilike',self), ('code','ilike',self)]" string="Analytic Account"/>
|
<field name="name" filter_domain="['|', ('name','ilike',self), ('code','ilike',self)]" string="Analytic Account"/>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="manager_id"/>
|
<field name="manager_id"/>
|
||||||
<field name="parent_id"/>
|
<field name="parent_id"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
|
|
|
@ -22,6 +22,7 @@ from dateutil.relativedelta import relativedelta
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
import traceback
|
||||||
|
|
||||||
from openerp.osv import osv, fields
|
from openerp.osv import osv, fields
|
||||||
from openerp.osv.orm import intersect, except_orm
|
from openerp.osv.orm import intersect, except_orm
|
||||||
|
@ -72,9 +73,7 @@ class account_analytic_invoice_line(osv.osv):
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
res = self.pool.get('product.product').browse(cr, uid, product, context=context)
|
res = self.pool.get('product.product').browse(cr, uid, product, context=context)
|
||||||
result.update({'name':res.partner_ref or False,'uom_id': uom_id or res.uom_id.id or False, 'price_unit': res.list_price or 0.0})
|
result.update({'name': name or res.description or False,'uom_id': uom_id or res.uom_id.id or False, 'price_unit': price_unit or res.list_price or 0.0})
|
||||||
if res.description:
|
|
||||||
result['name'] += '\n'+res.description
|
|
||||||
|
|
||||||
res_final = {'value':result}
|
res_final = {'value':result}
|
||||||
if result['uom_id'] != res.uom_id.id:
|
if result['uom_id'] != res.uom_id.id:
|
||||||
|
@ -721,23 +720,40 @@ class account_analytic_account(osv.osv):
|
||||||
inv_obj.button_compute(cr, uid, [invoice_id], context=context)
|
inv_obj.button_compute(cr, uid, [invoice_id], context=context)
|
||||||
return invoice_id
|
return invoice_id
|
||||||
|
|
||||||
def recurring_create_invoice(self, cr, uid, automatic=False, context=None):
|
def recurring_create_invoice(self, cr, uid, ids, context=None):
|
||||||
|
return self._recurring_create_invoice(cr, uid, ids, context=context)
|
||||||
|
|
||||||
|
def _cron_recurring_create_invoice(self, cr, uid, context=None):
|
||||||
|
return self._recurring_create_invoice(cr, uid, [], automatic=True, context=context)
|
||||||
|
|
||||||
|
def _recurring_create_invoice(self, cr, uid, ids, automatic=False, context=None):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
current_date = time.strftime('%Y-%m-%d')
|
current_date = time.strftime('%Y-%m-%d')
|
||||||
|
if ids:
|
||||||
contract_ids = self.search(cr, uid, [('recurring_next_date','<=', current_date), ('state','=', 'open'), ('recurring_invoices','=', True)])
|
contract_ids = ids
|
||||||
|
else:
|
||||||
|
contract_ids = self.search(cr, uid, [('recurring_next_date','<=', current_date), ('state','=', 'open'), ('recurring_invoices','=', True), ('type', '=', 'contract')])
|
||||||
for contract in self.browse(cr, uid, contract_ids, context=context):
|
for contract in self.browse(cr, uid, contract_ids, context=context):
|
||||||
invoice_id = self._prepare_invoice(cr, uid, contract, context=context)
|
try:
|
||||||
|
invoice_id = self._prepare_invoice(cr, uid, contract, context=context)
|
||||||
|
|
||||||
next_date = datetime.datetime.strptime(contract.recurring_next_date or current_date, "%Y-%m-%d")
|
next_date = datetime.datetime.strptime(contract.recurring_next_date or current_date, "%Y-%m-%d")
|
||||||
interval = contract.recurring_interval
|
interval = contract.recurring_interval
|
||||||
if contract.recurring_rule_type == 'daily':
|
if contract.recurring_rule_type == 'daily':
|
||||||
new_date = next_date+relativedelta(days=+interval)
|
new_date = next_date+relativedelta(days=+interval)
|
||||||
elif contract.recurring_rule_type == 'weekly':
|
elif contract.recurring_rule_type == 'weekly':
|
||||||
new_date = next_date+relativedelta(weeks=+interval)
|
new_date = next_date+relativedelta(weeks=+interval)
|
||||||
else:
|
else:
|
||||||
new_date = next_date+relativedelta(months=+interval)
|
new_date = next_date+relativedelta(months=+interval)
|
||||||
self.write(cr, uid, [contract.id], {'recurring_next_date': new_date.strftime('%Y-%m-%d')}, context=context)
|
self.write(cr, uid, [contract.id], {'recurring_next_date': new_date.strftime('%Y-%m-%d')}, context=context)
|
||||||
|
if automatic:
|
||||||
|
cr.commit()
|
||||||
|
except Exception:
|
||||||
|
if automatic:
|
||||||
|
cr.rollback()
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
else:
|
||||||
|
raise
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class account_analytic_account_summary_user(osv.osv):
|
class account_analytic_account_summary_user(osv.osv):
|
||||||
|
|
|
@ -93,7 +93,7 @@ OpenERP Automatic Email
|
||||||
<field name="interval_type">days</field>
|
<field name="interval_type">days</field>
|
||||||
<field name="numbercall">-1</field>
|
<field name="numbercall">-1</field>
|
||||||
<field name="model" eval="'account.analytic.account'"/>
|
<field name="model" eval="'account.analytic.account'"/>
|
||||||
<field name="function" eval="'recurring_create_invoice'"/>
|
<field name="function" eval="'_cron_recurring_create_invoice'"/>
|
||||||
<field name="args" eval="'()'"/>
|
<field name="args" eval="'()'"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
@ -151,8 +151,10 @@
|
||||||
</group>
|
</group>
|
||||||
<separator string="Recurring Invoices" attrs="{'invisible': [('recurring_invoices','!=',True)]}"/>
|
<separator string="Recurring Invoices" attrs="{'invisible': [('recurring_invoices','!=',True)]}"/>
|
||||||
<div>
|
<div>
|
||||||
<field name="recurring_invoices" on_change="onchange_recurring_invoices(recurring_invoices, date_start)" class="oe_inline"/>
|
<div attrs="{'invisible': [('type','!=', 'contract'), ('recurring_invoices', '=', False)]}">
|
||||||
<label for="recurring_invoices" />
|
<field name="recurring_invoices" on_change="onchange_recurring_invoices(recurring_invoices, date_start)" class="oe_inline" />
|
||||||
|
<label for="recurring_invoices" />
|
||||||
|
</div>
|
||||||
<button class="oe_link" name="recurring_create_invoice" attrs="{'invisible': [('recurring_invoices','!=',True)]}" string="⇒ create invoices" type="object" groups="base.group_no_one"/>
|
<button class="oe_link" name="recurring_create_invoice" attrs="{'invisible': [('recurring_invoices','!=',True)]}" string="⇒ create invoices" type="object" groups="base.group_no_one"/>
|
||||||
</div>
|
</div>
|
||||||
<group attrs="{'invisible': [('recurring_invoices','!=',True)]}">
|
<group attrs="{'invisible': [('recurring_invoices','!=',True)]}">
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
!record {model: account.analytic.account, id: contract_main}:
|
!record {model: account.analytic.account, id: contract_main}:
|
||||||
partner_id: base.main_partner
|
partner_id: base.main_partner
|
||||||
template_id: account_analytic_analysis.contract_template
|
template_id: account_analytic_analysis.contract_template
|
||||||
|
type: contract
|
||||||
-
|
-
|
||||||
I check that the contract inherited from data of the template
|
I check that the contract inherited from data of the template
|
||||||
-
|
-
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
I generate all invoices from contracts having recurring invoicing
|
I generate all invoices from contracts having recurring invoicing
|
||||||
-
|
-
|
||||||
!python {model: account.analytic.account}: |
|
!python {model: account.analytic.account}: |
|
||||||
self.recurring_create_invoice(cr, uid)
|
self.recurring_create_invoice(cr, uid, [])
|
||||||
-
|
-
|
||||||
I test the generated invoice
|
I test the generated invoice
|
||||||
-
|
-
|
||||||
|
|
|
@ -454,15 +454,10 @@ class account_bank_statement(osv.osv):
|
||||||
_inherit = "account.bank.statement"
|
_inherit = "account.bank.statement"
|
||||||
_name = "account.bank.statement"
|
_name = "account.bank.statement"
|
||||||
|
|
||||||
def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id, st_line_number, context=None):
|
def _prepare_bank_move_line(self, cr, uid, st_line, move_id, amount, company_currency_id, context=None):
|
||||||
account_move_line_pool = self.pool.get('account.move.line')
|
result = super(account_bank_statement,self)._prepare_bank_move_line(cr, uid, st_line,
|
||||||
account_bank_statement_line_pool = self.pool.get('account.bank.statement.line')
|
move_id, amount, company_currency_id, context=context)
|
||||||
st_line = account_bank_statement_line_pool.browse(cr, uid, st_line_id, context=context)
|
result['analytics_id'] = st_line.analytics_id.id
|
||||||
result = super(account_bank_statement,self).create_move_from_st_line(cr, uid, st_line_id, company_currency_id, st_line_number, context=context)
|
|
||||||
move = st_line.move_ids and st_line.move_ids[0] or False
|
|
||||||
if move:
|
|
||||||
for line in move.line_id:
|
|
||||||
account_move_line_pool.write(cr, uid, [line.id], {'analytics_id':st_line.analytics_id.id}, context=context)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def button_confirm_bank(self, cr, uid, ids, context=None):
|
def button_confirm_bank(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -123,6 +123,8 @@ class account_invoice_line(osv.osv):
|
||||||
if a == line['account_id'] and i_line.product_id.id == line['product_id']:
|
if a == line['account_id'] and i_line.product_id.id == line['product_id']:
|
||||||
uom = i_line.product_id.uos_id or i_line.product_id.uom_id
|
uom = i_line.product_id.uos_id or i_line.product_id.uom_id
|
||||||
valuation_price_unit = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, i_line.product_id.standard_price, i_line.uos_id.id)
|
valuation_price_unit = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, i_line.product_id.standard_price, i_line.uos_id.id)
|
||||||
|
if inv.currency_id.id != company_currency:
|
||||||
|
standard_price = self.pool.get('res.currency').compute(cr, uid, company_currency, inv.currency_id.id, standard_price, context={'date': inv.date_invoice})
|
||||||
if i_line.product_id.cost_method != 'standard' and i_line.purchase_line_id:
|
if i_line.product_id.cost_method != 'standard' and i_line.purchase_line_id:
|
||||||
#for average/fifo/lifo costing method, fetch real cost price from incomming moves
|
#for average/fifo/lifo costing method, fetch real cost price from incomming moves
|
||||||
stock_move_obj = self.pool.get('stock.move')
|
stock_move_obj = self.pool.get('stock.move')
|
||||||
|
|
|
@ -783,6 +783,7 @@ class account_voucher(osv.osv):
|
||||||
total_credit += line.credit and line.amount_currency or 0.0
|
total_credit += line.credit and line.amount_currency or 0.0
|
||||||
total_debit += line.debit and line.amount_currency or 0.0
|
total_debit += line.debit and line.amount_currency or 0.0
|
||||||
|
|
||||||
|
remaining_amount = price
|
||||||
#voucher line creation
|
#voucher line creation
|
||||||
for line in account_move_lines:
|
for line in account_move_lines:
|
||||||
|
|
||||||
|
@ -803,13 +804,13 @@ class account_voucher(osv.osv):
|
||||||
'move_line_id':line.id,
|
'move_line_id':line.id,
|
||||||
'account_id':line.account_id.id,
|
'account_id':line.account_id.id,
|
||||||
'amount_original': amount_original,
|
'amount_original': amount_original,
|
||||||
'amount': (line.id in move_lines_found) and min(abs(price), amount_unreconciled) or 0.0,
|
'amount': (line.id in move_lines_found) and min(abs(remaining_amount), amount_unreconciled) or 0.0,
|
||||||
'date_original':line.date,
|
'date_original':line.date,
|
||||||
'date_due':line.date_maturity,
|
'date_due':line.date_maturity,
|
||||||
'amount_unreconciled': amount_unreconciled,
|
'amount_unreconciled': amount_unreconciled,
|
||||||
'currency_id': line_currency_id,
|
'currency_id': line_currency_id,
|
||||||
}
|
}
|
||||||
price -= rs['amount']
|
remaining_amount -= rs['amount']
|
||||||
#in case a corresponding move_line hasn't been found, we now try to assign the voucher amount
|
#in case a corresponding move_line hasn't been found, we now try to assign the voucher amount
|
||||||
#on existing invoices: we split voucher amount by most old first, but only for lines in the same currency
|
#on existing invoices: we split voucher amount by most old first, but only for lines in the same currency
|
||||||
if not move_lines_found:
|
if not move_lines_found:
|
||||||
|
@ -937,19 +938,17 @@ class account_voucher(osv.osv):
|
||||||
def cancel_voucher(self, cr, uid, ids, context=None):
|
def cancel_voucher(self, cr, uid, ids, context=None):
|
||||||
reconcile_pool = self.pool.get('account.move.reconcile')
|
reconcile_pool = self.pool.get('account.move.reconcile')
|
||||||
move_pool = self.pool.get('account.move')
|
move_pool = self.pool.get('account.move')
|
||||||
|
move_line_pool = self.pool.get('account.move.line')
|
||||||
for voucher in self.browse(cr, uid, ids, context=context):
|
for voucher in self.browse(cr, uid, ids, context=context):
|
||||||
# refresh to make sure you don't unlink an already removed move
|
# refresh to make sure you don't unlink an already removed move
|
||||||
voucher.refresh()
|
voucher.refresh()
|
||||||
recs = []
|
|
||||||
for line in voucher.move_ids:
|
for line in voucher.move_ids:
|
||||||
if line.reconcile_id:
|
if line.reconcile_id:
|
||||||
recs += [line.reconcile_id.id]
|
move_lines = [move_line.id for move_line in line.reconcile_id.line_id]
|
||||||
if line.reconcile_partial_id:
|
move_lines.remove(line.id)
|
||||||
recs += [line.reconcile_partial_id.id]
|
reconcile_pool.unlink(cr, uid, [line.reconcile_id.id])
|
||||||
|
if len(move_lines) >= 2:
|
||||||
reconcile_pool.unlink(cr, uid, recs)
|
move_line_pool.reconcile_partial(cr, uid, move_lines, 'auto',context=context)
|
||||||
|
|
||||||
if voucher.move_id:
|
if voucher.move_id:
|
||||||
move_pool.button_cancel(cr, uid, [voucher.move_id.id])
|
move_pool.button_cancel(cr, uid, [voucher.move_id.id])
|
||||||
move_pool.unlink(cr, uid, [voucher.move_id.id])
|
move_pool.unlink(cr, uid, [voucher.move_id.id])
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
!python {model: account.voucher}: |
|
!python {model: account.voucher}: |
|
||||||
vals = {}
|
vals = {}
|
||||||
journal_id = self.default_get(cr, uid, ['journal_id']).get('journal_id',None)
|
journal_id = self.default_get(cr, uid, ['journal_id']).get('journal_id',None)
|
||||||
|
voucher = self.recompute_voucher_lines(cr, uid, [], ref("base.res_partner_19"), journal_id, 450.0, ref('base.EUR'), 'receipt', False)
|
||||||
|
assert (voucher['value'].get('writeoff_amount') == 0.0), "Writeoff amount calculated by recompute_voucher_lines() is not 0.0"
|
||||||
res = self.onchange_partner_id(cr, uid, [], ref("base.res_partner_19"), journal_id, 0.0, 1, ttype='receipt', date=False)
|
res = self.onchange_partner_id(cr, uid, [], ref("base.res_partner_19"), journal_id, 0.0, 1, ttype='receipt', date=False)
|
||||||
vals = {
|
vals = {
|
||||||
'account_id': ref('account.cash'),
|
'account_id': ref('account.cash'),
|
||||||
|
@ -64,6 +66,7 @@
|
||||||
vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
|
vals['line_cr_ids'] = [(0,0,i) for i in res['value']['line_cr_ids']]
|
||||||
id = self.create(cr, uid, vals)
|
id = self.create(cr, uid, vals)
|
||||||
voucher_id = self.browse(cr, uid, id)
|
voucher_id = self.browse(cr, uid, id)
|
||||||
|
assert (voucher_id.writeoff_amount == 0.0), "Writeoff amount is not 0.0"
|
||||||
assert (voucher_id.state=='draft'), "Voucher is not in draft state"
|
assert (voucher_id.state=='draft'), "Voucher is not in draft state"
|
||||||
self.signal_proforma_voucher(cr, uid, [voucher_id.id])
|
self.signal_proforma_voucher(cr, uid, [voucher_id.id])
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<data>
|
<data>
|
||||||
<template id="auth_signup.login" inherit_id="web.login" name="Sign up - Reset Password">
|
<template id="auth_signup.login" inherit_id="web.login" name="Sign up - Reset Password">
|
||||||
<xpath expr="//button[@type='submit']" position="before">
|
<xpath expr="//button[@type='submit']" position="before">
|
||||||
<a t-if="signup_enabled" t-attf-href="/web/signup?redirect=/web%3f{{ quote_plus(keep_query()) }}" class="btn btn-link pull-right">Sign up</a>
|
<a t-if="signup_enabled" t-attf-href="/web/signup?{{ keep_query() }}" class="btn btn-link pull-right">Sign up</a>
|
||||||
<a t-if="reset_password_enabled" t-attf-href="/web/reset_password?redirect=/web/login%3f{{ quote_plus(keep_query()) }}" class="btn btn-link pull-right">Reset Password</a>
|
<a t-if="reset_password_enabled" t-attf-href="/web/reset_password?{{ keep_query() }}" class="btn btn-link pull-right">Reset Password</a>
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -22,12 +22,13 @@
|
||||||
<div class="form-group field-name">
|
<div class="form-group field-name">
|
||||||
<label for="name" class="control-label">Your Name</label>
|
<label for="name" class="control-label">Your Name</label>
|
||||||
<input type="text" name="name" t-att-value="name" id="name" class="form-control" placeholder="e.g. John Doe"
|
<input type="text" name="name" t-att-value="name" id="name" class="form-control" placeholder="e.g. John Doe"
|
||||||
required="required" t-att-readonly="'readonly' if only_passwords else None"/>
|
required="required" t-att-readonly="'readonly' if only_passwords else None"
|
||||||
|
t-att-autofocus="'autofocus' if login and not only_passwords else None" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group field-password">
|
<div class="form-group field-password">
|
||||||
<label for="password" class="control-label">Password</label>
|
<label for="password" class="control-label">Password</label>
|
||||||
<input type="password" name="password" autofocus="autofocus" id="password" class="form-control"
|
<input type="password" name="password" id="password" class="form-control"
|
||||||
required="required" t-att-autofocus="'autofocus' if only_passwords else None"/>
|
required="required" t-att-autofocus="'autofocus' if only_passwords else None"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@
|
||||||
|
|
||||||
<template id="auth_signup.signup" name="Sign up login">
|
<template id="auth_signup.signup" name="Sign up login">
|
||||||
<t t-call="web.login_layout">
|
<t t-call="web.login_layout">
|
||||||
<form class="oe_signup_form" role="form" t-attf-action="/web/signup{{ '?debug' if debug else '' }}" method="post" t-if="not message">
|
<form class="oe_signup_form" role="form" method="post" t-if="not message">
|
||||||
|
|
||||||
<t t-call="auth_signup.fields"/>
|
<t t-call="auth_signup.fields"/>
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@
|
||||||
<input type="hidden" name="redirect" t-att-value="redirect"/>
|
<input type="hidden" name="redirect" t-att-value="redirect"/>
|
||||||
<input type="hidden" name="token" t-att-value="token"/>
|
<input type="hidden" name="token" t-att-value="token"/>
|
||||||
<div class="clearfix oe_login_buttons">
|
<div class="clearfix oe_login_buttons">
|
||||||
<a href="/web/login" class="btn btn-link pull-right">Back to Login</a>
|
<a t-attf-href="/web/login?{{ keep_query() }}" class="btn btn-link pull-right">Back to Login</a>
|
||||||
<button type="submit" class="btn btn-primary pull-left">Sign up</button>
|
<button type="submit" class="btn btn-primary pull-left">Sign up</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
<a href="/web/login" class="btn btn-link pull-right">Back to Login</a>
|
<a href="/web/login" class="btn btn-link pull-right">Back to Login</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="oe_reset_password_form" role="form" t-attf-action="/web/reset_password{{ '?debug' if debug else '' }}" method="post" t-if="not message">
|
<form class="oe_reset_password_form" role="form" method="post" t-if="not message">
|
||||||
|
|
||||||
<t t-if="token">
|
<t t-if="token">
|
||||||
<t t-call="auth_signup.fields">
|
<t t-call="auth_signup.fields">
|
||||||
|
@ -88,7 +89,7 @@
|
||||||
<input type="hidden" name="redirect" t-att-value="redirect"/>
|
<input type="hidden" name="redirect" t-att-value="redirect"/>
|
||||||
<input type="hidden" name="token" t-att-value="token"/>
|
<input type="hidden" name="token" t-att-value="token"/>
|
||||||
<div class="clearfix oe_login_buttons">
|
<div class="clearfix oe_login_buttons">
|
||||||
<a href="/web/login" class="btn btn-link pull-right">Back to Login</a>
|
<a t-attf-href="/web/login?{{ keep_query() }}" class="btn btn-link pull-right">Back to Login</a>
|
||||||
<button type="submit" class="btn btn-primary pull-left">Reset password</button>
|
<button type="submit" class="btn btn-primary pull-left">Reset password</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//notebook[last()]" position="inside">
|
<xpath expr="//notebook[last()]" position="inside">
|
||||||
<page string="Geo Localization" name="geo_localization" groups="base.group_no_one">
|
<page string="Geo Localization" name="geo_localization">
|
||||||
<group colspan="2" col="2">
|
<group colspan="2" col="2">
|
||||||
<separator string="Geo Localization" colspan="2"/>
|
<separator string="Geo Localization" colspan="2"/>
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -91,10 +91,10 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||||
var $dialog = new instance.web.Dialog(this, {
|
var $dialog = new instance.web.Dialog(this, {
|
||||||
title: _t("Edit Layout"),
|
title: _t("Edit Layout"),
|
||||||
}, QWeb.render('DashBoard.layouts', qdict)).open();
|
}, QWeb.render('DashBoard.layouts', qdict)).open();
|
||||||
$dialog.find('li').click(function() {
|
$dialog.$el.find('li').click(function() {
|
||||||
var layout = $(this).attr('data-layout');
|
var layout = $(this).attr('data-layout');
|
||||||
$dialog.modal('hide');
|
|
||||||
self.do_change_layout(layout);
|
self.do_change_layout(layout);
|
||||||
|
$dialog.$dialog_box.modal('hide');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
do_change_layout: function(new_layout) {
|
do_change_layout: function(new_layout) {
|
||||||
|
|
|
@ -994,7 +994,6 @@ class calendar_event(osv.Model):
|
||||||
sort_fields[ord] = '%s-%s' % (browse_event[ord], r_date.strftime("%Y%m%d%H%M%S"))
|
sort_fields[ord] = '%s-%s' % (browse_event[ord], r_date.strftime("%Y%m%d%H%M%S"))
|
||||||
else:
|
else:
|
||||||
sort_fields[ord] = browse_event[ord]
|
sort_fields[ord] = browse_event[ord]
|
||||||
'If we sort on FK, we obtain a browse_record, so we need to sort on name_get'
|
|
||||||
if type(browse_event[ord]) is openerp.osv.orm.browse_record:
|
if type(browse_event[ord]) is openerp.osv.orm.browse_record:
|
||||||
name_get = browse_event[ord].name_get()
|
name_get = browse_event[ord].name_get()
|
||||||
if len(name_get) and len(name_get[0]) >= 2:
|
if len(name_get) and len(name_get[0]) >= 2:
|
||||||
|
@ -1397,6 +1396,14 @@ class calendar_event(osv.Model):
|
||||||
'flags': {'form': {'action_buttons': True, 'options': {'mode': 'edit'}}}
|
'flags': {'form': {'action_buttons': True, 'options': {'mode': 'edit'}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100, name_get_uid=None):
|
||||||
|
for arg in args:
|
||||||
|
if arg[0] == 'id':
|
||||||
|
for n, calendar_id in enumerate(arg[2]):
|
||||||
|
if isinstance(calendar_id, str):
|
||||||
|
arg[2][n] = calendar_id.split('-')[0]
|
||||||
|
return super(calendar_event, self)._name_search(cr, user, name=name, args=args, operator=operator, context=context, limit=limit, name_get_uid=name_get_uid)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, values, context=None):
|
def write(self, cr, uid, ids, values, context=None):
|
||||||
def _only_changes_to_apply_on_real_ids(field_names):
|
def _only_changes_to_apply_on_real_ids(field_names):
|
||||||
''' return True if changes are only to be made on the real ids'''
|
''' return True if changes are only to be made on the real ids'''
|
||||||
|
|
|
@ -978,7 +978,7 @@ class crm_lead(format_address, osv.osv):
|
||||||
if obj.type == 'opportunity':
|
if obj.type == 'opportunity':
|
||||||
model, view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'crm_case_form_view_oppor')
|
model, view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm', 'crm_case_form_view_oppor')
|
||||||
else:
|
else:
|
||||||
view_id = super(crm_lead, self).get_formview_id(cr, uid, id, model=model, context=context)
|
view_id = super(crm_lead, self).get_formview_id(cr, uid, id, model='crm.lead', context=context)
|
||||||
return view_id
|
return view_id
|
||||||
|
|
||||||
def message_get_suggested_recipients(self, cr, uid, ids, context=None):
|
def message_get_suggested_recipients(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -327,7 +327,7 @@
|
||||||
<field name="categ_ids" string="Tag" filter_domain="[('categ_ids', 'ilike', self)]"/>
|
<field name="categ_ids" string="Tag" filter_domain="[('categ_ids', 'ilike', self)]"/>
|
||||||
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
|
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="create_date"/>
|
<field name="create_date"/>
|
||||||
<field name="country_id" context="{'invisible_country': False}"/>
|
<field name="country_id" context="{'invisible_country': False}"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
@ -547,7 +547,7 @@
|
||||||
<field name="categ_ids" string="Tag" filter_domain="[('categ_ids', 'ilike', self)]"/>
|
<field name="categ_ids" string="Tag" filter_domain="[('categ_ids', 'ilike', self)]"/>
|
||||||
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
|
<field name="section_id" context="{'invisible_section': False}" groups="base.group_multi_salesteams"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="stage_id" domain="[]"/>
|
<field name="stage_id" domain="[]"/>
|
||||||
<field name="probability"/>
|
<field name="probability"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
|
@ -176,7 +176,7 @@
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter string="Phone Calls Assigned to Me or My Team(s)" icon="terp-personal+" domain="['|', ('section_id.user_id','=',uid), ('user_id', '=', uid)]"
|
<filter string="Phone Calls Assigned to Me or My Team(s)" icon="terp-personal+" domain="['|', ('section_id.user_id','=',uid), ('user_id', '=', uid)]"
|
||||||
help="Phone Calls Assigned to the current user or with a team having the current user as team leader"/>
|
help="Phone Calls Assigned to the current user or with a team having the current user as team leader"/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="opportunity_id"/>
|
<field name="opportunity_id"/>
|
||||||
<field name="section_id" string="Sales Team"
|
<field name="section_id" string="Sales Team"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<graph string="Leads Analysis" type="pivot" stacked="True">
|
<graph string="Leads Analysis" type="pivot" stacked="True">
|
||||||
<field name="user_id" type="row"/>
|
<field name="user_id" type="row"/>
|
||||||
<field name="create_date" interval="week" type="col"/>
|
<field name="create_date" interval="year" type="col"/>
|
||||||
</graph>
|
</graph>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<graph string="Leads Analysis" type="pivot" stacked="True">
|
<graph string="Leads Analysis" type="pivot" stacked="True">
|
||||||
<field name="date_deadline" type="row"/>
|
<field name="date_deadline" type="row"/>
|
||||||
<field name="user_id" type="col"/>
|
<field name="stage_id" type="col"/>
|
||||||
<field name="planned_revenue" type="measure"/>
|
<field name="planned_revenue" type="measure"/>
|
||||||
</graph>
|
</graph>
|
||||||
</field>
|
</field>
|
||||||
|
@ -45,6 +45,9 @@
|
||||||
<field name="model">crm.lead.report</field>
|
<field name="model">crm.lead.report</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Leads Analysis">
|
<search string="Leads Analysis">
|
||||||
|
<filter name="lead" string="Lead" domain="[('type','=', 'lead')]" help="Show only lead"/>
|
||||||
|
<filter name="opportunity" string="Opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
|
||||||
|
<separator/>
|
||||||
<filter string="New" name="new"
|
<filter string="New" name="new"
|
||||||
domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
|
domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
|
||||||
<filter string="Won" name="won"
|
<filter string="Won" name="won"
|
||||||
|
@ -77,43 +80,37 @@
|
||||||
<field name="date_closed"/>
|
<field name="date_closed"/>
|
||||||
</group>
|
</group>
|
||||||
<group expand="1" string="Group By...">
|
<group expand="1" string="Group By...">
|
||||||
<filter string="Salesperson" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}" />
|
<filter string="Salesperson" domain="[]" context="{'group_by':'user_id'}" />
|
||||||
<filter string="Sales Team" icon="terp-personal+" domain="[]" context="{'group_by':'section_id'}" />
|
<filter string="Sales Team" domain="[]" context="{'group_by':'section_id'}" />
|
||||||
<filter string="Partner" icon="terp-partner" context="{'group_by':'partner_id'}" />
|
<filter string="Partner" context="{'group_by':'partner_id'}" />
|
||||||
<filter string="Country" icon="terp-go-home" context="{'group_by':'country_id'}" />
|
<filter string="Country" context="{'group_by':'country_id'}" />
|
||||||
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
|
<filter string="Company" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
|
||||||
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
|
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
|
||||||
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
|
<filter string="Stage" domain="[]" context="{'group_by':'stage_id'}"/>
|
||||||
<filter string="Campaign" icon="terp-gtk-jump-to-rtl"
|
<filter string="Priority" domain="[]" context="{'group_by':'priority'}" />
|
||||||
domain="[]" context="{'group_by':'type_id'}" />
|
<filter string="Campaign" domain="[]" context="{'group_by':'type_id'}" />
|
||||||
<filter string="Channel" icon="terp-call-start"
|
<filter string="Channel" domain="[]" context="{'group_by':'channel_id'}" />
|
||||||
domain="[]" context="{'group_by':'channel_id'}" />
|
|
||||||
<separator orientation="vertical" />
|
<separator orientation="vertical" />
|
||||||
<filter string="Creation date (day)" icon="terp-go-year"
|
<filter string="Creation date (day)" domain="[]" context="{'group_by':'create_date:day'}"/>
|
||||||
domain="[]" context="{'group_by':'create_date:day'}"/>
|
<filter string="Creation date (week)" domain="[]" context="{'group_by':'create_date:week'}"/>
|
||||||
<filter string="Creation date (week)" icon="terp-go-year"
|
<filter string="Creation date (month)" domain="[]" context="{'group_by':'create_date:month'}" name="month"/>
|
||||||
domain="[]" context="{'group_by':'create_date:week'}"/>
|
<filter string="Creation date (year)" domain="[]" context="{'group_by':'create_date:year'}"/>
|
||||||
<filter string="Creation date (month)" icon="terp-go-year"
|
|
||||||
domain="[]" context="{'group_by':'create_date:month'}" name="month"/>
|
|
||||||
<filter string="Creation date (year)" icon="terp-go-year"
|
|
||||||
domain="[]" context="{'group_by':'create_date:year'}"/>
|
|
||||||
<separator orientation="vertical" />
|
<separator orientation="vertical" />
|
||||||
<filter string="Exp. Closing" icon="terp-go-month"
|
<filter string="Exp. Closing" domain="[]" context="{'group_by':'date_deadline'}"/>
|
||||||
domain="[]" context="{'group_by':'date_deadline'}"/>
|
|
||||||
<filter string="Last Stage Update" context="{'group_by':'date_last_stage_update'}" />
|
<filter string="Last Stage Update" context="{'group_by':'date_last_stage_update'}" />
|
||||||
</group>
|
</group>
|
||||||
</search>
|
</search>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- Leads by user and section Action -->
|
<!-- Leads by user and section Action -->
|
||||||
|
|
||||||
<record id="action_report_crm_lead" model="ir.actions.act_window">
|
<record id="action_report_crm_lead" model="ir.actions.act_window">
|
||||||
<field name="name">Leads Analysis</field>
|
<field name="name">Leads Analysis</field>
|
||||||
<field name="res_model">crm.lead.report</field>
|
<field name="res_model">crm.lead.report</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">graph</field>
|
<field name="view_mode">graph</field>
|
||||||
<field name="domain">[('type','=', 'lead')]</field>
|
<field name="context">{'search_default_lead': 1}</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
<field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
|
<field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.actions.act_window.view" id="action_report_crm_lead_graph">
|
<record model="ir.actions.act_window.view" id="action_report_crm_lead_graph">
|
||||||
|
@ -122,27 +119,25 @@
|
||||||
<field name="view_id" ref="view_report_crm_lead_graph"/>
|
<field name="view_id" ref="view_report_crm_lead_graph"/>
|
||||||
<field name="act_window_id" ref="action_report_crm_lead"/>
|
<field name="act_window_id" ref="action_report_crm_lead"/>
|
||||||
</record>
|
</record>
|
||||||
|
<menuitem name="Leads Analysis" id="menu_report_crm_leads_tree"
|
||||||
|
groups="base.group_sale_manager"
|
||||||
|
parent="base.next_id_64" action="action_report_crm_lead" sequence="1"/>
|
||||||
|
|
||||||
<record id="action_report_crm_opportunity" model="ir.actions.act_window">
|
<record id="action_report_crm_opportunity" model="ir.actions.act_window">
|
||||||
<field name="name">Opportunities Analysis</field>
|
<field name="name">Opportunities Analysis</field>
|
||||||
<field name="res_model">crm.lead.report</field>
|
<field name="res_model">crm.lead.report</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">graph</field>
|
<field name="view_mode">graph</field>
|
||||||
<field name="domain">[('type','=', 'opportunity')]</field>
|
<field name="context">{'search_default_opportunity': 1}</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
|
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.actions.act_window.view" id="action_report_crm_opportunity_graph">
|
<record model="ir.actions.act_window.view" id="action_report_crm_opportunity_graph">
|
||||||
<field name="sequence" eval="2"/>
|
<field name="sequence" eval="2"/>
|
||||||
<field name="view_mode">graph</field>
|
<field name="view_mode">graph</field>
|
||||||
<field name="view_id" ref="view_report_crm_opportunity_graph"/>
|
<field name="view_id" ref="view_report_crm_opportunity_graph"/>
|
||||||
<field name="act_window_id" ref="action_report_crm_opportunity"/>
|
<field name="act_window_id" ref="action_report_crm_opportunity"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<menuitem name="Leads Analysis" id="menu_report_crm_leads_tree"
|
|
||||||
groups="base.group_sale_manager"
|
|
||||||
parent="base.next_id_64" action="action_report_crm_lead" sequence="1"/>
|
|
||||||
|
|
||||||
<menuitem name="Opportunities Analysis" id="menu_report_crm_opportunities_tree"
|
<menuitem name="Opportunities Analysis" id="menu_report_crm_opportunities_tree"
|
||||||
parent="base.next_id_64" action="action_report_crm_opportunity" sequence="5"/>
|
parent="base.next_id_64" action="action_report_crm_opportunity" sequence="5"/>
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
</group>
|
</group>
|
||||||
<group string="Categorization">
|
<group string="Categorization">
|
||||||
<field name="priority"/>
|
<field name="priority"/>
|
||||||
<field name="categ_id" domain="[('object_id.model', '=', 'crm.helpdesk')]"/>
|
<field name="categ_id" domain="[('object_id.model', '=', 'crm.helpdesk')]" context="{'object_name': 'crm.helpdesk'}"/>
|
||||||
<field name="channel_id"/>
|
<field name="channel_id"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
|
|
@ -194,9 +194,9 @@ class delivery_grid(osv.osv):
|
||||||
for line in order.order_line:
|
for line in order.order_line:
|
||||||
if not line.product_id or line.is_delivery:
|
if not line.product_id or line.is_delivery:
|
||||||
continue
|
continue
|
||||||
total += line.price_subtotal or 0.0
|
|
||||||
weight += (line.product_id.weight or 0.0) * line.product_uom_qty
|
weight += (line.product_id.weight or 0.0) * line.product_uom_qty
|
||||||
volume += (line.product_id.volume or 0.0) * line.product_uom_qty
|
volume += (line.product_id.volume or 0.0) * line.product_uom_qty
|
||||||
|
total = order.amount_total or 0.0
|
||||||
|
|
||||||
|
|
||||||
return self.get_price_from_picking(cr, uid, id, total,weight, volume, context=context)
|
return self.get_price_from_picking(cr, uid, id, total,weight, volume, context=context)
|
||||||
|
|
|
@ -431,7 +431,7 @@ class email_template(osv.osv):
|
||||||
is taken from template definition)
|
is taken from template definition)
|
||||||
:returns: a dict containing all relevant fields for creating a new
|
:returns: a dict containing all relevant fields for creating a new
|
||||||
mail.mail entry, with one extra key ``attachments``, in the
|
mail.mail entry, with one extra key ``attachments``, in the
|
||||||
format expected by :py:meth:`mail_thread.message_post`.
|
format [(report_name, data)] where data is base64 encoded.
|
||||||
"""
|
"""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -492,7 +492,8 @@ class email_template(osv.osv):
|
||||||
result, format = self.pool['report'].get_pdf(cr, uid, [res_id], report_service, context=ctx), 'pdf'
|
result, format = self.pool['report'].get_pdf(cr, uid, [res_id], report_service, context=ctx), 'pdf'
|
||||||
else:
|
else:
|
||||||
result, format = openerp.report.render_report(cr, uid, [res_id], report_service, {'model': template.model}, ctx)
|
result, format = openerp.report.render_report(cr, uid, [res_id], report_service, {'model': template.model}, ctx)
|
||||||
|
|
||||||
|
# TODO in trunk, change return format to binary to match message_post expected format
|
||||||
result = base64.b64encode(result)
|
result = base64.b64encode(result)
|
||||||
if not report_name:
|
if not report_name:
|
||||||
report_name = 'report.' + report_service
|
report_name = 'report.' + report_service
|
||||||
|
|
|
@ -62,7 +62,7 @@ class test_message_compose(TestMail):
|
||||||
'name': 'Pigs Template',
|
'name': 'Pigs Template',
|
||||||
'subject': '${object.name}',
|
'subject': '${object.name}',
|
||||||
'body_html': '${object.description}',
|
'body_html': '${object.description}',
|
||||||
'user_signature': True,
|
'user_signature': False,
|
||||||
'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])],
|
'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])],
|
||||||
'email_to': 'b@b.b, c@c.c',
|
'email_to': 'b@b.b, c@c.c',
|
||||||
'email_cc': 'd@d.d'
|
'email_cc': 'd@d.d'
|
||||||
|
@ -157,7 +157,7 @@ class test_message_compose(TestMail):
|
||||||
message_pids = [partner.id for partner in compose.partner_ids]
|
message_pids = [partner.id for partner in compose.partner_ids]
|
||||||
partner_ids = [p_a_id]
|
partner_ids = [p_a_id]
|
||||||
self.assertEqual(compose.subject, '${object.name}', 'mail.compose.message subject incorrect')
|
self.assertEqual(compose.subject, '${object.name}', 'mail.compose.message subject incorrect')
|
||||||
self.assertEqual(compose.body, '<p>${object.description}</p>', 'mail.compose.message body incorrect')
|
self.assertEqual(compose.body, '<p>${object.description}</p>', 'mail.compose.message body incorrect') # todo: check signature
|
||||||
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
|
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
|
||||||
|
|
||||||
# 2. Post the comment, get created message
|
# 2. Post the comment, get created message
|
||||||
|
|
|
@ -87,9 +87,16 @@ class mail_compose_message(osv.TransientModel):
|
||||||
""" - mass_mailing: we cannot render, so return the template values
|
""" - mass_mailing: we cannot render, so return the template values
|
||||||
- normal mode: return rendered values """
|
- normal mode: return rendered values """
|
||||||
if template_id and composition_mode == 'mass_mail':
|
if template_id and composition_mode == 'mass_mail':
|
||||||
fields = ['subject', 'body_html', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id']
|
fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id']
|
||||||
template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
|
template = self.pool['email.template'].browse(cr, uid, template_id, context=context)
|
||||||
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
|
values = dict((field, getattr(template, field)) for field in fields if getattr(template, field))
|
||||||
|
if template.attachment_ids:
|
||||||
|
values['attachment_ids'] = [att.id for att in template.attachment_ids]
|
||||||
|
if template.mail_server_id:
|
||||||
|
values['mail_server_id'] = template.mail_server_id.id
|
||||||
|
if template.user_signature and 'body_html' in values:
|
||||||
|
signature = self.pool.get('res.users').browse(cr, uid, uid, context).signature
|
||||||
|
values['body_html'] = tools.append_content_to_html(values['body_html'], signature)
|
||||||
elif template_id:
|
elif template_id:
|
||||||
values = self.generate_email_for_composer_batch(cr, uid, template_id, [res_id], context=context)[res_id]
|
values = self.generate_email_for_composer_batch(cr, uid, template_id, [res_id], context=context)[res_id]
|
||||||
# transform attachments into attachment_ids; not attached to the document because this will
|
# transform attachments into attachment_ids; not attached to the document because this will
|
||||||
|
|
|
@ -131,7 +131,7 @@ class event_event(osv.osv):
|
||||||
@return: Dictionary of function field values.
|
@return: Dictionary of function field values.
|
||||||
"""
|
"""
|
||||||
event_ids=set()
|
event_ids=set()
|
||||||
for registration in self.browse(cr, uid, ids, context=context):
|
for registration in self.pool['event.registration'].browse(cr, uid, ids, context=context):
|
||||||
event_ids.add(registration.event_id.id)
|
event_ids.add(registration.event_id.id)
|
||||||
return list(event_ids)
|
return list(event_ids)
|
||||||
|
|
||||||
|
@ -317,6 +317,7 @@ class event_registration(osv.osv):
|
||||||
def confirm_registration(self, cr, uid, ids, context=None):
|
def confirm_registration(self, cr, uid, ids, context=None):
|
||||||
for reg in self.browse(cr, uid, ids, context=context or {}):
|
for reg in self.browse(cr, uid, ids, context=context or {}):
|
||||||
self.pool.get('event.event').message_post(cr, uid, [reg.event_id.id], body=_('New registration confirmed: %s.') % (reg.name or '', ),subtype="event.mt_event_registration", context=context)
|
self.pool.get('event.event').message_post(cr, uid, [reg.event_id.id], body=_('New registration confirmed: %s.') % (reg.name or '', ),subtype="event.mt_event_registration", context=context)
|
||||||
|
self.message_post(cr, uid, reg.id, body=_('Event Registration confirmed.'), context=context)
|
||||||
return self.write(cr, uid, ids, {'state': 'open'}, context=context)
|
return self.write(cr, uid, ids, {'state': 'open'}, context=context)
|
||||||
|
|
||||||
def registration_open(self, cr, uid, ids, context=None):
|
def registration_open(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -105,9 +105,9 @@
|
||||||
<field name="phone"/>
|
<field name="phone"/>
|
||||||
<field name="nb_register" />
|
<field name="nb_register" />
|
||||||
<field name="state"/>
|
<field name="state"/>
|
||||||
<button name="registration_open" string="Confirm Registration" states="draft" type="object"/>
|
<button name="registration_open" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/>
|
||||||
<button name="button_reg_close" string="Attended the Event" states="open" type="object"/>
|
<button name="button_reg_close" string="Attended the Event" states="open" type="object" icon="gtk-jump-to"/>
|
||||||
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object"/>
|
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object" icon="gtk-cancel"/>
|
||||||
</tree>
|
</tree>
|
||||||
<form string="Registration">
|
<form string="Registration">
|
||||||
<field name="partner_id" attrs="{'readonly':[('state','!=', 'draft')]}" on_change="onchange_partner_id(partner_id, context)" />
|
<field name="partner_id" attrs="{'readonly':[('state','!=', 'draft')]}" on_change="onchange_partner_id(partner_id, context)" />
|
||||||
|
@ -125,9 +125,9 @@
|
||||||
<separator string="" colspan="4"/>
|
<separator string="" colspan="4"/>
|
||||||
<newline/>
|
<newline/>
|
||||||
<field name="state" colspan="2"/>
|
<field name="state" colspan="2"/>
|
||||||
<button name="registration_open" string="Confirm Registration" states="draft" type="object"/>
|
<button name="registration_open" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/>
|
||||||
<button name="button_reg_close" string="Attended the Event" states="open" type="object"/>
|
<button name="button_reg_close" string="Attended the Event" states="open" type="object" icon="gtk-jump-to"/>
|
||||||
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object"/>
|
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object" icon="gtk-cancel"/>
|
||||||
</group>
|
</group>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
|
@ -333,9 +333,9 @@
|
||||||
<field name="origin"/>
|
<field name="origin"/>
|
||||||
<field name="state"/>
|
<field name="state"/>
|
||||||
<field name="message_unread" invisible="1"/>
|
<field name="message_unread" invisible="1"/>
|
||||||
<button name="registration_open" string="Confirm Registration" states="draft" type="object"/>
|
<button name="registration_open" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/>
|
||||||
<button name="button_reg_close" string="Attended the Event" states="open" type="object"/>
|
<button name="button_reg_close" string="Attended the Event" states="open" type="object" icon="gtk-jump-to"/>
|
||||||
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object"/>
|
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object" icon="gtk-cancel"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -367,7 +367,7 @@
|
||||||
<field name="email" class="oe_inline"/>
|
<field name="email" class="oe_inline"/>
|
||||||
<button class="oe_inline oe_right" string="Send Email"
|
<button class="oe_inline oe_right" string="Send Email"
|
||||||
name="%(mail.action_email_compose_message_wizard)d"
|
name="%(mail.action_email_compose_message_wizard)d"
|
||||||
context= '{"default_email_to":email}' type="action"/>
|
icon="terp-mail-message-new" context= '{"default_email_to":email}' type="action"/>
|
||||||
</div>
|
</div>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
@ -434,6 +434,8 @@
|
||||||
<filter string="Partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
<filter string="Partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||||
<filter string="Event" name="group_event" domain="[]" context="{'group_by':'event_id'}"/>
|
<filter string="Event" name="group_event" domain="[]" context="{'group_by':'event_id'}"/>
|
||||||
<filter string="Status" domain="[]" context="{'group_by':'state'}"/>
|
<filter string="Status" domain="[]" context="{'group_by':'state'}"/>
|
||||||
|
<filter string="Registration Day" domain="[]" context="{'group_by': 'create_date:day'}"/>
|
||||||
|
<filter string="Registration Month" domain="[]" context="{'group_by': 'create_date:month'}"/>
|
||||||
</group>
|
</group>
|
||||||
</search>
|
</search>
|
||||||
</field>
|
</field>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp.addons.event.event import event_event as Event
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
@ -137,6 +138,17 @@ class event_event(osv.osv):
|
||||||
pass
|
pass
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def _get_ticket_events(self, cr, uid, ids, context=None):
|
||||||
|
# `self` is the event.event.ticket model when called by ORM!
|
||||||
|
return list(set(ticket.event_id.id
|
||||||
|
for ticket in self.browse(cr, uid, ids, context)))
|
||||||
|
|
||||||
|
# proxy method, can't import parent method directly as unbound_method: it would receive
|
||||||
|
# an invalid `self` <event_registration> when called by ORM
|
||||||
|
def _events_from_registrations(self, cr, uid, ids, context=None):
|
||||||
|
# `self` is the event.registration model when called by ORM
|
||||||
|
return self.pool['event.event']._get_events_from_registrations(cr, uid, ids, context=context)
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'event_ticket_ids': fields.one2many('event.event.ticket', "event_id", "Event Ticket"),
|
'event_ticket_ids': fields.one2many('event.event.ticket', "event_id", "Event Ticket"),
|
||||||
'seats_max': fields.function(_get_seats_max,
|
'seats_max': fields.function(_get_seats_max,
|
||||||
|
@ -144,7 +156,15 @@ class event_event(osv.osv):
|
||||||
help="The maximum registration level is equal to the sum of the maximum registration of event ticket." +
|
help="The maximum registration level is equal to the sum of the maximum registration of event ticket." +
|
||||||
"If you have too much registrations you are not able to confirm your event. (0 to ignore this rule )",
|
"If you have too much registrations you are not able to confirm your event. (0 to ignore this rule )",
|
||||||
type='integer',
|
type='integer',
|
||||||
readonly=True)
|
readonly=True),
|
||||||
|
'seats_available': fields.function(Event._get_seats, oldname='register_avail', string='Available Seats',
|
||||||
|
type='integer', multi='seats_reserved',
|
||||||
|
store={
|
||||||
|
'event.registration': (_events_from_registrations, ['state'], 10),
|
||||||
|
'event.event': (lambda self, cr, uid, ids, c = {}: ids,
|
||||||
|
['seats_max', 'registration_ids'], 20),
|
||||||
|
'event.event.ticket': (_get_ticket_events, ['seats_max'], 10),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'event_ticket_ids': _get_tickets
|
'event_ticket_ids': _get_tickets
|
||||||
|
@ -167,12 +187,23 @@ class event_ticket(osv.osv):
|
||||||
if ticket.seats_max > 0 else None
|
if ticket.seats_max > 0 else None
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def _is_expired(self, cr, uid, ids, field_name, args, context=None):
|
||||||
|
# FIXME: A ticket is considered expired when the deadline is passed. The deadline should
|
||||||
|
# be considered in the timezone of the event, not the timezone of the user!
|
||||||
|
# Until we add a TZ on the event we'll use the context's current date, more accurate
|
||||||
|
# than using UTC all the time.
|
||||||
|
current_date = fields.date.context_today(self, cr, uid, context=context)
|
||||||
|
return {ticket.id: ticket.deadline and ticket.deadline < current_date
|
||||||
|
for ticket in self.browse(cr, uid, ids, context=context)}
|
||||||
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Name', size=64, required=True, translate=True),
|
'name': fields.char('Name', size=64, 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'),
|
||||||
'deadline': fields.date("Sales End"),
|
'deadline': fields.date("Sales End"),
|
||||||
|
'is_expired': fields.function(_is_expired, type='boolean', string='Is Expired'),
|
||||||
'price': fields.float('Price'),
|
'price': fields.float('Price'),
|
||||||
'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 )"),
|
'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 )"),
|
||||||
'seats_reserved': fields.function(_get_seats, string='Reserved Seats', type='integer', multi='seats_reserved'),
|
'seats_reserved': fields.function(_get_seats, string='Reserved Seats', type='integer', multi='seats_reserved'),
|
||||||
|
|
|
@ -39,6 +39,17 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="view_event_registration_ticket_form">
|
||||||
|
<field name="name">event.registration.ticket.form</field>
|
||||||
|
<field name="model">event.registration</field>
|
||||||
|
<field name="inherit_id" ref="event.view_event_registration_form" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="user_id" position="after">
|
||||||
|
<field name="event_ticket_id" domain="[('event_id', '=', event_id)]"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="event_sale_product_template_form">
|
<record model="ir.ui.view" id="event_sale_product_template_form">
|
||||||
<field name="model">product.template</field>
|
<field name="model">product.template</field>
|
||||||
<field name="inherit_id" ref="product.product_template_form_view" />
|
<field name="inherit_id" ref="product.product_template_form_view" />
|
||||||
|
|
|
@ -41,10 +41,6 @@
|
||||||
<field name="description">Badge Granted</field>
|
<field name="description">Badge Granted</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
|
||||||
|
|
||||||
|
|
||||||
<data noupdate="0">
|
|
||||||
|
|
||||||
<record id="email_template_badge_received" model="email.template">
|
<record id="email_template_badge_received" model="email.template">
|
||||||
<field name="name">Received Badge</field>
|
<field name="name">Received Badge</field>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data noupdate="1">
|
||||||
<record forcecreate="True" id="ir_cron_check_challenge"
|
<record forcecreate="True" id="ir_cron_check_challenge"
|
||||||
model="ir.cron">
|
model="ir.cron">
|
||||||
<field name="name">Run Goal Challenge Checker</field>
|
<field name="name">Run Goal Challenge Checker</field>
|
||||||
|
|
|
@ -90,10 +90,6 @@
|
||||||
]]></field>
|
]]></field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<data>
|
|
||||||
|
|
||||||
<!-- goal definitions -->
|
<!-- goal definitions -->
|
||||||
<record model="gamification.goal.definition" id="definition_base_timezone">
|
<record model="gamification.goal.definition" id="definition_base_timezone">
|
||||||
<field name="name">Set your Timezone</field>
|
<field name="name">Set your Timezone</field>
|
||||||
|
|
|
@ -200,7 +200,6 @@ class gamification_challenge(osv.Model):
|
||||||
'visibility_mode': 'personal',
|
'visibility_mode': 'personal',
|
||||||
'report_message_frequency': 'never',
|
'report_message_frequency': 'never',
|
||||||
'last_report_date': fields.date.today,
|
'last_report_date': fields.date.today,
|
||||||
'start_date': fields.date.today,
|
|
||||||
'manager_id': lambda s, cr, uid, c: uid,
|
'manager_id': lambda s, cr, uid, c: uid,
|
||||||
'category': 'hr',
|
'category': 'hr',
|
||||||
'reward_failure': False,
|
'reward_failure': False,
|
||||||
|
@ -269,13 +268,15 @@ class gamification_challenge(osv.Model):
|
||||||
planned_challenge_ids = self.search(cr, uid, [
|
planned_challenge_ids = self.search(cr, uid, [
|
||||||
('state', '=', 'draft'),
|
('state', '=', 'draft'),
|
||||||
('start_date', '<=', fields.date.today())])
|
('start_date', '<=', fields.date.today())])
|
||||||
self.write(cr, uid, planned_challenge_ids, {'state': 'inprogress'}, context=context)
|
if planned_challenge_ids:
|
||||||
|
self.write(cr, uid, planned_challenge_ids, {'state': 'inprogress'}, context=context)
|
||||||
|
|
||||||
# close scheduled challenges
|
# close scheduled challenges
|
||||||
planned_challenge_ids = self.search(cr, uid, [
|
planned_challenge_ids = self.search(cr, uid, [
|
||||||
('state', '=', 'inprogress'),
|
('state', '=', 'inprogress'),
|
||||||
('end_date', '>=', fields.date.today())])
|
('end_date', '>=', fields.date.today())])
|
||||||
self.write(cr, uid, planned_challenge_ids, {'state': 'done'}, context=context)
|
if planned_challenge_ids:
|
||||||
|
self.write(cr, uid, planned_challenge_ids, {'state': 'done'}, context=context)
|
||||||
|
|
||||||
if not ids:
|
if not ids:
|
||||||
ids = self.search(cr, uid, [('state', '=', 'inprogress')], context=context)
|
ids = self.search(cr, uid, [('state', '=', 'inprogress')], context=context)
|
||||||
|
|
|
@ -39,5 +39,12 @@
|
||||||
<field name="domain_force">[(1, '=', 1)]</field>
|
<field name="domain_force">[(1, '=', 1)]</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="goal_global_multicompany" model="ir.rule">
|
||||||
|
<field name="name">User can only see his/her goals or goal from the same challenge in board visibility</field>
|
||||||
|
<field name="model_id" ref="model_gamification_goal"/>
|
||||||
|
<field name="domain_force">[('user_id.company_id', 'child_of', [user.company_id.id])]</field>
|
||||||
|
<field name="global" eval="True"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -118,7 +118,7 @@ openerp.gamification = function(instance) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.mail.Widget.include({
|
instance.mail.Wall.include({
|
||||||
start: function() {
|
start: function() {
|
||||||
this._super();
|
this._super();
|
||||||
var sidebar = new instance.gamification.Sidebar(this);
|
var sidebar = new instance.gamification.Sidebar(this);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data noupdate="1">
|
||||||
|
|
||||||
<!-- goal definitions -->
|
<!-- goal definitions -->
|
||||||
<record model="gamification.goal.definition" id="definition_crm_tot_invoices">
|
<record model="gamification.goal.definition" id="definition_crm_tot_invoices">
|
||||||
|
|
|
@ -4,18 +4,6 @@
|
||||||
|
|
||||||
<!-- challenges -->
|
<!-- challenges -->
|
||||||
<record model="gamification.challenge" id="challenge_crm_sale">
|
<record model="gamification.challenge" id="challenge_crm_sale">
|
||||||
<field name="user_ids" eval="[(4,ref('base.user_demo'))]" />
|
|
||||||
<field name="state">inprogress</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- goals -->
|
|
||||||
<record model="gamification.goal" id="goal_crm_sale1">
|
|
||||||
<field name="definition_id" eval="ref('definition_crm_tot_invoices')" />
|
|
||||||
<field name="user_id" eval="ref('base.user_demo')" />
|
|
||||||
<field name="line_id" eval="ref('line_crm_sale1')" />
|
|
||||||
<field name="start_date" eval="time.strftime('%Y-%m-01')" />
|
|
||||||
<field name="end_date" eval="(DateTime.today().replace(day=1)+relativedelta(months=1, days=-1)).strftime('%Y-%m-%d')" />
|
|
||||||
<field name="target_goal">2000</field>
|
|
||||||
<field name="state">inprogress</field>
|
<field name="state">inprogress</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ Get all your HR operations managed easily: knowledge sharing, recruitments, appr
|
||||||
<h2 class="oe_slogan">Manage Your Employees</h2>
|
<h2 class="oe_slogan">Manage Your Employees</h2>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
Oversee all important information in your company address book. Some information are restricted to HR managers, others are public to easily find colleagues.
|
Oversee all important information in your company address book. Some information are restricted to HR managers, others are public to easily look colleagues.
|
||||||
</p><p>
|
</p><p>
|
||||||
Record employee contracts and get alerts when they have to be renewed.
|
Record employee contracts and get alerts when they have to be renewed.
|
||||||
</p>
|
</p>
|
||||||
|
@ -154,7 +154,7 @@ Inspire achievement with challenges, goals and rewards. Define clear objectives
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_span4 oe_centered">
|
<div class="oe_span4 oe_centered">
|
||||||
<h3>Personnal Objectives</h3>
|
<h3>Personal Objectives</h3>
|
||||||
<div class="oe_row_img">
|
<div class="oe_row_img">
|
||||||
<img class="oe_picture" src="crm_game_02.png">
|
<img class="oe_picture" src="crm_game_02.png">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,19 +10,7 @@
|
||||||
<record id="survey.menu_surveys" model="ir.ui.menu">
|
<record id="survey.menu_surveys" model="ir.ui.menu">
|
||||||
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
||||||
</record>
|
</record>
|
||||||
<record id="survey.menu_define_survey" model="ir.ui.menu">
|
<record id="survey.menu_surveys_configuration" model="ir.ui.menu">
|
||||||
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
|
||||||
</record>
|
|
||||||
<record id="survey.menu_survey_form" model="ir.ui.menu">
|
|
||||||
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
|
||||||
</record>
|
|
||||||
<record id="survey.menu_survey_page_form1" model="ir.ui.menu">
|
|
||||||
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
|
||||||
</record>
|
|
||||||
<record id="survey.menu_survey_type_form1" model="ir.ui.menu">
|
|
||||||
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
|
||||||
</record>
|
|
||||||
<record id="survey.menu_answer_surveys" model="ir.ui.menu">
|
|
||||||
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
<field eval="[(4,ref('base.group_hr_manager'))]" name="groups_id"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<td>
|
<td>
|
||||||
<span t-field="line.name"/>
|
<span t-field="line.name"/>
|
||||||
<span t-field="line.description"/><br/>
|
<span t-field="line.description"/><br/>
|
||||||
<span t-field="line.analytic_account.complete_name"/>
|
<span t-field="line.analytic_account.complete_name" t-if="line.analytic_account"/>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-center">
|
<td style="text-center">
|
||||||
<span t-field="line.ref"/>
|
<span t-field="line.ref"/>
|
||||||
|
|
|
@ -20,10 +20,11 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
class hr_timesheet_sheet(osv.osv):
|
class hr_timesheet_sheet(osv.osv):
|
||||||
|
@ -62,28 +63,56 @@ class hr_timesheet_sheet(osv.osv):
|
||||||
def copy(self, cr, uid, ids, *args, **argv):
|
def copy(self, cr, uid, ids, *args, **argv):
|
||||||
raise osv.except_osv(_('Error!'), _('You cannot duplicate a timesheet.'))
|
raise osv.except_osv(_('Error!'), _('You cannot duplicate a timesheet.'))
|
||||||
|
|
||||||
def create(self, cr, uid, vals, *args, **argv):
|
def create(self, cr, uid, vals, context=None):
|
||||||
if 'employee_id' in vals:
|
if 'employee_id' in vals:
|
||||||
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).user_id:
|
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context).user_id:
|
||||||
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.'))
|
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.'))
|
||||||
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).product_id:
|
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context).product_id:
|
||||||
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product, like \'Consultant\'.'))
|
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product, like \'Consultant\'.'))
|
||||||
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).journal_id:
|
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context).journal_id:
|
||||||
raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.'))
|
raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.'))
|
||||||
return super(hr_timesheet_sheet, self).create(cr, uid, vals, *args, **argv)
|
if vals.get('attendances_ids'):
|
||||||
|
# If attendances, we sort them by date asc before writing them, to satisfy the alternance constraint
|
||||||
|
vals['attendances_ids'] = self.sort_attendances(cr, uid, vals['attendances_ids'], context=context)
|
||||||
|
return super(hr_timesheet_sheet, self).create(cr, uid, vals, context=context)
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, *args, **argv):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
if 'employee_id' in vals:
|
if 'employee_id' in vals:
|
||||||
new_user_id = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).user_id.id or False
|
new_user_id = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context).user_id.id or False
|
||||||
if not new_user_id:
|
if not new_user_id:
|
||||||
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.'))
|
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.'))
|
||||||
if not self._sheet_date(cr, uid, ids, forced_user_id=new_user_id):
|
if not self._sheet_date(cr, uid, ids, forced_user_id=new_user_id, context=context):
|
||||||
raise osv.except_osv(_('Error!'), _('You cannot have 2 timesheets that overlap!\nYou should use the menu \'My Timesheet\' to avoid this problem.'))
|
raise osv.except_osv(_('Error!'), _('You cannot have 2 timesheets that overlap!\nYou should use the menu \'My Timesheet\' to avoid this problem.'))
|
||||||
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).product_id:
|
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context).product_id:
|
||||||
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product.'))
|
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product.'))
|
||||||
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).journal_id:
|
if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id'], context=context).journal_id:
|
||||||
raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.'))
|
raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.'))
|
||||||
return super(hr_timesheet_sheet, self).write(cr, uid, ids, vals, *args, **argv)
|
if vals.get('attendances_ids'):
|
||||||
|
# If attendances, we sort them by date asc before writing them, to satisfy the alternance constraint
|
||||||
|
# In addition to the date order, deleting attendances are done before inserting attendances
|
||||||
|
vals['attendances_ids'] = self.sort_attendances(cr, uid, vals['attendances_ids'], context=context)
|
||||||
|
res = super(hr_timesheet_sheet, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
if vals.get('attendances_ids'):
|
||||||
|
for timesheet in self.browse(cr, uid, ids):
|
||||||
|
if not self.pool['hr.attendance']._altern_si_so(cr, uid, [att.id for att in timesheet.attendances_ids]):
|
||||||
|
raise osv.except_osv(_('Warning !'), _('Error ! Sign in (resp. Sign out) must follow Sign out (resp. Sign in)'))
|
||||||
|
return res
|
||||||
|
|
||||||
|
def sort_attendances(self, cr, uid, attendance_tuples, context=None):
|
||||||
|
date_attendances = []
|
||||||
|
for att_tuple in attendance_tuples:
|
||||||
|
if att_tuple[0] in [0,1,4]:
|
||||||
|
if att_tuple[0] in [0,1]:
|
||||||
|
name = att_tuple[2]['name']
|
||||||
|
else:
|
||||||
|
name = self.pool['hr.attendance'].browse(cr, uid, att_tuple[1]).name
|
||||||
|
date_attendances.append((1, name, att_tuple))
|
||||||
|
elif att_tuple[0] in [2,3]:
|
||||||
|
date_attendances.append((0, self.pool['hr.attendance'].browse(cr, uid, att_tuple[1]).name, att_tuple))
|
||||||
|
else:
|
||||||
|
date_attendances.append((0, False, att_tuple))
|
||||||
|
date_attendances.sort()
|
||||||
|
return [att[2] for att in date_attendances]
|
||||||
|
|
||||||
def button_confirm(self, cr, uid, ids, context=None):
|
def button_confirm(self, cr, uid, ids, context=None):
|
||||||
for sheet in self.browse(cr, uid, ids, context=context):
|
for sheet in self.browse(cr, uid, ids, context=context):
|
||||||
|
@ -368,18 +397,22 @@ class hr_attendance(osv.osv):
|
||||||
attendance_ids.extend([row[0] for row in cr.fetchall()])
|
attendance_ids.extend([row[0] for row in cr.fetchall()])
|
||||||
return attendance_ids
|
return attendance_ids
|
||||||
|
|
||||||
|
def _get_current_sheet(self, cr, uid, employee_id, date=False, context=None):
|
||||||
|
if not date:
|
||||||
|
date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
|
# ending date with no time to avoid timesheet with early date_to
|
||||||
|
date_to = date[0:10]+' 00:00:00'
|
||||||
|
# limit=1 because only one sheet possible for an employee between 2 dates
|
||||||
|
sheet_ids = self.pool.get('hr_timesheet_sheet.sheet').search(cr, uid, [
|
||||||
|
('date_to', '>=', date_to), ('date_from', '<=', date),
|
||||||
|
('employee_id', '=', employee_id)
|
||||||
|
], limit=1, context=context)
|
||||||
|
return sheet_ids and sheet_ids[0] or False
|
||||||
|
|
||||||
def _sheet(self, cursor, user, ids, name, args, context=None):
|
def _sheet(self, cursor, user, ids, name, args, context=None):
|
||||||
sheet_obj = self.pool.get('hr_timesheet_sheet.sheet')
|
|
||||||
res = {}.fromkeys(ids, False)
|
res = {}.fromkeys(ids, False)
|
||||||
for attendance in self.browse(cursor, user, ids, context=context):
|
for attendance in self.browse(cursor, user, ids, context=context):
|
||||||
date_to = datetime.strftime(datetime.strptime(attendance.name[0:10], '%Y-%m-%d'), '%Y-%m-%d %H:%M:%S')
|
res[attendance.id] = self._get_current_sheet(cursor, user, attendance.employee_id.id, attendance.name, context=context)
|
||||||
sheet_ids = sheet_obj.search(cursor, user,
|
|
||||||
[('date_to', '>=', date_to), ('date_from', '<=', attendance.name),
|
|
||||||
('employee_id', '=', attendance.employee_id.id)],
|
|
||||||
context=context)
|
|
||||||
if sheet_ids:
|
|
||||||
# [0] because only one sheet possible for an employee between 2 dates
|
|
||||||
res[attendance.id] = sheet_obj.name_get(cursor, user, sheet_ids, context=context)[0]
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -398,16 +431,15 @@ class hr_attendance(osv.osv):
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if 'sheet_id' in context:
|
|
||||||
ts = self.pool.get('hr_timesheet_sheet.sheet').browse(cr, uid, context['sheet_id'], context=context)
|
sheet_id = context.get('sheet_id') or self._get_current_sheet(cr, uid, vals.get('employee_id'), vals.get('name'), context=context)
|
||||||
|
if sheet_id:
|
||||||
|
ts = self.pool.get('hr_timesheet_sheet.sheet').browse(cr, uid, sheet_id, context=context)
|
||||||
if ts.state not in ('draft', 'new'):
|
if ts.state not in ('draft', 'new'):
|
||||||
raise osv.except_osv(_('Error!'), _('You cannot modify an entry in a confirmed timesheet.'))
|
raise osv.except_osv(_('Error!'), _('You can not enter an attendance in a submitted timesheet. Ask your manager to reset it before adding attendance.'))
|
||||||
res = super(hr_attendance,self).create(cr, uid, vals, context=context)
|
elif ts.date_from > vals.get('name') or ts.date_to < vals.get('name'):
|
||||||
if 'sheet_id' in context:
|
raise osv.except_osv(_('User Error!'), _('You can not enter an attendance date outside the current timesheet dates.'))
|
||||||
if context['sheet_id'] != self.browse(cr, uid, res, context=context).sheet_id.id:
|
return super(hr_attendance,self).create(cr, uid, vals, context=context)
|
||||||
raise osv.except_osv(_('User Error!'), _('You cannot enter an attendance ' \
|
|
||||||
'date outside the current timesheet dates.'))
|
|
||||||
return res
|
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, *args, **kwargs):
|
def unlink(self, cr, uid, ids, *args, **kwargs):
|
||||||
if isinstance(ids, (int, long)):
|
if isinstance(ids, (int, long)):
|
||||||
|
|
|
@ -17,38 +17,14 @@
|
||||||
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="lunch_mind_your_own_food" model="ir.rule">
|
|
||||||
<field name="name">lunch.order: do not see and create other people's order</field>
|
|
||||||
<field name="model_id" ref="model_lunch_order"/>
|
|
||||||
<field name="groups" eval="[(4, ref('group_lunch_user'))]"/>
|
|
||||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
|
||||||
</record>
|
|
||||||
<record id="lunch_mind_other_food" model="ir.rule">
|
|
||||||
<field name="name">lunch.order: do not see and create other people's order</field>
|
|
||||||
<field name="model_id" ref="model_lunch_order"/>
|
|
||||||
<field name="groups" eval="[(4, ref('group_lunch_manager'))]"/>
|
|
||||||
<field name="domain_force">[(1, '=', 1)]</field>
|
|
||||||
</record>
|
|
||||||
<record id="lunch_mind_your_own_food_line" model="ir.rule">
|
|
||||||
<field name="name">lunch.order.line: do not see and create other people's order line</field>
|
|
||||||
<field name="model_id" ref="model_lunch_order_line"/>
|
|
||||||
<field name="groups" eval="[(4, ref('group_lunch_user'))]"/>
|
|
||||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
|
||||||
</record>
|
|
||||||
<record id="lunch_mind_other_food_line" model="ir.rule">
|
|
||||||
<field name="name">lunch.order.line: do not see and create other people's order line</field>
|
|
||||||
<field name="model_id" ref="model_lunch_order_line"/>
|
|
||||||
<field name="groups" eval="[(4, ref('group_lunch_manager'))]"/>
|
|
||||||
<field name="domain_force">[(1, '=', 1)]</field>
|
|
||||||
</record>
|
|
||||||
<record id="lunch_mind_your_own_food_money" model="ir.rule">
|
<record id="lunch_mind_your_own_food_money" model="ir.rule">
|
||||||
<field name="name">lunch.cashmove: do not see and create other people's cashmove</field>
|
<field name="name">lunch.cashmove: do not see other people's cashmove</field>
|
||||||
<field name="model_id" ref="model_lunch_cashmove"/>
|
<field name="model_id" ref="model_lunch_cashmove"/>
|
||||||
<field name="groups" eval="[(4, ref('group_lunch_user'))]"/>
|
<field name="groups" eval="[(4, ref('group_lunch_user'))]"/>
|
||||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="lunch_mind_other_food_money" model="ir.rule">
|
<record id="lunch_mind_other_food_money" model="ir.rule">
|
||||||
<field name="name">lunch.cashmove: do not see and create other people's cashmove</field>
|
<field name="name">lunch.cashmove: do see other people's cashmove</field>
|
||||||
<field name="model_id" ref="model_lunch_cashmove"/>
|
<field name="model_id" ref="model_lunch_cashmove"/>
|
||||||
<field name="groups" eval="[(4, ref('group_lunch_manager'))]"/>
|
<field name="groups" eval="[(4, ref('group_lunch_manager'))]"/>
|
||||||
<field name="domain_force">[(1, '=', 1)]</field>
|
<field name="domain_force">[(1, '=', 1)]</field>
|
||||||
|
|
|
@ -135,7 +135,7 @@ class mail_mail(osv.Model):
|
||||||
:param browse_record mail: the mail that was just sent
|
:param browse_record mail: the mail that was just sent
|
||||||
:return: True
|
:return: True
|
||||||
"""
|
"""
|
||||||
if mail.auto_delete:
|
if mail_sent and mail.auto_delete:
|
||||||
# done with SUPERUSER_ID to avoid giving large unlink access rights
|
# done with SUPERUSER_ID to avoid giving large unlink access rights
|
||||||
self.unlink(cr, SUPERUSER_ID, [mail.id], context=context)
|
self.unlink(cr, SUPERUSER_ID, [mail.id], context=context)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
<field name="model">mail.mail</field>
|
<field name="model">mail.mail</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Email Search">
|
<search string="Email Search">
|
||||||
<field name="email_from" filter_domain="['|' '|',('email_from','ilike',self), ('email_to','ilike',self), ('subject','ilike',self)]" string="Email"/>
|
<field name="email_from" filter_domain="['|', '|',('email_from','ilike',self), ('email_to','ilike',self), ('subject','ilike',self)]" string="Email"/>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<filter icon="terp-camera_test" name="received" string="Received" domain="[('state','=','received')]"/>
|
<filter icon="terp-camera_test" name="received" string="Received" domain="[('state','=','received')]"/>
|
||||||
<filter icon="terp-call-start" name="outgoing" string="Outgoing" domain="[('state','=','outgoing')]"/>
|
<filter icon="terp-call-start" name="outgoing" string="Outgoing" domain="[('state','=','outgoing')]"/>
|
||||||
|
|
|
@ -14,7 +14,7 @@ class MassMailController(http.Controller):
|
||||||
mail_mail_stats.set_opened(request.cr, SUPERUSER_ID, mail_mail_ids=[mail_id])
|
mail_mail_stats.set_opened(request.cr, SUPERUSER_ID, mail_mail_ids=[mail_id])
|
||||||
response = werkzeug.wrappers.Response()
|
response = werkzeug.wrappers.Response()
|
||||||
response.mimetype = 'image/gif'
|
response.mimetype = 'image/gif'
|
||||||
response.set_data('R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='.decode('base64'))
|
response.data = 'R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='.decode('base64')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@http.route(['/mail/mailing/<int:mailing_id>/unsubscribe'], type='http', auth='none')
|
@http.route(['/mail/mailing/<int:mailing_id>/unsubscribe'], type='http', auth='none')
|
||||||
|
|
|
@ -271,9 +271,9 @@ class MassMailing(osv.Model):
|
||||||
date_begin_str = date_begin.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
date_begin_str = date_begin.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
date_end_str = date_end.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
date_end_str = date_end.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
domain = [('mass_mailing_id', '=', mailing.id), ('opened', '>=', date_begin_str), ('opened', '<=', date_end_str)]
|
domain = [('mass_mailing_id', '=', mailing.id), ('opened', '>=', date_begin_str), ('opened', '<=', date_end_str)]
|
||||||
res[mailing.id]['opened_dayly'] = json.dumps(self.__get_bar_values(cr, uid, obj, domain, ['opened'], 'opened_count', 'opened:day', date_begin, context=context))
|
res[mailing.id]['opened_daily'] = json.dumps(self.__get_bar_values(cr, uid, obj, domain, ['opened'], 'opened_count', 'opened:day', date_begin, context=context))
|
||||||
domain = [('mass_mailing_id', '=', mailing.id), ('replied', '>=', date_begin_str), ('replied', '<=', date_end_str)]
|
domain = [('mass_mailing_id', '=', mailing.id), ('replied', '>=', date_begin_str), ('replied', '<=', date_end_str)]
|
||||||
res[mailing.id]['replied_dayly'] = json.dumps(self.__get_bar_values(cr, uid, obj, domain, ['replied'], 'replied_count', 'replied:day', date_begin, context=context))
|
res[mailing.id]['replied_daily'] = json.dumps(self.__get_bar_values(cr, uid, obj, domain, ['replied'], 'replied_count', 'replied:day', date_begin, context=context))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _get_statistics(self, cr, uid, ids, name, arg, context=None):
|
def _get_statistics(self, cr, uid, ids, name, arg, context=None):
|
||||||
|
@ -314,7 +314,7 @@ class MassMailing(osv.Model):
|
||||||
'name': fields.char('Subject', required=True),
|
'name': fields.char('Subject', required=True),
|
||||||
'email_from': fields.char('From', required=True),
|
'email_from': fields.char('From', required=True),
|
||||||
'create_date': fields.datetime('Creation Date'),
|
'create_date': fields.datetime('Creation Date'),
|
||||||
'sent_date': fields.datetime('Sent Date'),
|
'sent_date': fields.datetime('Sent Date', oldname='date'),
|
||||||
'body_html': fields.html('Body'),
|
'body_html': fields.html('Body'),
|
||||||
'attachment_ids': fields.many2many(
|
'attachment_ids': fields.many2many(
|
||||||
'ir.attachment', 'mass_mailing_ir_attachments_rel',
|
'ir.attachment', 'mass_mailing_ir_attachments_rel',
|
||||||
|
@ -340,7 +340,7 @@ class MassMailing(osv.Model):
|
||||||
'reply_to': fields.char('Reply To', help='Preferred Reply-To Address'),
|
'reply_to': fields.char('Reply To', help='Preferred Reply-To Address'),
|
||||||
# recipients
|
# recipients
|
||||||
'mailing_model': fields.selection(_mailing_model, string='Recipients Model', required=True),
|
'mailing_model': fields.selection(_mailing_model, string='Recipients Model', required=True),
|
||||||
'mailing_domain': fields.char('Domain'),
|
'mailing_domain': fields.char('Domain', oldname='domain'),
|
||||||
'contact_list_ids': fields.many2many(
|
'contact_list_ids': fields.many2many(
|
||||||
'mail.mass_mailing.list', 'mail_mass_mailing_list_rel',
|
'mail.mass_mailing.list', 'mail_mass_mailing_list_rel',
|
||||||
string='Mailing Lists',
|
string='Mailing Lists',
|
||||||
|
@ -398,16 +398,14 @@ class MassMailing(osv.Model):
|
||||||
_get_statistics, string='Replied Ratio',
|
_get_statistics, string='Replied Ratio',
|
||||||
type='integer', multi='_get_statistics',
|
type='integer', multi='_get_statistics',
|
||||||
),
|
),
|
||||||
# dayly ratio
|
# daily ratio
|
||||||
'opened_dayly': fields.function(
|
'opened_daily': fields.function(
|
||||||
_get_daily_statistics, string='Opened',
|
_get_daily_statistics, string='Opened',
|
||||||
type='char', multi='_get_daily_statistics',
|
type='char', multi='_get_daily_statistics',
|
||||||
oldname='opened_monthly',
|
|
||||||
),
|
),
|
||||||
'replied_dayly': fields.function(
|
'replied_daily': fields.function(
|
||||||
_get_daily_statistics, string='Replied',
|
_get_daily_statistics, string='Replied',
|
||||||
type='char', multi='_get_daily_statistics',
|
type='char', multi='_get_daily_statistics',
|
||||||
oldname='replied_monthly',
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,23 +19,8 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from dateutil import relativedelta
|
|
||||||
import random
|
|
||||||
try:
|
|
||||||
import simplejson as json
|
|
||||||
except ImportError:
|
|
||||||
import json
|
|
||||||
import urllib
|
|
||||||
import urlparse
|
|
||||||
|
|
||||||
from openerp import tools
|
|
||||||
from openerp.exceptions import Warning
|
|
||||||
from openerp.tools.safe_eval import safe_eval as eval
|
|
||||||
from openerp.tools.translate import _
|
|
||||||
from openerp.osv import osv, fields
|
from openerp.osv import osv, fields
|
||||||
|
|
||||||
|
|
||||||
class MailMailStats(osv.Model):
|
class MailMailStats(osv.Model):
|
||||||
""" MailMailStats models the statistics collected about emails. Those statistics
|
""" MailMailStats models the statistics collected about emails. Those statistics
|
||||||
are stored in a separated model and table to avoid bloating the mail_mail table
|
are stored in a separated model and table to avoid bloating the mail_mail table
|
||||||
|
@ -48,11 +33,7 @@ class MailMailStats(osv.Model):
|
||||||
_order = 'message_id'
|
_order = 'message_id'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'mail_mail_id': fields.integer(
|
'mail_mail_id': fields.many2one('mail.mail', 'Mail ID', ondelete='set null'),
|
||||||
'Mail ID',
|
|
||||||
help='ID of the related mail_mail. This field is an integer field because'
|
|
||||||
'the related mail_mail can be deleted separately from its statistics.'
|
|
||||||
),
|
|
||||||
'message_id': fields.char('Message-ID'),
|
'message_id': fields.char('Message-ID'),
|
||||||
'model': fields.char('Document model'),
|
'model': fields.char('Document model'),
|
||||||
'res_id': fields.integer('Document ID'),
|
'res_id': fields.integer('Document ID'),
|
||||||
|
@ -106,4 +87,3 @@ class MailMailStats(osv.Model):
|
||||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('bounced', '=', False)], context)
|
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('bounced', '=', False)], context)
|
||||||
self.write(cr, uid, stat_ids, {'bounced': fields.datetime.now()}, context=context)
|
self.write(cr, uid, stat_ids, {'bounced': fields.datetime.now()}, context=context)
|
||||||
return stat_ids
|
return stat_ids
|
||||||
|
|
||||||
|
|
|
@ -215,11 +215,11 @@
|
||||||
</button>
|
</button>
|
||||||
<button name="%(action_view_mass_mailing_contacts)d"
|
<button name="%(action_view_mass_mailing_contacts)d"
|
||||||
type="action" class="oe_stat_button oe_inline">
|
type="action" class="oe_stat_button oe_inline">
|
||||||
<field name="opened_dayly" string="Opened Daily" widget="barchart"/>
|
<field name="opened_daily" string="Opened Daily" widget="barchart"/>
|
||||||
</button>
|
</button>
|
||||||
<button name="%(action_view_mass_mailing_contacts)d"
|
<button name="%(action_view_mass_mailing_contacts)d"
|
||||||
type="action" class="oe_stat_button oe_inline">
|
type="action" class="oe_stat_button oe_inline">
|
||||||
<field name="replied_dayly" string="Replied Daily" widget="barchart"/>
|
<field name="replied_daily" string="Replied Daily" widget="barchart"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_button_box" attrs="{'invisible': [('total', '=', 0)]}" style="margin-bottom: 32px">
|
<div class="oe_button_box" attrs="{'invisible': [('total', '=', 0)]}" style="margin-bottom: 32px">
|
||||||
|
|
|
@ -63,7 +63,7 @@ manufacturing orders.
|
||||||
|
|
||||||
<section class="oe_container oe_dark">
|
<section class="oe_container oe_dark">
|
||||||
<div class="oe_row oe_spaced">
|
<div class="oe_row oe_spaced">
|
||||||
<h2 class="oe_slogan">Get Flexibility In All Opertions</h2>
|
<h2 class="oe_slogan">Get Flexibility In All Operations</h2>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class="oe_mt32">
|
<p class="oe_mt32">
|
||||||
Edit manually all proposed operations at any level of the progress.
|
Edit manually all proposed operations at any level of the progress.
|
||||||
|
@ -110,7 +110,7 @@ meets your delivery schedule dates.
|
||||||
<div class="oe_span12">
|
<div class="oe_span12">
|
||||||
<p>
|
<p>
|
||||||
Organize manufacturing orders and work orders the way you like it. Process next
|
Organize manufacturing orders and work orders the way you like it. Process next
|
||||||
orders from the list view, control inthe calendar view and edit the proposed
|
orders from the list view, control in the calendar view and edit the proposed
|
||||||
schedule in the Gantt view.
|
schedule in the Gantt view.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
This module allows users to create their own notes inside OpenERP
|
This module allows users to create their own notes inside OpenERP
|
||||||
=================================================================
|
=================================================================
|
||||||
|
|
||||||
Use notes to write meeting minutes, organize ideas, organize personnal todo
|
Use notes to write meeting minutes, organize ideas, organize personal todo
|
||||||
lists, etc. Each user manages his own personnal Notes. Notes are available to
|
lists, etc. Each user manages his own personal Notes. Notes are available to
|
||||||
their authors only, but they can share notes to others users so that several
|
their authors only, but they can share notes to others users so that several
|
||||||
people can work on the same note in real time. It's very efficient to share
|
people can work on the same note in real time. It's very efficient to share
|
||||||
meeting minutes.
|
meeting minutes.
|
||||||
|
|
|
@ -123,16 +123,15 @@ class note_note(osv.osv):
|
||||||
current_stage_ids = self.pool.get('note.stage').search(cr,uid,[('user_id','=',uid)], context=context)
|
current_stage_ids = self.pool.get('note.stage').search(cr,uid,[('user_id','=',uid)], context=context)
|
||||||
|
|
||||||
if current_stage_ids: #if the user have some stages
|
if current_stage_ids: #if the user have some stages
|
||||||
|
stages = self.pool['note.stage'].browse(cr, uid, current_stage_ids, context=context)
|
||||||
#dict of stages: map les ids sur les noms
|
|
||||||
stage_name = dict(self.pool.get('note.stage').name_get(cr, uid, current_stage_ids, context=context))
|
|
||||||
|
|
||||||
result = [{ #notes by stage for stages user
|
result = [{ #notes by stage for stages user
|
||||||
'__context': {'group_by': groupby[1:]},
|
'__context': {'group_by': groupby[1:]},
|
||||||
'__domain': domain + [('stage_ids.id', '=', current_stage_id)],
|
'__domain': domain + [('stage_ids.id', '=', stage.id)],
|
||||||
'stage_id': (current_stage_id, stage_name[current_stage_id]),
|
'stage_id': (stage.id, stage.name),
|
||||||
'stage_id_count': self.search(cr,uid, domain+[('stage_ids', '=', current_stage_id)], context=context, count=True)
|
'stage_id_count': self.search(cr,uid, domain+[('stage_ids', '=', stage.id)], context=context, count=True),
|
||||||
} for current_stage_id in current_stage_ids]
|
'__fold': stage.fold,
|
||||||
|
} for stage in stages]
|
||||||
|
|
||||||
#note without user's stage
|
#note without user's stage
|
||||||
nb_notes_ws = self.search(cr,uid, domain+[('stage_ids', 'not in', current_stage_ids)], context=context, count=True)
|
nb_notes_ws = self.search(cr,uid, domain+[('stage_ids', 'not in', current_stage_ids)], context=context, count=True)
|
||||||
|
@ -148,8 +147,9 @@ class note_note(osv.osv):
|
||||||
result = [{
|
result = [{
|
||||||
'__context': {'group_by': groupby[1:]},
|
'__context': {'group_by': groupby[1:]},
|
||||||
'__domain': domain + [dom_not_in],
|
'__domain': domain + [dom_not_in],
|
||||||
'stage_id': (current_stage_ids[0], stage_name[current_stage_ids[0]]),
|
'stage_id': (stages[0].id, stages[0].name),
|
||||||
'stage_id_count':nb_notes_ws
|
'stage_id_count':nb_notes_ws,
|
||||||
|
'__fold': stages[0].name,
|
||||||
}] + result
|
}] + result
|
||||||
|
|
||||||
else: # if stage_ids is empty
|
else: # if stage_ids is empty
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class="oe_mt32">
|
<p class="oe_mt32">
|
||||||
Organize yourself with efficient todo lists and notes. From personnal tasks to collaborative meeting minutes, increase your user's productivity by giving them the tools to prioritize their work, share their ideas and collaborate on documents.
|
Organize yourself with efficient todo lists and notes. From personal tasks to collaborative meeting minutes, increase your user's productivity by giving them the tools to prioritize their work, share their ideas and collaborate on documents.
|
||||||
</p>
|
</p>
|
||||||
<div class="oe_centeralign oe_websiteonly">
|
<div class="oe_centeralign oe_websiteonly">
|
||||||
<a href="http://www.openerp.com/start?app=note" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
<a href="http://www.openerp.com/start?app=note" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||||
|
|
|
@ -117,9 +117,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class='oe_span4 '>
|
<div class='oe_span4 '>
|
||||||
<img class="oe_picture oe_screenshot" src="pos_ui_02.png">
|
<img class="oe_picture oe_screenshot" src="pos_ui_02.png">
|
||||||
<h3>Blasting fast search</h3>
|
<h3>Blazing fast search</h3>
|
||||||
<p>
|
<p>
|
||||||
Scan products, browse through hyerarchical categories, or get quick
|
Scan products, browse through hierarchical categories, or get quick
|
||||||
information about products with the blasting fast filter accross
|
information about products with the blasting fast filter accross
|
||||||
all your products.
|
all your products.
|
||||||
</p>
|
</p>
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class='oe_span6'>
|
<div class='oe_span6'>
|
||||||
<p>
|
<p>
|
||||||
Consolidate all your sales channel in real time: stores, ecommerce, sales teams.
|
Consolidate all your sales channels in real time: stores, ecommerce, sales teams.
|
||||||
Get real time control of the inventory and accurate forecasts to manage procurements.
|
Get real time control of the inventory and accurate forecasts to manage procurements.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -558,14 +558,14 @@ class stock_warehouse_orderpoint(osv.osv):
|
||||||
]
|
]
|
||||||
|
|
||||||
def default_get(self, cr, uid, fields, context=None):
|
def default_get(self, cr, uid, fields, context=None):
|
||||||
|
warehouse_obj = self.pool.get('stock.warehouse')
|
||||||
res = super(stock_warehouse_orderpoint, self).default_get(cr, uid, fields, context)
|
res = super(stock_warehouse_orderpoint, self).default_get(cr, uid, fields, context)
|
||||||
# default 'warehouse_id' and 'location_id'
|
# default 'warehouse_id' and 'location_id'
|
||||||
if 'warehouse_id' not in res:
|
if 'warehouse_id' not in res:
|
||||||
warehouse = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'warehouse0', context)
|
warehouse_ids = res.get('company_id') and warehouse_obj.search(cr, uid, [('company_id', '=', res['company_id'])], limit=1, context=context) or []
|
||||||
res['warehouse_id'] = warehouse.id
|
res['warehouse_id'] = warehouse_ids and warehouse_ids[0] or False
|
||||||
if 'location_id' not in res:
|
if 'location_id' not in res:
|
||||||
warehouse = self.pool.get('stock.warehouse').browse(cr, uid, res['warehouse_id'], context)
|
res['location_id'] = res.get('warehouse_id') and warehouse_obj.browse(cr, uid, res['warehouse_id'], context).lot_stock_id.id or False
|
||||||
res['location_id'] = warehouse.lot_stock_id.id
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context=None):
|
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context=None):
|
||||||
|
|
|
@ -805,9 +805,17 @@ class product_product(osv.osv):
|
||||||
price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
|
price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
|
||||||
|
|
||||||
res = {}
|
res = {}
|
||||||
|
# standard_price field can only be seen by users in base.group_user
|
||||||
|
# Thus, in order to compute the sale price from the cost price for users not in this group
|
||||||
|
# We fetch the standard price as the superuser
|
||||||
|
for product in products:
|
||||||
|
if ptype != 'standard_price':
|
||||||
|
res[product.id] = product[ptype] or 0.0
|
||||||
|
else:
|
||||||
|
res[product.id] = self.read(cr, SUPERUSER_ID, product.id, [ptype], context=context)[ptype] or 0.0
|
||||||
|
|
||||||
product_uom_obj = self.pool.get('product.uom')
|
product_uom_obj = self.pool.get('product.uom')
|
||||||
for product in products:
|
for product in products:
|
||||||
res[product.id] = product[ptype] or 0.0
|
|
||||||
if ptype == 'list_price':
|
if ptype == 'list_price':
|
||||||
res[product.id] = (res[product.id] * (product.price_margin or 1.0)) + \
|
res[product.id] = (res[product.id] * (product.price_margin or 1.0)) + \
|
||||||
product.price_extra
|
product.price_extra
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.ui.menu" id="base.menu_definitions">
|
<record model="ir.ui.menu" id="base.menu_definitions">
|
||||||
|
<field name="name">Configuration</field>
|
||||||
<field name="groups_id" eval="[(6,0,[ref('group_project_manager')])]"/>
|
<field name="groups_id" eval="[(6,0,[ref('group_project_manager')])]"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@
|
||||||
<search string="Issue Tracker Search">
|
<search string="Issue Tracker Search">
|
||||||
<field name="name" string="Issue" filter_domain="['|', '|', '|', ('partner_id','child_of',self), ('description','ilike',self),('email_from','ilike',self),('name','ilike',self)]"/>
|
<field name="name" string="Issue" filter_domain="['|', '|', '|', ('partner_id','child_of',self), ('description','ilike',self),('email_from','ilike',self),('name','ilike',self)]"/>
|
||||||
<field name="id"/>
|
<field name="id"/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<filter string="Unassigned" name="unassigned" domain="[('user_id', '=', False)]"/>
|
<filter string="Unassigned" name="unassigned" domain="[('user_id', '=', False)]"/>
|
||||||
<filter string="New" name="draft" domain="[('stage_id.sequence', '=', 1)]"/>
|
<filter string="New" name="draft" domain="[('stage_id.sequence', '=', 1)]"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
|
@ -273,7 +273,7 @@
|
||||||
<filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" help="Purchase order which are in the exception state"/>
|
<filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" help="Purchase order which are in the exception state"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
|
<filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
<field name="create_uid"/>
|
<field name="create_uid"/>
|
||||||
<group expand="0" string="Group By...">
|
<group expand="0" string="Group By...">
|
||||||
|
@ -300,7 +300,7 @@
|
||||||
<filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" help="Purchase orders which are in exception state"/>
|
<filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" help="Purchase orders which are in exception state"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
|
<filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
<field name="create_uid"/>
|
<field name="create_uid"/>
|
||||||
<group expand="0" string="Group By...">
|
<group expand="0" string="Group By...">
|
||||||
|
|
|
@ -32,9 +32,5 @@
|
||||||
<field name="header_spacing">35</field>
|
<field name="header_spacing">35</field>
|
||||||
<field name="dpi">90</field>
|
<field name="dpi">90</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="base.main_company" model="res.company">
|
|
||||||
<field name="paperformat_id" ref="paperformat_euro"></field>
|
|
||||||
</record>
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from openerp import SUPERUSER_ID
|
||||||
from openerp.osv import osv, fields
|
from openerp.osv import osv, fields
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,6 +117,24 @@ class res_company(osv.Model):
|
||||||
|
|
||||||
_columns = {'paperformat_id': fields.many2one('report.paperformat', 'Paper format')}
|
_columns = {'paperformat_id': fields.many2one('report.paperformat', 'Paper format')}
|
||||||
|
|
||||||
|
def init(self, cr):
|
||||||
|
# set a default paperformat based on rml one.
|
||||||
|
ref = partial(self.pool['ir.model.data'].xmlid_to_res_id, cr, SUPERUSER_ID)
|
||||||
|
|
||||||
|
ids = self.search(cr, SUPERUSER_ID, [('paperformat_id', '=', False)])
|
||||||
|
for company in self.browse(cr, SUPERUSER_ID, ids):
|
||||||
|
paperformat_id = {
|
||||||
|
'a4': ref('report.paperformat_euro'),
|
||||||
|
'us_letter': ref('report.paperformat_us'),
|
||||||
|
}.get(company.rml_paper_format) or ref('report.paperformat_euro')
|
||||||
|
|
||||||
|
if paperformat_id:
|
||||||
|
company.write({'paperformat_id': paperformat_id})
|
||||||
|
|
||||||
|
sup = super(res_company, self)
|
||||||
|
if hasattr(sup, 'init'):
|
||||||
|
sup.init(cr)
|
||||||
|
|
||||||
|
|
||||||
class ir_actions_report(osv.Model):
|
class ir_actions_report(osv.Model):
|
||||||
_inherit = 'ir.actions.report.xml'
|
_inherit = 'ir.actions.report.xml'
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
<template id="external_layout_footer">
|
<template id="external_layout_footer">
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="text-center" style="border-top: 1px solid black;">
|
<div class="text-center" style="border-top: 1px solid black;">
|
||||||
<ul class="list-inline">
|
<ul t-if="not company.custom_footer" class="list-inline">
|
||||||
<li t-if="company.phone">Phone: <span t-field="company.phone"/></li>
|
<li t-if="company.phone">Phone: <span t-field="company.phone"/></li>
|
||||||
|
|
||||||
<li t-if="company.fax and company.phone">&bull;</li>
|
<li t-if="company.fax and company.phone">&bull;</li>
|
||||||
|
@ -116,11 +116,15 @@
|
||||||
<li t-if="company.email">&bull;</li>
|
<li t-if="company.email">&bull;</li>
|
||||||
<li t-if="company.email">Email: <span t-field="company.email"/></li>
|
<li t-if="company.email">Email: <span t-field="company.email"/></li>
|
||||||
|
|
||||||
<li t-if="website">&bull;</li>
|
<li t-if="company.website">&bull;</li>
|
||||||
<li t-if="website">Website: <span t-esc="website.name"/></li>
|
<li t-if="company.website">Website: <span t-field="company.website"/></li>
|
||||||
<br/>
|
</ul>
|
||||||
<li><span t-field="company.rml_footer"/></li>
|
|
||||||
<li t-if="company.rml_footer">|</li>
|
<t t-if="company.custom_footer">
|
||||||
|
<span t-raw="company.rml_footer"/>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
<ul class="list-inline">
|
||||||
<li>Page:</li>
|
<li>Page:</li>
|
||||||
<li><span class="page"/></li>
|
<li><span class="page"/></li>
|
||||||
<li>/</li>
|
<li>/</li>
|
||||||
|
|
|
@ -99,10 +99,8 @@
|
||||||
<field name="model">res.company</field>
|
<field name="model">res.company</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="//group[@string='Footer Configuration']" position="after">
|
<xpath expr="//page[@string='Report Configuration']/group[@string='Configuration']" position="inside">
|
||||||
<group string="QWeb PDF Configuration">
|
<field name="paperformat_id" />
|
||||||
<field name="paperformat_id" />
|
|
||||||
</group>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
|
|
|
@ -79,7 +79,7 @@ TODO:
|
||||||
* Web client WYSIWYG
|
* Web client WYSIWYG
|
||||||
""",
|
""",
|
||||||
'version': '0.9',
|
'version': '0.9',
|
||||||
'depends': ['base'],
|
'depends': ['base','report'],
|
||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'category': 'Reporting', # i.e a technical module, not shown in Application install menu
|
'category': 'Reporting', # i.e a technical module, not shown in Application install menu
|
||||||
'url': 'http://http://www.camptocamp.com/',
|
'url': 'http://http://www.camptocamp.com/',
|
||||||
|
|
|
@ -5,14 +5,12 @@
|
||||||
<field name="model">res.company</field>
|
<field name="model">res.company</field>
|
||||||
<field name="inherit_id" ref="base.view_company_form"/>
|
<field name="inherit_id" ref="base.view_company_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<notebook position="inside">
|
<xpath expr="//page[@string='Report Configuration']/group[@string='Configuration']" position="after">
|
||||||
<page string="Webkit">
|
<group string="Configuration (Webkit)" col="2">
|
||||||
<separator string="Images" colspan="4"/>
|
<field name="header_image"/>
|
||||||
<field name="header_image" colspan="4" nolabel="1"/>
|
<field name="header_webkit"/>
|
||||||
<separator string="Headers" colspan="4"/>
|
</group>
|
||||||
<field name="header_webkit" colspan="4" nolabel="1"/>
|
</xpath>
|
||||||
</page>
|
|
||||||
</notebook>
|
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">tree,form</field>
|
||||||
</record>
|
</record>
|
||||||
<menuitem id="menu_webkit" name="Webkit" parent="base.menu_custom"/>
|
<menuitem id="menu_webkit" name="Webkit" parent="report.reporting_menuitem"/>
|
||||||
<menuitem action="action_header_img" id="menu_header_img" parent="menu_webkit" sequence="14"/>
|
<menuitem action="action_header_img" id="menu_header_img" parent="menu_webkit" sequence="14"/>
|
||||||
|
|
||||||
<record id="action_header_webkit" model="ir.actions.act_window">
|
<record id="action_header_webkit" model="ir.actions.act_window">
|
||||||
|
|
|
@ -324,7 +324,6 @@ Thanks!</field>
|
||||||
<field name="type">service</field>
|
<field name="type">service</field>
|
||||||
<field name="list_price">150.0</field>
|
<field name="list_price">150.0</field>
|
||||||
<field name="standard_price">100.0</field>
|
<field name="standard_price">100.0</field>
|
||||||
<field name="supply_method">produce</field> <!-- TODO this is a procurement field, which is not a sale dependency -->
|
|
||||||
<field name="uom_id" ref="product.product_uom_day"/>
|
<field name="uom_id" ref="product.product_uom_day"/>
|
||||||
<field name="uom_po_id" ref="product.product_uom_day"/>
|
<field name="uom_po_id" ref="product.product_uom_day"/>
|
||||||
<field name="company_id" eval="[]"/>
|
<field name="company_id" eval="[]"/>
|
||||||
|
|
|
@ -253,7 +253,7 @@
|
||||||
<filter icon="terp-dolar_ok!" string="Done" domain="[('state','=','done')]" help="Sales Order done"/>
|
<filter icon="terp-dolar_ok!" string="Done" domain="[('state','=','done')]" help="Sales Order done"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter string="My" domain="[('user_id','=',uid)]" help="My Sales Orders" icon="terp-personal" name="my_sale_orders_filter"/>
|
<filter string="My" domain="[('user_id','=',uid)]" help="My Sales Orders" icon="terp-personal" name="my_sale_orders_filter"/>
|
||||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
<field name="partner_id" operator="child_of"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="project_id"/>
|
<field name="project_id"/>
|
||||||
<group expand="0" string="Group By...">
|
<group expand="0" string="Group By...">
|
||||||
|
@ -421,7 +421,7 @@
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter string="My Sales Order Lines" icon="terp-personnal" domain="[('salesman_id','=',uid)]" help="Sales Order Lines related to a Sales Order of mine"/>
|
<filter string="My Sales Order Lines" icon="terp-personnal" domain="[('salesman_id','=',uid)]" help="Sales Order Lines related to a Sales Order of mine"/>
|
||||||
<field name="order_id"/>
|
<field name="order_id"/>
|
||||||
<field name="order_partner_id" filter_domain="[('order_partner_id', 'child_of', self)]"/>
|
<field name="order_partner_id" operator="child_of"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
<field name="salesman_id"/>
|
<field name="salesman_id"/>
|
||||||
<group expand="0" string="Group By...">
|
<group expand="0" string="Group By...">
|
||||||
|
@ -447,7 +447,7 @@
|
||||||
<separator/>
|
<separator/>
|
||||||
<filter string="My Sales Order Lines" icon="terp-personal" domain="[('salesman_id','=',uid)]" help="My Sales Order Lines"/>
|
<filter string="My Sales Order Lines" icon="terp-personal" domain="[('salesman_id','=',uid)]" help="My Sales Order Lines"/>
|
||||||
<field name="order_id"/>
|
<field name="order_id"/>
|
||||||
<field name="order_partner_id" filter_domain="[('order_partner_id', 'child_of', self)]"/>
|
<field name="order_partner_id" operator="child_of"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
<field name="salesman_id"/>
|
<field name="salesman_id"/>
|
||||||
<group expand="0" string="Group By...">
|
<group expand="0" string="Group By...">
|
||||||
|
|
|
@ -56,25 +56,6 @@ class SaleLayoutCategory(osv.Model):
|
||||||
'sequence': 10
|
'sequence': 10
|
||||||
}
|
}
|
||||||
|
|
||||||
# We want to forbid edit of a category if it is already linked to a report.
|
|
||||||
def _check(self, cr, uid, ids):
|
|
||||||
for cat in self.browse(cr, uid, ids):
|
|
||||||
invoice_obj = self.pool.get('account.invoice.line')
|
|
||||||
sale_obj = self.pool.get('sale.order.line')
|
|
||||||
ids = invoice_obj.search(cr, uid, [('sale_layout_cat_id', '=', cat.id)])
|
|
||||||
ids += sale_obj.search(cr, uid, [('sale_layout_cat_id', '=', cat.id)])
|
|
||||||
|
|
||||||
if len(ids) > 0:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
_constraints = [(
|
|
||||||
_check,
|
|
||||||
'This category could not be modified nor deleted because it is still used in an invoice or'
|
|
||||||
' a sale report.', ['name']
|
|
||||||
)]
|
|
||||||
|
|
||||||
|
|
||||||
class AccountInvoice(osv.Model):
|
class AccountInvoice(osv.Model):
|
||||||
_inherit = 'account.invoice'
|
_inherit = 'account.invoice'
|
||||||
|
@ -98,7 +79,7 @@ class AccountInvoiceLine(osv.Model):
|
||||||
_inherit = 'account.invoice.line'
|
_inherit = 'account.invoice.line'
|
||||||
_columns = {
|
_columns = {
|
||||||
'sale_layout_cat_id': fields.many2one('sale_layout.category',
|
'sale_layout_cat_id': fields.many2one('sale_layout.category',
|
||||||
'Layout Category'),
|
string='Section'),
|
||||||
'categ_sequence': fields.related('sale_layout_cat_id',
|
'categ_sequence': fields.related('sale_layout_cat_id',
|
||||||
'sequence', type='integer',
|
'sequence', type='integer',
|
||||||
string='Layout Sequence', store=True)
|
string='Layout Sequence', store=True)
|
||||||
|
@ -128,7 +109,7 @@ class SaleOrderLine(osv.Model):
|
||||||
_inherit = 'sale.order.line'
|
_inherit = 'sale.order.line'
|
||||||
_columns = {
|
_columns = {
|
||||||
'sale_layout_cat_id': fields.many2one('sale_layout.category',
|
'sale_layout_cat_id': fields.many2one('sale_layout.category',
|
||||||
'Layout Category'),
|
string='Section'),
|
||||||
'categ_sequence': fields.related('sale_layout_cat_id',
|
'categ_sequence': fields.related('sale_layout_cat_id',
|
||||||
'sequence', type='integer',
|
'sequence', type='integer',
|
||||||
string='Layout Sequence', store=True)
|
string='Layout Sequence', store=True)
|
||||||
|
|
|
@ -8,20 +8,10 @@
|
||||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="//notebook/page/field[@name='order_line']/tree" position="attributes">
|
<xpath expr="//notebook/page/field[@name='order_line']/tree[@string='Sales Order Lines']/field[@name='product_id']" position="after">
|
||||||
<attribute name="editable"></attribute>
|
<field name="sale_layout_cat_id"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
<xpath expr="//field[@name='order_line']/form/group/group/field[@name='product_id']" position="after">
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record model="ir.ui.view" id="view_order_form_inherit_2">
|
|
||||||
<field name="name">sale.order.line.form.inherit_2</field>
|
|
||||||
<field name="model">sale.order</field>
|
|
||||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<data>
|
|
||||||
<xpath expr="//field[@name='order_line']/form/group/group/field[@name='product_id']" position="before">
|
|
||||||
<field name="sale_layout_cat_id"/>
|
<field name="sale_layout_cat_id"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
@ -35,9 +25,10 @@
|
||||||
<field name="inherit_id" ref="account.invoice_form"/>
|
<field name="inherit_id" ref="account.invoice_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="//notebook/page/field[@name='invoice_line']/tree" position="attributes">
|
<xpath expr="//page[@string='Invoice Lines']/field[@name='invoice_line']/tree/field[@name='product_id']" position="after">
|
||||||
<attribute name="editable"></attribute>
|
<field name="sale_layout_cat_id"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -48,7 +39,7 @@
|
||||||
<field name="inherit_id" ref="account.view_invoice_line_form"/>
|
<field name="inherit_id" ref="account.view_invoice_line_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="//group/group/field[@name='product_id']" position="before">
|
<xpath expr="//group/group/field[@name='product_id']" position="after">
|
||||||
<field name="sale_layout_cat_id"/>
|
<field name="sale_layout_cat_id"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -356,7 +356,6 @@ class sale_order(osv.osv):
|
||||||
}
|
}
|
||||||
|
|
||||||
def ship_recreate(self, cr, uid, order, line, move_id, proc_id):
|
def ship_recreate(self, cr, uid, order, line, move_id, proc_id):
|
||||||
# FIXME: deals with potentially cancelled shipments, seems broken (specially if shipment has production lot)
|
|
||||||
"""
|
"""
|
||||||
Define ship_recreate for process after shipping exception
|
Define ship_recreate for process after shipping exception
|
||||||
param order: sales order to which the order lines belong
|
param order: sales order to which the order lines belong
|
||||||
|
@ -365,16 +364,25 @@ class sale_order(osv.osv):
|
||||||
param proc_id: the ID of procurement
|
param proc_id: the ID of procurement
|
||||||
"""
|
"""
|
||||||
move_obj = self.pool.get('stock.move')
|
move_obj = self.pool.get('stock.move')
|
||||||
if order.state == 'shipping_except':
|
proc_obj = self.pool.get('procurement.order')
|
||||||
for pick in order.picking_ids:
|
if move_id and order.state == 'shipping_except':
|
||||||
for move in pick.move_lines:
|
current_move = move_obj.browse(cr, uid, move_id)
|
||||||
if move.state == 'cancel':
|
moves = []
|
||||||
mov_ids = move_obj.search(cr, uid, [('state', '=', 'cancel'),('sale_line_id', '=', line.id),('picking_id', '=', pick.id)])
|
for picking in order.picking_ids:
|
||||||
if mov_ids:
|
if picking.id != current_move.picking_id.id and picking.state != 'cancel':
|
||||||
for mov in move_obj.browse(cr, uid, mov_ids):
|
moves.extend(move for move in picking.move_lines if move.state != 'cancel' and move.sale_line_id.id == line.id)
|
||||||
# FIXME: the following seems broken: what if move_id doesn't exist? What if there are several mov_ids? Shouldn't that be a sum?
|
if moves:
|
||||||
move_obj.write(cr, uid, [move_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
|
product_qty = current_move.product_qty
|
||||||
self.pool.get('procurement.order').write(cr, uid, [proc_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
|
product_uos_qty = current_move.product_uos_qty
|
||||||
|
for move in moves:
|
||||||
|
product_qty -= move.product_qty
|
||||||
|
product_uos_qty -= move.product_uos_qty
|
||||||
|
if product_qty > 0 or product_uos_qty > 0:
|
||||||
|
move_obj.write(cr, uid, [move_id], {'product_qty': product_qty, 'product_uos_qty': product_uos_qty})
|
||||||
|
proc_obj.write(cr, uid, [proc_id], {'product_qty': product_qty, 'product_uos_qty': product_uos_qty})
|
||||||
|
else:
|
||||||
|
current_move.unlink()
|
||||||
|
proc_obj.unlink(cr, uid, [proc_id])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _get_date_planned(self, cr, uid, order, line, start_date, context=None):
|
def _get_date_planned(self, cr, uid, order, line, start_date, context=None):
|
||||||
|
|
|
@ -54,6 +54,10 @@
|
||||||
<field name="type">make_to_order</field>
|
<field name="type">make_to_order</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="sale.advance_product_0" model="product.product">
|
||||||
|
<field name="supply_method">produce</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<!-- Run all schedulers -->
|
<!-- Run all schedulers -->
|
||||||
<function model="procurement.order" name="run_scheduler"/>
|
<function model="procurement.order" name="run_scheduler"/>
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ planning and jobs with the scheduler to reduce your process time.
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
Get your pickings, packings, receptions and internal moves scheduled
|
Get your pickings, packings, receptions and internal moves scheduled
|
||||||
automatically by OpenERP using your own routing rules. Define push and pull
|
automatically by OpenERP using your own routing rules. Define push and pull
|
||||||
rules to organize a warehouse or to manage produts's moves between several
|
rules to organize a warehouse or to manage products moves between several
|
||||||
warehouses.
|
warehouses.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -718,7 +718,6 @@ class stock_picking(osv.osv):
|
||||||
default = {}
|
default = {}
|
||||||
default = default.copy()
|
default = default.copy()
|
||||||
picking_obj = self.browse(cr, uid, id, context=context)
|
picking_obj = self.browse(cr, uid, id, context=context)
|
||||||
move_obj = self.pool.get('stock.move')
|
|
||||||
if ('name' not in default) or (picking_obj.name == '/'):
|
if ('name' not in default) or (picking_obj.name == '/'):
|
||||||
seq_obj_name = 'stock.picking.' + picking_obj.type
|
seq_obj_name = 'stock.picking.' + picking_obj.type
|
||||||
default['name'] = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name)
|
default['name'] = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name)
|
||||||
|
@ -727,10 +726,6 @@ class stock_picking(osv.osv):
|
||||||
if 'invoice_state' not in default and picking_obj.invoice_state == 'invoiced':
|
if 'invoice_state' not in default and picking_obj.invoice_state == 'invoiced':
|
||||||
default['invoice_state'] = '2binvoiced'
|
default['invoice_state'] = '2binvoiced'
|
||||||
res = super(stock_picking, self).copy(cr, uid, id, default, context)
|
res = super(stock_picking, self).copy(cr, uid, id, default, context)
|
||||||
if res:
|
|
||||||
picking_obj = self.browse(cr, uid, res, context=context)
|
|
||||||
for move in picking_obj.move_lines:
|
|
||||||
move_obj.write(cr, uid, [move.id], {'tracking_id': False, 'prodlot_id': False, 'move_history_ids2': [(6, 0, [])], 'move_history_ids': [(6, 0, [])]})
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
|
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
|
||||||
|
@ -1797,12 +1792,15 @@ class stock_move(osv.osv):
|
||||||
_('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).'))
|
_('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).'))
|
||||||
return super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
return super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
def copy(self, cr, uid, id, default=None, context=None):
|
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||||
if default is None:
|
if default is None:
|
||||||
default = {}
|
default = {}
|
||||||
default = default.copy()
|
default = default.copy()
|
||||||
default.update({'move_history_ids2': [], 'move_history_ids': []})
|
default.setdefault('tracking_id', False)
|
||||||
return super(stock_move, self).copy(cr, uid, id, default, context=context)
|
default.setdefault('prodlot_id', False)
|
||||||
|
default.setdefault('move_history_ids', [])
|
||||||
|
default.setdefault('move_history_ids2', [])
|
||||||
|
return super(stock_move, self).copy_data(cr, uid, id, default, context=context)
|
||||||
|
|
||||||
def _auto_init(self, cursor, context=None):
|
def _auto_init(self, cursor, context=None):
|
||||||
res = super(stock_move, self)._auto_init(cursor, context=context)
|
res = super(stock_move, self)._auto_init(cursor, context=context)
|
||||||
|
@ -2072,41 +2070,46 @@ class stock_move(osv.osv):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
seq_obj = self.pool.get('ir.sequence')
|
seq_obj = self.pool.get('ir.sequence')
|
||||||
for picking, todo in self._chain_compute(cr, uid, moves, context=context).items():
|
for picking, chained_moves in self._chain_compute(cr, uid, moves, context=context).items():
|
||||||
ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
|
# We group the moves by automatic move type, so it creates different pickings for different types
|
||||||
if picking:
|
moves_by_type = {}
|
||||||
# name of new picking according to its type
|
for move in chained_moves:
|
||||||
if ptype == 'internal':
|
moves_by_type.setdefault(move[1][1], []).append(move)
|
||||||
new_pick_name = seq_obj.get(cr, uid,'stock.picking')
|
for todo in moves_by_type.values():
|
||||||
else :
|
ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
|
||||||
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
|
if picking:
|
||||||
pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
|
# name of new picking according to its type
|
||||||
# Need to check name of old picking because it always considers picking as "OUT" when created from Sales Order
|
if ptype == 'internal':
|
||||||
old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
|
new_pick_name = seq_obj.get(cr, uid,'stock.picking')
|
||||||
if old_ptype != picking.type:
|
else :
|
||||||
old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype)
|
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
|
||||||
self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name, 'type': old_ptype}, context=context)
|
pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
|
||||||
else:
|
# Need to check name of old picking because it always considers picking as "OUT" when created from Sales Order
|
||||||
pickid = False
|
old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
|
||||||
for move, (loc, dummy, delay, dummy, company_id, ptype, invoice_state) in todo:
|
if old_ptype != picking.type:
|
||||||
new_id = move_obj.copy(cr, uid, move.id, {
|
old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype)
|
||||||
'location_id': move.location_dest_id.id,
|
self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name, 'type': old_ptype}, context=context)
|
||||||
'location_dest_id': loc.id,
|
else:
|
||||||
'date': time.strftime('%Y-%m-%d'),
|
pickid = False
|
||||||
'picking_id': pickid,
|
for move, (loc, dummy, delay, dummy, company_id, ptype, invoice_state) in todo:
|
||||||
'state': 'waiting',
|
new_id = move_obj.copy(cr, uid, move.id, {
|
||||||
'company_id': company_id or res_obj._company_default_get(cr, uid, 'stock.company', context=context) ,
|
'location_id': move.location_dest_id.id,
|
||||||
'move_history_ids': [],
|
'location_dest_id': loc.id,
|
||||||
'date_expected': (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=delay or 0)).strftime('%Y-%m-%d'),
|
'date': time.strftime('%Y-%m-%d'),
|
||||||
'move_history_ids2': []}
|
'picking_id': pickid,
|
||||||
)
|
'state': 'waiting',
|
||||||
move_obj.write(cr, uid, [move.id], {
|
'company_id': company_id or res_obj._company_default_get(cr, uid, 'stock.company', context=context) ,
|
||||||
'move_dest_id': new_id,
|
'move_history_ids': [],
|
||||||
'move_history_ids': [(4, new_id)]
|
'date_expected': (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=delay or 0)).strftime('%Y-%m-%d'),
|
||||||
})
|
'move_history_ids2': []}
|
||||||
new_moves.append(self.browse(cr, uid, [new_id])[0])
|
)
|
||||||
if pickid:
|
move_obj.write(cr, uid, [move.id], {
|
||||||
self.pool.get('stock.picking').signal_button_confirm(cr, uid, [pickid])
|
'move_dest_id': new_id,
|
||||||
|
'move_history_ids': [(4, new_id)]
|
||||||
|
})
|
||||||
|
new_moves.append(self.browse(cr, uid, [new_id])[0])
|
||||||
|
if pickid:
|
||||||
|
self.pool.get('stock.picking').signal_button_confirm(cr, uid, [pickid])
|
||||||
if new_moves:
|
if new_moves:
|
||||||
new_moves += self.create_chained_picking(cr, uid, new_moves, context)
|
new_moves += self.create_chained_picking(cr, uid, new_moves, context)
|
||||||
return new_moves
|
return new_moves
|
||||||
|
@ -2996,6 +2999,9 @@ class stock_picking_in(osv.osv):
|
||||||
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||||
return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load)
|
return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load)
|
||||||
|
|
||||||
|
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
|
||||||
|
return self.pool['stock.picking'].read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
|
||||||
|
|
||||||
def check_access_rights(self, cr, uid, operation, raise_exception=True):
|
def check_access_rights(self, cr, uid, operation, raise_exception=True):
|
||||||
#override in order to redirect the check of acces rights on the stock.picking object
|
#override in order to redirect the check of acces rights on the stock.picking object
|
||||||
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
|
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
|
||||||
|
@ -3076,6 +3082,9 @@ class stock_picking_out(osv.osv):
|
||||||
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||||
return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load)
|
return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load)
|
||||||
|
|
||||||
|
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
|
||||||
|
return self.pool['stock.picking'].read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
|
||||||
|
|
||||||
def check_access_rights(self, cr, uid, operation, raise_exception=True):
|
def check_access_rights(self, cr, uid, operation, raise_exception=True):
|
||||||
#override in order to redirect the check of acces rights on the stock.picking object
|
#override in order to redirect the check of acces rights on the stock.picking object
|
||||||
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
|
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
|
||||||
|
|
|
@ -1271,7 +1271,7 @@
|
||||||
<field name="date" attrs="{'invisible': [('state', '!=', 'done')]}"/>
|
<field name="date" attrs="{'invisible': [('state', '!=', 'done')]}"/>
|
||||||
</group>
|
</group>
|
||||||
<group string="Traceability"
|
<group string="Traceability"
|
||||||
groups="stock.group_tracking_lot">
|
groups="stock.group_tracking_lot,stock.group_production_lot">
|
||||||
<label for="tracking_id" groups="stock.group_tracking_lot"/>
|
<label for="tracking_id" groups="stock.group_tracking_lot"/>
|
||||||
<div groups="stock.group_tracking_lot">
|
<div groups="stock.group_tracking_lot">
|
||||||
<field name="tracking_id" class="oe_inline"/>
|
<field name="tracking_id" class="oe_inline"/>
|
||||||
|
|
|
@ -28,8 +28,8 @@ class stock_location_product(osv.osv_memory):
|
||||||
_columns = {
|
_columns = {
|
||||||
'from_date': fields.datetime('From'),
|
'from_date': fields.datetime('From'),
|
||||||
'to_date': fields.datetime('To'),
|
'to_date': fields.datetime('To'),
|
||||||
'type': fields.selection([('inventory','Analyse Current Inventory'),
|
'type': fields.selection([('inventory','Analyze current inventory'),
|
||||||
('period','Analyse a Period')], 'Analyse Type', required=True),
|
('period','Analyze period')], 'Analysis Type', required=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
def action_open_window(self, cr, uid, ids, context=None):
|
def action_open_window(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -284,7 +284,7 @@ class WebsiteSurvey(http.Controller):
|
||||||
# Printing routes
|
# Printing routes
|
||||||
@http.route(['/survey/print/<model("survey.survey"):survey>',
|
@http.route(['/survey/print/<model("survey.survey"):survey>',
|
||||||
'/survey/print/<model("survey.survey"):survey>/<string:token>'],
|
'/survey/print/<model("survey.survey"):survey>/<string:token>'],
|
||||||
type='http', auth='user', multilang=True, website=True)
|
type='http', auth='public', multilang=True, website=True)
|
||||||
def print_survey(self, survey, token=None, **post):
|
def print_survey(self, survey, token=None, **post):
|
||||||
'''Display an survey in printable view; if <token> is set, it will
|
'''Display an survey in printable view; if <token> is set, it will
|
||||||
grab the answers of the user_input_id that has <token>.'''
|
grab the answers of the user_input_id that has <token>.'''
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data noupdate="1">
|
||||||
<!-- Survey users -->
|
<!-- Survey users -->
|
||||||
<record model="res.groups" id="base.group_survey_user">
|
<record model="res.groups" id="base.group_survey_user">
|
||||||
<field name="name">Survey / User</field>
|
<field name="name">Survey / User</field>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<record id="survey_public_access" model="ir.rule">
|
<record id="survey_public_access" model="ir.rule">
|
||||||
<field name="name">Public access to surveys</field>
|
<field name="name">Public access to surveys</field>
|
||||||
<field name="model_id" ref="survey.model_survey_survey"/>
|
<field name="model_id" ref="survey.model_survey_survey"/>
|
||||||
<field name="domain_force">[('state', '=', 'open'), ('auth_required', '=', False)]</field>
|
<field name="domain_force">[('auth_required', '=', False)]</field>
|
||||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||||
<field eval="0" name="perm_unlink"/>
|
<field eval="0" name="perm_unlink"/>
|
||||||
<field eval="0" name="perm_write"/>
|
<field eval="0" name="perm_write"/>
|
||||||
|
@ -53,9 +53,9 @@
|
||||||
<field name="domain_force">[('create_uid', '=', user.id)]</field>
|
<field name="domain_force">[('create_uid', '=', user.id)]</field>
|
||||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||||
<field eval="0" name="perm_unlink"/>
|
<field eval="0" name="perm_unlink"/>
|
||||||
<field eval="1" name="perm_write"/>
|
<field eval="0" name="perm_write"/>
|
||||||
<field eval="1" name="perm_read"/>
|
<field eval="1" name="perm_read"/>
|
||||||
<field eval="1" name="perm_create"/>
|
<field eval="0" name="perm_create"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="survey_rule" model="ir.rule">
|
<record id="survey_rule" model="ir.rule">
|
||||||
|
@ -64,9 +64,9 @@
|
||||||
<field name="domain_force">[('create_uid', '=', user.id)]</field>
|
<field name="domain_force">[('create_uid', '=', user.id)]</field>
|
||||||
<field name="groups" eval="[(4, ref('base.group_survey_user'))]"/>
|
<field name="groups" eval="[(4, ref('base.group_survey_user'))]"/>
|
||||||
<field eval="0" name="perm_unlink"/>
|
<field eval="0" name="perm_unlink"/>
|
||||||
<field eval="1" name="perm_write"/>
|
<field eval="0" name="perm_write"/>
|
||||||
<field eval="1" name="perm_read"/>
|
<field eval="1" name="perm_read"/>
|
||||||
<field eval="1" name="perm_create"/>
|
<field eval="0" name="perm_create"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="survey_rule_manager" model="ir.rule">
|
<record id="survey_rule_manager" model="ir.rule">
|
||||||
|
|
|
@ -6,6 +6,7 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
|
import re
|
||||||
|
|
||||||
from sys import maxint
|
from sys import maxint
|
||||||
|
|
||||||
|
@ -101,7 +102,9 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||||
'url': "/page/" + xml_id,
|
'url': "/page/" + xml_id,
|
||||||
'parent_id': id,
|
'parent_id': id,
|
||||||
}, context=request.context)
|
}, context=request.context)
|
||||||
url = "/page/" + xml_id
|
# Reverse action in order to allow shortcut for /page/<website_xml_id>
|
||||||
|
url = "/page/" + re.sub(r"^website\.", '', xml_id)
|
||||||
|
|
||||||
if noredirect:
|
if noredirect:
|
||||||
return werkzeug.wrappers.Response(url, mimetype='text/plain')
|
return werkzeug.wrappers.Response(url, mimetype='text/plain')
|
||||||
return werkzeug.utils.redirect(url)
|
return werkzeug.utils.redirect(url)
|
||||||
|
@ -381,10 +384,18 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||||
|
|
||||||
image = Image.open(cStringIO.StringIO(data))
|
image = Image.open(cStringIO.StringIO(data))
|
||||||
response.mimetype = Image.MIME[image.format]
|
response.mimetype = Image.MIME[image.format]
|
||||||
|
|
||||||
|
# record provides a pre-resized version of the base field, use that
|
||||||
|
# directly
|
||||||
|
if record.get(presized):
|
||||||
|
response.data = data
|
||||||
|
return response
|
||||||
|
|
||||||
|
fit = int(max_width), int(max_height)
|
||||||
w, h = image.size
|
w, h = image.size
|
||||||
max_w, max_h = int(max_width), int(max_height)
|
max_w, max_h = int(max_width), int(max_height)
|
||||||
if w < max_w and h < max_h:
|
if w < max_w and h < max_h:
|
||||||
response.set_data(data)
|
response.data = data
|
||||||
else:
|
else:
|
||||||
image.thumbnail((max_w, max_h), Image.ANTIALIAS)
|
image.thumbnail((max_w, max_h), Image.ANTIALIAS)
|
||||||
image.save(response.stream, image.format)
|
image.save(response.stream, image.format)
|
||||||
|
|
|
@ -93,12 +93,13 @@ class ir_http(orm.AbstractModel):
|
||||||
except Exception:
|
except Exception:
|
||||||
return self._handle_exception(werkzeug.exceptions.NotFound())
|
return self._handle_exception(werkzeug.exceptions.NotFound())
|
||||||
|
|
||||||
generated_path = werkzeug.url_unquote_plus(path)
|
if request.httprequest.method in ('GET', 'HEAD'):
|
||||||
current_path = werkzeug.url_unquote_plus(request.httprequest.path)
|
generated_path = werkzeug.url_unquote_plus(path)
|
||||||
if generated_path != current_path:
|
current_path = werkzeug.url_unquote_plus(request.httprequest.path)
|
||||||
if request.lang != request.website.default_lang_code:
|
if generated_path != current_path:
|
||||||
path = '/' + request.lang + path
|
if request.lang != request.website.default_lang_code:
|
||||||
return werkzeug.utils.redirect(path)
|
path = '/' + request.lang + path
|
||||||
|
return werkzeug.utils.redirect(path)
|
||||||
|
|
||||||
def _serve_attachment(self):
|
def _serve_attachment(self):
|
||||||
domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)]
|
domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)]
|
||||||
|
@ -121,7 +122,7 @@ class ir_http(orm.AbstractModel):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
response.mimetype = attach[0]['mimetype']
|
response.mimetype = attach[0]['mimetype']
|
||||||
response.set_data(datas.decode('base64'))
|
response.data = datas.decode('base64')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def _handle_exception(self, exception=None, code=500):
|
def _handle_exception(self, exception=None, code=500):
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
access_website_public,website,website.model_website,,1,0,0,0
|
access_website_public,website,website.model_website,,1,0,0,0
|
||||||
access_website,website,website.model_website,base.group_user,1,0,0,0
|
access_website,website,website.model_website,base.group_website_designer,1,1,1,1
|
||||||
access_website_menu,access_website_menu,model_website_menu,,1,0,0,0
|
access_website_menu,access_website_menu,model_website_menu,,1,0,0,0
|
||||||
|
access_website,web menu manager,website.model_website,base.group_website_designer,1,1,1,1
|
||||||
access_website_converter_test,access_website_converter_test,model_website_converter_test,,1,1,1,1
|
access_website_converter_test,access_website_converter_test,model_website_converter_test,,1,1,1,1
|
||||||
access_website_converter_test_sub,access_website_converter_test_sub,model_website_converter_test_sub,,1,1,1,1
|
access_website_converter_test_sub,access_website_converter_test_sub,model_website_converter_test_sub,,1,1,1,1
|
||||||
access_website_ir_ui_view,access_website_ir_ui_view,model_ir_ui_view,base.group_website_designer,1,1,1,1
|
access_website_ir_ui_view,access_website_ir_ui_view,model_ir_ui_view,base.group_website_designer,1,1,1,1
|
||||||
access_seo_public,access_seo_public,model_website_seo_metadata,,1,0,0,0
|
access_seo_public,access_seo_public,model_website_seo_metadata,,1,0,0,0
|
||||||
|
access_seo_public,access_seo_manager,model_website_seo_metadata,base.group_website_designer,1,1,1,1
|
||||||
access_seo_designer,access_seo_designer,model_website_seo_metadata,base.group_website_designer,1,1,1,1
|
access_seo_designer,access_seo_designer,model_website_seo_metadata,base.group_website_designer,1,1,1,1
|
||||||
|
|
|
|
@ -15,6 +15,7 @@
|
||||||
<t t-call="web.assets_common"/>
|
<t t-call="web.assets_common"/>
|
||||||
<t t-call="website.theme"/>
|
<t t-call="website.theme"/>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/web/static/src/js/watch.js"></script>
|
||||||
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
|
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
|
||||||
<script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script>
|
<script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script>
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
<section class="oe_container">
|
<section class="oe_container">
|
||||||
<div class="oe_row">
|
<div class="oe_row">
|
||||||
<h2 class="oe_slogan">Automated Translation by Professionals</h2>
|
<h2 class="oe_slogan">Automated Translation by Professionals</h2>
|
||||||
<h3 class="oe_slogan">Reach multi-languages audiences without Pain</h3>
|
<h3 class="oe_slogan">Reach multi-language audiences without pain</h3>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<div class="oe_bg_img">
|
<div class="oe_bg_img">
|
||||||
<img class="oe_picture" src="openerp_translation_tool.png">
|
<img class="oe_picture" src="openerp_translation_tool.png">
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<h3 class="oe_slogan">Live chat with your visitors in one click</h3>
|
<h3 class="oe_slogan">Live chat with your visitors in one click</h3>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
The integrated live chat features allows you to start chatting in
|
The integrated live chat feature allows you to start chatting in
|
||||||
real time with your visitors to get feedback on your recent posts
|
real time with your visitors to get feedback on your recent posts
|
||||||
or get ideas to write new posts.
|
or get ideas to write new posts.
|
||||||
</p><p>
|
</p><p>
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
|
|
||||||
<section class="oe_container">
|
<section class="oe_container">
|
||||||
<div class="oe_row">
|
<div class="oe_row">
|
||||||
<h2 class="oe_slogan">Build Visitors Loyalty</h2>
|
<h2 class="oe_slogan">Build Visitor Loyalty</h2>
|
||||||
<h3 class="oe_slogan">Social Media Integration and Easy Following</h3>
|
<h3 class="oe_slogan">Social Media Integration and Easy Following</h3>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<img class="oe_picture oe_screenshot" src="social.png">
|
<img class="oe_picture oe_screenshot" src="social.png">
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
The one click <em>follow</em> button will allow visitors
|
The one click <em>follow</em> button will allow visitors
|
||||||
to receive your blog posts by email with no effort, without
|
to receive your blog posts by email with no effort, without
|
||||||
having to register. Social media icons allows visitors to share
|
having to register. Social media icons allow visitors to share
|
||||||
your best blog posts easily.
|
your best blog posts easily.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
Get a clear visibility of your sales funnel. OpenERP's Google
|
Get a clear visibility of your sales funnel. OpenERP's Google
|
||||||
Analytics trackers are configured by default to track all kind of
|
Analytics trackers are configured by default to track all kinds of
|
||||||
events related to shopping carts, call-to-actions, etc.
|
events related to shopping carts, call-to-actions, etc.
|
||||||
</p><p>
|
</p><p>
|
||||||
As OpenERP marketing tools (mass mailing, campaigns, etc) are also
|
As OpenERP marketing tools (mass mailing, campaigns, etc) are also
|
||||||
|
@ -141,13 +141,13 @@
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
SEO tools are ready to use, with no configuration required.
|
SEO tools are ready to use, with no configuration required.
|
||||||
OpenERP suggests keywords for your titles according to Google
|
OpenERP suggests keywords for your titles according to Google's
|
||||||
most searched terms, Google Analytics tracks interrests of your
|
most searched terms, Google Analytics tracks interests of your
|
||||||
visitors, sitemap are created automatically for Google
|
visitors, sitemaps are created automatically for quick Google
|
||||||
indexation, etc.
|
indexing, etc.
|
||||||
</p><p>
|
</p><p>
|
||||||
We even do structured content automatically to promote your
|
The system even creates structured content automatically to promote your
|
||||||
product and events efficiently in Google.
|
products and events effectively in Google.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -162,10 +162,10 @@
|
||||||
Themes are awesome and easy to design. You don't need to develop
|
Themes are awesome and easy to design. You don't need to develop
|
||||||
to create new pages, themes or building blocks. We use a clean
|
to create new pages, themes or building blocks. We use a clean
|
||||||
HTML structure, a <a href="http://getbootstrap.com/">bootstrap</a>
|
HTML structure, a <a href="http://getbootstrap.com/">bootstrap</a>
|
||||||
CSS and our modularity allows to distribute your themes easily.
|
CSS and our modularity allows you to distribute your themes easily.
|
||||||
</p><p>
|
</p><p>
|
||||||
The building block approach allows the website to remain clean
|
The building block approach allows the website to remain clean
|
||||||
after the end-users start creating new contents.
|
after end-users start creating new contents.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
<section class="oe_container">
|
<section class="oe_container">
|
||||||
<div class="oe_row">
|
<div class="oe_row">
|
||||||
<h2 class="oe_slogan">Easy Access Rights</h2>
|
<h2 class="oe_slogan">Easy Access Rights</h2>
|
||||||
<h3 class="oe_slogan">Adapt your publishing process to your own need</h3>
|
<h3 class="oe_slogan">A publishing process that meets your own needs</h3>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<div class="oe_bg_img">
|
<div class="oe_bg_img">
|
||||||
<img class="oe_picture oe_screenshot" src="blog_create.png">
|
<img class="oe_picture oe_screenshot" src="blog_create.png">
|
||||||
|
@ -187,13 +187,13 @@
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<p class='oe_mt32'>
|
<p class='oe_mt32'>
|
||||||
Not everyone requires the same access to your website.
|
Not everyone requires the same access to your website.
|
||||||
Designers manage the layout of the site, editors approves content and
|
Designers manage the layout of the site, editors approve content and
|
||||||
authors write that content. This lets you organize your publishing
|
authors write that content. This lets you organize your publishing
|
||||||
process according to your needs.
|
process according to your needs.
|
||||||
</p><p>
|
</p><p>
|
||||||
Others access rights related to business objects (products, people,
|
Other access rights are related to business objects (products, people,
|
||||||
events, etc) directly follows OpenERP's standard access right allowing
|
events, etc) and directly following OpenERP's standard access rights
|
||||||
you to not have to configure them twice.
|
management, so you do not have to configure things twice.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -381,7 +381,7 @@
|
||||||
</div>
|
</div>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//div[@id='snippet_options']" position="inside">
|
<xpath expr="//div[@id='snippet_options']" position="inside">
|
||||||
<div data-snippet-option-id='content'
|
<div data-snippet-option-id='country_events'
|
||||||
data-selector=".oe_country_events"
|
data-selector=".oe_country_events"
|
||||||
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel"
|
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel"
|
||||||
data-selector-children=".content"
|
data-selector-children=".content"
|
||||||
|
|
|
@ -7,15 +7,15 @@ from openerp.addons.web.http import request
|
||||||
class sale_order_line(osv.osv):
|
class sale_order_line(osv.osv):
|
||||||
_inherit = "sale.order.line"
|
_inherit = "sale.order.line"
|
||||||
|
|
||||||
def _recalculate_product_values(self, cr, uid, ids, product_id=0, context=None):
|
def _recalculate_product_values(self, cr, uid, ids, product_id=0, fiscal_position=False, context=None):
|
||||||
if not ids:
|
if not ids:
|
||||||
return super(sale_order_line, self)._recalculate_product_values(cr, uid, ids, product_id, context=context)
|
return super(sale_order_line, self)._recalculate_product_values(cr, uid, ids, product_id, fiscal_position=fiscal_position, context=context)
|
||||||
|
|
||||||
order_line = self.browse(cr, SUPERUSER_ID, ids[0], context=context)
|
order_line = self.browse(cr, SUPERUSER_ID, ids[0], context=context)
|
||||||
assert order_line.order_id.website_session_id == request.session['website_session_id']
|
assert order_line.order_id.website_session_id == request.session['website_session_id']
|
||||||
|
|
||||||
product = product_id and self.pool.get('product.product').browse(cr, uid, product_id, context=context) or order_line.product_id
|
product = product_id and self.pool.get('product.product').browse(cr, uid, product_id, context=context) or order_line.product_id
|
||||||
res = super(sale_order_line, self)._recalculate_product_values(cr, uid, ids, product.id, context=context)
|
res = super(sale_order_line, self)._recalculate_product_values(cr, uid, ids, product.id, fiscal_position=fiscal_position, context=context)
|
||||||
if product.event_type_id and order_line.event_ticket_id and order_line.event_ticket_id.price != product.lst_price:
|
if product.event_type_id and order_line.event_ticket_id and order_line.event_ticket_id.price != product.lst_price:
|
||||||
res.update({'price_unit': order_line.event_ticket_id.price})
|
res.update({'price_unit': order_line.event_ticket_id.price})
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,9 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr itemscope="itemscope" itemtype="http://data-vocabulary.org/Offer" t-foreach="event.event_ticket_ids" t-as="ticket">
|
<t t-foreach="event.event_ticket_ids" t-as="ticket">
|
||||||
<td itemscope="itemscope" itemtype="http://data-vocabulary.org/Product">
|
<tr itemscope="itemscope" itemtype="http://data-vocabulary.org/Offer" t-if="not ticket.is_expired">
|
||||||
|
<td itemscope="itemscope" itemtype="http://data-vocabulary.org/Product">
|
||||||
<div itemprop="name" t-field="ticket.name"/>
|
<div itemprop="name" t-field="ticket.name"/>
|
||||||
<div><small itemprop="description" t-field="ticket.product_id.description_sale"/></div>
|
<div><small itemprop="description" t-field="ticket.product_id.description_sale"/></div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -69,7 +70,8 @@
|
||||||
</select>
|
</select>
|
||||||
<span t-if="not ticket.seats_available">Sold Out</span>
|
<span t-if="not ticket.seats_available">Sold Out</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
</t>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<button type="submit" class="btn btn-primary btn-lg pull-right" t-if="event.seats_available">Order Now</button>
|
<button type="submit" class="btn btn-primary btn-lg pull-right" t-if="event.seats_available">Order Now</button>
|
||||||
|
|
|
@ -129,11 +129,16 @@ $(document).ready(function () {
|
||||||
cacheResults: true
|
cacheResults: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Note: Adding event handler of whitespaceKeyDown event.
|
// Adds: create tags on space + blur
|
||||||
$("input.load_tags").bind("whitespaceKeyDown",function () {
|
$("input.load_tags").on('whitespaceKeyDown blur', function () {
|
||||||
$(this).textext()[0].tags().addTags([ $(this).val() ]);
|
$(this).textext()[0].tags().addTags([ $(this).val() ]);
|
||||||
$(this).val("");
|
$(this).val("");
|
||||||
});
|
});
|
||||||
|
$("input.load_tags").on('isTagAllowed', function(e, data) {
|
||||||
|
if (_.indexOf($(this).textext()[0].tags()._formData, data.tag) != -1) {
|
||||||
|
data.result = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('textarea.load_editor').length) {
|
if ($('textarea.load_editor').length) {
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
<div t-foreach="notifications or []" t-as="notification" class="alert alert-success alert-dismissable">
|
<div t-foreach="notifications or []" t-as="notification" class="alert alert-success alert-dismissable">
|
||||||
<button type="button" class="close notification_close" t-att-id="notification.id" data-dismiss="alert" aria-hidden="true">&times;</button>
|
<button type="button" class="close notification_close" t-att-id="notification.id" data-dismiss="alert" aria-hidden="true">&times;</button>
|
||||||
<div t-field="notification.body"/>
|
<div t-field="notification.body"/>
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ slug(user) }#badges" class="fa fa-arrow-right">View Your Badges</a>
|
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ user.id }#badges" class="fa fa-arrow-right">View Your Badges</a>
|
||||||
</div>
|
</div>
|
||||||
<t t-raw="0"/>
|
<t t-raw="0"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -416,7 +416,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-left: 95px;">
|
<div style="margin-left: 95px;">
|
||||||
<h1 class="mt0">
|
<h1 class="mt0">
|
||||||
<span t-field="question.name"/>
|
<a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(question) }" t-field="question.name"/>
|
||||||
<span t-if="not question.active"><b> [Deleted]</b></span>
|
<span t-if="not question.active"><b> [Deleted]</b></span>
|
||||||
<span t-if="question.state == 'close'"><b> [Closed]</b></span>
|
<span t-if="question.state == 'close'"><b> [Closed]</b></span>
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -517,7 +517,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
<span t-field="answer.create_uid.image" t-field-options='{"widget": "image", "class":"pull-left img img-circle img-avatar"}'/>
|
<span t-field="answer.create_uid.image" t-field-options='{"widget": "image", "class":"pull-left img img-circle img-avatar"}'/>
|
||||||
<div>
|
<div>
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ user.id }"
|
<a t-attf-href="/forum/#{ slug(forum) }/user/#{ answer.create_uid.id }"
|
||||||
t-field="answer.create_uid"
|
t-field="answer.create_uid"
|
||||||
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
|
||||||
style="display: inline-block;"/>
|
style="display: inline-block;"/>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<field name="name">Job Positions: Public</field>
|
<field name="name">Job Positions: Public</field>
|
||||||
<field name="model_id" ref="hr.model_hr_job"/>
|
<field name="model_id" ref="hr.model_hr_job"/>
|
||||||
<field name="domain_force">[('website_published', '=', True)]</field>
|
<field name="domain_force">[('website_published', '=', True)]</field>
|
||||||
|
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||||
<field name="perm_read" eval="True"/>
|
<field name="perm_read" eval="True"/>
|
||||||
<field name="perm_write" eval="False"/>
|
<field name="perm_write" eval="False"/>
|
||||||
<field name="perm_create" eval="False"/>
|
<field name="perm_create" eval="False"/>
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
<field name="name">Job department: Public</field>
|
<field name="name">Job department: Public</field>
|
||||||
<field name="model_id" ref="hr.model_hr_department"/>
|
<field name="model_id" ref="hr.model_hr_department"/>
|
||||||
<field name="domain_force">[('jobs_ids.website_published', '=', True)]</field>
|
<field name="domain_force">[('jobs_ids.website_published', '=', True)]</field>
|
||||||
|
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||||
<field name="perm_read" eval="True"/>
|
<field name="perm_read" eval="True"/>
|
||||||
<field name="perm_write" eval="False"/>
|
<field name="perm_write" eval="False"/>
|
||||||
<field name="perm_create" eval="False"/>
|
<field name="perm_create" eval="False"/>
|
||||||
|
|
|
@ -428,7 +428,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
|
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
|
||||||
<a href="http://r.info.openerp.com/3bbh9o3y3tjskrk.html" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
|
<a href="http://www.openerp.com" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
|
||||||
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
|
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -445,7 +445,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
|
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
|
||||||
<a href="http://r.info.openerp.com/3bbh9o3y3tjskrk.html" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
|
<a href="http://www.openerp.com" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
|
||||||
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
|
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -462,7 +462,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
|
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
|
||||||
<a href="http://r.info.openerp.com/3bbh9o3y3tjskrk.html" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
|
<a href="http://www.openerp.com" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
|
||||||
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
|
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -180,7 +180,7 @@ class Ecommerce(http.Controller):
|
||||||
url = "/shop"
|
url = "/shop"
|
||||||
if category:
|
if category:
|
||||||
category_obj = request.registry.get('product.public.category')
|
category_obj = request.registry.get('product.public.category')
|
||||||
url = "%scategory/%s" % (url, slug(category_obj.browse(request.cr, request.uid, int(category), context=request.context)))
|
url = "%s/category/%s" % (url, slug(category_obj.browse(request.cr, request.uid, int(category), context=request.context)))
|
||||||
if filters:
|
if filters:
|
||||||
url = "%s?filters=%s" % (url, simplejson.dumps(filters))
|
url = "%s?filters=%s" % (url, simplejson.dumps(filters))
|
||||||
if post.get("search"):
|
if post.get("search"):
|
||||||
|
@ -406,14 +406,16 @@ class Ecommerce(http.Controller):
|
||||||
order.amount_total,
|
order.amount_total,
|
||||||
request.website._render("website_sale.total", {'website_sale_order': order})]
|
request.website._render("website_sale.total", {'website_sale_order': order})]
|
||||||
|
|
||||||
@http.route(['/shop/set_cart_json'], type='json', auth="public")
|
@http.route(['/shop/set_cart_json'], type='json', auth="public", website=True, multilang=True)
|
||||||
def set_cart_json(self, path=None, product_id=None, order_line_id=None, set_number=0, json=None):
|
def set_cart_json(self, path=None, product_id=None, order_line_id=None, set_number=0, json=None):
|
||||||
quantity = request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid,
|
quantity = request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid,
|
||||||
product_id=product_id, order_line_id=order_line_id, set_number=set_number,
|
product_id=product_id, order_line_id=order_line_id, set_number=set_number,
|
||||||
context=request.context)
|
context=request.context)
|
||||||
order = self.get_order()
|
order = self.get_order()
|
||||||
return [quantity,
|
return [quantity,
|
||||||
order.get_number_of_products()]
|
order.get_number_of_products(),
|
||||||
|
order.amount_total,
|
||||||
|
request.website._render("website_sale.total", {'website_sale_order': order})]
|
||||||
|
|
||||||
@http.route(['/shop/checkout'], type='http', auth="public", website=True, multilang=True)
|
@http.route(['/shop/checkout'], type='http', auth="public", website=True, multilang=True)
|
||||||
def checkout(self, **post):
|
def checkout(self, **post):
|
||||||
|
|
|
@ -33,7 +33,7 @@ class SaleOrder(osv.Model):
|
||||||
class SaleOrderLine(osv.Model):
|
class SaleOrderLine(osv.Model):
|
||||||
_inherit = "sale.order.line"
|
_inherit = "sale.order.line"
|
||||||
|
|
||||||
def _recalculate_product_values(self, cr, uid, ids, product_id=0, context=None):
|
def _recalculate_product_values(self, cr, uid, ids, product_id=0, fiscal_position=False, context=None):
|
||||||
# TDE FIXME: seems to be defined several times -> fix me ?
|
# TDE FIXME: seems to be defined several times -> fix me ?
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
@ -49,5 +49,6 @@ class SaleOrderLine(osv.Model):
|
||||||
pricelist=context.pop('pricelist'),
|
pricelist=context.pop('pricelist'),
|
||||||
product=product_id,
|
product=product_id,
|
||||||
partner_id=user_obj.browse(cr, SUPERUSER_ID, uid).partner_id.id,
|
partner_id=user_obj.browse(cr, SUPERUSER_ID, uid).partner_id.id,
|
||||||
|
fiscal_position=fiscal_position,
|
||||||
context=context
|
context=context
|
||||||
)['value']
|
)['value']
|
||||||
|
|
|
@ -102,11 +102,16 @@ class Website(orm.Model):
|
||||||
else:
|
else:
|
||||||
fields = [k for k, v in order_line_obj._columns.items()]
|
fields = [k for k, v in order_line_obj._columns.items()]
|
||||||
values = order_line_obj.default_get(cr, SUPERUSER_ID, fields, context=context)
|
values = order_line_obj.default_get(cr, SUPERUSER_ID, fields, context=context)
|
||||||
quantity = 1
|
if set_number >= 0:
|
||||||
|
quantity = set_number
|
||||||
|
elif number >= 0:
|
||||||
|
quantity = number
|
||||||
|
else:
|
||||||
|
quantity = 1
|
||||||
|
|
||||||
# change and record value
|
# change and record value
|
||||||
if quantity:
|
if quantity:
|
||||||
vals = order_line_obj._recalculate_product_values(cr, uid, order_line_ids, product_id, context=context)
|
vals = order_line_obj._recalculate_product_values(cr, uid, order_line_ids, product_id, fiscal_position=order.fiscal_position.id, context=context)
|
||||||
values.update(vals)
|
values.update(vals)
|
||||||
values['product_uom_qty'] = quantity
|
values['product_uom_qty'] = quantity
|
||||||
values['product_id'] = product_id
|
values['product_id'] = product_id
|
||||||
|
@ -114,12 +119,11 @@ class Website(orm.Model):
|
||||||
|
|
||||||
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
||||||
values['name'] = "%s: %s" % (product.name, product.variants) if product.variants else product.name
|
values['name'] = "%s: %s" % (product.name, product.variants) if product.variants else product.name
|
||||||
values['tax_id'] = [(6, 0, [tax.id for tax in product.taxes_id])]
|
if values.get('tax_id'):
|
||||||
if order_line_id:
|
values['tax_id'] = [(6, 0, values['tax_id'])]
|
||||||
order_line_obj.write(cr, SUPERUSER_ID, order_line_ids, values, context=context)
|
|
||||||
else:
|
order_obj.write(cr, SUPERUSER_ID, [order.id], {'order_line': [(1, order_line_id, values) if order_line_id else (0, 0, values)]}, context=context)
|
||||||
order_line_id = order_line_obj.create(cr, SUPERUSER_ID, values, context=context)
|
|
||||||
order_obj.write(cr, SUPERUSER_ID, [order.id], {'order_line': [(4, order_line_id)]}, context=context)
|
|
||||||
elif order_line_ids:
|
elif order_line_ids:
|
||||||
order_line_obj.unlink(cr, SUPERUSER_ID, order_line_ids, context=context)
|
order_line_obj.unlink(cr, SUPERUSER_ID, order_line_ids, context=context)
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,20 @@ $(document).ready(function () {
|
||||||
.fadeIn(600);
|
.fadeIn(600);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(".oe_website_sale .oe_mycart input.js_quantity").change(function () {
|
$(".oe_website_sale .oe_mycart input.js_quantity").change(function (ev) {
|
||||||
var $input = $(this);
|
var $input = $(this);
|
||||||
|
var $link = $(ev.currentTarget);
|
||||||
var value = parseInt($input.val(), 10);
|
var value = parseInt($input.val(), 10);
|
||||||
if (isNaN(value)) value = 0;
|
if (isNaN(value)) value = 0;
|
||||||
openerp.jsonRpc("/shop/set_cart_json", 'call', {'order_line_id': $input.data('id'), 'set_number': value})
|
openerp.jsonRpc("/shop/set_cart_json", 'call', {'order_line_id': $input.data('id'), 'set_number': value})
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
if (!data) {
|
if (!data[0]) {
|
||||||
location.reload();
|
location.reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
set_my_cart_quantity(data[1]);
|
set_my_cart_quantity(data[1]);
|
||||||
$input.val(data[0]);
|
$link.parents(".input-group:first").find(".js_quantity").val(data[0]);
|
||||||
|
$('#mycart_total').replaceWith(data[3]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -82,10 +82,10 @@ class SaleOrder(orm.Model):
|
||||||
carrier_id = delivery_id
|
carrier_id = delivery_id
|
||||||
break
|
break
|
||||||
order.write({'carrier_id': carrier_id}, context=context)
|
order.write({'carrier_id': carrier_id}, context=context)
|
||||||
if carrier_id:
|
if carrier_id:
|
||||||
order.delivery_set(context=context)
|
order.delivery_set(context=context)
|
||||||
else:
|
else:
|
||||||
order._delivery_unset(context=context)
|
order._delivery_unset(context=context)
|
||||||
|
|
||||||
return bool(carrier_id)
|
return bool(carrier_id)
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,5 @@ class Website(orm.Model):
|
||||||
product_id=product_id, order_line_id=order_line_id, number=number, set_number=set_number,
|
product_id=product_id, order_line_id=order_line_id, number=number, set_number=set_number,
|
||||||
context=context)
|
context=context)
|
||||||
order = self.ecommerce_get_current_order(cr, uid, context=context)
|
order = self.ecommerce_get_current_order(cr, uid, context=context)
|
||||||
return self.pool['sale.order']._check_carrier_quotation(cr, uid, order, force_carrier_id=None, context=context) and quantity or None
|
self.pool['sale.order']._check_carrier_quotation(cr, uid, order, force_carrier_id=None, context=context) and quantity or None
|
||||||
|
return quantity
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
access_website_twitter_tweet_public,access of twitter snippet,website_twitter.model_website_twitter_tweet,,1,0,0,0
|
access_website_twitter_tweet_public,access of twitter snippet,website_twitter.model_website_twitter_tweet,,1,0,0,0
|
||||||
|
access_website_twitter_tweet_manage,manage tweets,website_twitter.model_website_twitter_tweet,base.group_website_publisher,1,1,1,1
|
||||||
|
|
|
|
@ -2,30 +2,20 @@
|
||||||
-- Pure SQL
|
-- Pure SQL
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
CREATE TABLE ir_actions (
|
||||||
-- IR dictionary
|
id serial,
|
||||||
-------------------------------------------------------------------------
|
primary key(id)
|
||||||
|
|
||||||
create table ir_values
|
|
||||||
(
|
|
||||||
id serial,
|
|
||||||
name varchar(128) not null,
|
|
||||||
key varchar(128) not null,
|
|
||||||
key2 varchar(256) not null,
|
|
||||||
model varchar(128) not null,
|
|
||||||
value text,
|
|
||||||
meta text default NULL,
|
|
||||||
res_id integer default null,
|
|
||||||
primary key (id)
|
|
||||||
);
|
);
|
||||||
|
CREATE TABLE ir_act_window (primary key(id)) INHERITS (ir_actions);
|
||||||
|
CREATE TABLE ir_act_report_xml (primary key(id)) INHERITS (ir_actions);
|
||||||
|
CREATE TABLE ir_act_url (primary key(id)) INHERITS (ir_actions);
|
||||||
|
CREATE TABLE ir_act_server (primary key(id)) INHERITS (ir_actions);
|
||||||
|
CREATE TABLE ir_act_client (primary key(id)) INHERITS (ir_actions);
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
-- Modules Description
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CREATE TABLE ir_model (
|
CREATE TABLE ir_model (
|
||||||
id serial,
|
id serial,
|
||||||
model varchar DEFAULT ''::varchar NOT NULL,
|
model varchar NOT NULL,
|
||||||
name varchar,
|
name varchar,
|
||||||
state varchar,
|
state varchar,
|
||||||
info text,
|
info text,
|
||||||
|
@ -34,103 +24,27 @@ CREATE TABLE ir_model (
|
||||||
|
|
||||||
CREATE TABLE ir_model_fields (
|
CREATE TABLE ir_model_fields (
|
||||||
id serial,
|
id serial,
|
||||||
model varchar DEFAULT ''::varchar NOT NULL,
|
model varchar NOT NULL,
|
||||||
model_id int references ir_model on delete cascade,
|
model_id integer references ir_model on delete cascade,
|
||||||
name varchar DEFAULT ''::varchar NOT NULL,
|
name varchar NOT NULL,
|
||||||
relation varchar,
|
relation varchar,
|
||||||
select_level varchar,
|
select_level varchar,
|
||||||
field_description varchar,
|
field_description varchar,
|
||||||
ttype varchar,
|
ttype varchar,
|
||||||
state varchar default 'base',
|
state varchar default 'base',
|
||||||
relate boolean default False,
|
|
||||||
relation_field varchar,
|
relation_field varchar,
|
||||||
translate boolean default False,
|
translate boolean default False,
|
||||||
|
serialization_field_id integer references ir_model_fields on delete cascade,
|
||||||
primary key(id)
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE ir_model_fields ADD column serialization_field_id int references ir_model_fields on delete cascade;
|
CREATE TABLE res_lang (
|
||||||
|
id serial,
|
||||||
|
name VARCHAR(64) NOT NULL UNIQUE,
|
||||||
-------------------------------------------------------------------------
|
code VARCHAR(16) NOT NULL UNIQUE,
|
||||||
-- Actions
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CREATE TABLE ir_actions (
|
|
||||||
id serial NOT NULL,
|
|
||||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
|
||||||
"type" varchar(32) NOT NULL,
|
|
||||||
usage varchar(32) DEFAULT null,
|
|
||||||
primary key(id)
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE ir_act_window (
|
|
||||||
view_id integer,
|
|
||||||
res_model varchar(64),
|
|
||||||
view_type varchar(16),
|
|
||||||
"domain" varchar(250),
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
CREATE TABLE ir_act_report_xml (
|
|
||||||
model varchar(64) NOT NULL,
|
|
||||||
report_name varchar(64) NOT NULL,
|
|
||||||
report_xsl varchar(256),
|
|
||||||
report_xml varchar(256),
|
|
||||||
auto boolean default true,
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
create table ir_act_report_custom (
|
|
||||||
report_id int,
|
|
||||||
-- report_id int references ir_report_custom
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
CREATE TABLE ir_act_wizard (
|
|
||||||
wiz_name varchar(64) NOT NULL,
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
CREATE TABLE ir_act_url (
|
|
||||||
url text NOT NULL,
|
|
||||||
target varchar(64) NOT NULL,
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
CREATE TABLE ir_act_server (
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
CREATE TABLE ir_act_client (
|
|
||||||
primary key(id)
|
|
||||||
)
|
|
||||||
INHERITS (ir_actions);
|
|
||||||
|
|
||||||
CREATE TABLE ir_ui_menu (
|
|
||||||
id serial NOT NULL,
|
|
||||||
parent_id int references ir_ui_menu on delete set null,
|
|
||||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
|
||||||
icon varchar(64) DEFAULT ''::varchar,
|
|
||||||
primary key (id)
|
|
||||||
);
|
|
||||||
|
|
||||||
select setval('ir_ui_menu_id_seq', 2);
|
|
||||||
|
|
||||||
---------------------------------
|
|
||||||
-- Res users
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
-- level:
|
|
||||||
-- 0 RESTRICT TO USER
|
|
||||||
-- 1 RESTRICT TO GROUP
|
|
||||||
-- 2 PUBLIC
|
|
||||||
|
|
||||||
CREATE TABLE res_users (
|
CREATE TABLE res_users (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
active boolean default True,
|
active boolean default True,
|
||||||
|
@ -138,146 +52,44 @@ CREATE TABLE res_users (
|
||||||
password varchar(64) default null,
|
password varchar(64) default null,
|
||||||
-- No FK references below, will be added later by ORM
|
-- No FK references below, will be added later by ORM
|
||||||
-- (when the destination rows exist)
|
-- (when the destination rows exist)
|
||||||
company_id int,
|
company_id integer, -- references res_company,
|
||||||
partner_id int,
|
partner_id integer, -- references res_partner,
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
alter table res_users add constraint res_users_login_uniq unique (login);
|
|
||||||
|
|
||||||
CREATE TABLE res_groups (
|
|
||||||
id serial NOT NULL,
|
|
||||||
name varchar(64) NOT NULL,
|
|
||||||
primary key(id)
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE res_groups_users_rel (
|
create table wkf (
|
||||||
uid integer NOT NULL references res_users on delete cascade,
|
|
||||||
gid integer NOT NULL references res_groups on delete cascade,
|
|
||||||
UNIQUE("uid","gid")
|
|
||||||
);
|
|
||||||
|
|
||||||
create index res_groups_users_rel_uid_idx on res_groups_users_rel (uid);
|
|
||||||
create index res_groups_users_rel_gid_idx on res_groups_users_rel (gid);
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------------
|
|
||||||
-- Workflows
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
create table wkf
|
|
||||||
(
|
|
||||||
id serial,
|
id serial,
|
||||||
name varchar(64),
|
name varchar(64),
|
||||||
osv varchar(64),
|
osv varchar(64),
|
||||||
on_create bool default False,
|
on_create bool default false,
|
||||||
primary key(id)
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table wkf_activity
|
|
||||||
(
|
|
||||||
id serial,
|
|
||||||
wkf_id int references wkf on delete cascade,
|
|
||||||
subflow_id int references wkf on delete set null,
|
|
||||||
split_mode varchar(3) default 'XOR',
|
|
||||||
join_mode varchar(3) default 'XOR',
|
|
||||||
kind varchar(16) not null default 'dummy',
|
|
||||||
name varchar(64),
|
|
||||||
signal_send varchar(32) default null,
|
|
||||||
flow_start boolean default False,
|
|
||||||
flow_stop boolean default False,
|
|
||||||
action text default null,
|
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table wkf_transition
|
|
||||||
(
|
|
||||||
id serial,
|
|
||||||
act_from int references wkf_activity on delete cascade,
|
|
||||||
act_to int references wkf_activity on delete cascade,
|
|
||||||
condition varchar(128) default NULL,
|
|
||||||
|
|
||||||
trigger_type varchar(128) default NULL,
|
|
||||||
trigger_expr_id varchar(128) default NULL,
|
|
||||||
|
|
||||||
signal varchar(64) default null,
|
|
||||||
group_id int references res_groups on delete set null,
|
|
||||||
|
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table wkf_instance
|
|
||||||
(
|
|
||||||
id serial,
|
|
||||||
wkf_id int references wkf on delete restrict,
|
|
||||||
uid int default null,
|
|
||||||
res_id int not null,
|
|
||||||
res_type varchar(64) not null,
|
|
||||||
state varchar(32) not null default 'active',
|
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table wkf_workitem
|
|
||||||
(
|
|
||||||
id serial,
|
|
||||||
act_id int not null references wkf_activity on delete cascade,
|
|
||||||
inst_id int not null references wkf_instance on delete cascade,
|
|
||||||
subflow_id int references wkf_instance on delete cascade,
|
|
||||||
state varchar(64) default 'blocked',
|
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table wkf_witm_trans
|
|
||||||
(
|
|
||||||
trans_id int not null references wkf_transition on delete cascade,
|
|
||||||
inst_id int not null references wkf_instance on delete cascade
|
|
||||||
);
|
|
||||||
|
|
||||||
create index wkf_witm_trans_inst_idx on wkf_witm_trans (inst_id);
|
|
||||||
|
|
||||||
create table wkf_logs
|
|
||||||
(
|
|
||||||
id serial,
|
|
||||||
res_type varchar(128) not null,
|
|
||||||
res_id int not null,
|
|
||||||
uid int references res_users on delete set null,
|
|
||||||
act_id int references wkf_activity on delete set null,
|
|
||||||
time time not null,
|
|
||||||
info varchar(128) default NULL,
|
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
---------------------------------
|
|
||||||
-- Modules
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
CREATE TABLE ir_module_category (
|
CREATE TABLE ir_module_category (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
create_uid integer references res_users on delete set null,
|
create_uid integer, -- references res_users on delete set null,
|
||||||
create_date timestamp without time zone,
|
create_date timestamp without time zone,
|
||||||
write_date timestamp without time zone,
|
write_date timestamp without time zone,
|
||||||
write_uid integer references res_users on delete set null,
|
write_uid integer, -- references res_users on delete set null,
|
||||||
parent_id integer REFERENCES ir_module_category ON DELETE SET NULL,
|
parent_id integer REFERENCES ir_module_category ON DELETE SET NULL,
|
||||||
name character varying(128) NOT NULL,
|
name character varying(128) NOT NULL,
|
||||||
primary key(id)
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE ir_module_module (
|
CREATE TABLE ir_module_module (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
create_uid integer references res_users on delete set null,
|
create_uid integer, -- references res_users on delete set null,
|
||||||
create_date timestamp without time zone,
|
create_date timestamp without time zone,
|
||||||
write_date timestamp without time zone,
|
write_date timestamp without time zone,
|
||||||
write_uid integer references res_users on delete set null,
|
write_uid integer, -- references res_users on delete set null,
|
||||||
website character varying(256),
|
website character varying(256),
|
||||||
summary character varying(256),
|
summary character varying(256),
|
||||||
name character varying(128) NOT NULL,
|
name character varying(128) NOT NULL,
|
||||||
author character varying(128),
|
author character varying(128),
|
||||||
url character varying(128),
|
|
||||||
icon character varying(64),
|
icon character varying(64),
|
||||||
state character varying(16),
|
state character varying(16),
|
||||||
latest_version character varying(64),
|
latest_version character varying(64),
|
||||||
shortdesc character varying(256),
|
shortdesc character varying(256),
|
||||||
complexity character varying(32),
|
|
||||||
category_id integer REFERENCES ir_module_category ON DELETE SET NULL,
|
category_id integer REFERENCES ir_module_category ON DELETE SET NULL,
|
||||||
description text,
|
description text,
|
||||||
application boolean default False,
|
application boolean default False,
|
||||||
|
@ -292,45 +104,15 @@ ALTER TABLE ir_module_module add constraint name_uniq unique (name);
|
||||||
|
|
||||||
CREATE TABLE ir_module_module_dependency (
|
CREATE TABLE ir_module_module_dependency (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
create_uid integer references res_users on delete set null,
|
create_uid integer, -- references res_users on delete set null,
|
||||||
create_date timestamp without time zone,
|
create_date timestamp without time zone,
|
||||||
write_date timestamp without time zone,
|
write_date timestamp without time zone,
|
||||||
write_uid integer references res_users on delete set null,
|
write_uid integer, -- references res_users on delete set null,
|
||||||
name character varying(128),
|
name character varying(128),
|
||||||
version_pattern character varying(128) default NULL,
|
|
||||||
module_id integer REFERENCES ir_module_module ON DELETE cascade,
|
module_id integer REFERENCES ir_module_module ON DELETE cascade,
|
||||||
primary key(id)
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE res_partner (
|
|
||||||
id serial NOT NULL,
|
|
||||||
name character varying(128),
|
|
||||||
lang varchar(64),
|
|
||||||
company_id int,
|
|
||||||
primary key(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE res_currency (
|
|
||||||
id serial PRIMARY KEY,
|
|
||||||
name VARCHAR(32) NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE res_company (
|
|
||||||
id serial PRIMARY KEY,
|
|
||||||
name character varying(128) not null,
|
|
||||||
parent_id integer references res_company on delete set null,
|
|
||||||
partner_id integer not null references res_partner,
|
|
||||||
currency_id integer not null references res_currency
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE res_lang (
|
|
||||||
id serial PRIMARY KEY,
|
|
||||||
name VARCHAR(64) NOT NULL UNIQUE,
|
|
||||||
code VARCHAR(16) NOT NULL UNIQUE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE ir_model_data (
|
CREATE TABLE ir_model_data (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
create_uid integer,
|
create_uid integer,
|
||||||
|
@ -343,7 +125,8 @@ CREATE TABLE ir_model_data (
|
||||||
date_update timestamp without time zone,
|
date_update timestamp without time zone,
|
||||||
module varchar NOT NULL,
|
module varchar NOT NULL,
|
||||||
model varchar NOT NULL,
|
model varchar NOT NULL,
|
||||||
res_id integer, primary key(id)
|
res_id integer,
|
||||||
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Records foreign keys and constraints installed by a module (so they can be
|
-- Records foreign keys and constraints installed by a module (so they can be
|
||||||
|
@ -352,49 +135,64 @@ CREATE TABLE ir_model_data (
|
||||||
-- - for a constraint: type is 'u' (this is the convention PostgreSQL uses).
|
-- - for a constraint: type is 'u' (this is the convention PostgreSQL uses).
|
||||||
CREATE TABLE ir_model_constraint (
|
CREATE TABLE ir_model_constraint (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
create_uid integer,
|
|
||||||
create_date timestamp without time zone,
|
|
||||||
write_date timestamp without time zone,
|
|
||||||
write_uid integer,
|
|
||||||
date_init timestamp without time zone,
|
date_init timestamp without time zone,
|
||||||
date_update timestamp without time zone,
|
date_update timestamp without time zone,
|
||||||
module integer NOT NULL references ir_module_module on delete restrict,
|
module integer NOT NULL references ir_module_module on delete restrict,
|
||||||
model integer NOT NULL references ir_model on delete restrict,
|
model integer NOT NULL references ir_model on delete restrict,
|
||||||
type character varying(1) NOT NULL,
|
type character varying(1) NOT NULL,
|
||||||
name varchar NOT NULL
|
name varchar NOT NULL,
|
||||||
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Records relation tables (i.e. implementing many2many) installed by a module
|
-- Records relation tables (i.e. implementing many2many) installed by a module
|
||||||
-- (so they can be removed when the module is uninstalled).
|
-- (so they can be removed when the module is uninstalled).
|
||||||
CREATE TABLE ir_model_relation (
|
CREATE TABLE ir_model_relation (
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
create_uid integer,
|
|
||||||
create_date timestamp without time zone,
|
|
||||||
write_date timestamp without time zone,
|
|
||||||
write_uid integer,
|
|
||||||
date_init timestamp without time zone,
|
date_init timestamp without time zone,
|
||||||
date_update timestamp without time zone,
|
date_update timestamp without time zone,
|
||||||
module integer NOT NULL references ir_module_module on delete restrict,
|
module integer NOT NULL references ir_module_module on delete restrict,
|
||||||
model integer NOT NULL references ir_model on delete restrict,
|
model integer NOT NULL references ir_model on delete restrict,
|
||||||
name varchar NOT NULL
|
name varchar NOT NULL,
|
||||||
|
primary key(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
---------------------------------
|
CREATE TABLE res_currency (
|
||||||
-- Users
|
id serial,
|
||||||
---------------------------------
|
name varchar NOT NULL,
|
||||||
insert into res_users (id,login,password,active,company_id,partner_id) VALUES (1,'admin','admin',true,1,1);
|
primary key(id)
|
||||||
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('user_root','base','res.users',true,1);
|
);
|
||||||
|
|
||||||
insert into res_partner (id, name, lang, company_id) VALUES (1, 'Your Company', 'en_US', 1);
|
CREATE TABLE res_company (
|
||||||
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('main_partner','base','res.partner',true,1);
|
id serial,
|
||||||
|
name varchar NOT NULL,
|
||||||
|
partner_id integer,
|
||||||
|
currency_id integer,
|
||||||
|
primary key(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE res_partner (
|
||||||
|
id serial,
|
||||||
|
name varchar,
|
||||||
|
company_id integer,
|
||||||
|
primary key(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------
|
||||||
|
-- Default data
|
||||||
|
---------------------------------
|
||||||
insert into res_currency (id, name) VALUES (1, 'EUR');
|
insert into res_currency (id, name) VALUES (1, 'EUR');
|
||||||
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('EUR','base','res.currency',true,1);
|
insert into ir_model_data (name, module, model, noupdate, res_id) VALUES ('EUR', 'base', 'res.currency', true, 1);
|
||||||
|
select setval('res_currency_id_seq', 2);
|
||||||
|
|
||||||
insert into res_company (id, name, partner_id, currency_id) VALUES (1, 'Your Company', 1, 1);
|
insert into res_company (id, name, partner_id, currency_id) VALUES (1, 'Your Company', 1, 1);
|
||||||
insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('main_company','base','res.company',true,1);
|
insert into ir_model_data (name, module, model, noupdate, res_id) VALUES ('main_company', 'base', 'res.company', true, 1);
|
||||||
|
|
||||||
select setval('res_company_id_seq', 2);
|
select setval('res_company_id_seq', 2);
|
||||||
select setval('res_users_id_seq', 2);
|
|
||||||
|
insert into res_partner (id, name, company_id) VALUES (1, 'Your Company', 1);
|
||||||
|
insert into ir_model_data (name, module, model, noupdate, res_id) VALUES ('main_partner', 'base', 'res.partner', true, 1);
|
||||||
select setval('res_partner_id_seq', 2);
|
select setval('res_partner_id_seq', 2);
|
||||||
select setval('res_currency_id_seq', 2);
|
|
||||||
|
insert into res_users (id, login, password, active, partner_id, company_id) VALUES (1, 'admin', 'admin', true, 1, 1);
|
||||||
|
insert into ir_model_data (name, module, model, noupdate, res_id) VALUES ('user_root', 'base', 'res.users', true, 1);
|
||||||
|
select setval('res_users_id_seq', 2);
|
||||||
|
|
|
@ -859,7 +859,7 @@ class Contact(orm.AbstractModel):
|
||||||
|
|
||||||
id = getattr(record, field_name).id
|
id = getattr(record, field_name).id
|
||||||
field_browse = self.pool[column._obj].browse(cr, openerp.SUPERUSER_ID, id, context={"show_address": True})
|
field_browse = self.pool[column._obj].browse(cr, openerp.SUPERUSER_ID, id, context={"show_address": True})
|
||||||
value = werkzeug.utils.escape( field_browse.name_get()[0][1] )
|
value = field_browse.name_get()[0][1]
|
||||||
|
|
||||||
val = {
|
val = {
|
||||||
'name': value.split("\n")[0],
|
'name': value.split("\n")[0],
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue