[MERGE] from trunk

bzr revid: fva@openerp.com-20120817142625-z8f4sjcvoy4d2wyn
This commit is contained in:
Frédéric van der Essen 2012-08-17 16:26:25 +02:00
commit f3cc34175b
25 changed files with 381 additions and 230 deletions

View File

@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev_rc3\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
"PO-Revision-Date: 2011-01-13 18:03+0000\n"
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
"PO-Revision-Date: 2012-08-16 09:05+0000\n"
"Last-Translator: gagarin <Unknown>\n"
"Language-Team: <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-08-07 05:14+0000\n"
"X-Generator: Launchpad (build 15745)\n"
"X-Launchpad-Export-Date: 2012-08-17 04:38+0000\n"
"X-Generator: Launchpad (build 15810)\n"
#. module: account_analytic_analysis
#: field:account.analytic.account,revenue_per_hour:0
msgid "Revenue per Time (real)"
msgstr ""
msgstr "Ricavo orario (reale)"
#. module: account_analytic_analysis
#: help:account.analytic.account,remaining_ca:0
@ -38,11 +38,13 @@ msgid ""
"The contracts to be renewed because the deadline is passed or the working "
"hours are higher than the allocated hours"
msgstr ""
"I contratti da rinnovare perchè la scadenza è passata o le ore lavorate sono "
"maggiori delle ore allocate"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Pending contracts to renew with your customer"
msgstr ""
msgstr "Contratti in sospeso da rinnovare con il cliente"
#. module: account_analytic_analysis
#: help:account.analytic.account,hours_qtt_non_invoiced:0
@ -50,6 +52,8 @@ msgid ""
"Number of time (hours/days) (from journal of type 'general') that can be "
"invoiced if you invoice based on analytic account."
msgstr ""
"Tempo fatturabile (in ore/giorni, dal giornale di tipo 'generale') se si "
"fattura tramite conto analitico"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@ -59,17 +63,17 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Group By..."
msgstr ""
msgstr "Raggruppa per..."
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "End Date"
msgstr ""
msgstr "Data fine"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Create Invoice"
msgstr ""
msgstr "Crea Fattura"
#. module: account_analytic_analysis
#: field:account.analytic.account,last_invoice_date:0
@ -87,16 +91,18 @@ msgid ""
"Number of time you spent on the analytic account (from timesheet). It "
"computes quantities on all journal of type 'general'."
msgstr ""
"Costi orari da attribuire al conto analitico (da timesheet). Calcola "
"quantità su tutti i sezionali di tipo 'generale'."
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Contracts in progress"
msgstr ""
msgstr "Contratti attivi"
#. module: account_analytic_analysis
#: field:account.analytic.account,is_overdue_quantity:0
msgid "Overdue Quantity"
msgstr ""
msgstr "Quantità Scadute"
#. module: account_analytic_analysis
#: model:ir.actions.act_window,help:account_analytic_analysis.action_account_analytic_overdue
@ -108,16 +114,22 @@ msgid ""
"pending accounts and reopen or close the according to the negotiation with "
"the customer."
msgstr ""
"Qui troverai i contratti da rinnovare in quanto scaduti o le ore lavorate "
"sono maggiori di quelle allocate. OpenERP imposta automaticamente questi "
"conti analitici in stato sospeso, in modo da notificare un avviso durante la "
"fase di inserimento dei timesheet. I commerciali dovrebbero ricontrollare "
"tutti i contratti sospesi e riaprirli/chiuderli coerentemente con quanto il "
"cliente vuole rinegoziare."
#. module: account_analytic_analysis
#: field:account.analytic.account,ca_theorical:0
msgid "Theoretical Revenue"
msgstr "Ricavo teorico"
msgstr "Ricavo Teorico"
#. module: account_analytic_analysis
#: field:account.analytic.account,hours_qtt_non_invoiced:0
msgid "Uninvoiced Time"
msgstr ""
msgstr "Tempo non fatturato"
#. module: account_analytic_analysis
#: help:account.analytic.account,last_worked_invoiced_date:0
@ -131,7 +143,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "To Renew"
msgstr ""
msgstr "Da Rinnovare"
#. module: account_analytic_analysis
#: field:account.analytic.account,last_worked_date:0
@ -141,24 +153,25 @@ msgstr "Data dell'ultimo costo/lavoro"
#. module: account_analytic_analysis
#: field:account.analytic.account,hours_qtt_invoiced:0
msgid "Invoiced Time"
msgstr ""
msgstr "Tempo Fatturato"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid ""
"A contract in OpenERP is an analytic account having a partner set on it."
msgstr ""
"Un contratto in OpenERP è un conto analitico associato ad un partner."
#. module: account_analytic_analysis
#: field:account.analytic.account,remaining_hours:0
msgid "Remaining Time"
msgstr ""
msgstr "Tempo rimanente"
#. module: account_analytic_analysis
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_overdue
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_account_analytic_overdue
msgid "Contracts to Renew"
msgstr ""
msgstr "Contratti da Rinnovare"
#. module: account_analytic_analysis
#: field:account.analytic.account,theorical_margin:0
@ -168,7 +181,7 @@ msgstr "Margine teorico"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid " +1 Month"
msgstr ""
msgstr " +1 Mese"
#. module: account_analytic_analysis
#: help:account.analytic.account,ca_theorical:0
@ -184,7 +197,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Pending"
msgstr ""
msgstr "In sospeso"
#. module: account_analytic_analysis
#: field:account.analytic.account,ca_to_invoice:0
@ -199,7 +212,7 @@ msgstr "Calcolato utilizzando la formula: importo fatturato - totale costi"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Parent"
msgstr ""
msgstr "Mastro"
#. module: account_analytic_analysis
#: field:account.analytic.account,user_ids:0
@ -231,7 +244,7 @@ msgstr "Data dell'ultimo costo fatturato"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Contract"
msgstr ""
msgstr "Contratto"
#. module: account_analytic_analysis
#: field:account.analytic.account,real_margin_rate:0
@ -266,14 +279,14 @@ msgstr "Reddito rimanente"
#. module: account_analytic_analysis
#: help:account.analytic.account,remaining_hours:0
msgid "Computed using the formula: Maximum Time - Total Time"
msgstr ""
msgstr "Calcolato usando la formula: Tempo Massimo - Tempo Totale"
#. module: account_analytic_analysis
#: help:account.analytic.account,hours_qtt_invoiced:0
msgid ""
"Number of time (hours/days) that can be invoiced plus those that already "
"have been invoiced."
msgstr ""
msgstr "Tempo (ore/giorni) fatturabile più tempo già fatturato."
#. module: account_analytic_analysis
#: help:account.analytic.account,ca_to_invoice:0
@ -287,7 +300,7 @@ msgstr ""
#. module: account_analytic_analysis
#: help:account.analytic.account,revenue_per_hour:0
msgid "Computed using the formula: Invoiced Amount / Total Time"
msgstr ""
msgstr "Calcolato usando la formula: Fatturato / Tempo Totale"
#. module: account_analytic_analysis
#: field:account.analytic.account,total_cost:0
@ -312,12 +325,12 @@ msgstr "Contabilità Analitica"
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_overdue_all
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_account_analytic_overdue_all
msgid "Contracts"
msgstr ""
msgstr "Contratti"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Manager"
msgstr ""
msgstr "Manager"
#. module: account_analytic_analysis
#: model:ir.actions.act_window,name:account_analytic_analysis.action_hr_tree_invoiced_all
@ -328,12 +341,12 @@ msgstr "Voci da Fatturare"
#. module: account_analytic_analysis
#: help:account.analytic.account,last_invoice_date:0
msgid "If invoice from the costs, this is the date of the latest invoiced."
msgstr ""
msgstr "Se si fattura dai costi, questa è la data dell'ultima fattura."
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Associated Partner"
msgstr ""
msgstr "Partner Associato"
#. module: account_analytic_analysis
#: view:account.analytic.account:0
@ -343,7 +356,7 @@ msgstr ""
#. module: account_analytic_analysis
#: view:account.analytic.account:0
msgid "Contracts that are not assigned to an account manager."
msgstr ""
msgstr "Contratti non assegnati ad un responsabile del cliente"
#. module: account_analytic_analysis
#: field:account.analytic.account,hours_quantity:0

View File

@ -288,6 +288,7 @@
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
<field name="state" groups="base.group_no_one"/>
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
<field name="planned_revenue" sum="Expected Revenues"/>

View File

@ -34,8 +34,7 @@ The whole workflow is implemented:
* Draft expense
* Confirmation of the sheet by the employee
* Validation by his manager
* Validation by the accountant and invoice creation
* Payment of the invoice to the employee
* Validation by the accountant and receipt creation
This module also uses the analytic accounting and is compatible with
the invoice on timesheet module so that you will be able to automatically
@ -44,7 +43,7 @@ re-invoice your customer's expenses if your work by project.
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'images': ['images/hr_expenses_analysis.jpeg', 'images/hr_expenses.jpeg'],
'depends': ['hr', 'account'],
'depends': ['hr', 'account_voucher'],
'init_xml': [],
'update_xml': [
'security/ir.model.access.csv',

View File

@ -40,12 +40,16 @@ class hr_expense_expense(osv.osv):
if context is None:
context = {}
if not default: default = {}
default.update({'invoice_id': False, 'date_confirm': False, 'date_valid': False, 'user_valid': False})
default.update({'voucher_id': False, 'date_confirm': False, 'date_valid': False, 'user_valid': False})
return super(hr_expense_expense, self).copy(cr, uid, id, default, context=context)
def _amount(self, cr, uid, ids, field_name, arg, context=None):
cr.execute("SELECT s.id,COALESCE(SUM(l.unit_amount*l.unit_quantity),0) AS amount FROM hr_expense_expense s LEFT OUTER JOIN hr_expense_line l ON (s.id=l.expense_id) WHERE s.id IN %s GROUP BY s.id ", (tuple(ids),))
res = dict(cr.fetchall())
res= {}
for expense in self.browse(cr, uid, ids, context=context):
total = 0.0
for line in expense.line_ids:
total += line.unit_amount * line.unit_quantity
res[expense.id] = total
return res
def _get_currency(self, cr, uid, context=None):
@ -63,7 +67,7 @@ class hr_expense_expense(osv.osv):
'name': fields.char('Description', size=128, required=True),
'id': fields.integer('Sheet ID', readonly=True),
'date': fields.date('Date', select=True),
'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is invoiced"),
'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is done."),
'employee_id': fields.many2one('hr.employee', "Employee", required=True),
'user_id': fields.many2one('res.users', 'User', required=True),
'date_confirm': fields.date('Confirmation Date', select=True, help = "Date of the confirmation of the sheet expense. It's filled when the button Confirm is pressed."),
@ -73,7 +77,7 @@ class hr_expense_expense(osv.osv):
'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ),
'note': fields.text('Note'),
'amount': fields.function(_amount, string='Total Amount', digits_compute= dp.get_precision('Account')),
'invoice_id': fields.many2one('account.invoice', "Employee's Invoice"),
'voucher_id': fields.many2one('account.voucher', "Employee's Receipt"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
'department_id':fields.many2one('hr.department','Department'),
'company_id': fields.many2one('res.company', 'Company', required=True),
@ -82,11 +86,10 @@ class hr_expense_expense(osv.osv):
('cancelled', 'Refused'),
('confirm', 'Waiting Approval'),
('accepted', 'Approved'),
('invoiced', 'Invoiced'),
('paid', 'Reimbursed')
('done', 'Done'),
],
'Status', readonly=True, help='When the expense request is created the status is \'Draft\'.\n It is confirmed by the user and request is sent to admin, the status is \'Waiting Confirmation\'.\
\nIf the admin accepts it, the status is \'Accepted\'.\n If an invoice is made for the expense request, the status is \'Invoiced\'.\n If the expense is paid to user, the status is \'Reimbursed\'.'),
\nIf the admin accepts it, the status is \'Accepted\'.\n If a receipt is made for the expense request, the status is \'Done\'.'),
}
_defaults = {
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.employee', context=c),
@ -97,6 +100,13 @@ class hr_expense_expense(osv.osv):
'currency_id': _get_currency,
}
def onchange_currency_id(self, cr, uid, ids, currency_id=False, company_id=False, context=None):
res = {'value': {'journal_id': False}}
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type','=','purchase'), ('currency','=',currency_id), ('company_id', '=', company_id)], context=context)
if journal_ids:
res['value']['journal_id'] = journal_ids[0]
return res
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
emp_obj = self.pool.get('hr.employee')
department_id = False
@ -126,101 +136,94 @@ class hr_expense_expense(osv.osv):
self.write(cr, uid, ids, {'state':'cancelled'})
return True
def expense_paid(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state':'paid'})
return True
def invoice(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
mod_obj = self.pool.get('ir.model.data')
res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_supplier_form')
inv_ids = []
for id in ids:
wf_service.trg_validate(uid, 'hr.expense.expense', id, 'invoice', cr)
inv_ids.append(self.browse(cr, uid, id).invoice_id.id)
return {
'name': _('Supplier Invoices'),
'view_type': 'form',
'view_mode': 'form',
'view_id': [res and res[1] or False],
'res_model': 'account.invoice',
'context': "{'type':'out_invoice', 'journal_type': 'purchase'}",
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'current',
'res_id': inv_ids and inv_ids[0] or False,
}
def action_invoice_create(self, cr, uid, ids):
res = False
invoice_obj = self.pool.get('account.invoice')
def action_receipt_create(self, cr, uid, ids, context=None):
property_obj = self.pool.get('ir.property')
sequence_obj = self.pool.get('ir.sequence')
analytic_journal_obj = self.pool.get('account.analytic.journal')
account_journal = self.pool.get('account.journal')
for exp in self.browse(cr, uid, ids):
voucher_obj = self.pool.get('account.voucher')
currency_obj = self.pool.get('res.currency')
wkf_service = netsvc.LocalService("workflow")
if context is None:
context = {}
for exp in self.browse(cr, uid, ids, context=context):
company_id = exp.company_id.id
lines = []
for l in exp.line_ids:
tax_id = []
if l.product_id:
acc = l.product_id.product_tmpl_id.property_account_expense
total = 0.0
ctx = context.copy()
ctx.update({'date': exp.date})
journal = False
if exp.journal_id:
journal = exp.journal_id
else:
journal_id = voucher_obj._get_journal(cr, uid, context={'type': 'purchase', 'company_id': company_id})
if journal_id:
journal = account_journal.browse(cr, uid, journal_id, context=context)
for line in exp.line_ids:
if line.product_id:
acc = line.product_id.product_tmpl_id.property_account_expense
if not acc:
acc = l.product_id.categ_id.property_account_expense_categ
tax_id = [x.id for x in l.product_id.supplier_taxes_id]
acc = line.product_id.categ_id.property_account_expense_categ
else:
acc = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context={'force_company': company_id})
if not acc:
raise osv.except_osv(_('Error!'), _('Please configure Default Expense account for Product purchase: `property_account_expense_categ`.'))
total_amount = line.total_amount
if journal.currency:
if exp.currency_id != journal.currency:
total_amount = currency_obj.compute(cr, uid, exp.currency_id.id, journal.currency.id, total_amount, context=ctx)
elif exp.currency_id != exp.company_id.currency_id:
total_amount = currency_obj.compute(cr, uid, exp.currency_id.id, exp.company_id.currency_id.id, total_amount, context=ctx)
lines.append((0, False, {
'name': l.name,
'name': line.name,
'account_id': acc.id,
'price_unit': l.unit_amount,
'quantity': l.unit_quantity,
'uos_id': l.uom_id.id,
'product_id': l.product_id and l.product_id.id or False,
'invoice_line_tax_id': tax_id and [(6, 0, tax_id)] or False,
'account_analytic_id': l.analytic_account.id,
'account_analytic_id': line.analytic_account.id,
'amount': total_amount,
'type': 'dr'
}))
total += total_amount
if not exp.employee_id.address_home_id:
raise osv.except_osv(_('Error!'), _('The employee must have a home address.'))
acc = exp.employee_id.address_home_id.property_account_payable.id
payment_term_id = exp.employee_id.address_home_id.property_payment_term.id
inv = {
voucher = {
'name': exp.name,
'reference': sequence_obj.get(cr, uid, 'hr.expense.invoice'),
'account_id': acc,
'type': 'in_invoice',
'type': 'purchase',
'partner_id': exp.employee_id.address_home_id.id,
'company_id': company_id,
'origin': exp.name,
'invoice_line': lines,
'currency_id': exp.currency_id.id,
'payment_term': payment_term_id,
'fiscal_position': exp.employee_id.address_home_id.property_account_position.id
'line_ids': lines,
'amount': total,
'journal_id': journal.id,
}
if payment_term_id:
to_update = invoice_obj.onchange_payment_term_date_invoice(cr, uid, [], payment_term_id, None)
if to_update:
inv.update(to_update['value'])
journal = False
if exp.journal_id:
inv['journal_id']=exp.journal_id.id
journal = exp.journal_id
else:
journal_id = invoice_obj._get_journal(cr, uid, context={'type': 'in_invoice', 'company_id': company_id})
if journal_id:
inv['journal_id'] = journal_id
journal = account_journal.browse(cr, uid, journal_id)
if journal and not journal.analytic_journal_id:
analytic_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','purchase')])
analytic_journal_ids = analytic_journal_obj.search(cr, uid, [('type','=','purchase')], context=context)
if analytic_journal_ids:
account_journal.write(cr, uid, [journal.id],{'analytic_journal_id':analytic_journal_ids[0]})
inv_id = invoice_obj.create(cr, uid, inv, {'type': 'in_invoice'})
invoice_obj.button_compute(cr, uid, [inv_id], {'type': 'in_invoice'}, set_total=True)
self.write(cr, uid, [exp.id], {'invoice_id': inv_id, 'state': 'invoiced'})
res = inv_id
return res
account_journal.write(cr, uid, [journal.id], {'analytic_journal_id': analytic_journal_ids[0]}, context=context)
voucher_id = voucher_obj.create(cr, uid, voucher, context=context)
wkf_service.trg_validate(uid, 'account.voucher', voucher_id, 'proforma_voucher', cr)
self.write(cr, uid, [exp.id], {'voucher_id': voucher_id, 'state': 'done'}, context=context)
return True
def action_view_receipt(self, cr, uid, ids, context=None):
'''
This function returns an action that display existing receipt of given expense ids.
'''
assert len(ids) == 1, 'This option should only be used for a single id at a time'
voucher_id = self.browse(cr, uid, ids[0], context=context).voucher_id.id
res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_voucher', 'view_purchase_receipt_form')
result = {
'name': _('Expense Receipt'),
'view_type': 'form',
'view_mode': 'form',
'view_id': res and res[1] or False,
'res_model': 'account.voucher',
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'current',
'res_id': voucher_id,
}
return result
hr_expense_expense()

View File

@ -31,7 +31,7 @@
<field name="date"/>
<field name="user_id" invisible="1"/>
<field name="name"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="amount"/>
<field name="state"/>
</tree>
@ -42,7 +42,7 @@
<field name="name">hr.expense.expense.tree</field>
<field name="model">hr.expense.expense</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','invoiced','paid');gray:state == 'cancelled'" string="Expenses" editable="top">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','done');gray:state == 'cancelled'" string="Expenses" editable="top">
<field name="employee_id"/>
<field name="date"/>
<field name="department_id"/>
@ -64,9 +64,10 @@
<button name="confirm" states="draft" string="Submit to Manager" type="workflow" class="oe_highlight"/>
<button name="validate" states="confirm" string="Approve" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
<button name="draft" states="confirm,cancelled" string="Set to Draft" type="workflow" groups="base.group_hr_user" />
<button name="invoice" states="accepted" string="Invoice" type="object" groups="base.group_hr_user" class="oe_highlight"/>
<button name="done" states="accepted" string="Generate Accounting Entries" type="workflow" groups="account.group_account_invoice" class="oe_highlight"/>
<button name="action_view_receipt" states="done" string="Open Receipt" type="object"/>
<button name="refuse" states="confirm,accepted" string="Refuse" type="workflow" groups="base.group_hr_user" />
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,accepted" statusbar_colors='{"confirm":"blue","cancelled":"red"}'/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,accepted,done" statusbar_colors='{"confirm":"blue","cancelled":"red"}'/>
</header>
<sheet>
<group>
@ -79,7 +80,7 @@
<group>
<field name="name"/>
<field name="user_valid"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency" on_change="onchange_currency_id(currency_id, company_id)"/>
</group>
</group>
<notebook>
@ -105,14 +106,21 @@
</group>
</form>
</field>
<separator string="Notes"/>
<field name="note" placeholder="Free Notes"/>
<group>
<div>
<separator string="Notes"/>
<field name="note" placeholder="Free Notes"/>
</div>
<group class="oe_subtotal_footer">
<field name="amount"/>
</group>
</group>
</page>
<page string="Other Info">
<group>
<group string="Accounting Data">
<field name="journal_id"/>
<field name="invoice_id" context="{'type':'in_invoice', 'journal_type': 'purchase'}"/>
<field name="journal_id" widget="selection" domain="[('type', '=', 'purchase')]"/>
<field name="voucher_id" context="{'form_view_ref': 'account_voucher.view_purchase_receipt_form'}"/>
</group>
</group>
</page>

View File

@ -32,14 +32,6 @@
<field name="action">expense_accept()</field>
</record>
<record id="act_paid" model="workflow.activity">
<field name="wkf_id" ref="wkf_expenses"/>
<field name="name">paid</field>
<field name="kind">function</field>
<field name="action">expense_paid()</field>
<field name="flow_stop">True</field>
</record>
<record id="act_refused" model="workflow.activity">
<field name="wkf_id" ref="wkf_expenses"/>
<field name="name">refused</field>
@ -47,12 +39,11 @@
<field name="action">expense_canceled()</field>
</record>
<record id="act_invoice" model="workflow.activity">
<record id="act_done" model="workflow.activity">
<field name="wkf_id" ref="wkf_expenses"/>
<field name="name">invoice</field>
<field name="kind">subflow</field>
<field name="subflow_id" ref="account.wkf"/>
<field name="action">action_invoice_create()</field>
<field name="name">done</field>
<field name="kind">function</field>
<field name="action">action_receipt_create()</field>
</record>
<record id="t1" model="workflow.transition">
@ -91,15 +82,8 @@
<record id="t8" model="workflow.transition">
<field name="act_from" ref="act_accepted"/>
<field name="act_to" ref="act_invoice"/>
<field name="signal">invoice</field>
<field name="group_id" ref="base.group_hr_user"/>
</record>
<record id="t9" model="workflow.transition">
<field name="act_from" ref="act_invoice"/>
<field name="act_to" ref="act_paid"/>
<field name="signal">subflow.paid</field>
<field name="act_to" ref="act_done"/>
<field name="signal">done</field>
<field name="group_id" ref="base.group_hr_user"/>
</record>

View File

@ -39,11 +39,10 @@ class hr_expense_report(osv.osv):
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'journal_id': fields.many2one('account.journal', 'Force Journal', readonly=True),
'product_qty':fields.float('Qty', readonly=True),
'invoiced':fields.integer('# of Invoiced Lines', readonly=True),
'employee_id': fields.many2one('hr.employee', "Employee's Name", readonly=True),
'date_confirm': fields.date('Confirmation Date', readonly=True),
'date_valid': fields.date('Validation Date', readonly=True),
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True),
'voucher_id': fields.many2one('account.voucher', 'Receipt', readonly=True),
'department_id':fields.many2one('hr.department','Department', readonly=True),
'company_id':fields.many2one('res.company', 'Company', readonly=True),
'user_id':fields.many2one('res.users', 'Validation User', readonly=True),
@ -60,8 +59,7 @@ class hr_expense_report(osv.osv):
('draft', 'Draft'),
('confirm', 'Waiting confirmation'),
('accepted', 'Accepted'),
('invoiced', 'Invoiced'),
('paid', 'Reimbursed'),
('done', 'Done'),
('cancelled', 'Cancelled')],
'Status', readonly=True),
}
@ -78,8 +76,7 @@ class hr_expense_report(osv.osv):
s.currency_id,
to_date(to_char(s.date_confirm, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_confirm,
to_date(to_char(s.date_valid, 'dd-MM-YYYY'),'dd-MM-YYYY') as date_valid,
s.invoice_id,
count(s.invoice_id) as invoiced,
s.voucher_id,
s.user_valid as user_id,
s.department_id,
to_char(date_trunc('day',s.create_date), 'YYYY') as year,
@ -109,7 +106,7 @@ class hr_expense_report(osv.osv):
to_date(to_char(s.date_valid, 'dd-MM-YYYY'),'dd-MM-YYYY'),
l.product_id,
l.analytic_account,
s.invoice_id,
s.voucher_id,
s.currency_id,
s.user_valid,
s.department_id,

View File

@ -6,13 +6,13 @@
<field name="name">hr.expense.report.tree</field>
<field name="model">hr.expense.report</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','invoiced','paid');gray:state == 'cancelled'" string="Expenses Analysis">
<tree colors="blue:state == 'draft';black:state in ('confirm','accepted','done');gray:state == 'cancelled'" string="Expenses Analysis">
<field name="employee_id" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="year" invisible="1"/>
<field name="month" invisible="1"/>
<field name="day" invisible="1"/>
<field name="invoice_id" invisible="1"/>
<field name="voucher_id" invisible="1"/>
<field name="analytic_account" invisible="1" groups="analytic.group_analytic_accounting"/>
<field name="department_id" invisible="1"/>
<field name="company_id" invisible="1"/>
@ -22,7 +22,6 @@
<field name="state" invisible="1"/>
<field name="nbr" sum="# of Lines"/>
<field name="no_of_products" sum="# of Products"/>
<field name="invoiced" sum="Total Invoiced Lines"/>
<field name="price_average" avg="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="delay_confirm"/>
@ -50,7 +49,7 @@
<search string="Expenses Analysis">
<filter string="Waiting" icon="terp-gtk-media-pause" domain="[('state', '=' ,'confirm')]" help = "Confirm Expenses"/>
<filter string="Approved" icon="terp-check" domain="[('state','=','accepted')]" help = "Approved Expenses"/>
<filter string="Invoiced" icon="terp-dolar" domain="[('state','in', ('invoiced', 'paid'))]" help = "Invoiced Expenses"/>
<filter string="Done" icon="terp-dolar" domain="[('state','=', 'done')]" help = "Done Expenses"/>
<field name="employee_id"/>
<field name="department_id"/>
<group expand="0" string="Extended Filters...">

View File

@ -17,33 +17,20 @@
!assert {model: hr.expense.expense, id: sep_expenses, severity: error, string: Expense should be in Approved state}:
- state == 'accepted'
-
I make Invoice for the expense.
I make Receipt for the expense.
-
!python {model: hr.expense.expense}: |
self.invoice(cr, uid, [ref('sep_expenses')])
!workflow {model: hr.expense.expense, action: done, ref: sep_expenses}
-
I check invoice details.
I check receipt details.
-
!python {model: hr.expense.expense}: |
sep_expenses = self.browse(cr, uid, ref("sep_expenses"), context=context)
assert sep_expenses.state == 'invoiced', "Expense should be in 'Invoiced' state."
assert sep_expenses.invoice_id, "Expense should have link of Invoice."
assert sep_expenses.invoice_id.currency_id == sep_expenses.currency_id,"Invoice currency is not correspond with supplier invoice currency"
assert sep_expenses.invoice_id.origin == sep_expenses.name,"Invoice origin is not correspond with supplier invoice"
assert sep_expenses.invoice_id.type == 'in_invoice', "Invoice type is not supplier invoice"
assert sep_expenses.invoice_id.amount_total == sep_expenses.amount,"Invoice total amount is not correspond with supplier invoice total"
assert len(sep_expenses.invoice_id.invoice_line) == len(sep_expenses.line_ids),"Lines of Invoice and supplier invoice Line are not correspond"
#TODO: check invoice line details with Expenses lines
-
I pay the expenses.
-
!python {model: hr.expense.expense}: |
self.expense_paid(cr, uid, [ref('sep_expenses')])
-
I check that state of expenses is 'Paid'.
-
!assert {model: hr.expense.expense, id: sep_expenses, severity: error, string: Expense should be in Paid state}:
- state == 'paid'
assert sep_expenses.state == 'done', "Expense should be in 'Done' state."
assert sep_expenses.voucher_id, "Expense should have link of Purchase Receipt."
assert sep_expenses.voucher_id.type == 'purchase', "Receipt type is not purchase receipt."
assert sep_expenses.voucher_id.amount == sep_expenses.amount,"Receipt total amount is not correspond with expense total."
assert len(sep_expenses.voucher_id.line_dr_ids) == len(sep_expenses.line_ids),"Lines of Receipt and expense line are not correspond."
-
I duplicate the expenses and cancel duplicated.
-

View File

@ -19,12 +19,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Recruitment Process',
'version': '1.0',
'category': 'Human Resources',
"sequence": 24,
"summary": "Recruitment Process, Job Descriptions",
'sequence': 24,
'summary': 'Recruitment Process, Job Descriptions',
'description': """
Manages job positions and the recruitment process.
==================================================
@ -46,7 +47,7 @@ system to store and search in your CV base.
'base_calendar',
'fetchmail',
],
'update_xml': [
'data': [
'wizard/hr_recruitment_employee_hired.xml',
'wizard/hr_recruitment_create_partner_job_view.xml',
'hr_recruitment_view.xml',
@ -57,19 +58,18 @@ system to store and search in your CV base.
'board_hr_recruitment_statistical_view.xml',
'hr_recruitment_installer_view.xml',
'res_config_view.xml',
],
'init_xml': [
'hr_recruitment_data.xml'
],
'demo_xml': [
'demo': [
'hr_recruitment_demo.yml',
],
'test':[
'test/recruitment_process.yml',
],
'js': ['static/src/js/hr_recruitment.js'],
'test': [
'test/recruitment_process.yml',
],
'installable': True,
'auto_install': False,
'certificate' : '001073437025460275621',
'certificate': '001073437025460275621',
'application': True,
}

View File

@ -198,6 +198,7 @@ class hr_applicant(base_stage, osv.Model):
When the case is over, the state is set to \'Done\'.\
If the case needs to be reviewed then the state is \
set to \'Pending\'.'),
'categ_ids': fields.many2many('hr.applicant_category', string='Categories'),
'company_id': fields.many2one('res.company', 'Company'),
'user_id': fields.many2one('res.users', 'Responsible'),
# Applicant Columns
@ -350,7 +351,7 @@ class hr_applicant(base_stage, osv.Model):
if isinstance(ids, (str, int, long)):
ids = [ids]
if update_vals is None: vals = {}
update_vals.update({
'description': msg.get('body'),
'email_from': msg.get('from'),
@ -510,7 +511,7 @@ class hr_job(osv.osv):
_inherits = {'mail.alias': 'alias_id'}
_columns = {
'survey_id': fields.many2one('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"),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
help="Email alias for this job position. New emails will automatically "
"create new applicants for this job position."),
}
@ -521,13 +522,13 @@ class hr_job(osv.osv):
def _auto_init(self, cr, context=None):
"""Installation hook to create aliases for all jobs and avoid constraint errors."""
# disable the unique alias_id not null constraint, to avoid spurious warning during
# disable the unique alias_id not null constraint, to avoid spurious warning during
# super.auto_init. We'll reinstall it afterwards.
self._columns['alias_id'].required = False
super(hr_job,self)._auto_init(cr, context=context)
registry = RegistryManager.get(cr.dbname)
mail_alias = registry.get('mail.alias')
hr_jobs = registry.get('hr.job')
@ -555,7 +556,7 @@ class hr_job(osv.osv):
mail_alias = self.pool.get('mail.alias')
if not vals.get('alias_id'):
vals.pop('alias_name', None) # prevent errors during copy()
alias_id = mail_alias.create_unique_alias(cr, uid,
alias_id = mail_alias.create_unique_alias(cr, uid,
# Using '+' allows using subaddressing for those who don't
# have a catchall domain setup.
{'alias_name': 'jobs+'+vals['name']},
@ -573,7 +574,7 @@ class hr_job(osv.osv):
res = super(hr_job, self).unlink(cr, uid, ids, context=context)
mail_alias.unlink(cr, uid, alias_ids, context=context)
return res
def action_print_survey(self, cr, uid, ids, context=None):
if context is None:
context = {}
@ -591,4 +592,12 @@ class hr_job(osv.osv):
'nodestroy':True,
}
class applicant_category(osv.osv):
""" Category of applicant """
_name = "hr.applicant_category"
_description = "Category of applicant"
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -176,6 +176,9 @@
</div>
</group>
</group>
<group>
<field name="categ_ids" widget="many2many_tags"/>
</group>
<separator string="Application Summary"/>
<field name="description" placeholder="Feedback of interviews..."/>
</sheet>
@ -254,6 +257,7 @@
<field name="model">hr.applicant</field>
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
<field name="survey"/>
@ -264,6 +268,7 @@
<field name="job_id"/>
<field name="title_action"/>
<field name="department_id"/>
<field name="categ_ids"/>
<templates>
<t t-name="kanban-tooltip">
<ul class="oe_kanban_tooltip">
@ -308,6 +313,13 @@
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
</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>
</div>
</div>
<div class="oe_clear"></div>
</div>

View File

@ -8,3 +8,5 @@ access_survey_hr_user,survey.hr.user,survey.model_survey,base.group_hr_user,1,1,
access_crm_meeting_hruser,crm.meeting.hruser,base_calendar.model_crm_meeting,base.group_hr_user,1,1,1,1
access_hr_recruitment_source_hr_officer,hr.recruitment.source,model_hr_recruitment_source,base.group_hr_user,1,1,1,1
access_hr_recruitment_source_all,hr.recruitment.source,model_hr_recruitment_source,,1,0,0,0
access_hr_applicant_category,hr.applicant_category,model_hr_applicant_category,,1,0,0,0
access_hr_applicant_category_manager,hr.applicant_category,model_hr_applicant_category,base.group_hr_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
8 access_crm_meeting_hruser crm.meeting.hruser base_calendar.model_crm_meeting base.group_hr_user 1 1 1 1
9 access_hr_recruitment_source_hr_officer hr.recruitment.source model_hr_recruitment_source base.group_hr_user 1 1 1 1
10 access_hr_recruitment_source_all hr.recruitment.source model_hr_recruitment_source 1 0 0 0
11 access_hr_applicant_category hr.applicant_category model_hr_applicant_category 1 0 0 0
12 access_hr_applicant_category_manager hr.applicant_category model_hr_applicant_category base.group_hr_manager 1 1 1 1

View File

@ -0,0 +1,35 @@
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.$element.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']).then(function(result) {
_.each(result, function(v, k) {
// Set the proper value in the DOM and display the element
self.$element.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();
}
}
});
};

View File

@ -70,7 +70,7 @@
width: 486px;
}
.openerp div.oe_mail_msg_content li {
.openerp div.oe_mail_msg_content > li {
float: left;
margin-right: 3px;
}
@ -349,6 +349,11 @@
color: #888;
}
.openerp .oe_mail_msg_footer li {
float: left;
margin-right: 3px;
}
.openerp .oe_mail_msg_body {
margin-bottom: .5em;
text-align: justify;

View File

@ -851,6 +851,13 @@ openerp.mail = function(session) {
this.view.on("change:actual_mode", this, this._check_visibility);
this._check_visibility();
mail.ChatterUtils.bind_events(this);
this.$element.find('button.oe_mail_button_followers').click(function () { self.do_toggle_followers(); });
if (! this.params.see_subscribers_options) {
this.$element.find('button.oe_mail_button_followers').hide(); }
this.$element.find('button.oe_mail_button_follow').click(function () { self.do_follow(); });
this.$element.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); })
.mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
.mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
},
_check_visibility: function() {

View File

@ -61,6 +61,17 @@
<div class="oe_mail_recthread_main">
<!-- contains the document thread -->
</div>
<div class="oe_mail_recthread_aside">
<div class="oe_mail_recthread_actions">
<button type="button" class="oe_mail_button_follow">Follow</button>
<button type="button" class="oe_mail_button_unfollow oe_mail_button_mouseout">Following</button>
<button type="button" class="oe_mail_button_followers">Show followers</button>
</div>
<div class="oe_mail_recthread_followers">
<h4>Followers</h4>
<ul class="oe_mail_followers_display"></ul>
</div>
</div>
</div>
<!--
@ -104,7 +115,7 @@
<!-- default layout -->
<li t-name="mail.thread.message" class="oe_mail oe_mail_thread_msg">
<div t-attf-class="oe_mail_msg_#{record.type}">
<img class="oe_mail_icon oe_left" t-att-src="record.mini_url"/>
<img class="oe_mail_icon oe_mail_frame oe_left" t-att-src="record.mini_url"/>
<div class="oe_mail_msg_content">
<!-- dropdown menu with message options and actions -->
<span class="oe_dropdown_toggle oe_dropdown_arrow">

View File

@ -20,10 +20,14 @@
##############################################################################
{
'name' : "Portal",
'version' : "1.0",
'depends' : ["base", "share", "auth_anonymous"],
'author' : "OpenERP SA",
'name' : 'Portal',
'version' : '1.0',
'depends' : [
'base',
'share',
'auth_anonymous'
],
'author' : 'OpenERP SA',
'category': 'Portal',
'description': """
Customize access to your OpenERP database to external users by creating portals.

16
addons/portal_event/portal_event_view.xml Normal file → Executable file
View File

@ -2,8 +2,22 @@
<openerp>
<data>
<!--
Override the original action to set another help field and/or
another context field, more suited for portal members
-->
<record model="ir.actions.act_window" id="action_event_view">
<field name="name">Events</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">event.event</field>
<field name="view_mode">kanban,calendar,tree,form,graph</field>
<field name="context">{"search_default_upcoming":1}</field>
<field name="search_view_id" ref="event.view_event_search"/>
<field name="help">No public events.</field>
</record>
<menuitem name="Events" id="portal_company_events" parent="portal.portal_company"
action="event.action_event_view" sequence="40"/>
action="action_event_view" sequence="40"/>
</data>
</openerp>

View File

@ -2,16 +2,39 @@
<openerp>
<data>
<!--
Override the original action to set another help field and/or
another context field, more suited for portal members
-->
<record id="action_order_tree5" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="context">{"search_default_draft":1}</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="help">You dont have any quotation.</field>
</record>
<record id="action_order_form" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="search_view_id" ref="sale.view_sales_order_filter"/>
<field name="context">{"search_default_sales":1}</field>
<field name="help">You dont have any sale order.</field>
</record>
<record id="action_picking_tree" model="ir.actions.act_window">
<field name="name">Delivery Orders</field>
<field name="res_model">stock.picking.out</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('type','=','out')]</field>
<field name="context">{'default_type': 'out', 'contact_display': 'partner_address'}</field>
<field name="search_view_id" ref="stock.view_picking_out_search"/>
<field name="help">This is the list of all delivery orders that have to be prepared, according to your different orders.</field>
<field name="help">You dont have any delivery order.</field>
</record>
<record id="product_normal_action" model="ir.actions.act_window">
@ -22,21 +45,42 @@
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="product.product_kanban_view"/>
<field name="search_view_id" ref="product.product_search_form_view"/>
<field name="help">No public products.</field>
</record>
<record id="action_invoice_tree1" model="ir.actions.act_window">
<field name="name">Customer Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('type','=','out_invoice')]</field>
<field name="context">{'default_type':'out_invoice', 'type':'out_invoice', 'journal_type': 'sale'}</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
<field name="help">You dont have any invoice.</field>
</record>
<record id="action_vendor_receipt" model="ir.actions.act_window">
<field name="name">Customer Payment</field>
<field name="res_model">account.voucher</field>
<field name="domain">[('journal_id.type', 'in', ['bank', 'cash']), ('type','=','receipt')]</field>
<field name="context">{'type':'receipt'}</field>
<field name="search_view_id" ref="account_voucher.view_voucher_filter_customer_pay"/>
<field name="target">current</field>
<field name="help">You dont have any payment.</field>
</record>
<menuitem name="Quotations" id="portal_quotations" parent="portal.portal_orders"
action="sale.action_order_tree5" sequence="10"/>
action="action_order_tree5" sequence="10"/>
<menuitem name="Sales Orders" id="portal_sales_orders" parent="portal.portal_orders"
action="sale.action_order_form" sequence="20"/>
action="action_order_form" sequence="20"/>
<menuitem name="Delivery Orders" id="portal_delivery" parent="portal.portal_orders"
action="action_picking_tree" sequence="30"/>
<menuitem name="Products" id="portal_products" parent="portal.portal_orders"
action="product_normal_action" sequence="40"/>
<menuitem name="Invoice" id="portal_invoices" parent="portal.portal_invoices_payements"
action="account.action_invoice_tree1" sequence="10"/>
action="action_invoice_tree1" sequence="10"/>
<menuitem name="Refund/Payments" id="portal_payments" parent="portal.portal_invoices_payements"
action="account_voucher.action_vendor_receipt" sequence="20"/>
action="action_vendor_receipt" sequence="20"/>
</data>
</openerp>

View File

@ -19,18 +19,33 @@
#
##############################################################################
{
"name": "Project Management",
"version": "1.1",
"author": "OpenERP SA",
"website": "http://www.openerp.com",
"category": "Project Management",
"sequence": 8,
"summary": "Projects, Tasks",
"images": ["images/gantt.png", "images/project_dashboard.jpeg","images/project_task_tree.jpeg","images/project_task.jpeg","images/project.jpeg","images/task_analysis.jpeg"],
"depends": ["base_setup", "base_status", "product", "analytic", "board", "mail", "resource","web_kanban"],
"description": """
'name': 'Project Management',
'version': '1.1',
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'category': 'Project Management',
'sequence': 8,
'summary': 'Projects, Tasks',
'images': [
'images/gantt.png',
'images/project_dashboard.jpeg',
'images/project_task_tree.jpeg',
'images/project_task.jpeg',
'images/project.jpeg',
'images/task_analysis.jpeg'
],
'depends': [
'base_setup',
'base_status',
'product',
'analytic',
'board',
'mail',
'resource',
'web_kanban'
],
'description': """
Project Management module tracks multi-level projects, tasks, work done on tasks.
=================================================================================
@ -41,22 +56,21 @@ Dashboard for project management that includes:
* List of My Open Tasks
* Graph of My Remaining Hours by Project
""",
"init_xml": [],
"update_xml": [
"security/project_security.xml",
"wizard/project_task_delegate_view.xml",
"wizard/project_task_reevaluate_view.xml",
"security/ir.model.access.csv",
"project_data.xml",
"project_view.xml",
"process/task_process.xml",
"res_partner_view.xml",
"report/project_report_view.xml",
'data': [
'security/project_security.xml',
'wizard/project_task_delegate_view.xml',
'wizard/project_task_reevaluate_view.xml',
'security/ir.model.access.csv',
'project_data.xml',
'project_view.xml',
'process/task_process.xml',
'res_partner_view.xml',
'report/project_report_view.xml',
'report/project_cumulative.xml',
"board_project_view.xml",
'board_project_view.xml',
'res_config_view.xml',
],
'demo_xml': [
'demo': [
'project_demo.xml',
],
'test':[

View File

@ -229,7 +229,7 @@
<field name="alias_domain"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_auto_height oe_kanban_global_click">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_project oe_kanban_global_click">
<div class="oe_dropdown_toggle oe_dropdown_kanban">
<span class="oe_e">í</span>
<ul class="oe_dropdown_menu">

View File

@ -18,3 +18,5 @@ access_account_analytic_line_project,account.analytic.line project,analytic.mode
access_project_task_history,project.task.history project,project.model_project_task_history,project.group_project_user,1,1,1,0
access_project_task_history_cumulative,project.task.history project,project.model_project_task_history_cumulative,project.group_project_manager,1,0,0,0
access_resource_calendar,project.resource_calendar manager,resource.model_resource_calendar,project.group_project_manager,1,0,0,0
access_project_category,project.project_category,model_project_category,,1,0,0,0
access_project_category_manager,project.project_category,model_project_category,project.group_project_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
18 access_project_task_history project.task.history project project.model_project_task_history project.group_project_user 1 1 1 0
19 access_project_task_history_cumulative project.task.history project project.model_project_task_history_cumulative project.group_project_manager 1 0 0 0
20 access_resource_calendar project.resource_calendar manager resource.model_resource_calendar project.group_project_manager 1 0 0 0
21 access_project_category project.project_category model_project_category 1 0 0 0
22 access_project_category_manager project.project_category model_project_category project.group_project_manager 1 1 1 1

View File

@ -239,6 +239,7 @@
<field name="model">project.issue</field>
<field name="arch" type="xml">
<kanban default_group_by="stage_id">
<field name="stage_id"/>
<field name="color"/>
<field name="priority"/>
<field name="user_email"/>

View File

@ -323,7 +323,7 @@
<field name="name">purchase.order.tree</field>
<field name="model">purchase.order</field>
<field name="arch" type="xml">
<tree fonts="bold:needaction_pending==True" colors="grey:state=='cancel';blue:state in (confirmed');red:state in ('except_invoice','except_picking')" string="Purchase Order">
<tree fonts="bold:needaction_pending==True" colors="grey:state=='cancel';blue:state in ('confirmed');red:state in ('except_invoice','except_picking')" string="Purchase Order">
<field name="needaction_pending" invisible="1"/>
<field name="name" string="Reference"/>
<field name="date_order" />