[MERGE] Sync with trunk
bzr revid: tde@openerp.com-20140508123529-w91cb0e6ugzutqd1
This commit is contained in:
commit
400b194d60
|
@ -409,7 +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)
|
||||||
return self.pool['report'].get_action(cr, uid, [], 'account.report_invoice', context=context)
|
return self.pool['report'].get_action(cr, uid, ids, 'account.report_invoice', context=context)
|
||||||
|
|
||||||
def action_invoice_sent(self, cr, uid, ids, context=None):
|
def action_invoice_sent(self, cr, uid, ids, context=None):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1040,7 +1040,7 @@ class account_move_line(osv.osv):
|
||||||
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:
|
if len(all_moves) >= 2:
|
||||||
obj_move_line.reconcile_partial(cr, uid, all_moves, 'auto',context=context)
|
obj_move_line.reconcile_partial(cr, uid, all_moves, 'auto',context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -172,18 +172,15 @@ class res_partner(osv.osv):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _journal_item_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _journal_item_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'journal_item_count': 0, 'contracts_count': 0 }), ids))
|
MoveLine = self.pool('account.move.line')
|
||||||
|
AnalyticAccount = self.pool('account.analytic.account')
|
||||||
# the user may not have access rights
|
return {
|
||||||
try:
|
partner_id: {
|
||||||
for partner in self.browse(cr, uid, ids, context=context):
|
'journal_item_count': MoveLine.search_count(cr, uid, [('partner_id', '=', partner_id)], context=context),
|
||||||
res[partner.id] = {
|
'contracts_count': AnalyticAccount.search_count(cr,uid, [('partner_id', '=', partner_id)], context=context)
|
||||||
'journal_item_count': len(partner.journal_item_ids),
|
}
|
||||||
'contracts_count': len(partner.contract_ids)
|
for partner_id in ids
|
||||||
}
|
}
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
def has_something_to_reconcile(self, cr, uid, partner_id, context=None):
|
def has_something_to_reconcile(self, cr, uid, partner_id, context=None):
|
||||||
'''
|
'''
|
||||||
|
@ -215,7 +212,6 @@ class res_partner(osv.osv):
|
||||||
'debit_limit': fields.float('Payable Limit'),
|
'debit_limit': fields.float('Payable Limit'),
|
||||||
'total_invoiced': fields.function(_invoice_total, string="Total Invoiced", type='float'),
|
'total_invoiced': fields.function(_invoice_total, string="Total Invoiced", type='float'),
|
||||||
'contracts_count': fields.function(_journal_item_count, string="Contracts", type='integer', multi="invoice_journal"),
|
'contracts_count': fields.function(_journal_item_count, string="Contracts", type='integer', multi="invoice_journal"),
|
||||||
'journal_item_ids': fields.one2many('account.move.line', 'partner_id', 'Journal Items'),
|
|
||||||
'journal_item_count': fields.function(_journal_item_count, string="Journal Items", type="integer", multi="invoice_journal"),
|
'journal_item_count': fields.function(_journal_item_count, string="Journal Items", type="integer", multi="invoice_journal"),
|
||||||
'property_account_payable': fields.property(
|
'property_account_payable': fields.property(
|
||||||
type='many2one',
|
type='many2one',
|
||||||
|
|
|
@ -50,6 +50,6 @@ class account_analytic_balance(osv.osv_memory):
|
||||||
|
|
||||||
datas['form']['active_ids'] = context.get('active_ids', False)
|
datas['form']['active_ids'] = context.get('active_ids', False)
|
||||||
|
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticbalance', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_analyticbalance', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -49,6 +49,6 @@ class account_analytic_cost_ledger_journal_report(osv.osv_memory):
|
||||||
}
|
}
|
||||||
|
|
||||||
datas['form']['active_ids'] = context.get('active_ids', False)
|
datas['form']['active_ids'] = context.get('active_ids', False)
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticcostledgerquantity', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_analyticcostledgerquantity', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -49,6 +49,6 @@ class account_analytic_cost_ledger(osv.osv_memory):
|
||||||
|
|
||||||
datas['form']['active_ids'] = context.get('active_ids', False)
|
datas['form']['active_ids'] = context.get('active_ids', False)
|
||||||
|
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticcostledger', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_analyticcostledger', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -47,6 +47,6 @@ class account_analytic_inverted_balance(osv.osv_memory):
|
||||||
'form': data
|
'form': data
|
||||||
}
|
}
|
||||||
datas['form']['active_ids'] = context.get('active_ids', False)
|
datas['form']['active_ids'] = context.get('active_ids', False)
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_invertedanalyticbalance', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_invertedanalyticbalance', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -57,7 +57,7 @@ class account_analytic_journal_report(osv.osv_memory):
|
||||||
context2 = context.copy()
|
context2 = context.copy()
|
||||||
context2['active_model'] = 'account.analytic.journal'
|
context2['active_model'] = 'account.analytic.journal'
|
||||||
context2['active_ids'] = ids_list
|
context2['active_ids'] = ids_list
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticjournal', data=datas, context=context2)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_analyticjournal', data=datas, context=context2)
|
||||||
|
|
||||||
def default_get(self, cr, uid, fields, context=None):
|
def default_get(self, cr, uid, fields, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Quantity</th>
|
<th>Quantity</th>
|
||||||
<th groups="product.group_uom">Unit of measure</th>
|
|
||||||
<th class="text-right">Unit Price</th>
|
<th class="text-right">Unit Price</th>
|
||||||
<th class="text-right" groups="sale.group_discount_per_so_line">Discount (%)</th>
|
<th class="text-right" groups="sale.group_discount_per_so_line">Discount (%)</th>
|
||||||
<th class="text-right">Taxes</th>
|
<th class="text-right">Taxes</th>
|
||||||
|
@ -57,8 +56,10 @@
|
||||||
<tbody class="invoice_tbody">
|
<tbody class="invoice_tbody">
|
||||||
<tr t-foreach="o.invoice_line" t-as="l">
|
<tr t-foreach="o.invoice_line" t-as="l">
|
||||||
<td><span t-field="l.name"/></td>
|
<td><span t-field="l.name"/></td>
|
||||||
<td><span t-field="l.quantity"/></td>
|
<td>
|
||||||
<td groups="product.group_uom"><span t-field="l.uos_id"/></td>
|
<span t-field="l.quantity"/>
|
||||||
|
<span t-field="l.uos_id" groups="product.group_uom"/>
|
||||||
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<span t-field="l.price_unit"/>
|
<span t-field="l.price_unit"/>
|
||||||
</td>
|
</td>
|
||||||
|
@ -100,7 +101,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" t-if="o.tax_line">
|
<div class="row" t-if="o.tax_line">
|
||||||
<div class="col-xs-3">
|
<div class="col-xs-6">
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -136,7 +137,7 @@
|
||||||
</p>
|
</p>
|
||||||
<p t-if="o.fiscal_position">
|
<p t-if="o.fiscal_position">
|
||||||
<strong>Fiscal Position:</strong>
|
<strong>Fiscal Position:</strong>
|
||||||
<span t-field="o.fiscal_position.note"/>
|
<span t-field="o.fiscal_position"/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
|
|
|
@ -89,6 +89,6 @@ class accounting_report(osv.osv_memory):
|
||||||
|
|
||||||
def _print_report(self, cr, uid, ids, data, context=None):
|
def _print_report(self, cr, uid, ids, data, context=None):
|
||||||
data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter','target_move'], context=context)[0])
|
data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter','target_move'], context=context)[0])
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_financial', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_financial', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
|
||||||
class account_balance_report(osv.osv_memory):
|
class account_balance_report(osv.osv_memory):
|
||||||
_inherit = "account.common.account.report"
|
_inherit = "account.common.account.report"
|
||||||
_name = 'account.balance.report'
|
_name = 'account.balance.report'
|
||||||
|
@ -36,6 +37,6 @@ class account_balance_report(osv.osv_memory):
|
||||||
|
|
||||||
def _print_report(self, cr, uid, ids, data, context=None):
|
def _print_report(self, cr, uid, ids, data, context=None):
|
||||||
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_trialbalance', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_trialbalance', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -81,6 +81,6 @@ class account_aged_trial_balance(osv.osv_memory):
|
||||||
data['form'].update(res)
|
data['form'].update(res)
|
||||||
if data.get('form',False):
|
if data.get('form',False):
|
||||||
data['ids']=[data['form'].get('chart_account_id',False)]
|
data['ids']=[data['form'].get('chart_account_id',False)]
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_agedpartnerbalance', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_agedpartnerbalance', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
|
||||||
class account_central_journal(osv.osv_memory):
|
class account_central_journal(osv.osv_memory):
|
||||||
_name = 'account.central.journal'
|
_name = 'account.central.journal'
|
||||||
_description = 'Account Central Journal'
|
_description = 'Account Central Journal'
|
||||||
|
@ -32,6 +33,6 @@ class account_central_journal(osv.osv_memory):
|
||||||
|
|
||||||
def _print_report(self, cr, uid, ids, data, context=None):
|
def _print_report(self, cr, uid, ids, data, context=None):
|
||||||
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_centraljournal', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_centraljournal', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
|
||||||
class account_general_journal(osv.osv_memory):
|
class account_general_journal(osv.osv_memory):
|
||||||
_inherit = "account.common.journal.report"
|
_inherit = "account.common.journal.report"
|
||||||
_name = 'account.general.journal'
|
_name = 'account.general.journal'
|
||||||
|
@ -32,6 +33,6 @@ class account_general_journal(osv.osv_memory):
|
||||||
|
|
||||||
def _print_report(self, cr, uid, ids, data, context=None):
|
def _print_report(self, cr, uid, ids, data, context=None):
|
||||||
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_generaljournal', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_generaljournal', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -59,6 +59,6 @@ class account_report_general_ledger(osv.osv_memory):
|
||||||
if data['form']['landscape'] is False:
|
if data['form']['landscape'] is False:
|
||||||
data['form'].pop('landscape')
|
data['form'].pop('landscape')
|
||||||
|
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_generalledger', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_generalledger', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -44,6 +44,6 @@ class account_partner_balance(osv.osv_memory):
|
||||||
context = {}
|
context = {}
|
||||||
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
||||||
data['form'].update(self.read(cr, uid, ids, ['display_partner'])[0])
|
data['form'].update(self.read(cr, uid, ids, ['display_partner'])[0])
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerbalance', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_partnerbalance', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -58,7 +58,7 @@ class account_partner_ledger(osv.osv_memory):
|
||||||
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
||||||
data['form'].update(self.read(cr, uid, ids, ['initial_balance', 'filter', 'page_split', 'amount_currency'])[0])
|
data['form'].update(self.read(cr, uid, ids, ['initial_balance', 'filter', 'page_split', 'amount_currency'])[0])
|
||||||
if data['form'].get('page_split') is True:
|
if data['form'].get('page_split') is True:
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerledgerother', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_partnerledgerother', data=data, context=context)
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerledger', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_partnerledger', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -67,8 +67,8 @@ class account_print_journal(osv.osv_memory):
|
||||||
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
data = self.pre_print_report(cr, uid, ids, data, context=context)
|
||||||
data['form'].update(self.read(cr, uid, ids, ['sort_selection'], context=context)[0])
|
data['form'].update(self.read(cr, uid, ids, ['sort_selection'], context=context)[0])
|
||||||
if context.get('sale_purchase_only'):
|
if context.get('sale_purchase_only'):
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_salepurchasejournal', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_salepurchasejournal', data=data, context=context)
|
||||||
else:
|
else:
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_journal', data=data, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_journal', data=data, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -61,6 +61,6 @@ class account_vat_declaration(osv.osv_memory):
|
||||||
taxcode = taxcode_obj.browse(cr, uid, [taxcode_id], context=context)[0]
|
taxcode = taxcode_obj.browse(cr, uid, [taxcode_id], context=context)[0]
|
||||||
datas['form']['company_id'] = taxcode.company_id.id
|
datas['form']['company_id'] = taxcode.company_id.id
|
||||||
|
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account.report_vat', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account.report_vat', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -652,12 +652,10 @@ class account_analytic_account(osv.osv):
|
||||||
'nodestroy': True,
|
'nodestroy': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _prepare_invoice(self, cr, uid, contract, context=None):
|
def _prepare_invoice_data(self, cr, uid, contract, context=None):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
|
|
||||||
inv_obj = self.pool.get('account.invoice')
|
|
||||||
journal_obj = self.pool.get('account.journal')
|
journal_obj = self.pool.get('account.journal')
|
||||||
fpos_obj = self.pool.get('account.fiscal.position')
|
|
||||||
|
|
||||||
if not contract.partner_id:
|
if not contract.partner_id:
|
||||||
raise osv.except_osv(_('No Customer Defined!'),_("You must first select a Customer for Contract %s!") % contract.name )
|
raise osv.except_osv(_('No Customer Defined!'),_("You must first select a Customer for Contract %s!") % contract.name )
|
||||||
|
@ -678,33 +676,36 @@ class account_analytic_account(osv.osv):
|
||||||
elif contract.company_id:
|
elif contract.company_id:
|
||||||
currency_id = contract.company_id.currency_id.id
|
currency_id = contract.company_id.currency_id.id
|
||||||
|
|
||||||
inv_data = {
|
invoice = {
|
||||||
'reference': contract.code or False,
|
|
||||||
'account_id': contract.partner_id.property_account_receivable.id,
|
'account_id': contract.partner_id.property_account_receivable.id,
|
||||||
'type': 'out_invoice',
|
'type': 'out_invoice',
|
||||||
'partner_id': contract.partner_id.id,
|
'partner_id': contract.partner_id.id,
|
||||||
'currency_id': currency_id,
|
'currency_id': currency_id,
|
||||||
'journal_id': len(journal_ids) and journal_ids[0] or False,
|
'journal_id': len(journal_ids) and journal_ids[0] or False,
|
||||||
'date_invoice': contract.recurring_next_date,
|
'date_invoice': contract.recurring_next_date,
|
||||||
'origin': contract.name,
|
'origin': contract.code,
|
||||||
'fiscal_position': fpos and fpos.id,
|
'fiscal_position': fpos and fpos.id,
|
||||||
'payment_term': partner_payment_term,
|
'payment_term': partner_payment_term,
|
||||||
'company_id': contract.company_id.id or False,
|
'company_id': contract.company_id.id or False,
|
||||||
}
|
}
|
||||||
invoice_id = inv_obj.create(cr, uid, inv_data, context=context)
|
return invoice
|
||||||
|
|
||||||
|
def _prepare_invoice_lines(self, cr, uid, contract, fiscal_position_id, context=None):
|
||||||
|
fpos_obj = self.pool.get('account.fiscal.position')
|
||||||
|
fiscal_position = fpos_obj.browse(cr, uid, fiscal_position_id, context=context)
|
||||||
|
invoice_lines = []
|
||||||
for line in contract.recurring_invoice_line_ids:
|
for line in contract.recurring_invoice_line_ids:
|
||||||
|
|
||||||
res = line.product_id
|
res = line.product_id
|
||||||
account_id = res.property_account_income.id
|
account_id = res.property_account_income.id
|
||||||
if not account_id:
|
if not account_id:
|
||||||
account_id = res.categ_id.property_account_income_categ.id
|
account_id = res.categ_id.property_account_income_categ.id
|
||||||
account_id = fpos_obj.map_account(cr, uid, fpos, account_id)
|
account_id = fpos_obj.map_account(cr, uid, fiscal_position, account_id)
|
||||||
|
|
||||||
taxes = res.taxes_id or False
|
taxes = res.taxes_id or False
|
||||||
tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes)
|
tax_id = fpos_obj.map_tax(cr, uid, fiscal_position, taxes)
|
||||||
|
|
||||||
invoice_line_vals = {
|
invoice_lines.append((0, 0, {
|
||||||
'name': line.name,
|
'name': line.name,
|
||||||
'account_id': account_id,
|
'account_id': account_id,
|
||||||
'account_analytic_id': contract.id,
|
'account_analytic_id': contract.id,
|
||||||
|
@ -712,13 +713,14 @@ class account_analytic_account(osv.osv):
|
||||||
'quantity': line.quantity,
|
'quantity': line.quantity,
|
||||||
'uos_id': line.uom_id.id or False,
|
'uos_id': line.uom_id.id or False,
|
||||||
'product_id': line.product_id.id or False,
|
'product_id': line.product_id.id or False,
|
||||||
'invoice_id' : invoice_id,
|
|
||||||
'invoice_line_tax_id': [(6, 0, tax_id)],
|
'invoice_line_tax_id': [(6, 0, tax_id)],
|
||||||
}
|
}))
|
||||||
self.pool.get('account.invoice.line').create(cr, uid, invoice_line_vals, context=context)
|
return invoice_lines
|
||||||
|
|
||||||
inv_obj.button_compute(cr, uid, [invoice_id], context=context)
|
def _prepare_invoice(self, cr, uid, contract, context=None):
|
||||||
return invoice_id
|
invoice = self._prepare_invoice_data(cr, uid, contract, context=context)
|
||||||
|
invoice['invoice_line'] = self._prepare_invoice_lines(cr, uid, contract, invoice['fiscal_position'], context=context)
|
||||||
|
return invoice
|
||||||
|
|
||||||
def recurring_create_invoice(self, cr, uid, ids, context=None):
|
def recurring_create_invoice(self, cr, uid, ids, context=None):
|
||||||
return self._recurring_create_invoice(cr, uid, ids, context=context)
|
return self._recurring_create_invoice(cr, uid, ids, context=context)
|
||||||
|
@ -728,6 +730,7 @@ class account_analytic_account(osv.osv):
|
||||||
|
|
||||||
def _recurring_create_invoice(self, cr, uid, ids, automatic=False, context=None):
|
def _recurring_create_invoice(self, cr, uid, ids, automatic=False, context=None):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
|
invoice_ids = []
|
||||||
current_date = time.strftime('%Y-%m-%d')
|
current_date = time.strftime('%Y-%m-%d')
|
||||||
if ids:
|
if ids:
|
||||||
contract_ids = ids
|
contract_ids = ids
|
||||||
|
@ -735,8 +738,8 @@ class account_analytic_account(osv.osv):
|
||||||
contract_ids = self.search(cr, uid, [('recurring_next_date','<=', current_date), ('state','=', 'open'), ('recurring_invoices','=', True), ('type', '=', 'contract')])
|
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):
|
||||||
try:
|
try:
|
||||||
invoice_id = self._prepare_invoice(cr, uid, contract, context=context)
|
invoice_values = self._prepare_invoice(cr, uid, contract, context=context)
|
||||||
|
invoice_ids.append(self.pool['account.invoice'].create(cr, uid, invoice_values, 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':
|
||||||
|
@ -754,7 +757,7 @@ class account_analytic_account(osv.osv):
|
||||||
_logger.error(traceback.format_exc())
|
_logger.error(traceback.format_exc())
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
return True
|
return invoice_ids
|
||||||
|
|
||||||
class account_analytic_account_summary_user(osv.osv):
|
class account_analytic_account_summary_user(osv.osv):
|
||||||
_name = "account_analytic_analysis.summary.user"
|
_name = "account_analytic_analysis.summary.user"
|
||||||
|
|
|
@ -117,15 +117,12 @@ class sale_order_line(osv.osv):
|
||||||
class product_product(osv.Model):
|
class product_product(osv.Model):
|
||||||
_inherit = 'product.product'
|
_inherit = 'product.product'
|
||||||
def _rules_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _rules_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Analytic = self.pool['account.analytic.default']
|
||||||
try:
|
return {
|
||||||
for rule in self.browse(cr, uid, ids, context=context):
|
product_id: Analytic.search_count(cr, uid, [('product_id', '=', product_id)], context=context)
|
||||||
res[rule.id] = len(rule.rules_ids)
|
for product_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'rules_ids': fields.one2many('account.analytic.default', 'product_id', 'Analytic Rules '),
|
|
||||||
'rules_count': fields.function(_rules_count, string='# Analytic Rules', type='integer'),
|
'rules_count': fields.function(_rules_count, string='# Analytic Rules', type='integer'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import time
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
|
||||||
class account_crossovered_analytic(osv.osv_memory):
|
class account_crossovered_analytic(osv.osv_memory):
|
||||||
_name = "account.crossovered.analytic"
|
_name = "account.crossovered.analytic"
|
||||||
_description = "Print Crossovered Analytic"
|
_description = "Print Crossovered Analytic"
|
||||||
|
@ -65,6 +66,6 @@ class account_crossovered_analytic(osv.osv_memory):
|
||||||
'model': 'account.analytic.account',
|
'model': 'account.analytic.account',
|
||||||
'form': data
|
'form': data
|
||||||
}
|
}
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account_analytic_plans.report_crossoveredanalyticplans', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account_analytic_plans.report_crossoveredanalyticplans', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -238,13 +238,11 @@ class account_asset_asset(osv.osv):
|
||||||
val['value_residual'] = purchase_value - salvage_value
|
val['value_residual'] = purchase_value - salvage_value
|
||||||
return {'value': val}
|
return {'value': val}
|
||||||
def _entry_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _entry_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
MoveLine = self.pool('account.move.line')
|
||||||
try:
|
return {
|
||||||
for entry in self.browse(cr, uid, ids, context=context):
|
asset_id: MoveLine.search_count(cr, uid, [('asset_id', '=', asset_id)], context=context)
|
||||||
res[entry.id] = len(entry.account_move_line_ids)
|
for asset_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'account_move_line_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
|
'account_move_line_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
|
||||||
'entry_count': fields.function(_entry_count, string='# Asset Entries', type='integer'),
|
'entry_count': fields.function(_entry_count, string='# Asset Entries', type='integer'),
|
||||||
|
|
|
@ -46,6 +46,6 @@ class account_budget_analytic(osv.osv_memory):
|
||||||
'form': data
|
'form': data
|
||||||
}
|
}
|
||||||
datas['form']['ids'] = datas['ids']
|
datas['form']['ids'] = datas['ids']
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_analyticaccountbudget', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account_budget.report_analyticaccountbudget', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -47,6 +47,6 @@ class account_budget_crossvered_report(osv.osv_memory):
|
||||||
}
|
}
|
||||||
datas['form']['ids'] = datas['ids']
|
datas['form']['ids'] = datas['ids']
|
||||||
datas['form']['report'] = 'analytic-full'
|
datas['form']['report'] = 'analytic-full'
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_crossoveredbudget', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account_budget.report_crossoveredbudget', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -49,6 +49,6 @@ class account_budget_crossvered_summary_report(osv.osv_memory):
|
||||||
}
|
}
|
||||||
datas['form']['ids'] = datas['ids']
|
datas['form']['ids'] = datas['ids']
|
||||||
datas['form']['report'] = 'analytic-one'
|
datas['form']['report'] = 'analytic-one'
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_crossoveredbudget', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account_budget.report_crossoveredbudget', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -47,6 +47,6 @@ class account_budget_report(osv.osv_memory):
|
||||||
}
|
}
|
||||||
datas['form']['ids'] = datas['ids']
|
datas['form']['ids'] = datas['ids']
|
||||||
datas['form']['report'] = 'analytic-full'
|
datas['form']['report'] = 'analytic-full'
|
||||||
return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_budget', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account_budget.report_budget', data=datas, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -74,26 +74,17 @@ class account_voucher(osv.osv):
|
||||||
|
|
||||||
def print_check(self, cr, uid, ids, context=None):
|
def print_check(self, cr, uid, ids, context=None):
|
||||||
if not ids:
|
if not ids:
|
||||||
return {}
|
raise osv.except_osv(_('Printing error'), _('No check selected '))
|
||||||
|
|
||||||
check_layout_report = {
|
data = {
|
||||||
'top' : 'account.print.check.top',
|
'id': ids and ids[0],
|
||||||
'middle' : 'account.print.check.middle',
|
'ids': ids,
|
||||||
'bottom' : 'account.print.check.bottom',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_layout = self.browse(cr, uid, ids[0], context=context).company_id.check_layout
|
return self.pool['report'].get_action(
|
||||||
return {
|
cr, uid, [], 'account_check_writing.report_check', data=data, context=context
|
||||||
'type': 'ir.actions.report.xml',
|
)
|
||||||
'report_name':check_layout_report[check_layout],
|
|
||||||
'datas': {
|
|
||||||
'model':'account.voucher',
|
|
||||||
'id': ids and ids[0] or False,
|
|
||||||
'ids': ids and ids or [],
|
|
||||||
'report_type': 'pdf'
|
|
||||||
},
|
|
||||||
'nodestroy': True
|
|
||||||
}
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
if vals.get('amount') and vals.get('journal_id') and 'amount_in_word' not in vals:
|
if vals.get('amount') and vals.get('journal_id') and 'amount_in_word' not in vals:
|
||||||
vals['amount_in_word'] = self._amount_to_text(cr, uid, vals['amount'], vals.get('currency_id') or \
|
vals['amount_in_word'] = self._amount_to_text(cr, uid, vals['amount'], vals.get('currency_id') or \
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
|
||||||
class account_check_write(osv.osv_memory):
|
class account_check_write(osv.osv_memory):
|
||||||
_name = 'account.check.write'
|
_name = 'account.check.write'
|
||||||
_description = 'Prin Check in Batch'
|
_description = 'Prin Check in Batch'
|
||||||
|
@ -64,23 +64,11 @@ class account_check_write(osv.osv_memory):
|
||||||
ir_sequence_obj.write(cr, uid, sequence_id, {'number_next': new_value})
|
ir_sequence_obj.write(cr, uid, sequence_id, {'number_next': new_value})
|
||||||
|
|
||||||
#print the checks
|
#print the checks
|
||||||
check_layout_report = {
|
data = {
|
||||||
'top' : 'account.print.check.top',
|
'id': voucher_ids and voucher_ids[0],
|
||||||
'middle' : 'account.print.check.middle',
|
'ids': voucher_ids,
|
||||||
'bottom' : 'account.print.check.bottom',
|
|
||||||
}
|
}
|
||||||
check_layout = voucher_obj.browse(cr, uid, voucher_ids[0], context=context).company_id.check_layout
|
|
||||||
if not check_layout:
|
|
||||||
check_layout = 'top'
|
|
||||||
return {
|
|
||||||
'type': 'ir.actions.report.xml',
|
|
||||||
'report_name':check_layout_report[check_layout],
|
|
||||||
'datas': {
|
|
||||||
'model':'account.voucher',
|
|
||||||
'ids': voucher_ids,
|
|
||||||
'report_type': 'pdf'
|
|
||||||
},
|
|
||||||
'nodestroy': True
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
return self.pool['report'].get_action(
|
||||||
|
cr, uid, [], 'account_check_writing.report_check', data=data, context=context
|
||||||
|
)
|
||||||
|
|
|
@ -188,7 +188,7 @@ class res_partner(osv.osv):
|
||||||
'model': 'account_followup.followup',
|
'model': 'account_followup.followup',
|
||||||
'form': data
|
'form': data
|
||||||
}
|
}
|
||||||
return self.pool['report'].get_action(cr, uid, wizard_partner_ids, 'account_followup.report_followup', data=datas, context=context)
|
return self.pool['report'].get_action(cr, uid, [], 'account_followup.report_followup', data=datas, context=context)
|
||||||
|
|
||||||
def do_partner_mail(self, cr, uid, partner_ids, context=None):
|
def do_partner_mail(self, cr, uid, partner_ids, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="client_id" />
|
<field name="client_id" />
|
||||||
<field name="enabled" />
|
<field name="enabled" />
|
||||||
|
<field name="body" />
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="auth_endpoint" />
|
<field name="auth_endpoint" />
|
||||||
|
|
|
@ -14,7 +14,7 @@ msgstr ""
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2014-05-07 06:27+0000\n"
|
"X-Launchpad-Export-Date: 2014-05-08 05:38+0000\n"
|
||||||
"X-Generator: Launchpad (build 16996)\n"
|
"X-Generator: Launchpad (build 16996)\n"
|
||||||
"Language: zh_CN\n"
|
"Language: zh_CN\n"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
import stock_picking
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<div class="oe_right oe_button_box">
|
<div class="oe_right oe_button_box">
|
||||||
<button class="oe_inline oe_stat_button" type="action"
|
<button class="oe_inline oe_stat_button" type="action"
|
||||||
name="%(action_claim_from_delivery)d" icon="fa-comments" >
|
name="%(action_claim_from_delivery)d" icon="fa-comments" >
|
||||||
<field string="Claims" name="claim_count" widget="statinfo"/>
|
<field string="Claims" name="claim_count_out" widget="statinfo"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
|
||||||
|
class stock_picking(osv.osv):
|
||||||
|
_inherit = 'stock.picking'
|
||||||
|
|
||||||
|
def _claim_count_out(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
|
Claim = self.pool['crm.claim']
|
||||||
|
return {
|
||||||
|
id: Claim.search_count(cr, uid, [('ref', '=',('stock.picking.out,' + str(ids[0])))], context=context)
|
||||||
|
for id in ids
|
||||||
|
}
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'claim_count_out': fields.function(_claim_count_out, string='Claims', type='integer'),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Because of the way inheritance works in the ORM (bug), and the way stock.picking.out
|
||||||
|
# is defined (inherit from stock.picking, dispatch read to stock.picking), it is necessary
|
||||||
|
# to add the field claim_count_out to this class, even though the _claim_count_out method
|
||||||
|
# in stock_picking_out will not be called (but its existence will be checked).
|
||||||
|
class stock_picking_out(osv.osv):
|
||||||
|
_inherit = 'stock.picking.out'
|
||||||
|
|
||||||
|
def _claim_count_out(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
|
return super(stock_picking_out, self)._claim_count_out(cr, uid, ids, field_name, arg, context=context)
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'claim_count_out': fields.function(_claim_count_out, string='Claims', type='integer'),
|
||||||
|
}
|
|
@ -216,13 +216,11 @@ class crm_lead(format_address, osv.osv):
|
||||||
res[lead.id][field] = abs(int(duration))
|
res[lead.id][field] = abs(int(duration))
|
||||||
return res
|
return res
|
||||||
def _meeting_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _meeting_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Event = self.pool['calendar.event']
|
||||||
try:
|
return {
|
||||||
for meeting in self.browse(cr, uid, ids, context=context):
|
opp_id: Event.search_count(cr,uid, [('opportunity_id', '=', opp_id)], context=context)
|
||||||
res[meeting.id] = len(meeting.meeting_ids)
|
for opp_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange',
|
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange',
|
||||||
select=True, help="Linked partner (optional). Usually created when converting the lead."),
|
select=True, help="Linked partner (optional). Usually created when converting the lead."),
|
||||||
|
@ -297,7 +295,6 @@ class crm_lead(format_address, osv.osv):
|
||||||
'payment_mode': fields.many2one('crm.payment.mode', 'Payment Mode', \
|
'payment_mode': fields.many2one('crm.payment.mode', 'Payment Mode', \
|
||||||
domain="[('section_id','=',section_id)]"),
|
domain="[('section_id','=',section_id)]"),
|
||||||
'planned_cost': fields.float('Planned Costs'),
|
'planned_cost': fields.float('Planned Costs'),
|
||||||
'meeting_ids': fields.one2many('calendar.event', 'opportunity_id', 'Opportunities'),
|
|
||||||
'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'),
|
'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<record model="crm.case.stage" id="stage_lead2">
|
<record model="crm.case.stage" id="stage_lead2">
|
||||||
<field name="name">Dead</field>
|
<field name="name">Dead</field>
|
||||||
<field name="case_default">1</field>
|
<field name="case_default">1</field>
|
||||||
|
<field name="fold">1</field>
|
||||||
<field name="probability">0</field>
|
<field name="probability">0</field>
|
||||||
<field name="on_change">1</field>
|
<field name="on_change">1</field>
|
||||||
<field name="sequence">30</field>
|
<field name="sequence">30</field>
|
||||||
|
|
|
@ -32,14 +32,6 @@ class crm_phonecall(osv.osv):
|
||||||
_order = "id desc"
|
_order = "id desc"
|
||||||
_inherit = ['mail.thread']
|
_inherit = ['mail.thread']
|
||||||
|
|
||||||
def _meeting_count(self, cr, uid, ids, field_name, arg, context=None):
|
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
|
||||||
try:
|
|
||||||
for meeting in self.browse(cr, uid, ids, context=context):
|
|
||||||
res[meeting.id] = len(meeting.meeting_ids)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'date_action_last': fields.datetime('Last Action', readonly=1),
|
'date_action_last': fields.datetime('Last Action', readonly=1),
|
||||||
'date_action_next': fields.datetime('Next Action', readonly=1),
|
'date_action_next': fields.datetime('Next Action', readonly=1),
|
||||||
|
@ -74,8 +66,6 @@ class crm_phonecall(osv.osv):
|
||||||
'date_closed': fields.datetime('Closed', readonly=True),
|
'date_closed': fields.datetime('Closed', readonly=True),
|
||||||
'date': fields.datetime('Date'),
|
'date': fields.datetime('Date'),
|
||||||
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
|
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
|
||||||
'meeting_ids': fields.one2many('calendar.event', 'phonecall_id', 'Phonecalls'),
|
|
||||||
'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_default_state(self, cr, uid, context=None):
|
def _get_default_state(self, cr, uid, context=None):
|
||||||
|
|
|
@ -33,10 +33,11 @@ class res_partner(osv.osv):
|
||||||
res[partner.id] = {
|
res[partner.id] = {
|
||||||
'opportunity_count': len(partner.opportunity_ids),
|
'opportunity_count': len(partner.opportunity_ids),
|
||||||
'meeting_count': len(partner.meeting_ids),
|
'meeting_count': len(partner.meeting_ids),
|
||||||
'phonecall_count': len(partner.meeting_ids),
|
|
||||||
}
|
}
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
for partner in self.browse(cr, uid, ids, context):
|
||||||
|
res[partner.id]['phonecall_count'] = len(partner.phonecall_ids)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
|
|
@ -88,7 +88,7 @@ Find duplicates, merge leads and assign them to the right salesperson in one ope
|
||||||
<p class="oe_mt32">
|
<p class="oe_mt32">
|
||||||
Get your opportunities organized to stay focused on the best deals. Manage all your customer interactions from the opportunity like emails, phone calls, internal notes, meetings and quotations.
|
Get your opportunities organized to stay focused on the best deals. Manage all your customer interactions from the opportunity like emails, phone calls, internal notes, meetings and quotations.
|
||||||
</p><p>
|
</p><p>
|
||||||
Follow opportunities that interrests you to get notified upon specific events: deal won or lost, stage changed, new customer demand, etc.
|
Follow opportunities that interest you to get notified upon specific events: deal won or lost, stage changed, new customer demand, etc.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -191,15 +191,13 @@ class crm_claim(osv.osv):
|
||||||
class res_partner(osv.osv):
|
class res_partner(osv.osv):
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Claim = self.pool['crm.claim']
|
||||||
try:
|
return {
|
||||||
for partner in self.browse(cr, uid, ids, context=context):
|
partner_id: Claim.search_count(cr,uid, [('partner_id', '=', partner_id)], context=context)
|
||||||
res[partner.id] = len(partner.claims_ids)
|
for partner_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'claims_ids': fields.one2many('crm.claim', 'partner_id', 'Claims'),
|
|
||||||
'claim_count': fields.function(_claim_count, string='# Claims', type='integer'),
|
'claim_count': fields.function(_claim_count, string='# Claims', type='integer'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ class product_template(osv.osv):
|
||||||
|
|
||||||
class product(osv.osv):
|
class product(osv.osv):
|
||||||
_inherit = 'product.product'
|
_inherit = 'product.product'
|
||||||
|
_columns = {
|
||||||
|
'event_ticket_ids': fields.one2many('event.event.ticket', 'product_id', 'Event Tickets'),
|
||||||
|
}
|
||||||
|
|
||||||
def onchange_event_ok(self, cr, uid, ids, type, event_ok, context=None):
|
def onchange_event_ok(self, cr, uid, ids, type, event_ok, context=None):
|
||||||
# cannot directly forward to product.template as the ids are theoretically different
|
# cannot directly forward to product.template as the ids are theoretically different
|
||||||
|
|
|
@ -315,18 +315,21 @@ class fleet_vehicle(osv.Model):
|
||||||
return model_id
|
return model_id
|
||||||
|
|
||||||
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'odometer_count': 0, 'fuel_logs_count': 0, 'service_count': 0, 'contract_count': 0, 'cost_count': 0,}), ids))
|
Odometer = self.pool['fleet.vehicle.odometer']
|
||||||
try:
|
LogFuel = self.pool['fleet.vehicle.log.fuel']
|
||||||
for costs in self.browse(cr, uid, ids, context=context):
|
LogService = self.pool['fleet.vehicle.log.services']
|
||||||
res[costs.id] = {'odometer_count': len(costs.odometer_ids),
|
LogContract = self.pool['fleet.vehicle.log.contract']
|
||||||
'fuel_logs_count': len(costs.log_fuel),
|
Cost = self.pool['fleet.vehicle.cost']
|
||||||
'service_count': len(costs.log_services),
|
return {
|
||||||
'contract_count': len(costs.log_contracts),
|
vehicle_id: {
|
||||||
'cost_count': len(costs.costs_ids)
|
'odometer_count': Odometer.search_count(cr, uid, [('vehicle_id', '=', vehicle_id)], context=context),
|
||||||
}
|
'fuel_logs_count': LogFuel.search_count(cr, uid, [('vehicle_id', '=', vehicle_id)], context=context),
|
||||||
except:
|
'service_count': LogService.search_count(cr, uid, [('vehicle_id', '=', vehicle_id)], context=context),
|
||||||
pass
|
'contract_count': LogContract.search_count(cr, uid, [('vehicle_id', '=', vehicle_id)], context=context),
|
||||||
return res
|
'cost_count': Cost.search_count(cr, uid, [('vehicle_id', '=', vehicle_id), ('parent_id', '=', False)], context=context)
|
||||||
|
}
|
||||||
|
for vehicle_id in ids
|
||||||
|
}
|
||||||
|
|
||||||
_name = 'fleet.vehicle'
|
_name = 'fleet.vehicle'
|
||||||
_description = 'Information on a vehicle'
|
_description = 'Information on a vehicle'
|
||||||
|
@ -341,8 +344,6 @@ class fleet_vehicle(osv.Model):
|
||||||
'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'),
|
'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'),
|
||||||
'log_services': fields.one2many('fleet.vehicle.log.services', 'vehicle_id', 'Services Logs'),
|
'log_services': fields.one2many('fleet.vehicle.log.services', 'vehicle_id', 'Services Logs'),
|
||||||
'log_contracts': fields.one2many('fleet.vehicle.log.contract', 'vehicle_id', 'Contracts'),
|
'log_contracts': fields.one2many('fleet.vehicle.log.contract', 'vehicle_id', 'Contracts'),
|
||||||
'costs_ids': fields.one2many('fleet.vehicle.cost', 'vehicle_id', 'Costs'),
|
|
||||||
'odometer_ids': fields.one2many('fleet.vehicle.odometer', 'vehicle_id', 'Odometer'),
|
|
||||||
'cost_count': fields.function(_count_all, type='integer', string="Costs" , multi=True),
|
'cost_count': fields.function(_count_all, type='integer', string="Costs" , multi=True),
|
||||||
'contract_count': fields.function(_count_all, type='integer', string='Contracts', multi=True),
|
'contract_count': fields.function(_count_all, type='integer', string='Contracts', multi=True),
|
||||||
'service_count': fields.function(_count_all, type='integer', string='Services', multi=True),
|
'service_count': fields.function(_count_all, type='integer', string='Services', multi=True),
|
||||||
|
|
|
@ -217,15 +217,7 @@ class gamification_challenge(osv.Model):
|
||||||
vals['user_ids'] = []
|
vals['user_ids'] = []
|
||||||
vals['user_ids'] += [(4, user_id) for user_id in user_ids]
|
vals['user_ids'] += [(4, user_id) for user_id in user_ids]
|
||||||
|
|
||||||
create_res = super(gamification_challenge, self).create(cr, uid, vals, context=context)
|
return super(gamification_challenge, self).create(cr, uid, vals, context=context)
|
||||||
|
|
||||||
# subscribe new users to the challenge
|
|
||||||
if vals.get('user_ids'):
|
|
||||||
# done with browse after super to be sure catch all after orm process
|
|
||||||
challenge = self.browse(cr, uid, create_res, context=context)
|
|
||||||
self.message_subscribe_users(cr, uid, [challenge.id], [user.id for user in challenge.user_ids], context=context)
|
|
||||||
|
|
||||||
return create_res
|
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
if isinstance(ids, (int,long)):
|
if isinstance(ids, (int,long)):
|
||||||
|
@ -240,6 +232,11 @@ class gamification_challenge(osv.Model):
|
||||||
|
|
||||||
write_res = super(gamification_challenge, self).write(cr, uid, ids, vals, context=context)
|
write_res = super(gamification_challenge, self).write(cr, uid, ids, vals, context=context)
|
||||||
|
|
||||||
|
if vals.get('report_message_frequency', 'never') != 'never':
|
||||||
|
# _recompute_challenge_users do not set users for challenges with no reports, subscribing them now
|
||||||
|
for challenge in self.browse(cr, uid, ids, context=context):
|
||||||
|
self.message_subscribe(cr, uid, [challenge.id], [user.partner_id.id for user in challenge.user_ids], context=context)
|
||||||
|
|
||||||
if vals.get('state') == 'inprogress':
|
if vals.get('state') == 'inprogress':
|
||||||
self._recompute_challenge_users(cr, uid, ids, context=context)
|
self._recompute_challenge_users(cr, uid, ids, context=context)
|
||||||
self._generate_goals_from_challenge(cr, uid, ids, context=context)
|
self._generate_goals_from_challenge(cr, uid, ids, context=context)
|
||||||
|
@ -264,6 +261,9 @@ class gamification_challenge(osv.Model):
|
||||||
- Create the missing goals (eg: modified the challenge to add lines)
|
- Create the missing goals (eg: modified the challenge to add lines)
|
||||||
- Update every running challenge
|
- Update every running challenge
|
||||||
"""
|
"""
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
|
|
||||||
# start scheduled challenges
|
# start scheduled challenges
|
||||||
planned_challenge_ids = self.search(cr, uid, [
|
planned_challenge_ids = self.search(cr, uid, [
|
||||||
('state', '=', 'draft'),
|
('state', '=', 'draft'),
|
||||||
|
@ -281,6 +281,9 @@ class gamification_challenge(osv.Model):
|
||||||
if not ids:
|
if not ids:
|
||||||
ids = self.search(cr, uid, [('state', '=', 'inprogress')], context=context)
|
ids = self.search(cr, uid, [('state', '=', 'inprogress')], context=context)
|
||||||
|
|
||||||
|
# in cron mode, will do intermediate commits
|
||||||
|
# TODO in trunk: replace by parameter
|
||||||
|
context.update({'commit_gamification': True})
|
||||||
return self._update_all(cr, uid, ids, context=context)
|
return self._update_all(cr, uid, ids, context=context)
|
||||||
|
|
||||||
def _update_all(self, cr, uid, ids, context=None):
|
def _update_all(self, cr, uid, ids, context=None):
|
||||||
|
@ -355,11 +358,6 @@ class gamification_challenge(osv.Model):
|
||||||
if write_op:
|
if write_op:
|
||||||
self.write(cr, uid, [challenge.id], {'user_ids': write_op}, context=context)
|
self.write(cr, uid, [challenge.id], {'user_ids': write_op}, context=context)
|
||||||
|
|
||||||
if to_remove_ids:
|
|
||||||
self.message_unsubscribe_users(cr, uid, [challenge.id], to_remove_ids, context=None)
|
|
||||||
if to_add_ids:
|
|
||||||
self.message_subscribe_users(cr, uid, [challenge.id], to_add_ids, context=context)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,9 +391,9 @@ class gamification_challenge(osv.Model):
|
||||||
:param list(int) ids: the list of challenge concerned"""
|
:param list(int) ids: the list of challenge concerned"""
|
||||||
|
|
||||||
goal_obj = self.pool.get('gamification.goal')
|
goal_obj = self.pool.get('gamification.goal')
|
||||||
to_update = []
|
|
||||||
for challenge in self.browse(cr, uid, ids, context=context):
|
for challenge in self.browse(cr, uid, ids, context=context):
|
||||||
(start_date, end_date) = start_end_date_for_period(challenge.period)
|
(start_date, end_date) = start_end_date_for_period(challenge.period)
|
||||||
|
to_update = []
|
||||||
|
|
||||||
# if no periodicity, use challenge dates
|
# if no periodicity, use challenge dates
|
||||||
if not start_date and challenge.start_date:
|
if not start_date and challenge.start_date:
|
||||||
|
@ -426,7 +424,15 @@ class gamification_challenge(osv.Model):
|
||||||
|
|
||||||
cr.execute(query, query_params)
|
cr.execute(query, query_params)
|
||||||
user_with_goal_ids = cr.dictfetchall()
|
user_with_goal_ids = cr.dictfetchall()
|
||||||
user_without_goal_ids = list(set([user.id for user in challenge.user_ids]) - set([user['user_id'] for user in user_with_goal_ids]))
|
|
||||||
|
participant_user_ids = [user.id for user in challenge.user_ids]
|
||||||
|
user_without_goal_ids = list(set(participant_user_ids) - set([user['user_id'] for user in user_with_goal_ids]))
|
||||||
|
user_squating_challenge_ids = list(set([user['user_id'] for user in user_with_goal_ids]) - set(participant_user_ids))
|
||||||
|
if user_squating_challenge_ids:
|
||||||
|
# users that used to match the challenge
|
||||||
|
goal_to_remove_ids = goal_obj.search(cr, uid, [('challenge_id', '=', challenge.id), ('user_id', 'in', user_squating_challenge_ids)], context=context)
|
||||||
|
goal_obj.unlink(cr, uid, goal_to_remove_ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
'definition_id': line.definition_id.id,
|
'definition_id': line.definition_id.id,
|
||||||
|
@ -614,9 +620,10 @@ class gamification_challenge(osv.Model):
|
||||||
ctx.update({'challenge_lines': lines_boards})
|
ctx.update({'challenge_lines': lines_boards})
|
||||||
body_html = temp_obj.render_template(cr, uid, challenge.report_template_id.body_html, 'gamification.challenge', challenge.id, context=ctx)
|
body_html = temp_obj.render_template(cr, uid, challenge.report_template_id.body_html, 'gamification.challenge', challenge.id, context=ctx)
|
||||||
|
|
||||||
# send to every follower of the challenge
|
# send to every follower and participant of the challenge
|
||||||
self.message_post(cr, uid, challenge.id,
|
self.message_post(cr, uid, challenge.id,
|
||||||
body=body_html,
|
body=body_html,
|
||||||
|
partner_ids=[user.partner_id.id for user in challenge.user_ids],
|
||||||
context=context,
|
context=context,
|
||||||
subtype='mail.mt_comment')
|
subtype='mail.mt_comment')
|
||||||
if challenge.report_message_group_id:
|
if challenge.report_message_group_id:
|
||||||
|
@ -698,34 +705,35 @@ class gamification_challenge(osv.Model):
|
||||||
rewarded_users = []
|
rewarded_users = []
|
||||||
challenge_ended = end_date == yesterday.strftime(DF) or force
|
challenge_ended = end_date == yesterday.strftime(DF) or force
|
||||||
if challenge.reward_id and challenge_ended or challenge.reward_realtime:
|
if challenge.reward_id and challenge_ended or challenge.reward_realtime:
|
||||||
for user in challenge.user_ids:
|
# not using start_date as intemportal goals have a start date but no end_date
|
||||||
reached_goal_ids = self.pool.get('gamification.goal').search(cr, uid, [
|
reached_goals = self.pool.get('gamification.goal').read_group(cr, uid, [
|
||||||
('challenge_id', '=', challenge.id),
|
('challenge_id', '=', challenge.id),
|
||||||
('user_id', '=', user.id),
|
('end_date', '=', end_date),
|
||||||
('start_date', '=', start_date),
|
('state', '=', 'reached')
|
||||||
('end_date', '=', end_date),
|
], fields=['user_id'], groupby=['user_id'], context=context)
|
||||||
('state', '=', 'reached')
|
for reach_goals_user in reached_goals:
|
||||||
], context=context)
|
if reach_goals_user['user_id_count'] == len(challenge.line_ids):
|
||||||
if len(reached_goal_ids) == len(challenge.line_ids):
|
|
||||||
# the user has succeeded every assigned goal
|
# the user has succeeded every assigned goal
|
||||||
|
user_id = reach_goals_user['user_id'][0]
|
||||||
if challenge.reward_realtime:
|
if challenge.reward_realtime:
|
||||||
badges = self.pool['gamification.badge.user'].search(cr, uid, [
|
badges = self.pool['gamification.badge.user'].search(cr, uid, [
|
||||||
('challenge_id', '=', challenge.id),
|
('challenge_id', '=', challenge.id),
|
||||||
('badge_id', '=', challenge.reward_id.id),
|
('badge_id', '=', challenge.reward_id.id),
|
||||||
('user_id', '=', user.id),
|
('user_id', '=', user_id),
|
||||||
], count=True, context=context)
|
], count=True, context=context)
|
||||||
if badges > 0:
|
if badges > 0:
|
||||||
# has already recieved the badge for this challenge
|
# has already recieved the badge for this challenge
|
||||||
continue
|
continue
|
||||||
self.reward_user(cr, uid, user.id, challenge.reward_id.id, challenge.id, context=context)
|
self.reward_user(cr, uid, user_id, challenge.reward_id.id, challenge.id, context=context)
|
||||||
rewarded_users.append(user)
|
rewarded_users.append(user_id)
|
||||||
|
|
||||||
if challenge_ended:
|
if challenge_ended:
|
||||||
# open chatter message
|
# open chatter message
|
||||||
message_body = _("The challenge %s is finished." % challenge.name)
|
message_body = _("The challenge %s is finished." % challenge.name)
|
||||||
|
|
||||||
if rewarded_users:
|
if rewarded_users:
|
||||||
message_body += _("<br/>Reward (badge %s) for every succeeding user was sent to %s." % (challenge.reward_id.name, ", ".join([user.name for user in rewarded_users])))
|
user_names = self.pool['res.users'].name_get(cr, uid, rewarded_users, context=context)
|
||||||
|
message_body += _("<br/>Reward (badge %s) for every succeeding user was sent to %s." % (challenge.reward_id.name, ", ".join([name for (user_id, name) in user_names])))
|
||||||
else:
|
else:
|
||||||
message_body += _("<br/>Nobody has succeeded to reach every goal, no badge is rewared for this challenge.")
|
message_body += _("<br/>Nobody has succeeded to reach every goal, no badge is rewared for this challenge.")
|
||||||
|
|
||||||
|
@ -746,7 +754,10 @@ class gamification_challenge(osv.Model):
|
||||||
self.reward_user(cr, uid, third_user.id, challenge.reward_second_id.id, challenge.id, context=context)
|
self.reward_user(cr, uid, third_user.id, challenge.reward_second_id.id, challenge.id, context=context)
|
||||||
message_body += "<br/> 3. %s - %s" % (third_user.name, challenge.reward_third_id.name)
|
message_body += "<br/> 3. %s - %s" % (third_user.name, challenge.reward_third_id.name)
|
||||||
|
|
||||||
self.message_post(cr, uid, challenge.id, body=message_body, context=context)
|
self.message_post(cr, uid, challenge.id,
|
||||||
|
partner_ids=[user.partner_id.id for user in challenge.user_ids],
|
||||||
|
body=message_body,
|
||||||
|
context=context)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,6 @@ class gamification_goal(osv.Model):
|
||||||
|
|
||||||
_name = 'gamification.goal'
|
_name = 'gamification.goal'
|
||||||
_description = 'Gamification goal instance'
|
_description = 'Gamification goal instance'
|
||||||
_inherit = 'mail.thread'
|
|
||||||
|
|
||||||
def _get_completion(self, cr, uid, ids, field_name, arg, context=None):
|
def _get_completion(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
"""Return the percentage of completeness of the goal, between 0 and 100"""
|
"""Return the percentage of completeness of the goal, between 0 and 100"""
|
||||||
|
@ -226,8 +225,7 @@ class gamification_goal(osv.Model):
|
||||||
temp_obj = self.pool.get('email.template')
|
temp_obj = self.pool.get('email.template')
|
||||||
template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_goal_reminder', context)
|
template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_goal_reminder', context)
|
||||||
body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.goal', goal.id, context=context)
|
body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.goal', goal.id, context=context)
|
||||||
|
self.pool['mail.thread'].message_post(cr, uid, 0, body=body_html, partner_ids=[goal.user_id.partner_id.id], context=context, subtype='mail.mt_comment')
|
||||||
self.message_post(cr, uid, goal.id, body=body_html, partner_ids=[goal.user_id.partner_id.id], context=context, subtype='mail.mt_comment')
|
|
||||||
return {'to_update': True}
|
return {'to_update': True}
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
@ -241,9 +239,9 @@ class gamification_goal(osv.Model):
|
||||||
the target value being reached, the goal is set as failed."""
|
the target value being reached, the goal is set as failed."""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
commit = context.get('commit_gamification', False)
|
||||||
|
|
||||||
goals_by_definition = {}
|
goals_by_definition = {}
|
||||||
goals_to_write = {}
|
|
||||||
all_goals = {}
|
all_goals = {}
|
||||||
for goal in self.browse(cr, uid, ids, context=context):
|
for goal in self.browse(cr, uid, ids, context=context):
|
||||||
if goal.state in ('draft', 'canceled'):
|
if goal.state in ('draft', 'canceled'):
|
||||||
|
@ -251,10 +249,10 @@ class gamification_goal(osv.Model):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
goals_by_definition.setdefault(goal.definition_id, []).append(goal)
|
goals_by_definition.setdefault(goal.definition_id, []).append(goal)
|
||||||
goals_to_write[goal.id] = {}
|
|
||||||
all_goals[goal.id] = goal
|
all_goals[goal.id] = goal
|
||||||
|
|
||||||
for definition, goals in goals_by_definition.items():
|
for definition, goals in goals_by_definition.items():
|
||||||
|
goals_to_write = dict((goal.id, {}) for goal in goals)
|
||||||
if definition.computation_mode == 'manually':
|
if definition.computation_mode == 'manually':
|
||||||
for goal in goals:
|
for goal in goals:
|
||||||
goals_to_write[goal.id].update(self._check_remind_delay(cr, uid, goal, context))
|
goals_to_write[goal.id].update(self._check_remind_delay(cr, uid, goal, context))
|
||||||
|
@ -345,22 +343,24 @@ class gamification_goal(osv.Model):
|
||||||
if new_value != goal.current:
|
if new_value != goal.current:
|
||||||
goals_to_write[goal.id]['current'] = new_value
|
goals_to_write[goal.id]['current'] = new_value
|
||||||
|
|
||||||
for goal_id, value in goals_to_write.items():
|
for goal_id, value in goals_to_write.items():
|
||||||
if not value:
|
if not value:
|
||||||
continue
|
continue
|
||||||
goal = all_goals[goal_id]
|
goal = all_goals[goal_id]
|
||||||
|
|
||||||
# check goal target reached
|
# check goal target reached
|
||||||
if (goal.definition_condition == 'higher' and value.get('current', goal.current) >= goal.target_goal) \
|
if (goal.definition_condition == 'higher' and value.get('current', goal.current) >= goal.target_goal) \
|
||||||
or (goal.definition_condition == 'lower' and value.get('current', goal.current) <= goal.target_goal):
|
or (goal.definition_condition == 'lower' and value.get('current', goal.current) <= goal.target_goal):
|
||||||
value['state'] = 'reached'
|
value['state'] = 'reached'
|
||||||
|
|
||||||
# check goal failure
|
# check goal failure
|
||||||
elif goal.end_date and fields.date.today() > goal.end_date:
|
elif goal.end_date and fields.date.today() > goal.end_date:
|
||||||
value['state'] = 'failed'
|
value['state'] = 'failed'
|
||||||
value['closed'] = True
|
value['closed'] = True
|
||||||
if value:
|
if value:
|
||||||
self.write(cr, uid, [goal.id], value, context=context)
|
self.write(cr, uid, [goal.id], value, context=context)
|
||||||
|
if commit:
|
||||||
|
cr.commit()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_start(self, cr, uid, ids, context=None):
|
def action_start(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -86,10 +86,6 @@
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</sheet>
|
</sheet>
|
||||||
<div class="oe_chatter">
|
|
||||||
<field name="message_follower_ids" widget="mail_followers"/>
|
|
||||||
<field name="message_ids" widget="mail_thread"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -248,7 +248,13 @@ class hr_employee(osv.osv):
|
||||||
'image': _get_default_image,
|
'image': _get_default_image,
|
||||||
'color': 0,
|
'color': 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def copy_data(self, cr, uid, ids, default=None, context=None):
|
||||||
|
if default is None:
|
||||||
|
default = {}
|
||||||
|
default.update({'child_ids': False})
|
||||||
|
return super(hr_employee, self).copy_data(cr, uid, ids, default, context=context)
|
||||||
|
|
||||||
def _broadcast_welcome(self, cr, uid, employee_id, context=None):
|
def _broadcast_welcome(self, cr, uid, employee_id, context=None):
|
||||||
""" Broadcast the welcome message to all users in the employee company. """
|
""" Broadcast the welcome message to all users in the employee company. """
|
||||||
employee = self.browse(cr, uid, employee_id, context=context)
|
employee = self.browse(cr, uid, employee_id, context=context)
|
||||||
|
@ -421,18 +427,23 @@ class hr_department(osv.osv):
|
||||||
res.append((record['id'], name))
|
res.append((record['id'], name))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def copy(self, cr, uid, ids, default=None, context=None):
|
def copy_data(self, cr, uid, ids, default=None, context=None):
|
||||||
if default is None:
|
if default is None:
|
||||||
default = {}
|
default = {}
|
||||||
default = default.copy()
|
|
||||||
default['member_ids'] = []
|
default['member_ids'] = []
|
||||||
return super(hr_department, self).copy(cr, uid, ids, default, context=context)
|
return super(hr_department, self).copy_data(cr, uid, ids, default, context=context)
|
||||||
|
|
||||||
|
|
||||||
class res_users(osv.osv):
|
class res_users(osv.osv):
|
||||||
_name = 'res.users'
|
_name = 'res.users'
|
||||||
_inherit = 'res.users'
|
_inherit = 'res.users'
|
||||||
|
|
||||||
|
def copy_data(self, cr, uid, ids, default=None, context=None):
|
||||||
|
if default is None:
|
||||||
|
default = {}
|
||||||
|
default.update({'employee_ids': False})
|
||||||
|
return super(res_users, self).copy_data(cr, uid, ids, default, context=context)
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'employee_ids': fields.one2many('hr.employee', 'user_id', 'Related employees'),
|
'employee_ids': fields.one2many('hr.employee', 'user_id', 'Related employees'),
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,13 +39,11 @@ class hr_employee(osv.osv):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _contracts_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _contracts_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Contract = self.pool['hr.contract']
|
||||||
try:
|
return {
|
||||||
for employee in self.browse(cr, uid, ids, context=context):
|
employee_id: Contract.search_count(cr,uid, [('employee_id', '=', employee_id)], context=context)
|
||||||
res[employee.id] = len(employee.contract_ids)
|
for employee_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'manager': fields.boolean('Is a Manager'),
|
'manager': fields.boolean('Is a Manager'),
|
||||||
|
|
|
@ -104,19 +104,15 @@ class hr_employee(osv.Model):
|
||||||
_inherit="hr.employee"
|
_inherit="hr.employee"
|
||||||
|
|
||||||
def _appraisal_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _appraisal_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Evaluation = self.pool['hr.evaluation.interview']
|
||||||
try:
|
return {
|
||||||
for employee in self.browse(cr, uid, ids, context=context):
|
employee_id: Evaluation.search_count(cr, uid, [('user_to_review_id', '=', employee_id)], context=context)
|
||||||
res[employee.id] = len(employee.appraisal_ids)
|
for employee_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'evaluation_plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan'),
|
'evaluation_plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan'),
|
||||||
'evaluation_date': fields.date('Next Appraisal Date', help="The date of the next appraisal is computed by the appraisal plan's dates (first appraisal + periodicity)."),
|
'evaluation_date': fields.date('Next Appraisal Date', help="The date of the next appraisal is computed by the appraisal plan's dates (first appraisal + periodicity)."),
|
||||||
'appraisal_ids': fields.one2many('hr.evaluation.interview', 'user_to_review_id', 'Appraisal Interviews'),
|
|
||||||
'appraisal_count': fields.function(_appraisal_count, type='integer', string='Appraisal Interviews'),
|
'appraisal_count': fields.function(_appraisal_count, type='integer', string='Appraisal Interviews'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -550,13 +550,11 @@ class hr_employee(osv.osv):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _leaves_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _leaves_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Holidays = self.pool['hr.holidays']
|
||||||
try:
|
return {
|
||||||
for employee in self.browse(cr, uid, ids, context=context):
|
employee_id: Holidays.search_count(cr,uid, [('employee_id', '=', employee_id)], context=context)
|
||||||
res[employee.id] = len(employee.leave_ids)
|
for employee_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'remaining_leaves': fields.function(_get_remaining_days, string='Remaining Legal Leaves', fnct_inv=_set_remaining_days, type="float", help='Total number of legal leaves allocated to this employee, change this value to create allocation/leave request. Total based on all the leave types without overriding limit.'),
|
'remaining_leaves': fields.function(_get_remaining_days, string='Remaining Legal Leaves', fnct_inv=_set_remaining_days, type="float", help='Total number of legal leaves allocated to this employee, change this value to create allocation/leave request. Total based on all the leave types without overriding limit.'),
|
||||||
|
@ -566,7 +564,6 @@ class hr_employee(osv.osv):
|
||||||
'current_leave_id': fields.function(_get_leave_status, multi="leave_status", string="Current Leave Type",type='many2one', relation='hr.holidays.status'),
|
'current_leave_id': fields.function(_get_leave_status, multi="leave_status", string="Current Leave Type",type='many2one', relation='hr.holidays.status'),
|
||||||
'leave_date_from': fields.function(_get_leave_status, multi='leave_status', type='date', string='From Date'),
|
'leave_date_from': fields.function(_get_leave_status, multi='leave_status', type='date', string='From Date'),
|
||||||
'leave_date_to': fields.function(_get_leave_status, multi='leave_status', type='date', string='To Date'),
|
'leave_date_to': fields.function(_get_leave_status, multi='leave_status', type='date', string='To Date'),
|
||||||
'leave_ids': fields.one2many('hr.holidays', 'employee_id', 'Leaves'),
|
|
||||||
'leaves_count': fields.function(_leaves_count, type='integer', string='Leaves'),
|
'leaves_count': fields.function(_leaves_count, type='integer', string='Leaves'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,11 +261,8 @@ class hr_payslip(osv.osv):
|
||||||
|
|
||||||
def _count_detail_payslip(self, cr, uid, ids, field_name, arg, context=None):
|
def _count_detail_payslip(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = {}
|
res = {}
|
||||||
try:
|
for details in self.browse(cr, uid, ids, context=context):
|
||||||
for details in self.browse(cr, uid, ids, context=context):
|
res[details.id] = len(details.line_ids)
|
||||||
res[details.id] = len(details.line_ids)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -285,7 +282,6 @@ class hr_payslip(osv.osv):
|
||||||
\n* If the payslip is under verification, the status is \'Waiting\'. \
|
\n* If the payslip is under verification, the status is \'Waiting\'. \
|
||||||
\n* If the payslip is confirmed then status is set to \'Done\'.\
|
\n* If the payslip is confirmed then status is set to \'Done\'.\
|
||||||
\n* When user cancel payslip the status is \'Rejected\'.'),
|
\n* When user cancel payslip the status is \'Rejected\'.'),
|
||||||
# 'line_ids': fields.one2many('hr.payslip.line', 'slip_id', 'Payslip Line', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
|
||||||
'line_ids': one2many_mod2('hr.payslip.line', 'slip_id', 'Payslip Lines', readonly=True, states={'draft':[('readonly',False)]}),
|
'line_ids': one2many_mod2('hr.payslip.line', 'slip_id', 'Payslip Lines', readonly=True, states={'draft':[('readonly',False)]}),
|
||||||
'company_id': fields.many2one('res.company', 'Company', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
'company_id': fields.many2one('res.company', 'Company', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
||||||
'worked_days_line_ids': fields.one2many('hr.payslip.worked_days', 'payslip_id', 'Payslip Worked Days', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
'worked_days_line_ids': fields.one2many('hr.payslip.worked_days', 'payslip_id', 'Payslip Worked Days', required=False, readonly=True, states={'draft': [('readonly', False)]}),
|
||||||
|
@ -983,19 +979,16 @@ class hr_employee(osv.osv):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _payslip_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _payslip_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Payslip = self.pool['hr.payslip']
|
||||||
try:
|
return {
|
||||||
for employee in self.browse(cr, uid, ids, context=context):
|
employee_id: Payslip.search_count(cr,uid, [('employee_id', '=', employee_id)], context=context)
|
||||||
res[employee.id] = len(employee.payslip_ids)
|
for employee_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'slip_ids':fields.one2many('hr.payslip', 'employee_id', 'Payslips', required=False, readonly=True),
|
'slip_ids':fields.one2many('hr.payslip', 'employee_id', 'Payslips', required=False, readonly=True),
|
||||||
'total_wage': fields.function(_calculate_total_wage, method=True, type='float', string='Total Basic Salary', digits_compute=dp.get_precision('Payroll'), help="Sum of all current contract's wage of employee."),
|
'total_wage': fields.function(_calculate_total_wage, method=True, type='float', string='Total Basic Salary', digits_compute=dp.get_precision('Payroll'), help="Sum of all current contract's wage of employee."),
|
||||||
'payslip_count': fields.function(_payslip_count, type='integer', string='Payslips'),
|
'payslip_count': fields.function(_payslip_count, type='integer', string='Payslips'),
|
||||||
'payslip_ids': fields.one2many('hr.payslip', 'employee_id', 'Payslips'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -514,15 +514,14 @@ class hr_job(osv.osv):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'documents_count': 0, 'application_count': 0,}), ids))
|
Applicant = self.pool['hr.applicant']
|
||||||
try:
|
return {
|
||||||
for job in self.browse(cr, uid, ids, context=context):
|
job_id: {
|
||||||
res[job.id] = {'documents_count': len(job.document_ids),
|
'application_count': Applicant.search_count(cr,uid, [('job_id', '=', job_id)], context=context),
|
||||||
'application_count': len(job.applicant_ids),
|
'documents_count': len(self._get_attached_docs(cr, uid, [job_id], field_name, arg, context=context)[job_id])
|
||||||
}
|
}
|
||||||
except:
|
for job_id in ids
|
||||||
pass
|
}
|
||||||
return res
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'survey_id': fields.many2one('survey.survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
|
'survey_id': fields.many2one('survey.survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
|
||||||
|
|
|
@ -22,9 +22,11 @@
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from pytz import timezone
|
||||||
|
import pytz
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, 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):
|
||||||
|
@ -134,15 +136,15 @@ class hr_timesheet_sheet(osv.osv):
|
||||||
return hr_employee.attendance_action_change(cr, uid, employee_ids, context=context)
|
return hr_employee.attendance_action_change(cr, uid, employee_ids, context=context)
|
||||||
|
|
||||||
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'timesheet_activity_count': 0, 'attendance_count': 0,}), ids))
|
Timesheet = self.pool['hr.analytic.timesheet']
|
||||||
try:
|
Attendance = self.pool['hr.attendance']
|
||||||
for datas in self.browse(cr, uid, ids, context=context):
|
return {
|
||||||
res[datas.id] = {'timesheet_activity_count': len(datas.timesheet_activity_ids),
|
sheet_id: {
|
||||||
'attendance_count': len(datas.attendances_ids),
|
'timesheet_activity_count': Timesheet.search_count(cr,uid, [('sheet_id','=', sheet_id)], context=context),
|
||||||
}
|
'attendance_count': Attendance.search_count(cr,uid, [('sheed_id', '=', sheet_id)], context=context)
|
||||||
except:
|
}
|
||||||
pass
|
for sheet_id in ids
|
||||||
return res
|
}
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Note', size=64, select=1,
|
'name': fields.char('Note', size=64, select=1,
|
||||||
|
@ -174,7 +176,6 @@ class hr_timesheet_sheet(osv.osv):
|
||||||
'account_ids': fields.one2many('hr_timesheet_sheet.sheet.account', 'sheet_id', 'Analytic accounts', readonly=True),
|
'account_ids': fields.one2many('hr_timesheet_sheet.sheet.account', 'sheet_id', 'Analytic accounts', readonly=True),
|
||||||
'company_id': fields.many2one('res.company', 'Company'),
|
'company_id': fields.many2one('res.company', 'Company'),
|
||||||
'department_id':fields.many2one('hr.department','Department'),
|
'department_id':fields.many2one('hr.department','Department'),
|
||||||
'timesheet_activity_ids': fields.one2many('hr.analytic.timesheet', 'sheet_id', 'Timesheet Activities'),
|
|
||||||
'timesheet_activity_count': fields.function(_count_all, type='integer', string='Timesheet Activities', multi=True),
|
'timesheet_activity_count': fields.function(_count_all, type='integer', string='Timesheet Activities', multi=True),
|
||||||
'attendance_count': fields.function(_count_all, type='integer', string="Attendances", multi=True),
|
'attendance_count': fields.function(_count_all, type='integer', string="Attendances", multi=True),
|
||||||
}
|
}
|
||||||
|
@ -411,22 +412,56 @@ 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):
|
def _get_attendance_employee_tz(self, cr, uid, employee_id, date, context=None):
|
||||||
|
""" Simulate timesheet in employee timezone
|
||||||
|
|
||||||
|
Return the attendance date in string format in the employee
|
||||||
|
tz converted from utc timezone as we consider date of employee
|
||||||
|
timesheet is in employee timezone
|
||||||
|
"""
|
||||||
|
employee_obj = self.pool['hr.employee']
|
||||||
|
|
||||||
|
tz = False
|
||||||
|
if employee_id:
|
||||||
|
employee = employee_obj.browse(cr, uid, employee_id, context=context)
|
||||||
|
tz = employee.user_id.partner_id.tz
|
||||||
|
|
||||||
if not date:
|
if not date:
|
||||||
date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
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'
|
att_tz = timezone(tz or 'utc')
|
||||||
# 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, [
|
attendance_dt = datetime.strptime(date, DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
('date_to', '>=', date_to), ('date_from', '<=', date),
|
att_tz_dt = pytz.utc.localize(attendance_dt)
|
||||||
('employee_id', '=', employee_id)
|
att_tz_dt = att_tz_dt.astimezone(att_tz)
|
||||||
], limit=1, context=context)
|
# We take only the date omiting the hours as we compare with timesheet
|
||||||
|
# date_from which is a date format thus using hours would lead to
|
||||||
|
# be out of scope of timesheet
|
||||||
|
att_tz_date_str = datetime.strftime(att_tz_dt, DEFAULT_SERVER_DATE_FORMAT)
|
||||||
|
return att_tz_date_str
|
||||||
|
|
||||||
|
def _get_current_sheet(self, cr, uid, employee_id, date=False, context=None):
|
||||||
|
|
||||||
|
sheet_obj = self.pool['hr_timesheet_sheet.sheet']
|
||||||
|
if not date:
|
||||||
|
date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
|
|
||||||
|
att_tz_date_str = self._get_attendance_employee_tz(
|
||||||
|
cr, uid, employee_id,
|
||||||
|
date=date, context=context)
|
||||||
|
sheet_ids = sheet_obj.search(cr, uid,
|
||||||
|
[('date_from', '<=', att_tz_date_str),
|
||||||
|
('date_to', '>=', att_tz_date_str),
|
||||||
|
('employee_id', '=', employee_id)],
|
||||||
|
limit=1, context=context)
|
||||||
return sheet_ids and sheet_ids[0] or False
|
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):
|
||||||
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):
|
||||||
res[attendance.id] = self._get_current_sheet(cursor, user, attendance.employee_id.id, attendance.name, context=context)
|
res[attendance.id] = self._get_current_sheet(
|
||||||
|
cursor, user, attendance.employee_id.id, attendance.name,
|
||||||
|
context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -448,10 +483,13 @@ class hr_attendance(osv.osv):
|
||||||
|
|
||||||
sheet_id = context.get('sheet_id') or self._get_current_sheet(cr, uid, vals.get('employee_id'), vals.get('name'), 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:
|
if sheet_id:
|
||||||
|
att_tz_date_str = self._get_attendance_employee_tz(
|
||||||
|
cr, uid, vals.get('employee_id'),
|
||||||
|
date=vals.get('name'), context=context)
|
||||||
ts = self.pool.get('hr_timesheet_sheet.sheet').browse(cr, uid, sheet_id, context=context)
|
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 can not enter an attendance in a submitted timesheet. Ask your manager to reset it before adding attendance.'))
|
raise osv.except_osv(_('Error!'), _('You can not enter an attendance in a submitted timesheet. Ask your manager to reset it before adding attendance.'))
|
||||||
elif ts.date_from > vals.get('name') or ts.date_to < vals.get('name'):
|
elif ts.date_from > att_tz_date_str or ts.date_to < att_tz_date_str:
|
||||||
raise osv.except_osv(_('User Error!'), _('You can not enter an attendance date outside the current timesheet dates.'))
|
raise osv.except_osv(_('User Error!'), _('You can not enter an attendance date outside the current timesheet dates.'))
|
||||||
return super(hr_attendance,self).create(cr, uid, vals, context=context)
|
return super(hr_attendance,self).create(cr, uid, vals, context=context)
|
||||||
|
|
||||||
|
@ -610,17 +648,13 @@ class hr_employee(osv.osv):
|
||||||
_description = 'Employee'
|
_description = 'Employee'
|
||||||
|
|
||||||
def _timesheet_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _timesheet_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Sheet = self.pool['hr_timesheet_sheet.sheet']
|
||||||
try:
|
return {
|
||||||
for employee in self.browse(cr, uid, ids, context=context):
|
employee_id: Sheet.search_count(cr,uid, [('employee_id', '=', employee_id)], context=context)
|
||||||
res[employee.id] = len(employee.timesheet_ids)
|
for employee_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'timesheet_ids': fields.one2many('hr_timesheet_sheet.sheet', 'employee_id', 'Timesheets'),
|
'timesheet_count': fields.function(_timesheet_count, type='integer', string='Timesheets'),
|
||||||
'timesheet_count': fields.function(_timesheet_count, type='integer', string='Timsheets'),
|
|
||||||
}
|
}
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from openerp import SUPERUSER_ID
|
||||||
from openerp import http
|
from openerp import http
|
||||||
from openerp.http import request
|
from openerp.http import request
|
||||||
from openerp.addons.web.controllers.main import content_disposition
|
from openerp.addons.web.controllers.main import content_disposition
|
||||||
|
import mimetypes
|
||||||
|
|
||||||
|
|
||||||
class MailController(http.Controller):
|
class MailController(http.Controller):
|
||||||
|
@ -19,10 +20,11 @@ class MailController(http.Controller):
|
||||||
if res:
|
if res:
|
||||||
filecontent = base64.b64decode(res.get('base64'))
|
filecontent = base64.b64decode(res.get('base64'))
|
||||||
filename = res.get('filename')
|
filename = res.get('filename')
|
||||||
|
content_type = mimetypes.guess_type(filename)
|
||||||
if filecontent and filename:
|
if filecontent and filename:
|
||||||
return request.make_response(
|
return request.make_response(
|
||||||
filecontent,
|
filecontent,
|
||||||
headers=[('Content-Type', 'application/octet-stream'),
|
headers=[('Content-Type', content_type[0] or 'application/octet-stream'),
|
||||||
('Content-Disposition', content_disposition(filename))])
|
('Content-Disposition', content_disposition(filename))])
|
||||||
return request.not_found()
|
return request.not_found()
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,7 @@ class mail_mail(osv.Model):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
ir_mail_server = self.pool.get('ir.mail_server')
|
ir_mail_server = self.pool.get('ir.mail_server')
|
||||||
|
ir_attachment = self.pool['ir.attachment']
|
||||||
for mail in self.browse(cr, SUPERUSER_ID, ids, context=context):
|
for mail in self.browse(cr, SUPERUSER_ID, ids, context=context):
|
||||||
try:
|
try:
|
||||||
# TDE note: remove me when model_id field is present on mail.message - done here to avoid doing it multiple times in the sub method
|
# TDE note: remove me when model_id field is present on mail.message - done here to avoid doing it multiple times in the sub method
|
||||||
|
@ -248,10 +249,15 @@ class mail_mail(osv.Model):
|
||||||
model = None
|
model = None
|
||||||
if model:
|
if model:
|
||||||
context['model_name'] = model.name
|
context['model_name'] = model.name
|
||||||
# handle attachments
|
|
||||||
attachments = []
|
# load attachment binary data with a separate read(), as prefetching all
|
||||||
for attach in mail.attachment_ids:
|
# `datas` (binary field) could bloat the browse cache, triggerring
|
||||||
attachments.append((attach.datas_fname, base64.b64decode(attach.datas)))
|
# soft/hard mem limits with temporary data.
|
||||||
|
attachment_ids = [a.id for a in mail.attachment_ids]
|
||||||
|
attachments = [(a['datas_fname'], base64.b64decode(a['datas']))
|
||||||
|
for a in ir_attachment.read(cr, SUPERUSER_ID, attachment_ids,
|
||||||
|
['datas_fname', 'datas'])]
|
||||||
|
|
||||||
# specific behavior to customize the send email for notified partners
|
# specific behavior to customize the send email for notified partners
|
||||||
email_list = []
|
email_list = []
|
||||||
if mail.email_to:
|
if mail.email_to:
|
||||||
|
@ -300,6 +306,14 @@ class mail_mail(osv.Model):
|
||||||
# /!\ can't use mail.state here, as mail.refresh() will cause an error
|
# /!\ can't use mail.state here, as mail.refresh() will cause an error
|
||||||
# see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1
|
# see revid:odo@openerp.com-20120622152536-42b2s28lvdv3odyr in 6.1
|
||||||
self._postprocess_sent_message(cr, uid, mail, context=context, mail_sent=mail_sent)
|
self._postprocess_sent_message(cr, uid, mail, context=context, mail_sent=mail_sent)
|
||||||
|
_logger.info('Mail with ID %r and Message-Id %r successfully sent', mail.id, mail.message_id)
|
||||||
|
except MemoryError:
|
||||||
|
# prevent catching transient MemoryErrors, bubble up to notify user or abort cron job
|
||||||
|
# instead of marking the mail as failed
|
||||||
|
_logger.exception('MemoryError while processing mail with ID %r and Msg-Id %r. '\
|
||||||
|
'Consider raising the --limit-memory-hard startup option',
|
||||||
|
mail.id, mail.message_id)
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.exception('failed sending mail.mail %s', mail.id)
|
_logger.exception('failed sending mail.mail %s', mail.id)
|
||||||
mail.write({'state': 'exception'})
|
mail.write({'state': 'exception'})
|
||||||
|
|
|
@ -385,7 +385,7 @@ class mail_thread(osv.AbstractModel):
|
||||||
if not context.get('mail_notrack'):
|
if not context.get('mail_notrack'):
|
||||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
|
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
|
||||||
if tracked_fields:
|
if tracked_fields:
|
||||||
initial_values = {thread_id: dict((item, False) for item in tracked_fields)}
|
initial_values = {thread_id: dict.fromkeys(tracked_fields, False)}
|
||||||
self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
|
self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
|
||||||
return thread_id
|
return thread_id
|
||||||
|
|
||||||
|
@ -398,25 +398,24 @@ class mail_thread(osv.AbstractModel):
|
||||||
track_ctx = dict(context)
|
track_ctx = dict(context)
|
||||||
if 'lang' not in track_ctx:
|
if 'lang' not in track_ctx:
|
||||||
track_ctx['lang'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).lang
|
track_ctx['lang'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).lang
|
||||||
|
|
||||||
|
tracked_fields = None
|
||||||
if not context.get('mail_notrack'):
|
if not context.get('mail_notrack'):
|
||||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
|
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
|
||||||
else:
|
|
||||||
tracked_fields = []
|
|
||||||
if tracked_fields:
|
if tracked_fields:
|
||||||
records = self.browse(cr, uid, ids, context=track_ctx)
|
records = self.browse(cr, uid, ids, context=track_ctx)
|
||||||
initial_values = dict((this.id, dict((key, getattr(this, key)) for key in tracked_fields.keys())) for this in records)
|
initial_values = dict((record.id, dict((key, getattr(record, key)) for key in tracked_fields))
|
||||||
|
for record in records)
|
||||||
|
|
||||||
# Perform write, update followers
|
# Perform write, update followers
|
||||||
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
|
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
|
||||||
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
|
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
|
||||||
|
|
||||||
if not context.get('mail_notrack'):
|
# Perform the tracking
|
||||||
# Perform the tracking
|
|
||||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
|
|
||||||
else:
|
|
||||||
tracked_fields = None
|
|
||||||
if tracked_fields:
|
if tracked_fields:
|
||||||
self.message_track(cr, uid, ids, tracked_fields, initial_values, context=track_ctx)
|
self.message_track(cr, uid, ids, tracked_fields, initial_values, context=track_ctx)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, context=None):
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
|
@ -434,14 +433,14 @@ class mail_thread(osv.AbstractModel):
|
||||||
fol_obj.unlink(cr, SUPERUSER_ID, fol_ids, context=context)
|
fol_obj.unlink(cr, SUPERUSER_ID, fol_ids, context=context)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def copy(self, cr, uid, id, default=None, context=None):
|
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||||
# avoid tracking multiple temporary changes during copy
|
# avoid tracking multiple temporary changes during copy
|
||||||
context = dict(context or {}, mail_notrack=True)
|
context = dict(context or {}, mail_notrack=True)
|
||||||
|
|
||||||
default = default or {}
|
default = default or {}
|
||||||
default['message_ids'] = []
|
default['message_ids'] = []
|
||||||
default['message_follower_ids'] = []
|
default['message_follower_ids'] = []
|
||||||
return super(mail_thread, self).copy(cr, uid, id, default=default, context=context)
|
return super(mail_thread, self).copy_data(cr, uid, id, default=default, context=context)
|
||||||
|
|
||||||
#------------------------------------------------------
|
#------------------------------------------------------
|
||||||
# Automatically log tracked fields
|
# Automatically log tracked fields
|
||||||
|
@ -453,14 +452,15 @@ class mail_thread(osv.AbstractModel):
|
||||||
:return list: a list of (field_name, column_info obj), containing
|
:return list: a list of (field_name, column_info obj), containing
|
||||||
always tracked fields and modified on_change fields
|
always tracked fields and modified on_change fields
|
||||||
"""
|
"""
|
||||||
lst = []
|
tracked_fields = []
|
||||||
for name, column_info in self._all_columns.items():
|
for name, column_info in self._all_columns.items():
|
||||||
visibility = getattr(column_info.column, 'track_visibility', False)
|
visibility = getattr(column_info.column, 'track_visibility', False)
|
||||||
if visibility == 'always' or (visibility == 'onchange' and name in updated_fields) or name in self._track:
|
if visibility == 'always' or (visibility == 'onchange' and name in updated_fields) or name in self._track:
|
||||||
lst.append(name)
|
tracked_fields.append(name)
|
||||||
if not lst:
|
|
||||||
return lst
|
if tracked_fields:
|
||||||
return self.fields_get(cr, uid, lst, context=context)
|
return self.fields_get(cr, uid, tracked_fields, context=context)
|
||||||
|
return {}
|
||||||
|
|
||||||
def message_track(self, cr, uid, ids, tracked_fields, initial_values, context=None):
|
def message_track(self, cr, uid, ids, tracked_fields, initial_values, context=None):
|
||||||
|
|
||||||
|
@ -1871,4 +1871,4 @@ class mail_thread(osv.AbstractModel):
|
||||||
message_obj.write(cr, uid, msg_ids_comment, {"res_id" : new_res_id, "model" : new_model}, context=context)
|
message_obj.write(cr, uid, msg_ids_comment, {"res_id" : new_res_id, "model" : new_model}, context=context)
|
||||||
message_obj.write(cr, uid, msg_ids_not_comment, {"res_id" : new_res_id, "model" : new_model, "subtype_id" : None}, context=context)
|
message_obj.write(cr, uid, msg_ids_not_comment, {"res_id" : new_res_id, "model" : new_model, "subtype_id" : None}, context=context)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -34,14 +34,14 @@ class project_configuration(osv.TransientModel):
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_default_alias_domain(self, cr, uid, ids, context=None):
|
def get_default_alias_domain(self, cr, uid, ids, context=None):
|
||||||
alias_domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "mail.catchall.domain", context=context)
|
alias_domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "mail.catchall.domain", default=None, context=context)
|
||||||
if not alias_domain:
|
if alias_domain is None:
|
||||||
domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "web.base.url", context=context)
|
domain = self.pool.get("ir.config_parameter").get_param(cr, uid, "web.base.url", context=context)
|
||||||
try:
|
try:
|
||||||
alias_domain = urlparse.urlsplit(domain).netloc.split(':')[0]
|
alias_domain = urlparse.urlsplit(domain).netloc.split(':')[0]
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return {'alias_domain': alias_domain}
|
return {'alias_domain': alias_domain or False}
|
||||||
|
|
||||||
def set_alias_domain(self, cr, uid, ids, context=None):
|
def set_alias_domain(self, cr, uid, ids, context=None):
|
||||||
config_parameters = self.pool.get("ir.config_parameter")
|
config_parameters = self.pool.get("ir.config_parameter")
|
||||||
|
|
|
@ -187,7 +187,7 @@
|
||||||
</span>
|
</span>
|
||||||
</t>
|
</t>
|
||||||
</td>
|
</td>
|
||||||
<td><div class="oe_view_manager_view_search" t-opentag="true"/></td>
|
<td><div class="oe_view_manager_view_search"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1111,24 +1111,22 @@ class mrp_production_product_line(osv.osv):
|
||||||
|
|
||||||
class product_product(osv.osv):
|
class product_product(osv.osv):
|
||||||
_inherit = "product.product"
|
_inherit = "product.product"
|
||||||
def _bom_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _bom_orders_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'bom_count': 0, 'mo_count': 0, 'bom_strct':0}), ids))
|
Bom = self.pool('mrp.bom')
|
||||||
try:
|
Production = self.pool('mrp.production')
|
||||||
for bom in self.browse(cr, uid, ids, context=context):
|
return {
|
||||||
res[bom.id] = {
|
product_id: {
|
||||||
'bom_count': len(bom.bom_ids),
|
'bom_count': Bom.search_count(cr, uid, [('product_id', '=', product_id), ('bom_id', '=', False)], context=context),
|
||||||
'mo_count': len(bom.mo_ids),
|
'mo_count': Production.search_count(cr,uid, [('product_id', '=', product_id)], context=context),
|
||||||
'bom_strct':len(bom.bom_ids),
|
'bom_strct': Bom.search_count(cr, uid, [('product_id', '=', product_id), ('bom_id', '=', False)], context=context),
|
||||||
}
|
}
|
||||||
except:
|
for product_id in ids
|
||||||
pass
|
}
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'bom_ids': fields.one2many('mrp.bom', 'product_id', 'Bill of Materials'),
|
'bom_ids': fields.one2many('mrp.bom', 'product_id', 'Bill of Materials'),
|
||||||
'mo_ids': fields.one2many('mrp.production', 'product_id', 'Manufacturing Orders'),
|
'bom_count': fields.function(_bom_orders_count, string='# Bill of Material', type='integer', multi="_bom_order_count"),
|
||||||
'bom_count': fields.function(_bom_count, string='# Bill of Material', type='integer', multi="bom_count"),
|
'bom_strct': fields.function(_bom_orders_count, string='# Bill of Material Structure', type='integer', multi="_bom_order_count"),
|
||||||
'bom_strct': fields.function(_bom_count, string='# Bill of Material Structure', type='integer', multi="bom_count"),
|
'mo_count': fields.function(_bom_orders_count, string='# Manufacturing Orders', type='integer', multi="_bom_order_count"),
|
||||||
'mo_count': fields.function(_bom_count, string='# Manufacturing Orders', type='integer', multi="bom_count"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<record id="res_company_oerp_us" model="res.company">
|
<record id="res_company_oerp_us" model="res.company">
|
||||||
<field name="partner_id" ref="res_partner_oerp_us"/>
|
<field name="partner_id" ref="res_partner_oerp_us"/>
|
||||||
<field name="parent_id" ref="res_company_oerp_editor"/>
|
<field name="parent_id" ref="res_company_oerp_editor"/>
|
||||||
<field name="currency_id" ref="base.EUR"/>
|
<field name="currency_id" ref="base.USD"/>
|
||||||
<field name="name">OpenERP US</field>
|
<field name="name">OpenERP US</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="res_company_oerp_be" model="res.company">
|
<record id="res_company_oerp_be" model="res.company">
|
||||||
|
@ -400,7 +400,7 @@
|
||||||
</record>
|
</record>
|
||||||
<record id="project.project_project_3" model="project.project">
|
<record id="project.project_project_3" model="project.project">
|
||||||
<field name="company_id" ref="res_company_oerp_us"/>
|
<field name="company_id" ref="res_company_oerp_us"/>
|
||||||
<field name="currency_id" ref="base.EUR"/>
|
<field name="currency_id" ref="base.USD"/>
|
||||||
</record>
|
</record>
|
||||||
<record id="project.project_project_4" model="project.project">
|
<record id="project.project_project_4" model="project.project">
|
||||||
<field name="company_id" ref="res_company_oerp_be"/>
|
<field name="company_id" ref="res_company_oerp_be"/>
|
||||||
|
|
|
@ -1162,8 +1162,8 @@ class pos_order(osv.osv):
|
||||||
return self.write(cr, uid, ids, {'state': 'payment'}, context=context)
|
return self.write(cr, uid, ids, {'state': 'payment'}, context=context)
|
||||||
|
|
||||||
def action_paid(self, cr, uid, ids, context=None):
|
def action_paid(self, cr, uid, ids, context=None):
|
||||||
self.create_picking(cr, uid, ids, context=context)
|
|
||||||
self.write(cr, uid, ids, {'state': 'paid'}, context=context)
|
self.write(cr, uid, ids, {'state': 'paid'}, context=context)
|
||||||
|
self.create_picking(cr, uid, ids, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_cancel(self, cr, uid, ids, context=None):
|
def action_cancel(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -615,15 +615,12 @@ class product_template(osv.osv):
|
||||||
class product_product(osv.osv):
|
class product_product(osv.osv):
|
||||||
_inherit="product.product"
|
_inherit="product.product"
|
||||||
def _orderpoint_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _orderpoint_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
OrderPoints = self.pool('stock.warehouse.orderpoint')
|
||||||
try:
|
return {
|
||||||
for orderpoint in self.browse(cr, uid, ids, context=context):
|
product_id: OrderPoints.search_count(cr, uid, [('product_id', '=', product_id)], context=context)
|
||||||
res[orderpoint.id] = len(orderpoint.orderpoint_ids)
|
for product_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rules'),
|
|
||||||
'orderpoint_count': fields.function(_orderpoint_count, string='# Orderpoints', type='integer'),
|
'orderpoint_count': fields.function(_orderpoint_count, string='# Orderpoints', type='integer'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,11 @@ from openerp.osv import fields,osv
|
||||||
|
|
||||||
class res_partner(osv.osv):
|
class res_partner(osv.osv):
|
||||||
def _task_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _task_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Task = self.pool['project.task']
|
||||||
try:
|
return {
|
||||||
for partner in self.browse(cr, uid, ids, context):
|
partner_id: Task.search_count(cr,uid, [('partner_id', '=', partner_id)], context=context)
|
||||||
res[partner.id] = len(partner.task_ids)
|
for partner_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
""" Inherits partner and adds Tasks information in the partner form """
|
""" Inherits partner and adds Tasks information in the partner form """
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
@ -46,6 +44,4 @@ class res_partner(osv.osv):
|
||||||
return super(res_partner, self).copy(
|
return super(res_partner, self).copy(
|
||||||
cr, uid, record_id, default=default, context=context)
|
cr, uid, record_id, default=default, context=context)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -474,10 +474,11 @@ class project(osv.Model):
|
||||||
return [('project.task', "Tasks"), ("project.issue", "Issues")]
|
return [('project.task', "Tasks"), ("project.issue", "Issues")]
|
||||||
|
|
||||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res={}
|
Issue = self.pool['project.issue']
|
||||||
for issues in self.browse(cr, uid, ids, context):
|
return {
|
||||||
res[issues.id] = len(issues.issue_ids)
|
project_id: Issue.search_count(cr,uid, [('project_id', '=', project_id), ('stage_id.fold', '=', False)], context=context)
|
||||||
return res
|
for project_id in ids
|
||||||
|
}
|
||||||
_columns = {
|
_columns = {
|
||||||
'project_escalation_id': fields.many2one('project.project', 'Project Escalation',
|
'project_escalation_id': fields.many2one('project.project', 'Project Escalation',
|
||||||
help='If any issue is escalated from the current Project, it will be listed under the project selected here.',
|
help='If any issue is escalated from the current Project, it will be listed under the project selected here.',
|
||||||
|
@ -554,18 +555,15 @@ class project_project(osv.Model):
|
||||||
|
|
||||||
class res_partner(osv.osv):
|
class res_partner(osv.osv):
|
||||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Issue = self.pool['project.issue']
|
||||||
try:
|
return {
|
||||||
for partner in self.browse(cr, uid, ids, context=context):
|
partner_id: Issue.search_count(cr,uid, [('partner_id', '=', partner_id)])
|
||||||
res[partner.id] = len(partner.issue_ids)
|
for partner_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
""" Inherits partner and adds Issue information in the partner form """
|
""" Inherits partner and adds Issue information in the partner form """
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
_columns = {
|
_columns = {
|
||||||
'issue_ids': fields.one2many('project.issue', 'partner_id', 'Issues'),
|
|
||||||
'issue_count': fields.function(_issue_count, string='# Issues', type='integer'),
|
'issue_count': fields.function(_issue_count, string='# Issues', type='integer'),
|
||||||
}
|
}
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -25,22 +25,16 @@ class res_partner(osv.osv):
|
||||||
_name = 'res.partner'
|
_name = 'res.partner'
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
|
||||||
def _purchase_order_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _purchase_invoice_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'purchase_order_count': 0, 'supplier_invoice_count': 0}), ids))
|
PurchaseOrder = self.pool['purchase.order']
|
||||||
invoice_ids = self.pool.get('account.invoice').search(cr,uid, [('type', '=', 'in_invoice'), ('partner_id', '=', ids[0])])
|
Invoice = self.pool['account.invoice']
|
||||||
for partner in self.browse(cr, uid, ids, context=context):
|
return {
|
||||||
res[partner.id] = {
|
partner_id: {
|
||||||
'purchase_order_count': len(partner.purchase_order_ids),
|
'purchase_order_count': PurchaseOrder.search_count(cr,uid, [('partner_id', '=', partner_id)], context=context),
|
||||||
'supplier_invoice_count': len(invoice_ids),
|
'supplier_invoice_count': Invoice.search_count(cr,uid, [('partner_id', '=', partner_id), ('type','=','in_invoice')], context=context)
|
||||||
}
|
}
|
||||||
return res
|
for partner_id in ids
|
||||||
def copy(self, cr, uid, id, default=None, context=None):
|
}
|
||||||
if default is None:
|
|
||||||
default = {}
|
|
||||||
|
|
||||||
default.update({'purchase_order_ids': []})
|
|
||||||
|
|
||||||
return super(res_partner, self).copy(cr, uid, id, default=default, context=context)
|
|
||||||
|
|
||||||
def _commercial_fields(self, cr, uid, context=None):
|
def _commercial_fields(self, cr, uid, context=None):
|
||||||
return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist_purchase']
|
return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist_purchase']
|
||||||
|
@ -52,13 +46,9 @@ class res_partner(osv.osv):
|
||||||
domain=[('type','=','purchase')],
|
domain=[('type','=','purchase')],
|
||||||
string="Purchase Pricelist",
|
string="Purchase Pricelist",
|
||||||
help="This pricelist will be used, instead of the default one, for purchases from the current partner"),
|
help="This pricelist will be used, instead of the default one, for purchases from the current partner"),
|
||||||
'purchase_order_count': fields.function(_purchase_order_count, string='# of Purchase Order', type='integer', multi="count"),
|
'purchase_order_count': fields.function(_purchase_invoice_count, string='# of Purchase Order', type='integer', multi="count"),
|
||||||
'purchase_order_ids': fields.one2many('purchase.order','partner_id','Purchase Order'),
|
'supplier_invoice_count': fields.function(_purchase_invoice_count, string='# Supplier Invoices', type='integer', multi="count"),
|
||||||
'invoice_ids': fields.one2many('account.invoice','partner_id','Supplier Invoices'),
|
|
||||||
'supplier_invoice_count': fields.function(_purchase_order_count, string='# Supplier Invoices', type='integer', multi="count"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
|
|
|
@ -148,15 +148,13 @@ class purchase_order(osv.osv):
|
||||||
return res and res[0] or False
|
return res and res[0] or False
|
||||||
|
|
||||||
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
def _count_all(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,{'shipment_count': 0, 'invoice_count': 0,}), ids))
|
return {
|
||||||
try:
|
purchase.id: {
|
||||||
for data in self.browse(cr, uid, ids, context=context):
|
'shipment_count': len(purchase.picking_ids),
|
||||||
res[data.id] = {'shipment_count': len(data.picking_ids),
|
'invoice_count': len(purchase.invoice_ids),
|
||||||
'invoice_count': len(data.invoice_ids),
|
}
|
||||||
}
|
for purchase in self.browse(cr, uid, ids, context=context)
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
|
|
||||||
STATE_SELECTION = [
|
STATE_SELECTION = [
|
||||||
('draft', 'Draft PO'),
|
('draft', 'Draft PO'),
|
||||||
|
@ -1296,15 +1294,13 @@ class product_product(osv.Model):
|
||||||
_inherit = 'product.product'
|
_inherit = 'product.product'
|
||||||
|
|
||||||
def _purchase_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _purchase_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Purchase = self.pool['purchase.order']
|
||||||
try:
|
return {
|
||||||
for purchase in self.browse(cr, uid, ids, context=context):
|
product_id: Purchase.search_count(cr,uid, [('order_line.product_id', '=', product_id)], context=context)
|
||||||
res[purchase.id] = len(purchase.purchase_ids)
|
for product_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'purchase_ids': fields.one2many('purchase.order', 'product_id', 'Purchases'),
|
|
||||||
'purchase_count': fields.function(_purchase_count, string='# Purchases', type='integer'),
|
'purchase_count': fields.function(_purchase_count, string='# Purchases', type='integer'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,8 +260,14 @@ class Report(osv.Model):
|
||||||
def get_action(self, cr, uid, ids, report_name, data=None, context=None):
|
def get_action(self, cr, uid, ids, report_name, data=None, context=None):
|
||||||
"""Return an action of type ir.actions.report.xml.
|
"""Return an action of type ir.actions.report.xml.
|
||||||
|
|
||||||
|
:param ids: Ids of the records to print (if not used, pass an empty list)
|
||||||
:param report_name: Name of the template to generate an action for
|
:param report_name: Name of the template to generate an action for
|
||||||
"""
|
"""
|
||||||
|
if ids:
|
||||||
|
if not isinstance(ids, list):
|
||||||
|
ids = [ids]
|
||||||
|
context['active_ids'] = ids
|
||||||
|
|
||||||
report_obj = self.pool['ir.actions.report.xml']
|
report_obj = self.pool['ir.actions.report.xml']
|
||||||
idreport = report_obj.search(cr, uid, [('report_name', '=', report_name)], context=context)
|
idreport = report_obj.search(cr, uid, [('report_name', '=', report_name)], context=context)
|
||||||
try:
|
try:
|
||||||
|
@ -272,7 +278,7 @@ class Report(osv.Model):
|
||||||
_('This report is not loaded into the database: %s.' % report_name)
|
_('This report is not loaded into the database: %s.' % report_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
action = {
|
return {
|
||||||
'context': context,
|
'context': context,
|
||||||
'data': data,
|
'data': data,
|
||||||
'type': 'ir.actions.report.xml',
|
'type': 'ir.actions.report.xml',
|
||||||
|
@ -280,7 +286,6 @@ class Report(osv.Model):
|
||||||
'report_type': report.report_type,
|
'report_type': report.report_type,
|
||||||
'report_file': report.report_file,
|
'report_file': report.report_file,
|
||||||
}
|
}
|
||||||
return action
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# Report generation helpers
|
# Report generation helpers
|
||||||
|
|
|
@ -626,6 +626,48 @@ class sale_order(osv.osv):
|
||||||
def action_done(self, cr, uid, ids, context=None):
|
def action_done(self, cr, uid, ids, context=None):
|
||||||
return self.write(cr, uid, ids, {'state': 'done'}, context=context)
|
return self.write(cr, uid, ids, {'state': 'done'}, context=context)
|
||||||
|
|
||||||
|
def onchange_fiscal_position(self, cr, uid, ids, fiscal_position, order_lines, context=None):
|
||||||
|
'''Update taxes of order lines for each line where a product is defined
|
||||||
|
|
||||||
|
:param list ids: not used
|
||||||
|
:param int fiscal_position: sale order fiscal position
|
||||||
|
:param list order_lines: command list for one2many write method
|
||||||
|
'''
|
||||||
|
order_line = []
|
||||||
|
fiscal_obj = self.pool.get('account.fiscal.position')
|
||||||
|
product_obj = self.pool.get('product.product')
|
||||||
|
line_obj = self.pool.get('sale.order.line')
|
||||||
|
|
||||||
|
fpos = False
|
||||||
|
if fiscal_position:
|
||||||
|
fpos = fiscal_obj.browse(cr, uid, fiscal_position, context=context)
|
||||||
|
|
||||||
|
for line in order_lines:
|
||||||
|
# create (0, 0, { fields })
|
||||||
|
# update (1, ID, { fields })
|
||||||
|
if line[0] in [0, 1]:
|
||||||
|
prod = None
|
||||||
|
if line[2].get('product_id'):
|
||||||
|
prod = product_obj.browse(cr, uid, line[2]['product_id'], context=context)
|
||||||
|
elif line[1]:
|
||||||
|
prod = line_obj.browse(cr, uid, line[1], context=context).product_id
|
||||||
|
if prod and prod.taxes_id:
|
||||||
|
line[2]['tax_id'] = [[6, 0, fiscal_obj.map_tax(cr, uid, fpos, prod.taxes_id)]]
|
||||||
|
order_line.append(line)
|
||||||
|
|
||||||
|
# link (4, ID)
|
||||||
|
# link all (6, 0, IDS)
|
||||||
|
elif line[0] in [4, 6]:
|
||||||
|
line_ids = line[0] == 4 and [line[1]] or line[2]
|
||||||
|
for line_id in line_ids:
|
||||||
|
prod = line_obj.browse(cr, uid, line_id, context=context).product_id
|
||||||
|
if prod and prod.taxes_id:
|
||||||
|
order_line.append([1, line_id, {'tax_id': [[6, 0, fiscal_obj.map_tax(cr, uid, fpos, prod.taxes_id)]]}])
|
||||||
|
else:
|
||||||
|
order_line.append([4, line_id])
|
||||||
|
else:
|
||||||
|
order_line.append(line)
|
||||||
|
return {'value': {'order_line': order_line}}
|
||||||
|
|
||||||
|
|
||||||
# TODO add a field price_unit_uos
|
# TODO add a field price_unit_uos
|
||||||
|
@ -862,15 +904,15 @@ class sale_order_line(osv.osv):
|
||||||
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None):
|
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None):
|
||||||
context = context or {}
|
context = context or {}
|
||||||
lang = lang or context.get('lang',False)
|
lang = lang or context.get('lang',False)
|
||||||
if not partner_id:
|
if not partner_id:
|
||||||
raise osv.except_osv(_('No Customer Defined!'), _('Before choosing a product,\n select a customer in the sales form.'))
|
raise osv.except_osv(_('No Customer Defined!'), _('Before choosing a product,\n select a customer in the sales form.'))
|
||||||
warning = {}
|
warning = {}
|
||||||
product_uom_obj = self.pool.get('product.uom')
|
product_uom_obj = self.pool.get('product.uom')
|
||||||
partner_obj = self.pool.get('res.partner')
|
partner_obj = self.pool.get('res.partner')
|
||||||
product_obj = self.pool.get('product.product')
|
product_obj = self.pool.get('product.product')
|
||||||
context = {'lang': lang, 'partner_id': partner_id}
|
context = {'lang': lang, 'partner_id': partner_id}
|
||||||
if partner_id:
|
partner = partner_obj.browse(cr, uid, partner_id)
|
||||||
lang = partner_obj.browse(cr, uid, partner_id).lang
|
lang = partner.lang
|
||||||
context_partner = {'lang': lang, 'partner_id': partner_id}
|
context_partner = {'lang': lang, 'partner_id': partner_id}
|
||||||
|
|
||||||
if not product:
|
if not product:
|
||||||
|
@ -896,7 +938,12 @@ class sale_order_line(osv.osv):
|
||||||
uos = False
|
uos = False
|
||||||
else:
|
else:
|
||||||
uos = False
|
uos = False
|
||||||
fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
|
|
||||||
|
fpos = False
|
||||||
|
if not fiscal_position:
|
||||||
|
fpos = partner.property_account_position or False
|
||||||
|
else:
|
||||||
|
fpos = self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position)
|
||||||
if update_tax: #The quantity only have changed
|
if update_tax: #The quantity only have changed
|
||||||
result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
|
result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
|
||||||
|
|
||||||
|
@ -1027,15 +1074,12 @@ class account_invoice(osv.Model):
|
||||||
class product_product(osv.Model):
|
class product_product(osv.Model):
|
||||||
_inherit = 'product.product'
|
_inherit = 'product.product'
|
||||||
def _sales_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _sales_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
SaleOrderLine = self.pool['sale.order.line']
|
||||||
try:
|
return {
|
||||||
for sale in self.browse(cr, uid, ids, context=context):
|
product_id: SaleOrderLine.search_count(cr,uid, [('product_id', '=', product_id)], context=context)
|
||||||
res[sale.id] = len(sale.sales_ids)
|
for product_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'sales_ids': fields.one2many('sale.order.line', 'product_id', 'Sales '),
|
|
||||||
'sales_count': fields.function(_sales_count, string='# Sales', type='integer'),
|
'sales_count': fields.function(_sales_count, string='# Sales', type='integer'),
|
||||||
}
|
}
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -206,7 +206,8 @@
|
||||||
</group>
|
</group>
|
||||||
<group name="sale_pay">
|
<group name="sale_pay">
|
||||||
<field name="payment_term" options="{'no_create': True}"/>
|
<field name="payment_term" options="{'no_create': True}"/>
|
||||||
<field name="fiscal_position" options="{'no_create': True}"/>
|
<field name="fiscal_position" options="{'no_create': True}"
|
||||||
|
on_change="onchange_fiscal_position(fiscal_position, order_line, context)"/>
|
||||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
|
|
@ -105,7 +105,9 @@ class product_product(osv.osv):
|
||||||
'compute_child': False
|
'compute_child': False
|
||||||
})
|
})
|
||||||
|
|
||||||
qty = product.qty_available
|
# qty_available depends of the location in the context
|
||||||
|
qty = self.read(cr, uid, [product.id], ['qty_available'], context=c)[0]['qty_available']
|
||||||
|
|
||||||
diff = product.standard_price - new_price
|
diff = product.standard_price - new_price
|
||||||
if not diff: raise osv.except_osv(_('Error!'), _("No difference between standard price and new price!"))
|
if not diff: raise osv.except_osv(_('Error!'), _("No difference between standard price and new price!"))
|
||||||
if qty:
|
if qty:
|
||||||
|
@ -353,13 +355,11 @@ class product_product(osv.osv):
|
||||||
res[id][f] = stock.get(id, 0.0)
|
res[id][f] = stock.get(id, 0.0)
|
||||||
return res
|
return res
|
||||||
def _move_count(self, cr, uid, ids, field_name, arg, context=None):
|
def _move_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
res = dict(map(lambda x: (x,0), ids))
|
Move = self.pool['stock.move']
|
||||||
try:
|
return {
|
||||||
for move in self.browse(cr, uid, ids, context=context):
|
product_id: Move.search_count(cr, uid, [('product_id', '=', product_id)], context=context)
|
||||||
res[move.id] = len(move.move_ids)
|
for product_id in ids
|
||||||
except:
|
}
|
||||||
pass
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'reception_count': fields.function(_stock_move_count, string="Reception", type='integer', multi='pickings'),
|
'reception_count': fields.function(_stock_move_count, string="Reception", type='integer', multi='pickings'),
|
||||||
'delivery_count': fields.function(_stock_move_count, string="Delivery", type='integer', multi='pickings'),
|
'delivery_count': fields.function(_stock_move_count, string="Delivery", type='integer', multi='pickings'),
|
||||||
|
@ -420,7 +420,6 @@ class product_product(osv.osv):
|
||||||
help="If real-time valuation is enabled for a product, the system will automatically write journal entries corresponding to stock moves." \
|
help="If real-time valuation is enabled for a product, the system will automatically write journal entries corresponding to stock moves." \
|
||||||
"The inventory variation account set on the product category will represent the current inventory value, and the stock input and stock output account will hold the counterpart moves for incoming and outgoing products."
|
"The inventory variation account set on the product category will represent the current inventory value, and the stock input and stock output account will hold the counterpart moves for incoming and outgoing products."
|
||||||
, required=True),
|
, required=True),
|
||||||
'move_ids': fields.one2many('stock.move', 'product_id', 'Moves'),
|
|
||||||
'move_count': fields.function(_move_count, string='# Moves', type='integer'),
|
'move_count': fields.function(_move_count, string='# Moves', type='integer'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -636,11 +636,7 @@ class stock_picking(osv.osv):
|
||||||
vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name)
|
vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name)
|
||||||
new_id = super(stock_picking, self).create(cr, user, vals, context)
|
new_id = super(stock_picking, self).create(cr, user, vals, context)
|
||||||
return new_id
|
return new_id
|
||||||
def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
|
|
||||||
res = {}
|
|
||||||
claim = self.pool.get('crm.claim').search(cr, uid, [('ref', '=',('stock.picking.out,' + str(ids[0])))], context=context)
|
|
||||||
res[ids[0]] = len(claim)
|
|
||||||
return res
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||||
'origin': fields.char('Source Document', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True),
|
'origin': fields.char('Source Document', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True),
|
||||||
|
@ -684,7 +680,6 @@ class stock_picking(osv.osv):
|
||||||
("none", "Not Applicable")], "Invoice Control",
|
("none", "Not Applicable")], "Invoice Control",
|
||||||
select=True, required=True, readonly=True, track_visibility='onchange', states={'draft': [('readonly', False)]}),
|
select=True, required=True, readonly=True, track_visibility='onchange', states={'draft': [('readonly', False)]}),
|
||||||
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||||
'claim_count': fields.function(_claim_count, string='Claims', type='integer'),
|
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'name': lambda self, cr, uid, context: '/',
|
'name': lambda self, cr, uid, context: '/',
|
||||||
|
@ -2312,7 +2307,9 @@ class stock_move(osv.osv):
|
||||||
|
|
||||||
# if product is set to average price and a specific value was entered in the picking wizard,
|
# if product is set to average price and a specific value was entered in the picking wizard,
|
||||||
# we use it
|
# we use it
|
||||||
if move.product_id.cost_method == 'average' and move.price_unit:
|
if move.location_dest_id.usage != 'internal' and move.product_id.cost_method == 'average':
|
||||||
|
reference_amount = qty * move.product_id.standard_price
|
||||||
|
elif move.product_id.cost_method == 'average' and move.price_unit:
|
||||||
reference_amount = qty * move.price_unit
|
reference_amount = qty * move.price_unit
|
||||||
reference_currency_id = move.price_currency_id.id or reference_currency_id
|
reference_currency_id = move.price_currency_id.id or reference_currency_id
|
||||||
|
|
||||||
|
@ -3136,8 +3133,6 @@ class stock_picking_out(osv.osv):
|
||||||
out_defaults = super(stock_picking_out, self).default_get(cr, uid, fields_list, context=context)
|
out_defaults = super(stock_picking_out, self).default_get(cr, uid, fields_list, context=context)
|
||||||
defaults.update(out_defaults)
|
defaults.update(out_defaults)
|
||||||
return defaults
|
return defaults
|
||||||
def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
|
|
||||||
return super(stock_picking_out, self)._claim_count(cr, uid, ids, field_name, arg, context=context)
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
|
||||||
|
@ -3155,7 +3150,6 @@ class stock_picking_out(osv.osv):
|
||||||
* Ready to Deliver: products reserved, simply waiting for confirmation.\n
|
* Ready to Deliver: products reserved, simply waiting for confirmation.\n
|
||||||
* Delivered: has been processed, can't be modified or cancelled anymore\n
|
* Delivered: has been processed, can't be modified or cancelled anymore\n
|
||||||
* Cancelled: has been cancelled, can't be confirmed anymore"""),
|
* Cancelled: has been cancelled, can't be confirmed anymore"""),
|
||||||
'claim_count': fields.function(_claim_count, string='Claims', type='integer'),
|
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'type': 'out',
|
'type': 'out',
|
||||||
|
|
|
@ -811,7 +811,7 @@
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Products">
|
<page string="Products">
|
||||||
<field name="move_lines" context="{'address_in_id': partner_id, 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree', 'picking_type': 'internal'}" options='{"reload_on_button": true}'/>
|
<field name="move_lines" string="Stock Move" context="{'address_in_id': partner_id, 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree', 'picking_type': 'internal'}" options='{"reload_on_button": true}'/>
|
||||||
<field name="note" placeholder="Add an internal note..." class="oe_inline"/>
|
<field name="note" placeholder="Add an internal note..." class="oe_inline"/>
|
||||||
</page>
|
</page>
|
||||||
<page string="Additional Info">
|
<page string="Additional Info">
|
||||||
|
@ -945,7 +945,7 @@
|
||||||
<field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Customer" domain="[('customer','=',True)]" />
|
<field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Customer" domain="[('customer','=',True)]" />
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='move_lines']" position="replace">
|
<xpath expr="//field[@name='move_lines']" position="replace">
|
||||||
<field name="move_lines" context="{'address_out_id': partner_id, 'picking_type': 'out', 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
<field name="move_lines" string="Stock Move" context="{'address_out_id': partner_id, 'picking_type': 'out', 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/form/sheet" position="after">
|
<xpath expr="/form/sheet" position="after">
|
||||||
<div class="oe_chatter">
|
<div class="oe_chatter">
|
||||||
|
@ -1072,7 +1072,7 @@
|
||||||
<field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Supplier" domain="[('supplier','=',True)]" context="{'default_supplier':1,'default_customer':0}"/>
|
<field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Supplier" domain="[('supplier','=',True)]" context="{'default_supplier':1,'default_customer':0}"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='move_lines']" position="replace">
|
<xpath expr="//field[@name='move_lines']" position="replace">
|
||||||
<field name="move_lines" context="{'address_in_id': partner_id, 'picking_type': 'in', 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
<field name="move_lines" string="Stock Move" context="{'address_in_id': partner_id, 'picking_type': 'in', 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/form/sheet" position="after">
|
<xpath expr="/form/sheet" position="after">
|
||||||
<div class="oe_chatter">
|
<div class="oe_chatter">
|
||||||
|
@ -1359,7 +1359,7 @@
|
||||||
|
|
||||||
<group string="Locations" groups="stock.group_locations">
|
<group string="Locations" groups="stock.group_locations">
|
||||||
<field name="location_id" domain="[('usage','<>','view')]"/>
|
<field name="location_id" domain="[('usage','<>','view')]"/>
|
||||||
<field name="location_dest_id" domain="[('usage','=','internal')]" groups="stock.group_locations"/>
|
<field name="location_dest_id" domain="[('usage','in', ['internal', 'supplier', 'customer'])]" groups="stock.group_locations"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group groups="stock.group_tracking_lot" string="Traceability">
|
<group groups="stock.group_tracking_lot" string="Traceability">
|
||||||
|
|
|
@ -62,14 +62,14 @@ class sale_order(osv.osv):
|
||||||
message = False
|
message = False
|
||||||
partner = self.pool.get('res.partner').browse(cr, uid, part, context=context)
|
partner = self.pool.get('res.partner').browse(cr, uid, part, context=context)
|
||||||
if partner.sale_warn != 'no-message':
|
if partner.sale_warn != 'no-message':
|
||||||
if partner.sale_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (partner.name), partner.sale_warn_msg)
|
|
||||||
title = _("Warning for %s") % partner.name
|
title = _("Warning for %s") % partner.name
|
||||||
message = partner.sale_warn_msg
|
message = partner.sale_warn_msg
|
||||||
warning = {
|
warning = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'message': message,
|
'message': message,
|
||||||
}
|
}
|
||||||
|
if partner.sale_warn == 'block':
|
||||||
|
return {'value': {'partner_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(sale_order, self).onchange_partner_id(cr, uid, ids, part, context=context)
|
result = super(sale_order, self).onchange_partner_id(cr, uid, ids, part, context=context)
|
||||||
|
|
||||||
|
@ -90,14 +90,15 @@ class purchase_order(osv.osv):
|
||||||
message = False
|
message = False
|
||||||
partner = self.pool.get('res.partner').browse(cr, uid, part)
|
partner = self.pool.get('res.partner').browse(cr, uid, part)
|
||||||
if partner.purchase_warn != 'no-message':
|
if partner.purchase_warn != 'no-message':
|
||||||
if partner.purchase_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (partner.name), partner.purchase_warn_msg)
|
|
||||||
title = _("Warning for %s") % partner.name
|
title = _("Warning for %s") % partner.name
|
||||||
message = partner.purchase_warn_msg
|
message = partner.purchase_warn_msg
|
||||||
warning = {
|
warning = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
if partner.purchase_warn == 'block':
|
||||||
|
return {'value': {'partner_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(purchase_order, self).onchange_partner_id(cr, uid, ids, part)
|
result = super(purchase_order, self).onchange_partner_id(cr, uid, ids, part)
|
||||||
|
|
||||||
if result.get('warning',False):
|
if result.get('warning',False):
|
||||||
|
@ -123,15 +124,16 @@ class account_invoice(osv.osv):
|
||||||
message = False
|
message = False
|
||||||
partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
|
partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
|
||||||
if partner.invoice_warn != 'no-message':
|
if partner.invoice_warn != 'no-message':
|
||||||
if partner.invoice_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (partner.name), partner.invoice_warn_msg)
|
|
||||||
|
|
||||||
title = _("Warning for %s") % partner.name
|
title = _("Warning for %s") % partner.name
|
||||||
message = partner.invoice_warn_msg
|
message = partner.invoice_warn_msg
|
||||||
warning = {
|
warning = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if partner.invoice_warn == 'block':
|
||||||
|
return {'value': {'partner_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(account_invoice, self).onchange_partner_id(cr, uid, ids, type, partner_id,
|
result = super(account_invoice, self).onchange_partner_id(cr, uid, ids, type, partner_id,
|
||||||
date_invoice=date_invoice, payment_term=payment_term,
|
date_invoice=date_invoice, payment_term=payment_term,
|
||||||
partner_bank_id=partner_bank_id, company_id=company_id)
|
partner_bank_id=partner_bank_id, company_id=company_id)
|
||||||
|
@ -154,14 +156,15 @@ class stock_picking(osv.osv):
|
||||||
title = False
|
title = False
|
||||||
message = False
|
message = False
|
||||||
if partner.picking_warn != 'no-message':
|
if partner.picking_warn != 'no-message':
|
||||||
if partner.picking_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (partner.name), partner.picking_warn_msg)
|
|
||||||
title = _("Warning for %s") % partner.name
|
title = _("Warning for %s") % partner.name
|
||||||
message = partner.picking_warn_msg
|
message = partner.picking_warn_msg
|
||||||
warning = {
|
warning = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
if partner.picking_warn == 'block':
|
||||||
|
return {'value': {'partner_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(stock_picking, self).onchange_partner_in(cr, uid, ids, partner_id, context)
|
result = super(stock_picking, self).onchange_partner_in(cr, uid, ids, partner_id, context)
|
||||||
if result.get('warning',False):
|
if result.get('warning',False):
|
||||||
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
|
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
|
||||||
|
@ -183,14 +186,15 @@ class stock_picking_in(osv.osv):
|
||||||
title = False
|
title = False
|
||||||
message = False
|
message = False
|
||||||
if partner.picking_warn != 'no-message':
|
if partner.picking_warn != 'no-message':
|
||||||
if partner.picking_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (partner.name), partner.picking_warn_msg)
|
|
||||||
title = _("Warning for %s") % partner.name
|
title = _("Warning for %s") % partner.name
|
||||||
message = partner.picking_warn_msg
|
message = partner.picking_warn_msg
|
||||||
warning = {
|
warning = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
if partner.picking_warn == 'block':
|
||||||
|
return {'value': {'partner_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(stock_picking_in, self).onchange_partner_in(cr, uid, ids, partner_id, context)
|
result = super(stock_picking_in, self).onchange_partner_in(cr, uid, ids, partner_id, context)
|
||||||
if result.get('warning',False):
|
if result.get('warning',False):
|
||||||
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
|
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
|
||||||
|
@ -209,14 +213,15 @@ class stock_picking_out(osv.osv):
|
||||||
title = False
|
title = False
|
||||||
message = False
|
message = False
|
||||||
if partner.picking_warn != 'no-message':
|
if partner.picking_warn != 'no-message':
|
||||||
if partner.picking_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (partner.name), partner.picking_warn_msg)
|
|
||||||
title = _("Warning for %s") % partner.name
|
title = _("Warning for %s") % partner.name
|
||||||
message = partner.picking_warn_msg
|
message = partner.picking_warn_msg
|
||||||
warning = {
|
warning = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'message': message
|
'message': message
|
||||||
}
|
}
|
||||||
|
if partner.picking_warn == 'block':
|
||||||
|
return {'value': {'partner_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(stock_picking_out, self).onchange_partner_in(cr, uid, ids, partner_id, context)
|
result = super(stock_picking_out, self).onchange_partner_in(cr, uid, ids, partner_id, context)
|
||||||
if result.get('warning',False):
|
if result.get('warning',False):
|
||||||
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
|
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
|
||||||
|
@ -256,12 +261,12 @@ class sale_order_line(osv.osv):
|
||||||
message = False
|
message = False
|
||||||
|
|
||||||
if product_info.sale_line_warn != 'no-message':
|
if product_info.sale_line_warn != 'no-message':
|
||||||
if product_info.sale_line_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (product_info.name), product_info.sale_line_warn_msg)
|
|
||||||
title = _("Warning for %s") % product_info.name
|
title = _("Warning for %s") % product_info.name
|
||||||
message = product_info.sale_line_warn_msg
|
message = product_info.sale_line_warn_msg
|
||||||
warning['title'] = title
|
warning['title'] = title
|
||||||
warning['message'] = message
|
warning['message'] = message
|
||||||
|
if product_info.sale_line_warn == 'block':
|
||||||
|
return {'value': {'product_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty,
|
result = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty,
|
||||||
uom, qty_uos, uos, name, partner_id,
|
uom, qty_uos, uos, name, partner_id,
|
||||||
|
@ -288,12 +293,12 @@ class purchase_order_line(osv.osv):
|
||||||
message = False
|
message = False
|
||||||
|
|
||||||
if product_info.purchase_line_warn != 'no-message':
|
if product_info.purchase_line_warn != 'no-message':
|
||||||
if product_info.purchase_line_warn == 'block':
|
|
||||||
raise osv.except_osv(_('Alert for %s!') % (product_info.name), product_info.purchase_line_warn_msg)
|
|
||||||
title = _("Warning for %s") % product_info.name
|
title = _("Warning for %s") % product_info.name
|
||||||
message = product_info.purchase_line_warn_msg
|
message = product_info.purchase_line_warn_msg
|
||||||
warning['title'] = title
|
warning['title'] = title
|
||||||
warning['message'] = message
|
warning['message'] = message
|
||||||
|
if product_info.purchase_line_warn == 'block':
|
||||||
|
return {'value': {'product_id': False}, 'warning': warning}
|
||||||
|
|
||||||
result = super(purchase_order_line, self).onchange_product_id(cr, uid, ids, pricelist, product, qty, uom,
|
result = super(purchase_order_line, self).onchange_product_id(cr, uid, ids, pricelist, product, qty, uom,
|
||||||
partner_id, date_order, fiscal_position_id)
|
partner_id, date_order, fiscal_position_id)
|
||||||
|
|
|
@ -12,7 +12,7 @@ OpenERP Website CMS
|
||||||
'depends': ['web', 'share', 'mail'],
|
'depends': ['web', 'share', 'mail'],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'data': [
|
'data': [
|
||||||
'data/website_data.xml',
|
'data/data.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'security/ir_ui_view.xml',
|
'security/ir_ui_view.xml',
|
||||||
'views/website_templates.xml',
|
'views/website_templates.xml',
|
||||||
|
@ -23,7 +23,7 @@ OpenERP Website CMS
|
||||||
'views/ir_actions.xml',
|
'views/ir_actions.xml',
|
||||||
],
|
],
|
||||||
'demo': [
|
'demo': [
|
||||||
'data/website_demo.xml',
|
'data/demo.xml',
|
||||||
],
|
],
|
||||||
'qweb': ['static/src/xml/website.backend.xml'],
|
'qweb': ['static/src/xml/website.backend.xml'],
|
||||||
'application': True,
|
'application': True,
|
||||||
|
|
|
@ -32,6 +32,13 @@ class ir_http(orm.AbstractModel):
|
||||||
page=PageConverter,
|
page=PageConverter,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _auth_method_public(self):
|
||||||
|
# TODO: select user_id from matching website
|
||||||
|
if not request.session.uid:
|
||||||
|
request.uid = self.pool['ir.model.data'].xmlid_to_res_id(request.cr, openerp.SUPERUSER_ID, 'base.public_user')
|
||||||
|
else:
|
||||||
|
request.uid = request.session.uid
|
||||||
|
|
||||||
def _dispatch(self):
|
def _dispatch(self):
|
||||||
first_pass = not hasattr(request, 'website')
|
first_pass = not hasattr(request, 'website')
|
||||||
request.website = None
|
request.website = None
|
||||||
|
@ -54,7 +61,6 @@ class ir_http(orm.AbstractModel):
|
||||||
if first_pass:
|
if first_pass:
|
||||||
request.lang = request.website.default_lang_code
|
request.lang = request.website.default_lang_code
|
||||||
request.context['lang'] = request.lang
|
request.context['lang'] = request.lang
|
||||||
request.website.preprocess_request(request)
|
|
||||||
if not func:
|
if not func:
|
||||||
path = request.httprequest.path.split('/')
|
path = request.httprequest.path.split('/')
|
||||||
langs = [lg[0] for lg in request.website.get_languages()]
|
langs = [lg[0] for lg in request.website.get_languages()]
|
||||||
|
|
|
@ -109,10 +109,6 @@ class website(osv.osv):
|
||||||
menu = menus and menus[0] or False
|
menu = menus and menus[0] or False
|
||||||
return dict( map(lambda x: (x, menu), ids) )
|
return dict( map(lambda x: (x, menu), ids) )
|
||||||
|
|
||||||
def _get_public_user(self, cr, uid, ids, name='public_user', arg=(), context=None):
|
|
||||||
ref = self.get_public_user(cr, uid, context=context)
|
|
||||||
return dict( map(lambda x: (x, ref), ids) )
|
|
||||||
|
|
||||||
_name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
|
_name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
|
||||||
_description = "Website"
|
_description = "Website"
|
||||||
_columns = {
|
_columns = {
|
||||||
|
@ -129,13 +125,17 @@ class website(osv.osv):
|
||||||
'social_googleplus': fields.char('Google+ Account'),
|
'social_googleplus': fields.char('Google+ Account'),
|
||||||
'google_analytics_key': fields.char('Google Analytics Key'),
|
'google_analytics_key': fields.char('Google Analytics Key'),
|
||||||
'user_id': fields.many2one('res.users', string='Public User'),
|
'user_id': fields.many2one('res.users', string='Public User'),
|
||||||
'public_user': fields.function(_get_public_user, relation='res.users', type='many2one', string='Public User'),
|
'partner_id': fields.related('user_id','partner_id', type='many2one', relation='res.partner', string='Public Partner'),
|
||||||
'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu',
|
'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu',
|
||||||
store= {
|
store= {
|
||||||
'website.menu': (_get_menu_website, ['sequence','parent_id','website_id'], 10)
|
'website.menu': (_get_menu_website, ['sequence','parent_id','website_id'], 10)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_defaults = {
|
||||||
|
'company_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID, 'base.public_user'),
|
||||||
|
}
|
||||||
|
|
||||||
# cf. Wizard hack in website_views.xml
|
# cf. Wizard hack in website_views.xml
|
||||||
def noop(self, *args, **kwargs):
|
def noop(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
@ -186,11 +186,6 @@ class website(osv.osv):
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_public_user(self, cr, uid, context=None):
|
|
||||||
uid = openerp.SUPERUSER_ID
|
|
||||||
res = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'public_user')
|
|
||||||
return res and res[1] or False
|
|
||||||
|
|
||||||
@openerp.tools.ormcache(skiparg=3)
|
@openerp.tools.ormcache(skiparg=3)
|
||||||
def _get_languages(self, cr, uid, id, context=None):
|
def _get_languages(self, cr, uid, id, context=None):
|
||||||
website = self.browse(cr, uid, id)
|
website = self.browse(cr, uid, id)
|
||||||
|
@ -203,9 +198,6 @@ class website(osv.osv):
|
||||||
# TODO: Select website, currently hard coded
|
# TODO: Select website, currently hard coded
|
||||||
return self.pool['website'].browse(cr, uid, 1, context=context)
|
return self.pool['website'].browse(cr, uid, 1, context=context)
|
||||||
|
|
||||||
def preprocess_request(self, cr, uid, ids, request, context=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def is_publisher(self, cr, uid, ids, context=None):
|
def is_publisher(self, cr, uid, ids, context=None):
|
||||||
Access = self.pool['ir.model.access']
|
Access = self.pool['ir.model.access']
|
||||||
is_website_publisher = Access.check(cr, uid, 'ir.ui.view', 'write', False, context)
|
is_website_publisher = Access.check(cr, uid, 'ir.ui.view', 'write', False, context)
|
||||||
|
@ -342,7 +334,7 @@ class website(osv.osv):
|
||||||
"""
|
"""
|
||||||
router = request.httprequest.app.get_db_router(request.db)
|
router = request.httprequest.app.get_db_router(request.db)
|
||||||
# Force enumeration to be performed as public user
|
# Force enumeration to be performed as public user
|
||||||
uid = self.get_public_user(cr, uid, context=context)
|
uid = request.website.user_id.id
|
||||||
url_list = []
|
url_list = []
|
||||||
for rule in router.iter_rules():
|
for rule in router.iter_rules():
|
||||||
if not self.rule_is_enumerable(rule):
|
if not self.rule_is_enumerable(rule):
|
||||||
|
|
|
@ -2,6 +2,7 @@ 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_website_designer,1,1,1,1
|
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_menu_designer,Web Menu Manager,model_website_menu,base.group_website_designer,1,1,1,1
|
||||||
access_website,web menu manager,website.model_website,base.group_website_designer,1,1,1,1
|
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
|
||||||
|
|
|
|
@ -1056,6 +1056,7 @@
|
||||||
this.trigger("saved");
|
this.trigger("saved");
|
||||||
},
|
},
|
||||||
cancel: function () {
|
cancel: function () {
|
||||||
|
this.trigger("cancel");
|
||||||
},
|
},
|
||||||
close: function () {
|
close: function () {
|
||||||
this.$el.modal('hide');
|
this.$el.modal('hide');
|
||||||
|
|
|
@ -879,20 +879,29 @@
|
||||||
this._super(np);
|
this._super(np);
|
||||||
if (np.$next) {
|
if (np.$next) {
|
||||||
if (np.$next.hasClass("oe_custom_bg")) {
|
if (np.$next.hasClass("oe_custom_bg")) {
|
||||||
var editor = new website.editor.ImageDialog();
|
var $image = $('<img class="hidden"/>');
|
||||||
editor.on('start', self, function (o) {o.url = np.$prev && np.$prev.data("src") || np.$next && np.$next.data("src") || "";});
|
$image.attr("src", np.$prev ? np.$prev.data("src") : '');
|
||||||
editor.on('save', self, function (o) {
|
$image.appendTo(self.$target);
|
||||||
self._set_bg(o.url);
|
|
||||||
np.$next.data("src", o.url);
|
self.element = new CKEDITOR.dom.element($image[0]);
|
||||||
|
var editor = new website.editor.MediaDialog(self, self.element);
|
||||||
|
editor.appendTo(document.body);
|
||||||
|
editor.$('[href="#editor-media-video"], [href="#editor-media-icon"]').addClass('hidden');
|
||||||
|
|
||||||
|
$image.on('saved', self, function (o) {
|
||||||
|
var src = $image.attr("src");
|
||||||
|
self._set_bg(src);
|
||||||
|
np.$next.data("src", src);
|
||||||
self.$target.trigger("snippet-style-change", [self, np]);
|
self.$target.trigger("snippet-style-change", [self, np]);
|
||||||
|
$image.remove();
|
||||||
});
|
});
|
||||||
editor.on('cancel', self, function () {
|
editor.on('cancel', self, function () {
|
||||||
if (!np.$prev || np.$prev.data("src") === "") {
|
if (!np.$prev || np.$prev.data("src") === "") {
|
||||||
self.$target.removeClass(np.$next.data("value"));
|
self.$target.removeClass(np.$next.data("value"));
|
||||||
self.$target.trigger("snippet-style-change", [self, np]);
|
self.$target.trigger("snippet-style-change", [self, np]);
|
||||||
}
|
}
|
||||||
|
$image.remove();
|
||||||
});
|
});
|
||||||
editor.appendTo($('body'));
|
|
||||||
} else {
|
} else {
|
||||||
this._set_bg(np.$next.data("src"));
|
this._set_bg(np.$next.data("src"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,11 +104,11 @@ var T = website.Tour = {
|
||||||
if (tour.path && !window.location.href.match(new RegExp("("+T.getLang()+")?"+tour.path+"#?$", "i"))) {
|
if (tour.path && !window.location.href.match(new RegExp("("+T.getLang()+")?"+tour.path+"#?$", "i"))) {
|
||||||
var href = "/"+T.getLang()+tour.path;
|
var href = "/"+T.getLang()+tour.path;
|
||||||
console.log("Tour Begin from run method (redirection to "+href+")");
|
console.log("Tour Begin from run method (redirection to "+href+")");
|
||||||
T.saveState(tour.id, mode || tour.mode, -1);
|
T.saveState(tour.id, mode || tour.mode, -1, 0);
|
||||||
window.location.href = href;
|
window.location.href = href;
|
||||||
} else {
|
} else {
|
||||||
console.log("Tour Begin from run method");
|
console.log("Tour Begin from run method");
|
||||||
T.saveState(tour.id, mode || tour.mode, 0);
|
T.saveState(tour.id, mode || tour.mode, 0, 0);
|
||||||
T.running();
|
T.running();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -311,7 +311,7 @@ var T = website.Tour = {
|
||||||
};
|
};
|
||||||
window.location.hash = "";
|
window.location.hash = "";
|
||||||
console.log("Tour Begin from url hash");
|
console.log("Tour Begin from url hash");
|
||||||
T.saveState(state.id, state.mode, state.step_id);
|
T.saveState(state.id, state.mode, state.step_id, 0);
|
||||||
}
|
}
|
||||||
if (!state.id) {
|
if (!state.id) {
|
||||||
return;
|
return;
|
||||||
|
@ -341,8 +341,8 @@ var T = website.Tour = {
|
||||||
}
|
}
|
||||||
return tour_ids;
|
return tour_ids;
|
||||||
},
|
},
|
||||||
saveState: function (tour_id, mode, step_id) {
|
saveState: function (tour_id, mode, step_id, number) {
|
||||||
localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id || 0, "time": this.time}));
|
localStorage.setItem("tour", JSON.stringify({"id":tour_id, "mode":mode, "step_id":step_id || 0, "time": this.time, "number": number+1}));
|
||||||
},
|
},
|
||||||
reset: function () {
|
reset: function () {
|
||||||
var state = T.getState();
|
var state = T.getState();
|
||||||
|
@ -402,6 +402,7 @@ var T = website.Tour = {
|
||||||
if (T.check(next)) {
|
if (T.check(next)) {
|
||||||
clearTimeout(T.currentTimer);
|
clearTimeout(T.currentTimer);
|
||||||
// use an other timeout for cke dom loading
|
// use an other timeout for cke dom loading
|
||||||
|
T.saveState(state.id, state.mode, state.step.id, 0);
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
T.nextStep(next);
|
T.nextStep(next);
|
||||||
}, T.defaultDelay);
|
}, T.defaultDelay);
|
||||||
|
@ -421,7 +422,13 @@ var T = website.Tour = {
|
||||||
}
|
}
|
||||||
|
|
||||||
step = step || state.step;
|
step = step || state.step;
|
||||||
T.saveState(state.id, state.mode, step.id);
|
var next = state.tour.steps[step.id+1];
|
||||||
|
|
||||||
|
if (state.number > 3) {
|
||||||
|
T.error(next, "Cycling. Can't reach the next step");
|
||||||
|
}
|
||||||
|
|
||||||
|
T.saveState(state.id, state.mode, step.id, state.number);
|
||||||
|
|
||||||
if (step.id !== state.step_id) {
|
if (step.id !== state.step_id) {
|
||||||
console.log("Tour Step: '" + (step._title || step.title) + "' (" + (new Date().getTime() - this.time) + "ms)");
|
console.log("Tour Step: '" + (step._title || step.title) + "' (" + (new Date().getTime() - this.time) + "ms)");
|
||||||
|
@ -433,7 +440,6 @@ var T = website.Tour = {
|
||||||
step.onload();
|
step.onload();
|
||||||
}
|
}
|
||||||
|
|
||||||
var next = state.tour.steps[step.id+1];
|
|
||||||
if (next) {
|
if (next) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
T.waitNextStep();
|
T.waitNextStep();
|
||||||
|
|
|
@ -34,6 +34,7 @@ import time
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from openerp import tools
|
from openerp import tools
|
||||||
import werkzeug.urls
|
import werkzeug.urls
|
||||||
|
from openerp.addons.website.models.website import slug
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import GeoIP
|
import GeoIP
|
||||||
|
@ -211,7 +212,8 @@ class website_event(http.Controller):
|
||||||
'date_end': (date_begin + timedelta(days=(1))).strftime('%Y-%m-%d'),
|
'date_end': (date_begin + timedelta(days=(1))).strftime('%Y-%m-%d'),
|
||||||
}
|
}
|
||||||
event_id = Event.create(request.cr, request.uid, vals, context=context)
|
event_id = Event.create(request.cr, request.uid, vals, context=context)
|
||||||
return request.redirect("/event/%s?enable_editor=1" % event_id)
|
event = Event.browse(request.cr, request.uid, event_id, context=context)
|
||||||
|
return request.redirect("/event/%s/register?enable_editor=1" % slug(event))
|
||||||
|
|
||||||
def get_visitors_country(self):
|
def get_visitors_country(self):
|
||||||
GI = GeoIP.open('/usr/share/GeoIP/GeoIP.dat', 0)
|
GI = GeoIP.open('/usr/share/GeoIP/GeoIP.dat', 0)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
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_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0
|
access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0
|
||||||
|
access_event_event_portal,event.event.portal,event.model_event_event,base.group_portal,1,0,0,0
|
||||||
access_event_type_public,event.type.public,event.model_event_type,base.group_public,1,0,0,0
|
access_event_type_public,event.type.public,event.model_event_type,base.group_public,1,0,0,0
|
||||||
|
access_event_type_portal,event.type.portal,event.model_event_type,base.group_portal,1,0,0,0
|
||||||
|
|
|
|
@ -27,57 +27,24 @@ from openerp.tools.translate import _
|
||||||
|
|
||||||
|
|
||||||
class website_event(website_event):
|
class website_event(website_event):
|
||||||
@http.route(['/event/add_cart'], type='http', auth="public", website=True, multilang=True)
|
|
||||||
def add_cart(self, event_id, **post):
|
@http.route(['/event/cart/update'], type='http', auth="public", methods=['POST'], website=True, multilang=True)
|
||||||
user_obj = request.registry['res.users']
|
def cart_update(self, event_id, **post):
|
||||||
order_line_obj = request.registry.get('sale.order.line')
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
ticket_obj = request.registry.get('event.event.ticket')
|
ticket_obj = request.registry.get('event.event.ticket')
|
||||||
order_obj = request.registry.get('sale.order')
|
|
||||||
website = request.registry['website']
|
|
||||||
|
|
||||||
order = website.ecommerce_get_current_order(request.cr, request.uid, context=request.context)
|
sale = False
|
||||||
if not order:
|
|
||||||
order = website.ecommerce_get_new_order(request.cr, request.uid, context=request.context)
|
|
||||||
|
|
||||||
partner_id = user_obj.browse(request.cr, SUPERUSER_ID, request.uid,
|
|
||||||
context=request.context).partner_id.id
|
|
||||||
|
|
||||||
fields = [k for k, v in order_line_obj._columns.items()]
|
|
||||||
values = order_line_obj.default_get(request.cr, SUPERUSER_ID, fields,
|
|
||||||
context=request.context)
|
|
||||||
|
|
||||||
_values = None
|
|
||||||
for key, value in post.items():
|
for key, value in post.items():
|
||||||
try:
|
quantity = int(value or "0")
|
||||||
quantity = int(value)
|
if not quantity:
|
||||||
assert quantity > 0
|
|
||||||
except:
|
|
||||||
quantity = None
|
|
||||||
ticket_id = key.split("-")[0] == 'ticket' and int(key.split("-")[1]) or None
|
|
||||||
if not ticket_id or not quantity:
|
|
||||||
continue
|
continue
|
||||||
ticket = ticket_obj.browse(request.cr, request.uid, ticket_id,
|
sale = True
|
||||||
context=request.context)
|
ticket_id = key.split("-")[0] == 'ticket' and int(key.split("-")[1]) or None
|
||||||
|
ticket = ticket_obj.browse(cr, SUPERUSER_ID, ticket_id, context=context)
|
||||||
|
request.website.sale_get_order(force_create=1)._cart_update(
|
||||||
|
product_id=ticket.product_id.id, add_qty=quantity, context=dict(context, event_ticket_id=ticket.id))
|
||||||
|
|
||||||
values['product_id'] = ticket.product_id.id
|
if not sale:
|
||||||
values['event_id'] = ticket.event_id.id
|
|
||||||
values['event_ticket_id'] = ticket.id
|
|
||||||
values['product_uom_qty'] = quantity
|
|
||||||
values['price_unit'] = ticket.price
|
|
||||||
values['order_id'] = order.id
|
|
||||||
values['name'] = "%s: %s" % (ticket.event_id.name, ticket.name)
|
|
||||||
|
|
||||||
# change and record value
|
|
||||||
pricelist_id = order.pricelist_id and order.pricelist_id.id or False
|
|
||||||
_values = order_line_obj.product_id_change(
|
|
||||||
request.cr, SUPERUSER_ID, [], pricelist_id, ticket.product_id.id,
|
|
||||||
partner_id=partner_id, context=request.context)['value']
|
|
||||||
_values.update(values)
|
|
||||||
|
|
||||||
order_line_id = order_line_obj.create(request.cr, SUPERUSER_ID, _values, context=request.context)
|
|
||||||
order_obj.write(request.cr, SUPERUSER_ID, [order.id], {'order_line': [(4, order_line_id)]}, context=request.context)
|
|
||||||
|
|
||||||
if not _values:
|
|
||||||
return request.redirect("/event/%s" % event_id)
|
return request.redirect("/event/%s" % event_id)
|
||||||
return request.redirect("/shop/checkout")
|
return request.redirect("/shop/checkout")
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
import product
|
import product
|
||||||
import sale_order
|
|
||||||
import website
|
import website
|
||||||
|
import sale_order
|
||||||
|
|
|
@ -1,22 +1,49 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from openerp.osv import osv
|
|
||||||
from openerp import SUPERUSER_ID
|
from openerp import SUPERUSER_ID
|
||||||
from openerp.addons.web.http import request
|
from openerp.osv import osv, fields
|
||||||
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
# defined for access rules
|
||||||
|
class sale_order(osv.Model):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
class sale_order_line(osv.osv):
|
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, context=None):
|
||||||
_inherit = "sale.order.line"
|
for so in self.browse(cr, uid, ids, context=context):
|
||||||
|
order_line_id = None
|
||||||
|
domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
|
||||||
|
if line_id:
|
||||||
|
domain += [('id', '=', line_id)]
|
||||||
|
elif context.get("event_ticket_id"):
|
||||||
|
domain += [('event_ticket_id', '=', context.get("event_ticket_id"))]
|
||||||
|
order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
|
||||||
|
if order_line_ids:
|
||||||
|
order_line_id = order_line_ids[0]
|
||||||
|
return order_line_id
|
||||||
|
|
||||||
def _recalculate_product_values(self, cr, uid, ids, product_id=0, fiscal_position=False, context=None):
|
def _website_product_id_change(self, cr, uid, ids, order_id, product_id, line_id=None, context=None):
|
||||||
if not ids:
|
values = super(sale_order,self)._website_product_id_change(cr, uid, ids, order_id, product_id, line_id=None, context=None)
|
||||||
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)
|
event_ticket_id = None
|
||||||
assert order_line.order_id.website_session_id == request.session['website_session_id']
|
if context.get("event_ticket_id"):
|
||||||
|
event_ticket_id = context.get("event_ticket_id")
|
||||||
|
elif line_id:
|
||||||
|
line = self.pool.get('sale.order.line').browse(cr, SUPERUSER_ID, line_id, context=context)
|
||||||
|
if line.event_ticket_id:
|
||||||
|
event_ticket_id = line.event_ticket_id.id
|
||||||
|
else:
|
||||||
|
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
||||||
|
if product.event_ticket_ids:
|
||||||
|
event_ticket_id = product.event_ticket_ids[0]
|
||||||
|
|
||||||
product = product_id and self.pool.get('product.product').browse(cr, uid, product_id, context=context) or order_line.product_id
|
if event_ticket_id:
|
||||||
res = super(sale_order_line, self)._recalculate_product_values(cr, uid, ids, product.id, fiscal_position=fiscal_position, context=context)
|
ticket = self.pool.get('event.event.ticket').browse(cr, uid, event_ticket_id, 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_id != ticket.product_id.id:
|
||||||
res.update({'price_unit': order_line.event_ticket_id.price})
|
raise osv.except_osv(_('Error!'),_("The ticket doesn't match with this product."))
|
||||||
|
|
||||||
return res
|
values['product_id'] = ticket.product_id.id
|
||||||
|
values['event_id'] = ticket.event_id.id
|
||||||
|
values['event_ticket_id'] = ticket.id
|
||||||
|
values['price_unit'] = ticket.price
|
||||||
|
values['name'] = "%s: %s" % (ticket.event_id.name, ticket.name)
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
|
@ -5,6 +5,6 @@ from openerp.osv import orm
|
||||||
class Website(orm.Model):
|
class Website(orm.Model):
|
||||||
_inherit = 'website'
|
_inherit = 'website'
|
||||||
|
|
||||||
def ecommerce_get_product_domain(self):
|
def sale_product_domain(self, cr, uid, ids, context=None):
|
||||||
# remove product event from the website content grid and list view (not removed in detail view)
|
# remove product event from the website content grid and list view (not removed in detail view)
|
||||||
return ['&'] + super(Website, self).ecommerce_get_product_domain() + [('event_ok', '=', False)]
|
return ['&'] + super(Website, self).sale_product_domain(cr, uid, ids, context=context) + [('event_ok', '=', False)]
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template id="mycart" inherit_id="website_sale.mycart" name="My Cart Event's Price">
|
<template id="cart" inherit_id="website_sale.cart" name="My Cart Event's Price">
|
||||||
<xpath expr="//td[@name='price']/t" position="attributes">
|
<xpath expr="//td[@name='price']/t" position="attributes">
|
||||||
<attribute name="t-if">abs(line.product_id.lst_price - line.price_unit) > 0.2 and not line.product_id.event_ok</attribute>
|
<attribute name="t-if">abs(line.product_id.lst_price - line.price_unit) > 0.2 and not line.product_id.event_ok</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
<template id="event_description_full" inherit_id="website_event.event_description_full" inherit_option_id="website_event.event_description_full" name="Event's Ticket form">
|
<template id="event_description_full" inherit_id="website_event.event_description_full" inherit_option_id="website_event.event_description_full" name="Event's Ticket form">
|
||||||
<xpath expr="//div[@t-field='event.description']" position="before">
|
<xpath expr="//div[@t-field='event.description']" position="before">
|
||||||
<form t-attf-action="/event/add_cart?event_id=#{ event.id }" method="post" t-if="event.event_ticket_ids">
|
<form t-attf-action="/event/cart/update?event_id=#{ event.id }" method="post" t-if="event.event_ticket_ids">
|
||||||
<table itemprop="offers" class="table table-striped">
|
<table itemprop="offers" class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -124,6 +124,7 @@ class WebsiteForum(http.Controller):
|
||||||
values.update({
|
values.update({
|
||||||
'main_object': tag or forum,
|
'main_object': tag or forum,
|
||||||
'question_ids': question_ids,
|
'question_ids': question_ids,
|
||||||
|
'question_count': question_count,
|
||||||
'pager': pager,
|
'pager': pager,
|
||||||
'tag': tag,
|
'tag': tag,
|
||||||
'filters': filters,
|
'filters': filters,
|
||||||
|
@ -134,7 +135,7 @@ class WebsiteForum(http.Controller):
|
||||||
|
|
||||||
@http.route(['/forum/<model("forum.forum"):forum>/faq'], type='http', auth="public", website=True, multilang=True)
|
@http.route(['/forum/<model("forum.forum"):forum>/faq'], type='http', auth="public", website=True, multilang=True)
|
||||||
def forum_faq(self, forum, **post):
|
def forum_faq(self, forum, **post):
|
||||||
values = self._prepare_forum_values(forum=forum, searches=dict(), **post)
|
values = self._prepare_forum_values(forum=forum, searches=dict(), header={'is_guidelines': True}, **post)
|
||||||
return request.website.render("website_forum.faq", values)
|
return request.website.render("website_forum.faq", values)
|
||||||
|
|
||||||
@http.route('/forum/get_tags', type='http', auth="public", multilang=True, methods=['GET'], website=True)
|
@http.route('/forum/get_tags', type='http', auth="public", multilang=True, methods=['GET'], website=True)
|
||||||
|
@ -147,7 +148,7 @@ class WebsiteForum(http.Controller):
|
||||||
def tags(self, forum, page=1, **post):
|
def tags(self, forum, page=1, **post):
|
||||||
cr, uid, context = request.cr, request.uid, request.context
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
Tag = request.registry['forum.tag']
|
Tag = request.registry['forum.tag']
|
||||||
obj_ids = Tag.search(cr, uid, [('forum_id', '=', forum.id)], limit=None, context=context)
|
obj_ids = Tag.search(cr, uid, [('forum_id', '=', forum.id), ('posts_count', '>', 0)], limit=None, order='posts_count DESC', context=context)
|
||||||
tags = Tag.browse(cr, uid, obj_ids, context=context)
|
tags = Tag.browse(cr, uid, obj_ids, context=context)
|
||||||
values = self._prepare_forum_values(forum=forum, searches={'tags': True}, **post)
|
values = self._prepare_forum_values(forum=forum, searches={'tags': True}, **post)
|
||||||
values.update({
|
values.update({
|
||||||
|
@ -427,7 +428,7 @@ class WebsiteForum(http.Controller):
|
||||||
tag_count = User.search(cr, SUPERUSER_ID, [('karma', '>', 1)], count=True, context=context)
|
tag_count = User.search(cr, SUPERUSER_ID, [('karma', '>', 1)], count=True, context=context)
|
||||||
pager = request.website.pager(url="/forum/users", total=tag_count, page=page, step=step, scope=30)
|
pager = request.website.pager(url="/forum/users", total=tag_count, page=page, step=step, scope=30)
|
||||||
|
|
||||||
obj_ids = User.search(cr, SUPERUSER_ID, [('karma', '>', 1)], limit=step, offset=pager['offset'], context=context)
|
obj_ids = User.search(cr, SUPERUSER_ID, [('karma', '>', 1)], limit=step, offset=pager['offset'], order='karma DESC', context=context)
|
||||||
users = User.browse(cr, SUPERUSER_ID, obj_ids, context=context)
|
users = User.browse(cr, SUPERUSER_ID, obj_ids, context=context)
|
||||||
searches['users'] = 'True'
|
searches['users'] = 'True'
|
||||||
|
|
||||||
|
@ -591,12 +592,13 @@ class WebsiteForum(http.Controller):
|
||||||
|
|
||||||
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/comment/<model("mail.message"):comment>/convert_to_answer', type='http', auth="public", multilang=True, website=True)
|
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/comment/<model("mail.message"):comment>/convert_to_answer', type='http', auth="public", multilang=True, website=True)
|
||||||
def convert_comment_to_answer(self, forum, post, comment, **kwarg):
|
def convert_comment_to_answer(self, forum, post, comment, **kwarg):
|
||||||
values = {
|
body = comment.body
|
||||||
'content': comment.body,
|
|
||||||
}
|
|
||||||
request.registry['mail.message'].unlink(request.cr, request.uid, [comment.id], context=request.context)
|
request.registry['mail.message'].unlink(request.cr, request.uid, [comment.id], context=request.context)
|
||||||
question = post.parent_id if post.parent_id else post
|
question = post.parent_id if post.parent_id else post
|
||||||
return self.post_new(forum, question, **values)
|
for answer in question.child_ids:
|
||||||
|
if answer.create_uid.id == request.uid:
|
||||||
|
return self.post_comment(forum, answer, comment=html2plaintext(body))
|
||||||
|
return self.post_new(forum, question, content=body)
|
||||||
|
|
||||||
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/convert_to_comment', type='http', auth="user", multilang=True, website=True)
|
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/convert_to_comment', type='http', auth="user", multilang=True, website=True)
|
||||||
def convert_answer_to_comment(self, forum, post, **kwarg):
|
def convert_answer_to_comment(self, forum, post, **kwarg):
|
||||||
|
|
|
@ -13,10 +13,7 @@
|
||||||
<field name="sequence" type="int">35</field>
|
<field name="sequence" type="int">35</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="default_allow_auth_signup" model="ir.config_parameter">
|
<function model="ir.config_parameter" name="set_param" eval="('auth_signup.allow_uninvited', True)" />
|
||||||
<field name="key">auth_signup.allow_uninvited</field>
|
|
||||||
<field name="value" eval="True"/>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- JUMP TO FORUM AT INSTALL -->
|
<!-- JUMP TO FORUM AT INSTALL -->
|
||||||
<record id="action_open_forum" model="ir.actions.act_url">
|
<record id="action_open_forum" model="ir.actions.act_url">
|
||||||
|
|
|
@ -70,6 +70,7 @@ class Post(osv.Model):
|
||||||
_name = 'forum.post'
|
_name = 'forum.post'
|
||||||
_description = 'Forum Post'
|
_description = 'Forum Post'
|
||||||
_inherit = ['mail.thread', 'website.seo.metadata']
|
_inherit = ['mail.thread', 'website.seo.metadata']
|
||||||
|
_order = "is_correct DESC, vote_count DESC"
|
||||||
|
|
||||||
def _get_user_vote(self, cr, uid, ids, field_name, arg, context):
|
def _get_user_vote(self, cr, uid, ids, field_name, arg, context):
|
||||||
res = dict.fromkeys(ids, 0)
|
res = dict.fromkeys(ids, 0)
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
background-color: #cccccc;
|
background-color: #cccccc;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
.question .badge-active {
|
||||||
|
background-color: #428bca;
|
||||||
|
}
|
||||||
|
|
||||||
.oe_grey {
|
.oe_grey {
|
||||||
background-color: #eeeeee;
|
background-color: #eeeeee;
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
.badge
|
.badge
|
||||||
background-color: #ccc
|
background-color: #ccc
|
||||||
margin-left: 4px
|
margin-left: 4px
|
||||||
|
.badge-active
|
||||||
|
background-color: #428bca
|
||||||
|
|
||||||
.oe_grey
|
.oe_grey
|
||||||
background-color: #eeeeee
|
background-color: #eeeeee
|
||||||
|
|
|
@ -94,7 +94,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<t t-raw="forum.description"/><br/>
|
<t t-raw="forum.description"/><br/>
|
||||||
<a t-attf-href="/forum/#{slug(forum)}/faq" class="fa fa-arrow-right"> Read Guidelines</a>
|
<a t-if="not header.get('is_guidelines')" t-attf-href="/forum/#{slug(forum)}/faq" class="fa fa-arrow-right"> Read Guidelines</a>
|
||||||
|
<a t-if="header.get('is_guidelines')" t-attf-href="/forum/#{slug(forum)}" class="fa fa-arrow-right"> Back to <span t-field="forum.name"/></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div t-if="header.get('question_data')">
|
<div t-if="header.get('question_data')">
|
||||||
|
@ -146,8 +147,11 @@
|
||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
<t t-foreach="question.tag_ids" t-as="tag">
|
<t t-foreach="question.tag_ids" t-as="question_tag">
|
||||||
<a t-attf-href="/forum/#{ slug(forum) }/tag/#{ tag.id }/questions" class="badge pull-right" t-field="tag.name"/>
|
<a t-attf-href="/forum/#{ slug(forum) }/tag/#{slug(question_tag)}/questions">
|
||||||
|
<span t-attf-class="pull-right badge #{tag and tag.name == question_tag.name and 'badge-active' ''}" t-field="question_tag.name"
|
||||||
|
style="margin-right: 4px;"/>
|
||||||
|
</a>
|
||||||
</t>
|
</t>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
by <a t-attf-href="/forum/#{ slug(forum) }/user/#{ question.create_uid.id }"
|
by <a t-attf-href="/forum/#{ slug(forum) }/user/#{ question.create_uid.id }"
|
||||||
|
@ -210,14 +214,14 @@
|
||||||
<template id="forum_index" name="Forum">
|
<template id="forum_index" name="Forum">
|
||||||
<t t-call="website_forum.header">
|
<t t-call="website_forum.header">
|
||||||
<h1 class="page-header mt0">
|
<h1 class="page-header mt0">
|
||||||
<t t-esc="len(question_ids)"/> <span>Questions</span>
|
<t t-esc="question_count"/> <span>Questions</span>
|
||||||
<t t-esc="search"/>
|
<t t-esc="search"/>
|
||||||
<small class="dropdown" t-if="filters in ('all', 'unanswered','followed', 'tag')">
|
<small class="dropdown" t-if="filters in ('all', 'unanswered','followed', 'tag')">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||||
<t t-if="filters == 'all'">All</t>
|
<t t-if="filters == 'all'">All</t>
|
||||||
<t t-if="filters == 'unanswered'">Unanswered</t>
|
<t t-if="filters == 'unanswered'">Unanswered</t>
|
||||||
<t t-if="filters == 'followed'">Followed</t>
|
<t t-if="filters == 'followed'">Followed</t>
|
||||||
<t t-if="filters == 'tag'">Tag</t>
|
<t t-if="tag"><span t-field="tag.name"/></t>
|
||||||
<t t-if="sorting == 'date'"> by activity date</t>
|
<t t-if="sorting == 'date'"> by activity date</t>
|
||||||
<t t-if="sorting == 'answered'"> by most answered</t>
|
<t t-if="sorting == 'answered'"> by most answered</t>
|
||||||
<t t-if="sorting == 'vote'"> by most voted</t>
|
<t t-if="sorting == 'vote'"> by most voted</t>
|
||||||
|
@ -334,12 +338,12 @@
|
||||||
users having a high karma can see closed questions to moderate
|
users having a high karma can see closed questions to moderate
|
||||||
them.
|
them.
|
||||||
</p>
|
</p>
|
||||||
<form t-attf-action="/forum/#{ slug(forum) }/question/#{slug(post)}/close" method="post" role="form" class="form-horizontal mt32 mb64">
|
<form t-attf-action="/forum/#{ slug(forum) }/question/#{slug(question)}/close" method="post" role="form" class="form-horizontal mt32 mb64">
|
||||||
<input name="post_id" t-att-value="question.id" type="hidden"/>
|
<input name="post_id" t-att-value="question.id" type="hidden"/>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-3 control-label" for="reason">Question:</label>
|
<label class="col-md-3 control-label" for="reason">Question:</label>
|
||||||
<div class="col-md-8 mt8">
|
<div class="col-md-8 mt8">
|
||||||
<span t-field="post.name"/>
|
<span t-field="question.name"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -356,7 +360,7 @@
|
||||||
<div class="col-md-offset-3 col-md-8">
|
<div class="col-md-offset-3 col-md-8">
|
||||||
<button class="btn btn-primary">Close question</button>
|
<button class="btn btn-primary">Close question</button>
|
||||||
<span class="text-muted">or</span>
|
<span class="text-muted">or</span>
|
||||||
<a class="btn btn-link" t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post) }">back to question</a>
|
<a class="btn btn-link" t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(question) }">back to question</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -453,7 +457,7 @@
|
||||||
<a class="text-muted fa fa-times" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/ask_for_close"> Close</a>
|
<a class="text-muted fa fa-times" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/ask_for_close"> Close</a>
|
||||||
</li>
|
</li>
|
||||||
<li t-if="question.state == 'close' and ((user.id == question.create_uid.id and can_close_own) or can_close_all)">
|
<li t-if="question.state == 'close' and ((user.id == question.create_uid.id and can_close_own) or can_close_all)">
|
||||||
<a class="text-muted fa fa-undo" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)/reopen"> Reopen</a>
|
<a class="text-muted fa fa-undo" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/reopen"> Reopen</a>
|
||||||
</li>
|
</li>
|
||||||
<li t-if="(user.id == question.create_uid.id and can_edit_own) or can_edit_all">
|
<li t-if="(user.id == question.create_uid.id and can_edit_own) or can_edit_all">
|
||||||
<a class="text-muted fa fa-edit" t-attf-href="/forum/#{ slug(forum) }/post/#{slug(question)}/edit"> Edit</a>
|
<a class="text-muted fa fa-edit" t-attf-href="/forum/#{ slug(forum) }/post/#{slug(question)}/edit"> Edit</a>
|
||||||
|
@ -469,7 +473,7 @@
|
||||||
<div>
|
<div>
|
||||||
<span t-field="question.create_uid.image" t-field-options='{"widget": "image", "class":"pull-left img img-circle img-avatar"}'/>
|
<span t-field="question.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/#{ question.create_uid.id }"
|
||||||
t-field="question.create_uid"
|
t-field="question.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;"/>
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>var partner_url = '<t t-raw="partner_url or ''"/>';</script>
|
<script>var partner_url = '<t t-raw="partner_url or ''"/>';</script>
|
||||||
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
<script src="//maps.google.com/maps/api/js?sensor=false"></script>
|
||||||
<script type="text/javascript" t-attf-src="/google_map/partners.json?partner_ids=#{ partner_ids }"></script>
|
<script type="text/javascript" t-attf-src="/google_map/partners.json?partner_ids=#{ partner_ids }"></script>
|
||||||
<script type="text/javascript" src="/website_google_map/static/src/js/markerclusterer_compiled.js"></script>
|
<script type="text/javascript" src="/website_google_map/static/src/js/markerclusterer_compiled.js"></script>
|
||||||
<script src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
|
<script src="//code.jquery.com/jquery-1.6.1.min.js"></script>
|
||||||
<script type="text/javascript" src="/website_google_map/static/src/js/google_map.js"></script>
|
<script type="text/javascript" src="/website_google_map/static/src/js/google_map.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -32,14 +32,13 @@ class WebsiteMail(http.Controller):
|
||||||
|
|
||||||
partner_obj = request.registry['res.partner']
|
partner_obj = request.registry['res.partner']
|
||||||
user_obj = request.registry['res.users']
|
user_obj = request.registry['res.users']
|
||||||
website = request.registry['website']
|
|
||||||
|
|
||||||
_id = int(id)
|
_id = int(id)
|
||||||
_message_is_follower = message_is_follower == 'on'
|
_message_is_follower = message_is_follower == 'on'
|
||||||
_object = request.registry[object]
|
_object = request.registry[object]
|
||||||
|
|
||||||
# search partner_id
|
# search partner_id
|
||||||
public_id = website.get_public_user(cr, uid, context)
|
public_id = request.website.user_id.id
|
||||||
if uid != public_id:
|
if uid != public_id:
|
||||||
partner_ids = [user_obj.browse(cr, uid, uid, context).partner_id.id]
|
partner_ids = [user_obj.browse(cr, uid, uid, context).partner_id.id]
|
||||||
else:
|
else:
|
||||||
|
@ -68,10 +67,9 @@ class WebsiteMail(http.Controller):
|
||||||
partner_obj = request.registry.get('res.partner')
|
partner_obj = request.registry.get('res.partner')
|
||||||
users_obj = request.registry.get('res.users')
|
users_obj = request.registry.get('res.users')
|
||||||
obj = request.registry.get(model)
|
obj = request.registry.get(model)
|
||||||
website = request.registry['website']
|
|
||||||
|
|
||||||
partner_id = None
|
partner_id = None
|
||||||
public_id = website.get_public_user(cr, uid, context)
|
public_id = request.website.user_id.id
|
||||||
if uid != public_id:
|
if uid != public_id:
|
||||||
partner_id = users_obj.browse(cr, SUPERUSER_ID, uid, context).partner_id
|
partner_id = users_obj.browse(cr, SUPERUSER_ID, uid, context).partner_id
|
||||||
elif request.session.get('partner_id'):
|
elif request.session.get('partner_id'):
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
.. _changelog:
|
|
||||||
|
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
`trunk (saas-3)`
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- created ``website_mail`` menu, holding website-related stuff about mail module
|
|
|
@ -1,10 +0,0 @@
|
||||||
Website Mail Module documentation topics
|
|
||||||
''''''''''''''''''''''''''''''''''''''''
|
|
||||||
|
|
||||||
Changelog
|
|
||||||
'''''''''
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
changelog.rst
|
|
|
@ -32,7 +32,7 @@
|
||||||
'views/website_partner_view.xml',
|
'views/website_partner_view.xml',
|
||||||
'data/website_data.xml',
|
'data/website_data.xml',
|
||||||
],
|
],
|
||||||
'demo': ['website_partner_demo.xml'],
|
'demo': ['data/demo.xml'],
|
||||||
'qweb': [
|
'qweb': [
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue