[MERGE] Sync with trunk.

bzr revid: tde@openerp.com-20121128155246-33vcdcysd47uk4k5
This commit is contained in:
Thibault Delavallée
2012-11-28 16:52:46 +01:00
36 changed files with 349 additions and 354 deletions
+54 -7
View File
@@ -641,8 +641,7 @@ class account_account(osv.osv):
return True
def _check_allow_type_change(self, cr, uid, ids, new_type, context=None):
group1 = ['payable', 'receivable', 'other']
group2 = ['consolidation','view']
restricted_groups = ['consolidation','view']
line_obj = self.pool.get('account.move.line')
for account in self.browse(cr, uid, ids, context=context):
old_type = account.type
@@ -650,14 +649,25 @@ class account_account(osv.osv):
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
#Check for 'Closed' type
if old_type == 'closed' and new_type !='closed':
raise osv.except_osv(_('Warning!'), _("You cannot change the type of account from 'Closed' to any other type which contains journal items!"))
#Check for change From group1 to group2 and vice versa
if (old_type in group1 and new_type in group2) or (old_type in group2 and new_type in group1):
raise osv.except_osv(_('Warning!'), _("You cannot change the type of account from '%s' to '%s' type as it contains journal items!") % (old_type,new_type,))
raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type as it contains journal items!"))
# Forbid to change an account type for restricted_groups as it contains journal items (or if one of its children does)
if (new_type in restricted_groups):
raise osv.except_osv(_('Warning !'), _("You cannot change the type of account to '%s' type as it contains journal items!") % (new_type,))
return True
# For legal reason (forbiden to modify journal entries which belongs to a closed fy or period), Forbid to modify
# the code of an account if journal entries have been already posted on this account. This cannot be simply
# 'configurable' since it can lead to a lack of confidence in OpenERP and this is what we want to change.
def _check_allow_code_change(self, cr, uid, ids, context=None):
line_obj = self.pool.get('account.move.line')
for account in self.browse(cr, uid, ids, context=context):
account_ids = self.search(cr, uid, [('id', 'child_of', [account.id])], context=context)
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)], context=context):
raise osv.except_osv(_('Warning !'), _("You cannot change the code of account which contains journal items!"))
return True
def write(self, cr, uid, ids, vals, context=None):
if context is None:
context = {}
if not ids:
@@ -677,6 +687,8 @@ class account_account(osv.osv):
self._check_moves(cr, uid, ids, "write", context=context)
if 'type' in vals.keys():
self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
if 'code' in vals.keys():
self._check_allow_code_change(cr, uid, ids, context=context)
return super(account_account, self).write(cr, uid, ids, vals, context=context)
def unlink(self, cr, uid, ids, context=None):
@@ -1470,6 +1482,11 @@ class account_move(osv.osv):
raise osv.except_osv(_('User Error!'),
_('You cannot delete a posted journal entry "%s".') % \
move['name'])
for line in move.line_id:
if line.invoice:
raise osv.except_osv(_('User Error!'),
_("Move cannot be deleted if linked to an invoice. (Invoice: %s - Move ID:%s)") % \
(line.invoice.number,move.name))
line_ids = map(lambda x: x.id, move.line_id)
context['journal_id'] = move.journal_id.id
context['period_id'] = move.period_id.id
@@ -1678,11 +1695,41 @@ class account_move_reconcile(osv.osv):
'line_id': fields.one2many('account.move.line', 'reconcile_id', 'Entry Lines'),
'line_partial_ids': fields.one2many('account.move.line', 'reconcile_partial_id', 'Partial Entry lines'),
'create_date': fields.date('Creation date', readonly=True),
'opening_reconciliation': fields.boolean('Opening Entries Reconciliation', help="Is this reconciliation produced by the opening of a new fiscal year ?."),
}
_defaults = {
'name': lambda self,cr,uid,ctx=None: self.pool.get('ir.sequence').get(cr, uid, 'account.reconcile', context=ctx) or '/',
}
# You cannot unlink a reconciliation if it is a opening_reconciliation one,
# you should use the generate opening entries wizard for that
def unlink(self, cr, uid, ids, context=None):
for move_rec in self.browse(cr, uid, ids, context=context):
if move_rec.opening_reconciliation:
raise osv.except_osv(_('Error!'), _('You cannot unreconcile journal items if they has been generated by the \
opening/closing fiscal year process.'))
return super(account_move_reconcile, self).unlink(cr, uid, ids, context=context)
# Look in the line_id and line_partial_ids to ensure the partner is the same or empty
# on all lines. We allow that only for opening/closing period
def _check_same_partner(self, cr, uid, ids, context=None):
for reconcile in self.browse(cr, uid, ids, context=context):
move_lines = []
if not reconcile.opening_reconciliation:
if reconcile.line_id:
first_partner = reconcile.line_id[0].partner_id.id
move_lines = reconcile.line_id
elif reconcile.line_partial_ids:
first_partner = reconcile.line_partial_ids[0].partner_id.id
move_lines = reconcile.line_partial_ids
if any([line.partner_id.id != first_partner for line in move_lines]):
return False
return True
_constraints = [
(_check_same_partner, 'You can only reconcile journal items with the same partner.', ['line_id']),
]
def reconcile_partial_check(self, cr, uid, ids, type='auto', context=None):
total = 0.0
for rec in self.browse(cr, uid, ids, context=context):
+1 -1
View File
@@ -311,7 +311,7 @@ class account_bank_statement(osv.osv):
'statement_id': st_line.statement_id.id,
'journal_id': st_line.statement_id.journal_id.id,
'period_id': st_line.statement_id.period_id.id,
'currency_id': cur_id,
'currency_id': amount_currency and cur_id,
'amount_currency': amount_currency,
'analytic_account_id': analytic_id,
}
+8 -4
View File
@@ -1073,8 +1073,9 @@ class account_invoice(osv.osv):
self.message_post(cr, uid, [inv_id], body=message, context=context)
return True
def action_cancel(self, cr, uid, ids, *args):
context = {} # TODO: Use context from arguments
def action_cancel(self, cr, uid, ids, context=None):
if context is None:
context = {}
account_move_obj = self.pool.get('account.move')
invoices = self.read(cr, uid, ids, ['move_id', 'payment_ids'])
move_ids = [] # ones that we will need to remove
@@ -1244,12 +1245,15 @@ class account_invoice(osv.osv):
ref = invoice.reference
else:
ref = self._convert_ref(cr, uid, invoice.number)
partner = invoice.partner_id
if partner.parent_id and not partner.is_company:
partner = partner.parent_id
# Pay attention to the sign for both debit/credit AND amount_currency
l1 = {
'debit': direction * pay_amount>0 and direction * pay_amount,
'credit': direction * pay_amount<0 and - direction * pay_amount,
'account_id': src_account_id,
'partner_id': invoice.partner_id.id,
'partner_id': partner.id,
'ref':ref,
'date': date,
'currency_id':currency_id,
@@ -1260,7 +1264,7 @@ class account_invoice(osv.osv):
'debit': direction * pay_amount<0 and - direction * pay_amount,
'credit': direction * pay_amount>0 and direction * pay_amount,
'account_id': pay_account_id,
'partner_id': invoice.partner_id.id,
'partner_id': partner.id,
'ref':ref,
'date': date,
'currency_id':currency_id,
+25 -1
View File
@@ -620,12 +620,34 @@ class account_move_line(osv.osv):
return False
return True
def _check_currency_and_amount(self, cr, uid, ids, context=None):
for l in self.browse(cr, uid, ids, context=context):
if (l.amount_currency and not l.currency_id):
return False
return True
def _check_currency_amount(self, cr, uid, ids, context=None):
for l in self.browse(cr, uid, ids, context=context):
if l.amount_currency:
if (l.amount_currency > 0.0 and l.credit > 0.0) or (l.amount_currency < 0.0 and l.debit > 0.0):
return False
return True
def _check_currency_company(self, cr, uid, ids, context=None):
for l in self.browse(cr, uid, ids, context=context):
if l.currency_id.id == l.company_id.currency_id.id:
return False
return True
_constraints = [
(_check_no_view, 'You cannot create journal items on an account of type view.', ['account_id']),
(_check_no_closed, 'You cannot create journal items on closed account.', ['account_id']),
(_check_company_id, 'Account and Period must belong to the same company.', ['company_id']),
(_check_date, 'The date of your Journal Entry is not in the defined period! You should change the date or remove this constraint from the journal.', ['date']),
(_check_currency, 'The selected account of your Journal Entry forces to provide a secondary currency. You should remove the secondary currency on the account or select a multi-currency view on the journal.', ['currency_id']),
(_check_currency_and_amount, "You cannot create journal items with a secondary currency without recording both 'currency' and 'amount currency' field.", ['currency_id','amount_currency']),
(_check_currency_amount, 'The amount expressed in the secondary currency must be positif when journal item are debit and negatif when journal item are credit.', ['amount_currency']),
(_check_currency_company, "You cannot provide a secondary currency if it is the same than the company one." , ['currency_id']),
]
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
@@ -1111,7 +1133,7 @@ class account_move_line(osv.osv):
'has been confirmed.') % res[2])
return res
def _remove_move_reconcile(self, cr, uid, move_ids=None, context=None):
def _remove_move_reconcile(self, cr, uid, move_ids=None, opening_reconciliation=False, context=None):
# Function remove move rencocile ids related with moves
obj_move_line = self.pool.get('account.move.line')
obj_move_rec = self.pool.get('account.move.reconcile')
@@ -1126,6 +1148,8 @@ class account_move_line(osv.osv):
unlink_ids += rec_ids
unlink_ids += part_rec_ids
if unlink_ids:
if opening_reconciliation:
obj_move_rec.write(cr, uid, unlink_ids, {'opening_reconciliation': False})
obj_move_rec.unlink(cr, uid, unlink_ids)
return True
@@ -60,7 +60,7 @@ class account_fiscalyear_close(osv.osv_memory):
cr.execute('select distinct(company_id) from account_move_line where id in %s',(tuple(ids),))
if len(cr.fetchall()) > 1:
raise osv.except_osv(_('Warning!'), _('The entries to reconcile should belong to the same company.'))
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {'type': 'auto'})
r_id = self.pool.get('account.move.reconcile').create(cr, uid, {'type': 'auto', 'opening_reconciliation': True})
cr.execute('update account_move_line set reconcile_id = %s where id in %s',(r_id, tuple(ids),))
return r_id
@@ -107,7 +107,7 @@ class account_fiscalyear_close(osv.osv_memory):
('journal_id', '=', new_journal.id), ('period_id', '=', period.id)])
if move_ids:
move_line_ids = obj_acc_move_line.search(cr, uid, [('move_id', 'in', move_ids)])
obj_acc_move_line._remove_move_reconcile(cr, uid, move_line_ids, context=context)
obj_acc_move_line._remove_move_reconcile(cr, uid, move_line_ids, opening_reconciliation=True, context=context)
obj_acc_move_line.unlink(cr, uid, move_line_ids, context=context)
obj_acc_move.unlink(cr, uid, move_ids, context=context)
@@ -75,15 +75,21 @@ class account_analytic_account(osv.osv):
res[id][f] = 0.0
res2 = {}
for account in accounts:
cr.execute("SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id, name " \
"FROM account_analytic_line as line " \
"WHERE account_id = %s " \
"AND invoice_id is NULL AND to_invoice IS NOT NULL " \
"GROUP BY product_id, user_id, to_invoice, product_uom_id, name", (account.id,))
cr.execute("""
SELECT product_id, sum(amount), user_id, to_invoice, sum(unit_amount), product_uom_id, line.name
FROM account_analytic_line line
LEFT JOIN account_analytic_journal journal ON (journal.id = line.journal_id)
WHERE account_id = %s
AND journal.type != 'purchase'
AND invoice_id IS NULL
AND to_invoice IS NOT NULL
GROUP BY product_id, user_id, to_invoice, product_uom_id, line.name""", (account.id,))
res[account.id][f] = 0.0
for product_id, user_id, factor_id, qty, uom, line_name in cr.fetchall():
price = self.pool.get('account.analytic.line')._get_invoice_price(cr, uid, account, product_id, user_id, qty, context)
for product_id, price, user_id, factor_id, qty, uom, line_name in cr.fetchall():
price = -price
if product_id:
price = self.pool.get('account.analytic.line')._get_invoice_price(cr, uid, account, product_id, user_id, qty, context)
factor = self.pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context=context)
res[account.id][f] += price * qty * (100-factor.factor or 0.0) / 100.0
+18 -1
View File
@@ -20,12 +20,29 @@
##############################################################################
from datetime import datetime
from tools.translate import _
from osv import fields, osv
class Invoice(osv.osv):
_inherit = 'account.invoice'
# Forbid to cancel an invoice if the related move lines have already been
# used in a payment order. The risk is that importing the payment line
# in the bank statement will result in a crash cause no more move will
# be found in the payment line
def action_cancel(self, cr, uid, ids, context=None):
payment_line_obj = self.pool.get('payment.line')
for inv in self.browse(cr, uid, ids, context=context):
pl_line_ids = []
if inv.move_id and inv.move_id.line_id:
inv_mv_lines = [x.id for x in inv.move_id.line_id]
pl_line_ids = payment_line_obj.search(cr, uid, [('move_line_id','in',inv_mv_lines)], context=context)
if pl_line_ids:
pay_line = payment_line_obj.browse(cr, uid, pl_line_ids, context=context)
payment_order_name = ','.join(map(lambda x: x.order_id.reference, pay_line))
raise osv.except_osv(_('Error!'), _("You cannot cancel an invoice which has already been imported in a payment order. Remove it from the following payment order : %s."%(payment_order_name)))
return super(Invoice, self).action_cancel(cr, uid, ids, context=context)
def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
'''Return the amount still to pay regarding all the payment orders'''
if not ids:
@@ -1549,6 +1549,15 @@ class account_bank_statement(osv.osv):
return move_line_obj.write(cr, uid, [x.id for x in v.move_ids], {'statement_id': st_line.statement_id.id}, context=context)
return super(account_bank_statement, self).create_move_from_st_line(cr, uid, st_line.id, company_currency_id, next_number, context=context)
def write(self, cr, uid, ids, vals, context=None):
# Restrict to modify the journal if we already have some voucher of reconciliation created/generated.
# Because the voucher keeps in memory the journal it was created with.
for bk_st in self.browse(cr, uid, ids, context=context):
if vals.get('journal_id') and bk_st.line_ids:
if any([x.voucher_id and True or False for x in bk_st.line_ids]):
raise osv.except_osv(_('Unable to change journal !'), _('You can not change the journal as you already reconciled some statement lines!'))
return super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
account_bank_statement()
class account_bank_statement_line(osv.osv):
@@ -4,10 +4,10 @@
-
I create a cash account with currency USD
-
!record {model: account.account, id: account_cash_usd_id}:
!record {model: account.account, id: account_cash_usd_id2}:
currency_id: base.USD
name: "cash account in usd"
code: "Xcash usd"
code: "Xcash usd2"
type: 'liquidity'
user_type: "account.data_account_type_cash"
@@ -56,8 +56,8 @@
type: bank
analytic_journal_id: account.sit
sequence_id: account.sequence_bank_journal
default_debit_account_id: account_cash_usd_id
default_credit_account_id: account_cash_usd_id
default_debit_account_id: account_cash_usd_id2
default_credit_account_id: account_cash_usd_id2
currency: base.USD
company_id: base.main_company
view_id: account.account_journal_bank_view
@@ -65,39 +65,25 @@ class account_analytic_account(osv.osv):
def _expense_to_invoice_calc(self, cr, uid, ids, name, arg, context=None):
res = {}
res_final = {}
child_ids = tuple(ids) #We don't want consolidation for each of these fields because those complex computation is resource-greedy.
for i in child_ids:
res[i] = 0.0
if not child_ids:
return res
#We don't want consolidation for each of these fields because those complex computation is resource-greedy.
for account in self.pool.get('account.analytic.account').browse(cr, uid, ids, context=context):
cr.execute("""
SELECT product_id, sum(amount), user_id, to_invoice, sum(unit_amount), product_uom_id, line.name
FROM account_analytic_line line
LEFT JOIN account_analytic_journal journal ON (journal.id = line.journal_id)
WHERE account_id = %s
AND journal.type = 'purchase'
AND invoice_id IS NULL
AND to_invoice IS NOT NULL
GROUP BY product_id, user_id, to_invoice, product_uom_id, line.name""", (account.id,))
if child_ids:
cr.execute("""SELECT account_analytic_account.id, \
COALESCE(SUM (product_template.list_price * \
account_analytic_line.unit_amount * \
((100-hr_timesheet_invoice_factor.factor)/100)), 0.0) \
AS ca_to_invoice \
FROM product_template \
JOIN product_product \
ON product_template.id = product_product.product_tmpl_id \
JOIN account_analytic_line \
ON account_analytic_line.product_id = product_product.id \
JOIN account_analytic_journal \
ON account_analytic_line.journal_id = account_analytic_journal.id \
JOIN account_analytic_account \
ON account_analytic_account.id = account_analytic_line.account_id \
JOIN hr_timesheet_invoice_factor \
ON hr_timesheet_invoice_factor.id = account_analytic_account.to_invoice \
WHERE account_analytic_account.id IN %s \
AND account_analytic_line.invoice_id IS NULL \
AND account_analytic_line.to_invoice IS NOT NULL \
AND account_analytic_journal.type = 'purchase' \
GROUP BY account_analytic_account.id;""",(child_ids,))
for account_id, sum in cr.fetchall():
res[account_id] = sum
res_final = res
return res_final
res[account.id] = 0.0
for product_id, price, user_id, factor_id, qty, uom, line_name in cr.fetchall():
#the amount to reinvoice is the real cost. We don't use the pricelist
price = -price
factor = self.pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context=context)
res[account.id] += price * qty * (100 - factor.factor or 0.0) / 100.0
return res
def _expense_invoiced_calc(self, cr, uid, ids, name, arg, context=None):
lines_obj = self.pool.get('account.analytic.line')
@@ -36,6 +36,9 @@ openerp.auth_oauth = function(instance) {
ev.preventDefault();
var index = $(ev.target).data('index');
var provider = this.oauth_providers[index];
return this.do_oauth_sign_in(provider);
},
do_oauth_sign_in: function(provider) {
var return_url = _.str.sprintf('%s//%s/auth_oauth/signin', location.protocol, location.host);
if (instance.session.debug) {
return_url += '?debug';
+3
View File
@@ -21,6 +21,7 @@
from openerp.osv import osv, fields
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.translate import _
from datetime import datetime, timedelta
@@ -54,6 +55,8 @@ class res_users(osv.osv):
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_reset_password', 'reset_password_email')
assert template._name == 'email.template'
for user in self.browse(cr, uid, ids, context):
if not user.email:
raise osv.except_osv(_("Cannot send email: user has no email address."), user.name)
self.pool.get('email.template').send_mail(cr, uid, template.id, user.id, context=context)
return True
@@ -7,11 +7,17 @@
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<!-- Reset Password button -->
<xpath expr="//sheet/*[1]" position="before">
<div class="oe_right oe_button_box">
<button string="Reset Password" type="object" name="action_reset_password"/>
<button string="Reset Password" type="object" name="action_reset_password"
help="Send a special url by email to make the user (re)set their password."/>
</div>
</xpath>
<!-- password is never required; one can use Reset Password -->
<field name="new_password" position="attributes">
<attribute name="attrs">{}</attribute>
</field>
</field>
</record>
+6 -2
View File
@@ -150,8 +150,12 @@ class res_users(osv.Model):
_inherit = 'res.users'
def _get_state(self, cr, uid, ids, name, arg, context=None):
return dict((user.id, 'new' if not user.login_date else 'reset' if user.signup_token else 'active')
for user in self.browse(cr, uid, ids, context))
res = {}
for user in self.browse(cr, uid, ids, context):
res[user.id] = ('reset' if user.signup_valid else
'active' if user.login_date else
'new')
return res
_columns = {
'state': fields.function(_get_state, string='Status', type='selection',
+2 -2
View File
@@ -5,7 +5,7 @@
<!-- Read/Unread actions -->
<record id="actions_server_crm_meeting_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">CRM Meeting: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_meeting"/>
@@ -23,7 +23,7 @@
</record>
<record id="actions_server_crm_meeting_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">CRM Meeting: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_meeting"/>
+2 -2
View File
@@ -4,7 +4,7 @@
<!-- Read/Unread actions -->
<record id="actions_server_crm_lead_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">CRM Lead: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_lead"/>
@@ -22,7 +22,7 @@
</record>
<record id="actions_server_crm_lead_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">CRM Lead: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_lead"/>
+2 -2
View File
@@ -4,7 +4,7 @@
<!-- Read/Unread actions -->
<record id="actions_server_crm_phonecall_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">CRM Phonecall: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_phonecall"/>
@@ -22,7 +22,7 @@
</record>
<record id="actions_server_crm_phonecall_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">CRM Phonecall: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_crm_phonecall"/>
+4 -4
View File
@@ -59,7 +59,7 @@
<!-- Event Read/Unread actions -->
<record id="actions_server_event_event_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Event: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_event"/>
@@ -77,7 +77,7 @@
</record>
<record id="actions_server_event_event_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Event: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_event"/>
@@ -377,7 +377,7 @@
<!-- Registration Read/Unread actions -->
<record id="actions_server_event_registration_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Event registration : Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_registration"/>
@@ -395,7 +395,7 @@
</record>
<record id="actions_server_event_registration_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Event registration : Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_event_registration"/>
+1 -6
View File
@@ -318,12 +318,7 @@
</ul>
<div class="oe_kanban_partner_categories">
<span class="oe_kanban_list_many2many">
<div modifiers="{}" name="tag_ids" class="oe_form_field oe_tags" model="fleet.vehicle.tag" t-att-data="record.tag_ids.raw_value" />
</span>
</div>
<field name="tag_ids"/>
</div>
</div>
</t>
+2 -2
View File
@@ -3,7 +3,7 @@
<!-- Hr holidays Read/Unread actions -->
<record id="actions_server_holidays_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Holidays: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_holidays"/>
@@ -21,7 +21,7 @@
</record>
<record id="actions_server_holidays_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Holidays: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_holidays"/>
-1
View File
@@ -60,7 +60,6 @@ You can define the different phases of interviews and easily rate the applicant
'hr_recruitment_data.xml'
],
'demo': ['hr_recruitment_demo.yml'],
'js': ['static/src/js/hr_recruitment.js'],
'test': ['test/recruitment_process.yml'],
'installable': True,
'auto_install': False,
@@ -37,7 +37,7 @@
<!-- Jobs -->
<!-- Applicant Read/Unread actions -->
<record id="actions_server_applicant_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">HR Applicant: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_applicant"/>
@@ -55,7 +55,7 @@
</record>
<record id="actions_server_applicant_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">HR Applicant: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_hr_applicant"/>
@@ -314,9 +314,7 @@
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
<div class="oe_left oe_tags">
<field name="categ_ids"/>
</div>
<field name="categ_ids"/>
</div>
</div>
<div class="oe_clear"></div>
@@ -1,35 +0,0 @@
openerp.hr_recruitment = function(openerp) {
openerp.web_kanban.KanbanView.include({
applicant_display_categ_names: function() {
/*
* Set proper names to applicant categories.
* In kanban views, many2many fields only return a list of ids.
* Therefore, we have to fetch the matching data by ourselves.
*/
var self = this;
var categ_ids = [];
// Collect categories ids
self.$el.find('span[data-categ_id]').each(function() {
categ_ids.push($(this).data('categ_id'));
});
// Find their matching names
var dataset = new openerp.web.DataSetSearch(self, 'hr.applicant_category', self.session.context, [['id', 'in', _.uniq(categ_ids)]]);
dataset.read_slice(['id', 'name']).done(function(result) {
_.each(result, function(v, k) {
// Set the proper value in the DOM and display the element
self.$el.find('span[data-categ_id=' + v.id + ']').text(v.name);
});
});
},
on_groups_started: function() {
var self = this;
self._super.apply(self, arguments);
if (self.dataset.model === 'hr.applicant') {
self.applicant_display_categ_names();
}
}
});
};
@@ -19,8 +19,9 @@
#
##############################################################################
from osv import fields, osv
import time
from osv import fields, osv
from tools.translate import _
class hr_timesheet_invoice_factor(osv.osv):
@@ -172,6 +173,143 @@ class account_analytic_line(osv.osv):
return super(account_analytic_line, self).copy(cursor, user, obj_id,
default, context=context)
def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
pro_price_obj = self.pool.get('product.pricelist')
if account.pricelist_id:
pl = account.pricelist_id.id
price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=context)[pl]
else:
price = 0.0
return price
def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
analytic_account_obj = self.pool.get('account.analytic.account')
account_payment_term_obj = self.pool.get('account.payment.term')
invoice_obj = self.pool.get('account.invoice')
product_obj = self.pool.get('product.product')
invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
fiscal_pos_obj = self.pool.get('account.fiscal.position')
product_uom_obj = self.pool.get('product.uom')
invoice_line_obj = self.pool.get('account.invoice.line')
invoices = []
if context is None:
context = {}
if data is None:
data = {}
journal_types = {}
for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context):
if line.journal_id.type not in journal_types:
journal_types[line.journal_id.type] = set()
journal_types[line.journal_id.type].add(line.account_id.id)
for journal_type, account_ids in journal_types.items():
for account in analytic_account_obj.browse(cr, uid, list(account_ids), context=context):
partner = account.partner_id
if (not partner) or not (account.pricelist_id):
raise osv.except_osv(_('Analytic Account incomplete !'),
_('Contract incomplete. Please fill in the Customer and Pricelist fields.'))
date_due = False
if partner.property_payment_term:
pterm_list= account_payment_term_obj.compute(cr, uid,
partner.property_payment_term.id, value=1,
date_ref=time.strftime('%Y-%m-%d'))
if pterm_list:
pterm_list = [line[0] for line in pterm_list]
pterm_list.sort()
date_due = pterm_list[-1]
curr_invoice = {
'name': time.strftime('%d/%m/%Y') + ' - '+account.name,
'partner_id': account.partner_id.id,
'company_id': account.company_id.id,
'payment_term': partner.property_payment_term.id or False,
'account_id': partner.property_account_receivable.id,
'currency_id': account.pricelist_id.currency_id.id,
'date_due': date_due,
'fiscal_position': account.partner_id.property_account_position.id
}
context2 = context.copy()
context2['lang'] = partner.lang
# set company_id in context, so the correct default journal will be selected
context2['force_company'] = curr_invoice['company_id']
# set force_company in context so the correct product properties are selected (eg. income account)
context2['company_id'] = curr_invoice['company_id']
last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
invoices.append(last_invoice)
cr.execute("""SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id
FROM account_analytic_line as line LEFT JOIN account_analytic_journal journal ON (line.journal_id = journal.id)
WHERE account_id = %s
AND line.id IN %s AND journal.type = %s AND to_invoice IS NOT NULL
GROUP BY product_id, user_id, to_invoice, product_uom_id""", (account.id, tuple(ids), journal_type))
for product_id, user_id, factor_id, qty, uom in cr.fetchall():
if data.get('product'):
product_id = data['product'][0]
product = product_obj.browse(cr, uid, product_id, context=context2)
if not product:
raise osv.except_osv(_('Error!'), _('There is no product defined. Please select one or force the product through the wizard.'))
factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
if factor.customer_name:
factor_name += ' - ' + factor.customer_name
ctx = context.copy()
ctx.update({'uom':uom})
price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, ctx)
general_account = product.product_tmpl_id.property_account_income or product.categ_id.property_account_income_categ
if not general_account:
raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
taxes = product.taxes_id or general_account.tax_ids
tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
curr_line = {
'price_unit': price,
'quantity': qty,
'discount':factor.factor,
'invoice_line_tax_id': [(6,0,tax )],
'invoice_id': last_invoice,
'name': factor_name,
'product_id': product_id,
'invoice_line_tax_id': [(6,0,tax)],
'uos_id': uom,
'account_id': general_account.id,
'account_analytic_id': account.id,
}
#
# Compute for lines
#
cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))
line_ids = cr.dictfetchall()
note = []
for line in line_ids:
# set invoice_line_note
details = []
if data.get('date', False):
details.append(line['date'])
if data.get('time', False):
if line['product_uom_id']:
details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
else:
details.append("%s" % (line['unit_amount'], ))
if data.get('name', False):
details.append(line['name'])
note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
if note:
curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
invoice_line_obj.create(cr, uid, curr_line, context=context)
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
return invoices
account_analytic_line()
@@ -19,163 +19,10 @@
#
##############################################################################
import time
from osv import osv, fields
from tools.translate import _
## Create an invoice based on selected timesheet lines
#
class account_analytic_line(osv.osv):
_inherit = "account.analytic.line"
def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
pro_price_obj = self.pool.get('product.pricelist')
if account.pricelist_id:
pl = account.pricelist_id.id
price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=context)[pl]
else:
price = 0.0
return price
#
# data = {
# 'date': boolean
# 'time': boolean
# 'name': boolean
# 'price': boolean
# 'product': many2one id
# }
def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
analytic_account_obj = self.pool.get('account.analytic.account')
account_payment_term_obj = self.pool.get('account.payment.term')
invoice_obj = self.pool.get('account.invoice')
product_obj = self.pool.get('product.product')
invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
fiscal_pos_obj = self.pool.get('account.fiscal.position')
product_uom_obj = self.pool.get('product.uom')
invoice_line_obj = self.pool.get('account.invoice.line')
invoices = []
if context is None:
context = {}
if data is None:
data = {}
account_ids = [line.account_id.id for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context)]
for account in analytic_account_obj.browse(cr, uid, account_ids, context=context):
partner = account.partner_id
if (not partner) or not (account.pricelist_id):
raise osv.except_osv(_('Analytic Account incomplete !'),
_('Contract incomplete. Please fill in the Customer and Pricelist fields.'))
date_due = False
if partner.property_payment_term:
pterm_list= account_payment_term_obj.compute(cr, uid,
partner.property_payment_term.id, value=1,
date_ref=time.strftime('%Y-%m-%d'))
if pterm_list:
pterm_list = [line[0] for line in pterm_list]
pterm_list.sort()
date_due = pterm_list[-1]
curr_invoice = {
'name': time.strftime('%d/%m/%Y')+' - '+account.name,
'partner_id': account.partner_id.id,
'company_id': account.company_id.id,
'payment_term': partner.property_payment_term.id or False,
'account_id': partner.property_account_receivable.id,
'currency_id': account.pricelist_id.currency_id.id,
'date_due': date_due,
'fiscal_position': account.partner_id.property_account_position.id
}
context2 = context.copy()
context2['lang'] = partner.lang
# set company_id in context, so the correct default journal will be selected
context2['force_company'] = curr_invoice['company_id']
# set force_company in context so the correct product properties are selected (eg. income account)
context2['company_id'] = curr_invoice['company_id']
last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
invoices.append(last_invoice)
cr.execute("SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id " \
"FROM account_analytic_line as line " \
"WHERE account_id = %s " \
"AND id IN %s AND to_invoice IS NOT NULL " \
"GROUP BY product_id, user_id, to_invoice, product_uom_id", (account.id, tuple(ids),))
for product_id, user_id, factor_id, qty, uom in cr.fetchall():
if data.get('product'):
product_id = data['product'][0]
product = product_obj.browse(cr, uid, product_id, context=context2)
if not product:
raise osv.except_osv(_('Error!'), _('There is no product defined. Please select one or force the product through the wizard.'))
factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
if factor.customer_name:
factor_name += ' - ' + factor.customer_name
ctx = context.copy()
ctx.update({'uom':uom})
price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, ctx)
general_account = product.product_tmpl_id.property_account_income or product.categ_id.property_account_income_categ
if not general_account:
raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
taxes = product.taxes_id or general_account.tax_ids
tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
curr_line = {
'price_unit': price,
'quantity': qty,
'discount':factor.factor,
'invoice_line_tax_id': [(6,0,tax )],
'invoice_id': last_invoice,
'name': factor_name,
'product_id': product_id,
'invoice_line_tax_id': [(6,0,tax)],
'uos_id': uom,
'account_id': general_account.id,
'account_analytic_id': account.id,
}
#
# Compute for lines
#
cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))
line_ids = cr.dictfetchall()
note = []
for line in line_ids:
# set invoice_line_note
details = []
if data.get('date', False):
details.append(line['date'])
if data.get('time', False):
if line['product_uom_id']:
details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
else:
details.append("%s" % (line['unit_amount'], ))
if data.get('name', False):
details.append(line['name'])
note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
if note:
curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
invoice_line_obj.create(cr, uid, curr_line, context=context)
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
return invoices
#
# TODO: check unit of measure !!!
#
class hr_timesheet_invoice_create(osv.osv_memory):
_name = 'hr.timesheet.invoice.create'
@@ -189,8 +36,8 @@ class hr_timesheet_invoice_create(osv.osv_memory):
}
_defaults = {
'date': lambda *args: 1,
'name': lambda *args: 1
'date': 1,
'name': 1,
}
def view_init(self, cr, uid, fields, context=None):
@@ -210,6 +57,7 @@ class hr_timesheet_invoice_create(osv.osv_memory):
def do_create(self, cr, uid, ids, context=None):
data = self.read(cr, uid, ids, [], context=context)[0]
# Create an invoice based on selected timesheet lines
invs = self.pool.get('account.analytic.line').invoice_cost_create(cr, uid, context['active_ids'], data, context=context)
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
+3 -3
View File
@@ -483,16 +483,16 @@ class Invoice(osv.osv):
'''Invoice'''
_inherit = 'account.invoice'
def action_cancel(self, cr, uid, ids, *args):
def action_cancel(self, cr, uid, ids, context=None):
'''Create a 'date_cancel' on the membership_line object'''
member_line_obj = self.pool.get('membership.membership_line')
today = time.strftime('%Y-%m-%d')
for invoice in self.browse(cr, uid, ids):
for invoice in self.browse(cr, uid, ids, context=context):
mlines = member_line_obj.search(cr, uid,
[('account_invoice_line', 'in',
[l.id for l in invoice.invoice_line])])
member_line_obj.write(cr, uid, mlines, {'date_cancel': today})
return super(Invoice, self).action_cancel(cr, uid, ids)
return super(Invoice, self).action_cancel(cr, uid, ids, context=context)
Invoice()
+4 -2
View File
@@ -213,8 +213,10 @@ function openerp_pos_db(instance, module){
var stored_products = this.load('products',{});
var product_ids = stored_categories[category_id];
var list = [];
for(var i = 0, len = Math.min(product_ids.length,this.limit); i < len; i++){
list.push(stored_products[product_ids[i]]);
if (product_ids) {
for (var i = 0, len = Math.min(product_ids.length, this.limit); i < len; i++) {
list.push(stored_products[product_ids[i]]);
}
}
return list;
},
@@ -24,12 +24,7 @@
<field name="version_id"/>
</div>
<div class="oe_kanban_footer_left">
<div class="oe_left oe_tags">
<t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
<span class="oe_tag" t-att-data-categ_id="categ_id"></span>
</t>
<field name="categ_ids"/>
</div>
<field name="categ_ids"/>
<div class="oe_right">
Creation: <field name="create_date"/>
<span class="oe_kanban_highlight">
+5 -9
View File
@@ -21,7 +21,7 @@
<!-- Project Read/Unread actions -->
<record id="actions_server_project_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Project: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_project"/>
@@ -39,7 +39,7 @@
</record>
<record id="actions_server_project_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Project: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_project"/>
@@ -344,7 +344,7 @@
<!-- Task Read/Unread actions -->
<record id="actions_server_project_task_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Task: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_task"/>
@@ -362,7 +362,7 @@
</record>
<record id="actions_server_project_task_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Task: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_task"/>
@@ -546,11 +546,7 @@
</span>
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
<div class="oe_left oe_tags">
<t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
<span class="oe_tag" t-att-data-categ_id="categ_id"></span>
</t>
</div>
<field name="categ_ids"/>
</div>
</div>
<div class="oe_clear"></div>
-29
View File
@@ -25,37 +25,12 @@ openerp.project = function(openerp) {
});
});
},
project_display_categ_names: function() {
/*
* Set proper names to project categories.
* In kanban views, many2many fields only return a list of ids.
* Therefore, we have to fetch the matching data by ourselves.
*/
var self = this;
var categ_ids = [];
// Collect categories ids
self.$el.find('span[data-categ_id]').each(function() {
categ_ids.push($(this).data('categ_id'));
});
// Find their matching names
var dataset = new openerp.web.DataSetSearch(self, 'project.category', self.session.context, [['id', 'in', _.uniq(categ_ids)]]);
dataset.read_slice(['id', 'name']).done(function(result) {
_.each(result, function(v, k) {
// Set the proper value in the DOM and display the element
self.$el.find('span[data-categ_id=' + v.id + ']').text(v.name);
});
});
},
on_groups_started: function() {
var self = this;
self._super.apply(self, arguments);
if (self.dataset.model === 'project.project') {
self.project_display_members_names();
} else if (self.dataset.model === 'project.task') {
self.project_display_categ_names();
}
},
on_record_moved: function(record, old_group, old_index, new_group, new_index){
@@ -74,9 +49,5 @@ openerp.project = function(openerp) {
this._super.apply(this, arguments);
}
},
bind_events: function() {
this._super();
this.view.project_display_categ_names();
},
});
};
-1
View File
@@ -61,7 +61,6 @@ It allows the manager to quickly check the issues, assign them and decide on the
'installable': True,
'auto_install': False,
'application': True,
'js': ['static/src/js/project_issue.js'],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+3 -5
View File
@@ -6,7 +6,7 @@
<!-- Project issue Read/Unread actions -->
<record id="actions_server_project_issue_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Issue: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_issue"/>
@@ -24,7 +24,7 @@
</record>
<record id="actions_server_project_issue_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Issue: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_project_issue"/>
@@ -264,9 +264,7 @@
<field name="version_id"/>
</div>
<div class="oe_kanban_footer_left">
<div class="oe_left oe_tags">
<field name="categ_ids"/>
</div>
<field name="categ_ids"/>
<div class="oe_right">
<span class="oe_kanban_highlight">
<t t-set="priority" t-value="record.priority.raw_value || 5"/>
@@ -1,13 +0,0 @@
openerp.portal_project_issue = function(openerp) {
openerp.web_kanban.KanbanView.include({
on_groups_started: function() {
var self = this;
self._super.apply(this, arguments);
if (self.dataset.model === 'project.issue') {
// Load project's categories names from m2m field
self.project_display_categ_names();
}
}
});
};
+2 -2
View File
@@ -134,7 +134,7 @@
<!-- Purchase order Read/Unread actions -->
<record id="actions_server_purchase_order_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Purchase: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_purchase_order"/>
@@ -152,7 +152,7 @@
</record>
<record id="actions_server_purchase_order_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Purchase: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_purchase_order"/>
@@ -149,11 +149,6 @@
<para style="terp_default_Right_9">[[ (order_line.product_uom and order_line.product_uom.name) or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="terp_default_8_italic">[[ format(order_line.notes or removeParentNode('tr')) ]]</para>
</td>
</tr>
</blockTable>
</section>
<para style="terp_default_9">
+2 -2
View File
@@ -68,7 +68,7 @@
<!-- Sale order Read/Unread actions -->
<record id="actions_server_sale_order_unread" model="ir.actions.server">
<field name="name">Mark unread</field>
<field name="name">Sale: Mark unread</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_sale_order"/>
@@ -86,7 +86,7 @@
</record>
<record id="actions_server_sale_order_read" model="ir.actions.server">
<field name="name">Mark read</field>
<field name="name">Sale: Mark read</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_sale_order"/>