[MERGE] forward port of branch saas-3 up to revid 9429 chs@openerp.com-20140424123538-rxk9got9k2on1ki1
bzr revid: chs@openerp.com-20140424131824-4ksluvhnegp7kplb bzr revid: chs@openerp.com-20140424134533-lhhcd32n3s0m9cqk
This commit is contained in:
commit
7a7d7febf8
|
@ -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'])]
|
||||||
|
|
|
@ -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/>
|
||||||
|
|
|
@ -1020,10 +1020,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):
|
||||||
|
|
|
@ -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
|
||||||
|
@ -721,23 +722,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])
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'''
|
||||||
|
|
|
@ -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="section_id" string="Sales Team"
|
<field name="section_id" string="Sales Team"
|
||||||
groups="base.group_multi_salesteams"/>
|
groups="base.group_multi_salesteams"/>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -167,12 +167,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'),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -62,28 +62,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 assign it to a user.'))
|
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must assign it 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 assign it to a user.'))
|
raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must assign it 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):
|
||||||
|
|
|
@ -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')]"/>
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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...">
|
||||||
|
|
|
@ -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...">
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -1609,8 +1609,11 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
|
||||||
return facetValue.get('label');
|
return facetValue.get('label');
|
||||||
},
|
},
|
||||||
make_domain: function (name, operator, facetValue) {
|
make_domain: function (name, operator, facetValue) {
|
||||||
if (operator === this.default_operator) {
|
switch(operator){
|
||||||
|
case this.default_operator:
|
||||||
return [[name, '=', facetValue.get('value')]];
|
return [[name, '=', facetValue.get('value')]];
|
||||||
|
case 'child_of':
|
||||||
|
return [[name, 'child_of', facetValue.get('value')]];
|
||||||
}
|
}
|
||||||
return this._super(name, operator, facetValue);
|
return this._super(name, operator, facetValue);
|
||||||
},
|
},
|
||||||
|
|
|
@ -3471,7 +3471,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
|
||||||
self.display_value_backup = {};
|
self.display_value_backup = {};
|
||||||
self.render_value();
|
self.render_value();
|
||||||
self.focus();
|
self.focus();
|
||||||
self.view.do_onchange(self);
|
self.trigger('changed_value');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
t-att-data-view-xmlid="xmlid if editable else None"
|
t-att-data-view-xmlid="xmlid if editable else None"
|
||||||
t-att-data-main-object="repr(main_object) if editable else None">
|
t-att-data-main-object="repr(main_object) if editable else None">
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript" src="/web/static/js/watch.js"></script>
|
<script type="text/javascript" src="/web/static/src/js/watch.js"></script>
|
||||||
<t t-if="main_object and 'website_meta_title' in main_object">
|
<t t-if="main_object and 'website_meta_title' in main_object">
|
||||||
<t t-set="title" t-value="main_object.website_meta_title"/>
|
<t t-set="title" t-value="main_object.website_meta_title"/>
|
||||||
</t>
|
</t>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue