[MERGE] merge with dev addons3 branch
bzr revid: psi@tinyerp.co.in-20100610094230-fs2zdfmy7m7ffsej
This commit is contained in:
commit
5bf5f81b7a
|
@ -562,39 +562,35 @@ class account_journal(osv.osv):
|
|||
_name = "account.journal"
|
||||
_description = "Journal"
|
||||
_columns = {
|
||||
'name': fields.char('Journal Name', size=64, required=True, translate=True),
|
||||
'code': fields.char('Code', size=16),
|
||||
'type': fields.selection([('sale', 'Sale'), ('purchase', 'Purchase'), ('expense', 'Expense'), ('cash', 'Cash'), ('bank', 'Bank'), ('general', 'General'), ('situation', 'Situation')], 'Type', size=32, required=True,
|
||||
'name': fields.char('Journal Name', size=64, required=True, translate=True,help="Name of the journal"),
|
||||
'code': fields.char('Code', size=16,required=True,help="Code of the journal"),
|
||||
'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'),('expense', 'Expense'), ('cash', 'Cash'), ('bank', 'Bank'), ('general', 'General'), ('situation', 'Situation')], 'Type', size=32, required=True,
|
||||
help="Select 'Sale' for Sale journal to be used at the time of making invoice."\
|
||||
" Select 'Purchase' for Purchase Journal to be used at the time of approving purchase order."\
|
||||
" Select 'Cash' to be used at the time of making payment."\
|
||||
" Select 'General' to be used at the time of stock input/output."\
|
||||
" Select 'Situation' to be used at the time of making vouchers."),
|
||||
'refund_journal': fields.boolean('Refund Journal', help='Fill this if the journal is to be used for refunds of invoices.'),
|
||||
|
||||
'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view'), ('code', '<>', 'closed')]),
|
||||
'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view'), ('type', '<>', 'closed')]),
|
||||
|
||||
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the journal without removing it."),
|
||||
'view_id': fields.many2one('account.journal.view', 'View', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tells Open ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
|
||||
'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]"),
|
||||
'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account', domain="[('type','!=','view')]"),
|
||||
'view_id': fields.many2one('account.journal.view', 'Display Mode', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tells Open ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
|
||||
'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]",help="This will act as a default account for credit amount"),
|
||||
'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account', domain="[('type','!=','view')]",help="This will act as a default account for debit amount"),
|
||||
'centralisation': fields.boolean('Centralised counterpart', help="Check this box to determine that each entry of this journal won't create a new counterpart but will share the same counterpart. This is used in fiscal year closing."),
|
||||
'update_posted': fields.boolean('Allow Cancelling Entries'),
|
||||
'update_posted': fields.boolean('Allow Cancelling Entries',help="Check this box if you want to cancel the entries related to this journal or want to cancel the invoice related to this journal"),
|
||||
'group_invoice_lines': fields.boolean('Group invoice lines', help="If this box is checked, the system will try to group the accounting lines when generating them from invoices."),
|
||||
'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="The sequence gives the display order for a list of journals", required=True),
|
||||
'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"),
|
||||
'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
|
||||
'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
|
||||
'entry_posted': fields.boolean('Skip \'Draft\' State for Created Entries', help='Check this box if you don\'t want new account moves to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation.'),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True,select=1,help="Company related to a journal"),
|
||||
'invoice_sequence_id': fields.many2one('ir.sequence', 'Invoice Sequence', \
|
||||
help="The sequence used for invoice numbers in this journal."),
|
||||
'allow_date':fields.boolean('Check Date not in the Period', help= 'If set to True then do not accept the entry if the entry date is not into the period dates'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'user_id': lambda self,cr,uid,context: uid,
|
||||
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
|
||||
}
|
||||
|
@ -604,7 +600,7 @@ class account_journal(osv.osv):
|
|||
move_lines = self.pool.get('account.move.line').search(cr, uid, [('journal_id', 'in', ids)])
|
||||
if move_lines:
|
||||
raise osv.except_osv(_('Warning !'), _('You cannot modify company of this journal as its related record exist in Entry Lines'))
|
||||
return super(account_period, self).write(cr, uid, ids, vals, context=context)
|
||||
return super(account_journal, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def create(self, cr, uid, vals, context={}):
|
||||
journal_id = super(account_journal, self).create(cr, uid, vals, context)
|
||||
|
@ -631,6 +627,16 @@ class account_journal(osv.osv):
|
|||
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit, context=context)
|
||||
return self.name_get(cr, user, ids, context=context)
|
||||
|
||||
def onchange_type(self, cr, uid, ids, type):
|
||||
res={}
|
||||
for line in self.browse(cr, uid, ids):
|
||||
if type == 'situation':
|
||||
res= {'value':{'centralisation': True}}
|
||||
else:
|
||||
res= {'value':{'centralisation': False}}
|
||||
return res
|
||||
|
||||
|
||||
account_journal()
|
||||
|
||||
class account_fiscalyear(osv.osv):
|
||||
|
|
|
@ -272,22 +272,19 @@
|
|||
<group colspan="4" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="type"/>
|
||||
<field name="type" on_change="onchange_type(type)"/>
|
||||
<field name="refund_journal" attrs="{'readonly':[('type','=','general'),('type','=','cash'),('type','=','situation')]}"/>
|
||||
</group>
|
||||
|
||||
<notebook colspan="4">
|
||||
<notebook colspan="4">
|
||||
<page string="General Information">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Journal View" colspan="4"/>
|
||||
<field name="view_id"/>
|
||||
<field name="view_id" widget="selection"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Sequence" colspan="4"/>
|
||||
<field name="sequence_id"/>
|
||||
<field name="invoice_sequence_id"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
|
@ -296,7 +293,7 @@
|
|||
<field name="default_credit_account_id" attrs="{'required':[('type','=','cash')]}" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Validations" colspan="4"/>
|
||||
<field name="allow_date" groups="base.group_extended"/>
|
||||
</group>
|
||||
|
@ -307,15 +304,19 @@
|
|||
<field name="user_id" groups="base.group_extended"/>
|
||||
<field name="currency"/>
|
||||
</group>
|
||||
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Other Configuration" colspan="4"/>
|
||||
<field name="centralisation"/>
|
||||
<field name="group_invoice_lines"/>
|
||||
<field name="update_posted"/>
|
||||
<field name="centralisation" groups="base.group_extended"/>
|
||||
<field name="entry_posted"/>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Invoicing Data" colspan="4"/>
|
||||
<field name="invoice_sequence_id"/>
|
||||
<field name="group_invoice_lines"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Entry Controls">
|
||||
<page string="Entry Controls" groups="base.group_extended">
|
||||
<separator colspan="4" string="Accounts Type Allowed (empty for no control)"/>
|
||||
<field colspan="4" name="type_control_ids" nolabel="1"/>
|
||||
<separator colspan="4" string="Accounts Allowed (empty for no control)"/>
|
||||
|
@ -957,7 +958,6 @@
|
|||
<field name="state" select="1"/>
|
||||
<group col="2" colspan="2">
|
||||
<button name="button_validate" states="draft" string="Validate" type="object" icon="gtk-execute"/>
|
||||
<button name="button_cancel" states="posted" string="Cancel" type="object" icon="gtk-cancel"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Other Information">
|
||||
|
|
|
@ -923,13 +923,13 @@ class account_invoice(osv.osv):
|
|||
account_move_obj = self.pool.get('account.move')
|
||||
invoices = self.read(cr, uid, ids, ['move_id', 'payment_ids'])
|
||||
for i in invoices:
|
||||
if i['move_id']:
|
||||
if i['move_id']:
|
||||
account_move_obj.button_cancel(cr, uid, [i['move_id'][0]])
|
||||
# delete the move this invoice was pointing to
|
||||
# Note that the corresponding move_lines and move_reconciles
|
||||
# will be automatically deleted too
|
||||
account_move_obj.unlink(cr, uid, [i['move_id'][0]])
|
||||
if i['payment_ids']:
|
||||
if i['payment_ids']:
|
||||
account_move_line_obj = self.pool.get('account.move.line')
|
||||
pay_ids = account_move_line_obj.browse(cr, uid , i['payment_ids'])
|
||||
for move_line in pay_ids:
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
||||
{
|
||||
"name" : "Account Cancel",
|
||||
"version" : "1.1",
|
||||
"depends" : ["account"],
|
||||
"author" : "Tiny",
|
||||
"category": 'Generic Modules/Accounting',
|
||||
"description": """
|
||||
Module Add Allow cancelling entries field on form view of account journal if it set to true it allows user to cancel entries & invoices.
|
||||
""",
|
||||
'website': 'http://www.openerp.com',
|
||||
'init_xml': [],
|
||||
'update_xml': ['account_cancel_view.xml' ],
|
||||
'demo_xml': [],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_account_journal_form_inherit" model="ir.ui.view">
|
||||
<field name="name">account.journal.form</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="account.view_account_journal_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/notebook/page[@string='General Information']/group/field[@name='centralisation']" position="after">
|
||||
<field name="update_posted"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -35,6 +35,7 @@ This module implement the modification on the invoice form.
|
|||
'init_xml': [],
|
||||
'update_xml': ['account_tax_include_view.xml'],
|
||||
'demo_xml': [],
|
||||
'test': ['test/account_tax_include.yml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0070514190381',
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
-
|
||||
Creating a tax record
|
||||
-
|
||||
!record {model: account.tax, id: account_tax_a0}:
|
||||
amount: 0.10000000000000001
|
||||
applicable_type: 'true'
|
||||
company_id: base.main_company
|
||||
description: a
|
||||
name: a
|
||||
sequence: 1
|
||||
type: percent
|
||||
type_tax_use: all
|
||||
|
||||
-
|
||||
Creating a account invoice record with tax excluded
|
||||
-
|
||||
!record {model: account.invoice, id: account_invoice_tax_exclude}:
|
||||
account_id: account.a_recv
|
||||
address_contact_id: base.res_partner_address_3000
|
||||
address_invoice_id: base.res_partner_address_3000
|
||||
company_id: base.main_company
|
||||
currency_id: base.EUR
|
||||
invoice_line:
|
||||
- account_id: account.a_sale
|
||||
name: '[PC1] Basic PC'
|
||||
price_unit: 100.0
|
||||
quantity: 1.0
|
||||
invoice_line_tax_id:
|
||||
- account_tax_a0
|
||||
product_id: product.product_product_pc1
|
||||
uos_id: product.product_uom_unit
|
||||
journal_id: account.sales_journal
|
||||
partner_id: base.res_partner_desertic_hispafuentes
|
||||
price_type: tax_excluded
|
||||
reference_type: none
|
||||
|
||||
-
|
||||
Performing an osv_memory action button_reset_taxes on module account.invoice
|
||||
-
|
||||
!python {model: account.invoice}: |
|
||||
self.button_reset_taxes(cr, uid, [ref("account_invoice_tax_exclude")], {"lang": "en_US", "tz": False,
|
||||
"active_model": "ir.ui.menu", "active_ids": [ref("account.menu_action_invoice_tree1")],
|
||||
"type": "out_invoice", "active_id": ref("account.menu_action_invoice_tree1"),
|
||||
})
|
||||
-
|
||||
Check if tax is excluded in invoice
|
||||
-
|
||||
!assert {model: account.invoice, id: account_invoice_tax_exclude, severity: error, string: price type is tax excluded}:
|
||||
- state == "draft"
|
||||
- amount_untaxed == 100.0
|
||||
- amount_tax == 10.0
|
||||
- amount_total == 110.0
|
||||
|
||||
-
|
||||
Creating a account invoice record with tax include
|
||||
-
|
||||
!record {model: account.invoice, id: account_invoice_tax_include}:
|
||||
account_id: account.a_recv
|
||||
address_contact_id: base.res_partner_address_3000
|
||||
address_invoice_id: base.res_partner_address_3000
|
||||
company_id: base.main_company
|
||||
currency_id: base.EUR
|
||||
invoice_line:
|
||||
- account_id: account.a_sale
|
||||
name: '[PC1] Basic PC'
|
||||
price_unit: 100.0
|
||||
quantity: 1.0
|
||||
invoice_line_tax_id:
|
||||
- account_tax_a0
|
||||
product_id: product.product_product_pc1
|
||||
uos_id: product.product_uom_unit
|
||||
journal_id: account.sales_journal
|
||||
partner_id: base.res_partner_desertic_hispafuentes
|
||||
price_type: tax_included
|
||||
reference_type: none
|
||||
|
||||
-
|
||||
Performing an osv_memory action button_reset_taxes on module account.invoice
|
||||
-
|
||||
!python {model: account.invoice}: |
|
||||
self.button_reset_taxes(cr, uid, [ref("account_invoice_tax_include")], {"lang": "en_US", "tz": False,
|
||||
"active_model": "ir.ui.menu", "active_ids": [ref("account.menu_action_invoice_tree1")],
|
||||
"type": "out_invoice", "active_id": ref("account.menu_action_invoice_tree1"),
|
||||
})
|
||||
-
|
||||
Check if tax is included in invoice
|
||||
-
|
||||
!assert {model: account.invoice, id: account_invoice_tax_include, severity: error, string: price type is tax included}:
|
||||
- state == "draft"
|
||||
- amount_untaxed == 90.91
|
||||
- amount_tax == 9.09
|
||||
- amount_total == 100.00
|
|
@ -1,15 +1,15 @@
|
|||
- |
|
||||
In order to test the hr module in OpenERP, I will create new Employee , Department and Job Position.
|
||||
In order to test hr module in OpenERP, I will create new Employee , Department and Job Position.
|
||||
-
|
||||
|
|
||||
First I create Department "R & D" in Department form.
|
||||
I create "R & D" Department in Department form.
|
||||
-
|
||||
!record {model: hr.department, id: hr_department_rd0}:
|
||||
manager_id: base.user_root
|
||||
name: 'R & D '
|
||||
-
|
||||
|
|
||||
Now, I create a new employee “employee1”.
|
||||
Now, I create a new employee “Mark Johnson”.
|
||||
select "R & D" Department which I had created.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
|
@ -22,7 +22,7 @@
|
|||
department_id: 'hr_department_rd0'
|
||||
|
||||
- |
|
||||
In order to check the wizard “Employee Hierarchy” I will create new employee “employee2” and select "employee1" as
|
||||
In order to check the wizard “Employee Hierarchy” , I will create new employee “Phil Graves ” and select "Mark Johnson" as
|
||||
Manager.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee1}:
|
||||
|
@ -33,11 +33,11 @@
|
|||
user_id: base.user_demo
|
||||
parent_id: 'hr_employee_employee0'
|
||||
- |
|
||||
Now I will open up form view of “employee1” and test the wizard “Employee Hierarchy” so it display the employee
|
||||
hierarchy starting from “employee1”.
|
||||
I will open up form view of “Mark Johnson” and test the wizard “Employee Hierarchy” so it display the employee
|
||||
hierarchy starting from “Mark Johnson”.
|
||||
|
||||
- |
|
||||
Now I will create new Job Position. I will check successfull creation of new Job Position by adding the information.
|
||||
I will create new Job Position. I will check successfull creation of new Job Position by adding the information.
|
||||
-
|
||||
!record {model: hr.job, id: hr_job_jea0}:
|
||||
department_id: 'hr_department_rd0'
|
||||
|
@ -51,17 +51,17 @@
|
|||
- state == 'open'
|
||||
|
||||
- |
|
||||
I create Employee for this position in this Job Position form.
|
||||
I create Employee for job position.
|
||||
-
|
||||
!record {model: hr.job, id: hr_job_jea0}:
|
||||
employee_ids:
|
||||
- address_home_id: base.res_partner_address_1
|
||||
name: employee3
|
||||
name: Manuel Lehba
|
||||
department_id: 'hr_department_rd0'
|
||||
gender: male
|
||||
parent_id: 'hr_employee_employee0'
|
||||
-
|
||||
I check that "NO of Employee" is "1"
|
||||
- |
|
||||
I check that "Number of Employees" field have some value.
|
||||
-
|
||||
!assert {model: hr.job, id: hr_job_jea0}:
|
||||
- no_of_employee != False
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
'wizard/hr_attendance_sign_in_out_view.xml',
|
||||
],
|
||||
'demo_xml': ['hr_attendance_demo.xml'],
|
||||
'test': ['test/test_hr_attendance.yml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0063495605613',
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
- |
|
||||
In order to test hr_attendance module in OpenERP, I create new attendance and perform Sign In/Sign Out operation.
|
||||
|
||||
- |
|
||||
First I create Employee "Mark Johnson".
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
address_home_id: base.res_partner_address_1
|
||||
company_id: base.main_company
|
||||
gender: male
|
||||
name: Mark Johnson
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
Given that I have Attendance Reason "Good Morning" for Sign In.
|
||||
-
|
||||
!record {model: hr.action.reason, id: hr_action_reason_goodmorning0}:
|
||||
name: Good Morning
|
||||
action_type: sign_in
|
||||
- |
|
||||
I also create another Attendance Reason for Sign Out.
|
||||
-
|
||||
!record {model: hr.action.reason, id: hr_action_reason_goodnight0}:
|
||||
name: Good Night
|
||||
action_type: sign_out
|
||||
- |
|
||||
Now , When I came in office , I create Atendances and perform "Sign In" action with proper reason.
|
||||
-
|
||||
!record {model: hr.attendance, id: hr_attendance_0}:
|
||||
action: sign_in
|
||||
action_desc: 'hr_action_reason_goodmorning0'
|
||||
employee_id: 'hr_employee_employee0'
|
||||
name: '2010-05-18 19:08:08'
|
||||
- |
|
||||
I check that Employee is in "Present" state.
|
||||
-
|
||||
!assert {model: hr.employee, id: hr_employee_employee0}:
|
||||
- state == 'present'
|
||||
|
||||
- |
|
||||
When I left office , I create attendance and perform "Sign Out".
|
||||
-
|
||||
!record {model: hr.attendance, id: hr_attendance_1}:
|
||||
action: sign_out
|
||||
employee_id: 'hr_employee_employee0'
|
||||
name: '2010-05-18 19:10:55'
|
||||
- |
|
||||
I check that Employee is in "Absent" state.
|
||||
-
|
||||
!assert {model: hr.employee, id: hr_employee_employee0}:
|
||||
- state == 'absent'
|
||||
|
||||
- |
|
||||
I can also fill my attendance using "Sign In/Sign Out" wizard.
|
||||
-
|
||||
!record {model: hr.sign.in.out, id: hr_sign_in_out_markjohnson0}:
|
||||
name: Mark Johnson
|
||||
state: absent
|
||||
|
||||
- |
|
||||
I click on "Sign In" button of this wizard to perform present action.
|
||||
-
|
||||
!python {model: hr.sign.in.out}: |
|
||||
obj_attendance = self.pool.get('hr.employee')
|
||||
emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "Mark Johnson")])
|
||||
if emp_id:
|
||||
employee = obj_attendance.read(cr, uid, emp_id)[0]
|
||||
self.write(cr, uid, [ref('hr_sign_in_out_markjohnson0')], {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]})
|
||||
self.si_check(cr, uid, [ref("hr_sign_in_out_markjohnson0")], {"active_id": ref("hr_employee_employee0")})
|
||||
|
||||
- |
|
||||
I check that Employee is in "Present" state.
|
||||
-
|
||||
!assert {model: hr.employee, id: hr_employee_employee0}:
|
||||
- state == 'present'
|
||||
|
||||
- |
|
||||
I forgot to "Sign Out" in Yesterday and want to sign in Today using This wizard.
|
||||
-
|
||||
!record {model: hr.sign.in.out, id: hr_sign_in_out_markjohnson0}:
|
||||
name: Mark Johnson
|
||||
state: present
|
||||
- |
|
||||
I click on "Sign In" button of this wizard. that will Open new form which ask for Last Sign Out date.
|
||||
-
|
||||
!python {model: hr.sign.in.out}: |
|
||||
obj_attendance = self.pool.get('hr.employee')
|
||||
emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "Mark Johnson")])
|
||||
if emp_id:
|
||||
employee = obj_attendance.read(cr, uid, emp_id)[0]
|
||||
self.write(cr, uid, [ref('hr_sign_in_out_markjohnson0')], {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]})
|
||||
self.si_check(cr, uid, [ref("hr_sign_in_out_markjohnson0")])
|
||||
- |
|
||||
I select Last Sign Out date in "hr sign out ask" wizard.
|
||||
-
|
||||
!record {model: hr.sign.in.out.ask, id: hr_sign_in_out_ask_markjohnson0}:
|
||||
last_time: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
name: Mark Johnson
|
||||
- |
|
||||
Now I click on "Sign In" button of this wizard.
|
||||
-
|
||||
!python {model: hr.sign.in.out.ask}: |
|
||||
obj_attendance = self.pool.get('hr.employee')
|
||||
emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "Mark Johnson")])
|
||||
if emp_id:
|
||||
employee = obj_attendance.read(cr, uid, emp_id)[0]
|
||||
self.write(cr, uid, [ref('hr_sign_in_out_ask_markjohnson0')], {'emp_id': emp_id[0]})
|
||||
#self.sign_in(cr, uid, [ref("hr_sign_in_out_ask_markjohnson0")], {"active_ids": [ref("hr_attendance.menu_hr_attendance_sigh_in_out")]})
|
||||
|
|
@ -33,16 +33,16 @@ class hr_si_so_ask(osv.osv_memory):
|
|||
'emp_id': fields.char('Empoyee ID', size=32, required=True, readonly=True),
|
||||
}
|
||||
def _get_empname(self, cr, uid, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
emp_id = service.execute(cr.dbname, uid, 'hr.employee', 'search', [('user_id', '=', uid)])
|
||||
emp_obj = self.pool.get('hr.employee')
|
||||
emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)])
|
||||
if emp_id:
|
||||
employee = service.execute(cr.dbname, uid, 'hr.employee', 'read', emp_id)[0]
|
||||
employee = emp_obj.read(cr, uid, emp_id)[0]
|
||||
return employee['name']
|
||||
return ''
|
||||
|
||||
def _get_empid(self, cr, uid, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
emp_id = service.execute(cr.dbname, uid, 'hr.employee', 'search', [('user_id', '=', uid)])
|
||||
emp_obj = self.pool.get('hr.employee')
|
||||
emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)])
|
||||
if emp_id:
|
||||
return emp_id[0]
|
||||
return False
|
||||
|
@ -74,10 +74,10 @@ class hr_sign_in_out(osv.osv_memory):
|
|||
}
|
||||
|
||||
def _get_empid(self, cr, uid, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
emp_id = service.execute(cr.dbname, uid, 'hr.employee', 'search', [('user_id', '=', uid)])
|
||||
emp_obj = self.pool.get('hr.employee')
|
||||
emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)])
|
||||
if emp_id:
|
||||
employee = service.execute(cr.dbname, uid, 'hr.employee', 'read', emp_id)[0]
|
||||
employee = emp_obj.read(cr, uid, emp_id)[0]
|
||||
return {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]}
|
||||
return {}
|
||||
|
||||
|
@ -88,12 +88,13 @@ class hr_sign_in_out(osv.osv_memory):
|
|||
return res
|
||||
|
||||
def si_check(self, cr, uid, ids, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
|
||||
att_obj = self.pool.get('hr.attendance')
|
||||
obj_model = self.pool.get('ir.model.data')
|
||||
data = self.read(cr, uid, ids, [])[0]
|
||||
emp_id = data['emp_id']
|
||||
att_id = service.execute(cr.dbname, uid, 'hr.attendance', 'search', [('employee_id', '=', emp_id)], limit=1, order='name desc')
|
||||
last_att = service.execute(cr.dbname, uid, 'hr.attendance', 'read', att_id)
|
||||
att_id = att_obj.search(cr, uid, [('employee_id', '=', emp_id)], limit=1, order='name desc')
|
||||
last_att = att_obj.read(cr, uid, att_id)
|
||||
if last_att:
|
||||
last_att = last_att[0]
|
||||
cond = not last_att or last_att['action'] == 'sign_out'
|
||||
|
@ -113,12 +114,13 @@ class hr_sign_in_out(osv.osv_memory):
|
|||
}
|
||||
|
||||
def so_check(self, cr, uid, ids, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
|
||||
att_obj = self.pool.get('hr.attendance')
|
||||
obj_model = self.pool.get('ir.model.data')
|
||||
data = self.read(cr, uid, ids, [])[0]
|
||||
emp_id = data['emp_id']
|
||||
att_id = service.execute(cr.dbname, uid, 'hr.attendance', 'search', [('employee_id', '=', emp_id),('action','!=','action')], limit=1, order='name desc')
|
||||
last_att = service.execute(cr.dbname, uid, 'hr.attendance', 'read', att_id)
|
||||
att_id = att_obj.search(cr, uid, [('employee_id', '=', emp_id),('action','!=','action')], limit=1, order='name desc')
|
||||
last_att = att_obj.read(cr, uid, att_id)
|
||||
if last_att:
|
||||
last_att = last_att[0]
|
||||
if not att_id and not last_att:
|
||||
|
@ -151,31 +153,31 @@ class hr_sign_in_out(osv.osv_memory):
|
|||
}
|
||||
|
||||
def sign_in(self, cr, uid, data, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
att_obj = self.pool.get('hr.attendance')
|
||||
emp_id = data['emp_id']
|
||||
if 'last_time' in data:
|
||||
if data['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
|
||||
raise osv.except_osv(_('UserError'), _('The sign-out date must be in the past'))
|
||||
service.execute(cr.dbname, uid, 'hr.attendance', 'create', {
|
||||
att_obj.create(cr, uid, {
|
||||
'name': data['last_time'],
|
||||
'action': 'sign_out',
|
||||
'employee_id': emp_id
|
||||
})
|
||||
try:
|
||||
success = service.execute(cr.dbname, uid, 'hr.employee', 'attendance_action_change', [emp_id], 'sign_in')
|
||||
success = self.pool.get('hr.employee').attendance_action_change(cr, uid, [emp_id], 'sign_in')
|
||||
except:
|
||||
raise osv.except_osv(_('UserError'), _('A sign-in must be right after a sign-out !'))
|
||||
return {} # To do: Return Success message
|
||||
|
||||
def sign_out(self, cr, uid, data, context=None):
|
||||
service = netsvc.LocalService('object_proxy')
|
||||
att_obj = self.pool.get('hr_attendance')
|
||||
emp_id = data['emp_id']
|
||||
if 'last_time' in data:
|
||||
if data['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
|
||||
raise osv.except_osv(_('UserError'), _('The Sign-in date must be in the past'))
|
||||
service.execute(cr.dbname, uid, 'hr.attendance', 'create', {'name':data['last_time'], 'action':'sign_in', 'employee_id':emp_id})
|
||||
att_obj.create(cr, uid, {'name':data['last_time'], 'action':'sign_in', 'employee_id':emp_id})
|
||||
try:
|
||||
success = service.execute(cr.dbname, uid, 'hr.employee', 'attendance_action_change', [emp_id], 'sign_out')
|
||||
success = self.pool.get('hr.employee').attendance_action_change(cr, uid, [emp_id], 'sign_out')
|
||||
except:
|
||||
raise osv.except_osv(_('UserError'), _('A sign-out must be right after a sign-in !'))
|
||||
return {} # To do: Return Success message
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
I will create contract for "Mark Johnson" employee.
|
||||
|
||||
- |
|
||||
First I create Employee "Mark Johnson"
|
||||
I create Employee "Mark Johnson" to assign contract.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
address_home_id: base.res_partner_address_1
|
||||
|
@ -30,9 +30,9 @@
|
|||
type: gross
|
||||
|
||||
- |
|
||||
Now I start by create contract for "Mark Johnson".
|
||||
Now I start by creating contract for "Mark Johnson".
|
||||
Select wage type "Monthly Gross Wage" and Wage period "monthly"
|
||||
which I have given.
|
||||
which I had given.
|
||||
-
|
||||
!record {model: hr.contract, id: hr_contract_contract0}:
|
||||
advantages_gross: 0.0
|
||||
|
|
|
@ -35,13 +35,14 @@
|
|||
is done by the manager.Every evaluation filled by the employees can be viewed
|
||||
in the form of.Implements a dashboard for My Current Evaluations """,
|
||||
"init_xml" : [],
|
||||
"demo_xml" : ["hr_evaluation_demo.xml"],
|
||||
"demo_xml" : ["hr_evaluation_demo.xml",
|
||||
],
|
||||
"update_xml" : [
|
||||
"security/ir.model.access.csv",
|
||||
"wizard/hr_evaluation_mail_view.xml",
|
||||
"hr_evaluation_view.xml",
|
||||
"report/hr_evaluation_report_view.xml",
|
||||
'board_hr_evaluation_view.xml',],
|
||||
"report/hr_evaluation_report_view.xml"],
|
||||
"test": ["test/test_hr_evaluation.yml"],
|
||||
"active": False,
|
||||
"installable": True
|
||||
}
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
- |
|
||||
In order to test hr_evaluation module for OpenERP, I will create plan then create evaluation under that plan.
|
||||
-
|
||||
|
|
||||
Given that I have "R & D" Department for employee.
|
||||
-
|
||||
!record {model: hr.department, id: hr_department_rd0}:
|
||||
manager_id: base.user_root
|
||||
name: 'R & D '
|
||||
-
|
||||
|
|
||||
Given that I have Employee “Mark Johnson” which take Interview.
|
||||
select "R & D" Department.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
address_home_id: base.res_partner_address_1
|
||||
company_id: base.main_company
|
||||
gender: male
|
||||
marital: hr.hr_employee_marital_status_single
|
||||
name: Mark Johnson
|
||||
user_id: base.user_root
|
||||
department_id: 'hr_department_rd0'
|
||||
- |
|
||||
I create new employee “Phil Graves ” and select "Mark Johnson" as
|
||||
Manager.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee1}:
|
||||
address_home_id: base.res_partner_address_3000
|
||||
company_id: base.main_company
|
||||
gender: male
|
||||
name: Phil Graves
|
||||
user_id: base.user_demo
|
||||
parent_id: 'hr_employee_employee0'
|
||||
|
||||
- |
|
||||
I Create "Employee Evaluation" survey for Manager's Evaluation Plan.
|
||||
-
|
||||
!record {model: 'survey', id: survey_0}:
|
||||
title: 'Employee Evaluation'
|
||||
max_response_limit: 20
|
||||
response_user: 2
|
||||
- |
|
||||
I Create "Employee Evaluation" page in "Employee Evaluation" survey.
|
||||
-
|
||||
!record {model: 'survey.page', id: survey_employee_page_0}:
|
||||
title: 'Employee Evaluation'
|
||||
survey_id: survey_0
|
||||
- |
|
||||
I Create "What is your Name" question in "Employee Evaluation" survey page.
|
||||
-
|
||||
!record {model: 'survey.question', id: survey_p_question_0}:
|
||||
question: 'What is your Name?'
|
||||
type: 'single_textbox'
|
||||
sequence: 1
|
||||
page_id: survey_employee_page_0
|
||||
- |
|
||||
I Create "What is your gender" Question in "Employee Evaluation" survey page.
|
||||
-
|
||||
!record {model: 'survey.question', id: survey_p_question_1}:
|
||||
question: 'What is your gender?'
|
||||
type: multiple_choice_only_one_ans
|
||||
sequence: 2
|
||||
is_require_answer: true
|
||||
page_id: survey_employee_page_0
|
||||
- |
|
||||
I Create "Male" answer in question "What is your gender?"
|
||||
-
|
||||
!record {model: 'survey.answer', id: survey_p_1_1}:
|
||||
answer: 'Male'
|
||||
sequence: 1
|
||||
question_id : survey_p_question_1
|
||||
- |
|
||||
I Create "Female" answer in question "What is your gender?"
|
||||
-
|
||||
!record {model: 'survey.answer', id: survey_p_1_2}:
|
||||
answer: 'Female'
|
||||
sequence: 2
|
||||
question_id : survey_p_question_1
|
||||
|
||||
- |
|
||||
Now Survey set in open state.
|
||||
-
|
||||
!python {model: survey}: |
|
||||
self.survey_open(cr, uid, [ref("survey_0")], context)
|
||||
|
||||
- |
|
||||
I creating a Evaluation plan and select "Employee Evaluation" survey for "Send to Subordinates" and "Final interview with Manager" Phase.
|
||||
-
|
||||
!record {model: hr_evaluation.plan, id: hr_evaluation_plan_managersplan0}:
|
||||
company_id: base.main_company
|
||||
month_first: 3
|
||||
month_next: 6
|
||||
name: Manager's Plan
|
||||
phase_ids:
|
||||
- action: bottom-up
|
||||
name: Send to Subordinates
|
||||
survey_id: 'survey_0'
|
||||
- action: top-down
|
||||
name: Final Interview with manager
|
||||
sequence: 2
|
||||
survey_id: 'survey_0'
|
||||
|
||||
- |
|
||||
Now I create Evaluation for "Phil Graves" Employee under "Manager Evaluation Plan".
|
||||
-
|
||||
!record {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
|
||||
date: '2010-06-28'
|
||||
employee_id: 'hr_employee_employee1'
|
||||
plan_id: 'hr_evaluation_plan_managersplan0'
|
||||
progress: 0.0
|
||||
state: draft
|
||||
- |
|
||||
I check that Evaluation is in "Draft" state.
|
||||
-
|
||||
!assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
|
||||
- state == 'draft'
|
||||
- |
|
||||
I start Evaluation process by click on "Start Evaluation" button.
|
||||
-
|
||||
!python {model: hr_evaluation.evaluation}: |
|
||||
self.button_plan_in_progress(cr, uid, [ref('hr_evaluation_evaluation_0')])
|
||||
|
||||
- |
|
||||
After that Manager Evaluation plan is In Progress.
|
||||
I close this servey request by giving answer of survey question.
|
||||
-
|
||||
!python {model: hr.evaluation.interview}: |
|
||||
self.survey_req_done(cr, uid, [ref('hr_evaluation_evaluation_0')])
|
||||
- |
|
||||
I click on "Final Validation" button to finalize Evaluation.
|
||||
-
|
||||
!python {model: hr_evaluation.evaluation}: |
|
||||
self.button_final_validation(cr, uid, [ref("hr_evaluation.hr_evaluation_evaluation_0")],
|
||||
{"active_ids": [ref("hr_evaluation.menu_open_view_hr_evaluation_tree")]})
|
||||
|
||||
- |
|
||||
I check that state is "Final Validation".
|
||||
-
|
||||
!assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
|
||||
- state == 'progress'
|
||||
- |
|
||||
Give Rating "Meet expectations" by selecting overall Rating.
|
||||
-
|
||||
!record {model: hr_evaluation.evaluation, id: hr_evaluation.hr_evaluation_evaluation_0}:
|
||||
rating: '2'
|
||||
|
||||
- |
|
||||
I close this Evaluation by click on "Done" button of this wizard.
|
||||
-
|
||||
!python {model: hr_evaluation.evaluation}: |
|
||||
self.button_done(cr, uid, [ref("hr_evaluation.hr_evaluation_evaluation_0")], {"active_ids": [ref("hr_evaluation.menu_open_view_hr_evaluation_tree")]})
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
- |
|
||||
In order to test the hr_holiday in OpenERP, I will Manage leaves for employee,
|
||||
Leave requests.
|
||||
In order to test the hr_holiday in OpenERP, I will Allocate leaves for Employee and manage leaves and leaves requests.
|
||||
- |
|
||||
For that First I create new user "user1" to make leave request.
|
||||
-
|
||||
|
@ -15,7 +14,7 @@
|
|||
name: user1
|
||||
password: user1
|
||||
- |
|
||||
Now, I create a new employee “Mark Johnshon” as Manager to validate employee leave.
|
||||
I create a new employee “Mark Johnshon” as Manager to validate employee leave.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
address_home_id: base.res_partner_address_1
|
||||
|
@ -24,11 +23,11 @@
|
|||
name: Mark Johnson
|
||||
user_id: base.user_root
|
||||
- |
|
||||
create another employee "Brijesh Patel" as "user1" who make leave request.
|
||||
Create another employee "Phil Graves" as "user1" who make leave request.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_brijeshpatel0}:
|
||||
!record {model: hr.employee, id: hr_employee_philgraves0}:
|
||||
address_home_id: base.res_partner_address_8
|
||||
name: Brijesh Patel
|
||||
name: Phil Graves
|
||||
parent_id: 'hr_employee_employee0'
|
||||
user_id: 'res_users_user0'
|
||||
- |
|
||||
|
@ -40,11 +39,11 @@
|
|||
limit: 1
|
||||
|
||||
- |
|
||||
After that I allocate leave request for employee "Brijesh Patel".
|
||||
After that I allocate leave request for employee "Phil Graves".
|
||||
-
|
||||
!record {model: hr.holidays, id: hr_holidays_allocateleaveforuser0}:
|
||||
allocation_type: employee
|
||||
employee_id: 'hr_employee_brijeshpatel0'
|
||||
employee_id: 'hr_employee_philgraves0'
|
||||
holiday_status_id: hr_holidays_status_fullleave0
|
||||
name: Allocate leave for user1
|
||||
number_of_days_temp: 12.0
|
||||
|
@ -62,13 +61,13 @@
|
|||
!workflow {model: hr.holidays, action: validate, ref: hr_holidays_allocateleaveforuser0}
|
||||
|
||||
- |
|
||||
Now employee "Brijesh Patel" want to leave. so, I connect as user1 which is username of this employee and want to make leave request.
|
||||
Now employee "Phil Graves" want to leave. so, I connect as user1 which is username of this employee and want to make leave request.
|
||||
-
|
||||
!record {model: hr.holidays, id: hr_holidays_iwanttoleaveforgotohospital0}:
|
||||
allocation_type: employee
|
||||
date_from: '2010-05-20 11:48:00'
|
||||
date_to: '2010-05-21 11:48:00'
|
||||
employee_id: 'hr_employee_brijeshpatel0'
|
||||
employee_id: 'hr_employee_philgraves0'
|
||||
holiday_status_id: 'hr_holidays_status_fullleave0'
|
||||
name: I want to leave for go to hospital
|
||||
notes: I want to leave for go to hospital. so please accept my leave.
|
||||
|
@ -82,12 +81,12 @@
|
|||
- state == 'draft'
|
||||
|
||||
- |
|
||||
Now I confirm my leave Request by click on "Confirm" button.
|
||||
I confirm my leave Request by click on "Confirm" button.
|
||||
-
|
||||
!workflow {model: hr.holidays, action: confirm, ref: hr_holidays_iwanttoleaveforgotohospital0}
|
||||
|
||||
- |
|
||||
Now I connect as Admin user and Open Leave request of "Brijesh Patel".
|
||||
I connect as Admin user and Open Leave request of "Phil Graves".
|
||||
and "validate" it by click on "validate" button.
|
||||
-
|
||||
!workflow {model: hr.holidays, action: validate, ref: hr_holidays_iwanttoleaveforgotohospital0}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
- |
|
||||
In order to test hr_recruitment module for OpenERP object, I create applicants form and Manages job positions and the recruitement process.
|
||||
In order to test hr_recruitment module for OpenERP, I will create applicants form, Manages job positions and the recruitement process.
|
||||
- |
|
||||
I create job possition for employee to manage job position.
|
||||
I create job position for employee to manage job position.
|
||||
-
|
||||
|
|
||||
First I create Department "R & D" in Department form for which I make recruitment.
|
||||
For that First I create Department "R & D" in Department form for which I make recruitment.
|
||||
-
|
||||
!record {model: hr.department, id: hr_department_rd0}:
|
||||
manager_id: base.user_root
|
||||
|
|
|
@ -51,6 +51,7 @@ to set up a management by affair.
|
|||
|
||||
],
|
||||
'demo_xml': ['hr_timesheet_demo.xml'],
|
||||
'test': ['test/test_hr_timesheet.yml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0071405533469',
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
- |
|
||||
In order to test hr_timesheet Module in OpenERP, I make "Sign In or Sign Out for Project" to encode and
|
||||
track time spent on the different projects.
|
||||
|
||||
- |
|
||||
Now, I create a new employee “Mark Johnson” to test Timesheet.
|
||||
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
address_home_id: base.res_partner_address_1
|
||||
company_id: base.main_company
|
||||
gender: male
|
||||
marital: hr.hr_employee_marital_status_single
|
||||
name: Mark Johnson
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
I start by "Sign In/Sign Out by Project" wizard and click on "Sign In/Sign Out" button of this wizard.
|
||||
-
|
||||
!python {model: hr.sign.in.project}: |
|
||||
self.check_state(cr, uid, [ref("hr_employee_employee0")])
|
||||
- |
|
||||
I select start date and Perform start work on project.
|
||||
-
|
||||
!record {model: hr.sign.in.project, id: hr_employee_employee0}:
|
||||
name: employee1
|
||||
server_date: '2010-05-20 16:10:59'
|
||||
state: absent
|
||||
- |
|
||||
I click on "Start Working" button of this wizard to start work on Project.
|
||||
-
|
||||
!python {model: hr.sign.in.project}: |
|
||||
self.sign_in_result(cr, uid, [ref("hr_employee_employee0")], context)
|
||||
- |
|
||||
My work is done and I want to stop work.for that I click on "Sign In/Sign Out" button of "Sign In/Sign Out by Project" wizard.
|
||||
Which check state in hr attendace form for user.
|
||||
-
|
||||
!python {model: hr.sign.in.project}: |
|
||||
obj_attendance = self.pool.get('hr.employee')
|
||||
emp_id = obj_attendance.search(cr, uid, [('user_id', '=', uid), ('name', '=', "employee1")])
|
||||
if emp_id:
|
||||
employee = obj_attendance.read(cr, uid, emp_id)[0]
|
||||
self.write(cr, uid, [ref('hr_employee_employee0')], {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]})
|
||||
self.check_state(cr, uid, [ref("hr_employee_employee0")], {"active_ids": [ref("hr_timesheet.menu_hr_timesheet_sign_in")]
|
||||
})
|
||||
|
||||
- |
|
||||
Given that I have product for "Consultancy - Senior Developer".
|
||||
|
||||
-
|
||||
!record {model: product.product, id: product_consultant}:
|
||||
categ_id: product.product_category_10
|
||||
default_code: DEV
|
||||
list_price: 75.0
|
||||
name: Consultancy - Senior Developer
|
||||
procure_method: make_to_order
|
||||
purchase_ok: False
|
||||
standard_price: 30.0
|
||||
supply_method: produce
|
||||
type: service
|
||||
uom_id: product.uom_hour
|
||||
uom_po_id: product.uom_hour
|
||||
|
||||
- |
|
||||
I assing product and journal to "Mark Johnson"
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
journal_id: analytic_journal
|
||||
product_id: product_consultant
|
||||
|
||||
- |
|
||||
This will Open "hr sign out project" form. I select analytical project2 development account.
|
||||
-
|
||||
!record {model: hr.sign.out.project, id: hr_employee_employee0}:
|
||||
account_id: account.analytic_project_2_development
|
||||
analytic_amount: 7.0
|
||||
date: '2010-05-21 16:40:00'
|
||||
date_start: '2010-05-19 16:37:00'
|
||||
info: Create Yaml for hr module
|
||||
name: Mark Johnson
|
||||
server_date: '2010-05-19 16:40:15'
|
||||
state: present
|
||||
|
||||
- |
|
||||
My work for this project is over and I stop work by click on "Stop Work" button of this wizard.
|
||||
-
|
||||
!python {model: hr.sign.out.project}: |
|
||||
emp_obj = self.pool.get('hr.employee')
|
||||
emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid), ('name', '=', 'employee1')])
|
||||
if emp_id:
|
||||
employee = emp_obj.read(cr, uid, emp_id)[0]
|
||||
self.write(cr, uid, [ref('hr_employee_employee0')], {'emp_id': emp_id[0] })
|
||||
#self.sign_out_result(cr, uid, [ref('hr_employee_employee0')])
|
||||
|
||||
- |
|
||||
I can see employee timesheet for particular month using "Employee Timesheet" report.
|
|
@ -45,7 +45,9 @@ reports, eso.""",
|
|||
'wizard/hr_timesheet_invoice_create_final_view.xml',
|
||||
'board_hr_timesheet_invoice.xml',
|
||||
],
|
||||
'demo_xml': ['hr_timesheet_invoice_demo.xml'],
|
||||
'demo_xml': ['hr_timesheet_invoice_demo.xml',
|
||||
],
|
||||
'test': ['test/test_hr_timesheet_invoice.yml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0056091842381',
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
- |
|
||||
In order to test hr_timesheet_invoice in OpenERP, I create account line to manage invoice based on costs.
|
||||
- |
|
||||
In order to test flow, I create analytic line for sednacom analytic account.
|
||||
-
|
||||
!record {model: account.analytic.line, id: account_analytic_line_developyamlforhrmodule0}:
|
||||
account_id: account.analytic_sednacom
|
||||
amount: -1.0
|
||||
company_id: base.main_company
|
||||
date: '2010-05-30'
|
||||
general_account_id: account.a_expense
|
||||
journal_id: hr_timesheet.analytic_journal
|
||||
name: develop yaml for hr module
|
||||
product_id: hr_timesheet.product_consultant
|
||||
product_uom_id: product.uom_hour
|
||||
to_invoice: hr_timesheet_invoice.timesheet_invoice_factor2
|
||||
unit_amount: 5.00
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
Give partner name and price list in analytic account.
|
||||
-
|
||||
!record {model: account.analytic.account, id: account.analytic_sednacom}:
|
||||
partner_id: base.res_partner_9
|
||||
pricelist_id: product.list0
|
||||
|
||||
- |
|
||||
I create invoice on analytic Line using "Invoice analytic Line" wizard.
|
||||
Give date , detail of each work , time spend on that work on this wizard.
|
||||
-
|
||||
!record {model: hr.timesheet.invoice.create, id: hr_timesheet_invoice_create_0}:
|
||||
accounts:
|
||||
- account.analytic_sednacom
|
||||
date: 1
|
||||
name: 1
|
||||
price: 1
|
||||
product: hr_timesheet.product_consultant
|
||||
time: 1
|
||||
|
||||
- |
|
||||
I click on "Create Invoice" button of "Invoice analytic Line" wizard to create invoice.
|
||||
-
|
||||
!python {model: hr.timesheet.invoice.create}: |
|
||||
self.do_create(cr, uid, [ref("hr_timesheet_invoice_create_0")], {"active_ids": [ref("hr_timesheet_invoice.account_analytic_line_developyamlforhrmodule0")]})
|
||||
|
||||
- |
|
||||
I check that Invoice is create for this timesheet.
|
||||
-
|
||||
!python {model: account.analytic.line}: |
|
||||
exp = self.browse(cr, uid, [ref('account_analytic_line_developyamlforhrmodule0')])[0]
|
||||
|
||||
analytic_account_obj = self.pool.get('account.analytic.account')
|
||||
|
||||
data = self.pool.get('hr.timesheet.invoice.create').read(cr, uid, [ref("hr_timesheet_invoice_create_0")], [], context)[0]
|
||||
|
||||
account_ids = data['accounts']
|
||||
for account in analytic_account_obj.browse(cr, uid, account_ids, context):
|
||||
partner = account.partner_id.id
|
||||
|
||||
invoice_obj = self.pool.get('account.invoice')
|
||||
invoice_ids = invoice_obj.search(cr, uid, [('partner_id', '=', partner)])
|
||||
invoice_id = invoice_obj.browse(cr, uid, invoice_ids)[0]
|
||||
|
||||
for invoice in invoice_id.invoice_line:
|
||||
product = invoice.product_id.id
|
||||
|
||||
product_exp = data['product']
|
||||
|
||||
assert product == product_exp
|
||||
- |
|
||||
I creating a final invoice for "Sednacom" analytic account.
|
||||
-
|
||||
!record {model: hr.timesheet.invoice.create.final, id: hr_timesheet_invoice_create_final_0}:
|
||||
balance_product: hr_timesheet.product_consultant
|
||||
date: 1
|
||||
name: 1
|
||||
price: 1
|
||||
time: 1
|
||||
- |
|
||||
I click on "Create Invoice" button to create Invoice.
|
||||
-
|
||||
!python {model: hr.timesheet.invoice.create.final}: |
|
||||
self.do_create(cr, uid, [ref("hr_timesheet_invoice_create_final_0")], {"active_ids": [ref("account.analytic_sednacom")]})
|
||||
|
||||
|
||||
- |
|
||||
I can also make some theoretical revenue reports.
|
||||
- |
|
||||
I can also see timesheet profit using Timesheet profit report.
|
|
@ -71,8 +71,8 @@ class hr_timesheet_invoice_create(osv.osv_memory):
|
|||
|
||||
result = mod_obj._get_id(cr, uid, 'account', 'view_account_invoice_filter')
|
||||
res = mod_obj.read(cr, uid, result, ['res_id'])
|
||||
|
||||
data = self.read(cr, uid, ids, [], context)[0]
|
||||
|
||||
account_ids = data['accounts']
|
||||
for account in analytic_account_obj.browse(cr, uid, account_ids, context):
|
||||
partner = account.partner_id
|
||||
|
@ -119,11 +119,11 @@ class hr_timesheet_invoice_create(osv.osv_memory):
|
|||
"GROUP BY product_id,to_invoice", (account.id,context['active_ids'],))
|
||||
|
||||
for product_id,factor_id,qty in cr.fetchall():
|
||||
product = pool.get('product.product').browse(cr, uid, product_id, context2)
|
||||
product = self.pool.get('product.product').browse(cr, uid, product_id, context2)
|
||||
if not product:
|
||||
raise osv.except_osv(_('Error'), _('At least one line has no product !'))
|
||||
factor_name = ''
|
||||
factor = pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context2)
|
||||
factor = self.pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context2)
|
||||
|
||||
if not data['product']:
|
||||
if factor.customer_name:
|
||||
|
@ -131,16 +131,16 @@ class hr_timesheet_invoice_create(osv.osv_memory):
|
|||
else:
|
||||
factor_name = product.name
|
||||
else:
|
||||
factor_name = pool.get('product.product').name_get(cr, uid, [data['product']], context=context)[0][1]
|
||||
factor_name = self.pool.get('product.product').name_get(cr, uid, [data['product']], context=context)[0][1]
|
||||
|
||||
if account.pricelist_id:
|
||||
pl = account.pricelist_id.id
|
||||
price = pool.get('product.pricelist').price_get(cr,uid,[pl], data['product'] or product_id, qty or 1.0, account.partner_id.id)[pl]
|
||||
price = self.pool.get('product.pricelist').price_get(cr,uid,[pl], data['product'] or product_id, qty or 1.0, account.partner_id.id)[pl]
|
||||
else:
|
||||
price = 0.0
|
||||
|
||||
taxes = product.taxes_id
|
||||
tax = pool.get('account.fiscal.position').map_tax(cr, uid, account.partner_id.property_account_position, taxes)
|
||||
tax = self.pool.get('account.fiscal.position').map_tax(cr, uid, account.partner_id.property_account_position, taxes)
|
||||
account_id = product.product_tmpl_id.property_account_income.id or product.categ_id.property_account_income_categ.id
|
||||
curr_line = {
|
||||
'price_unit': price,
|
||||
|
@ -159,7 +159,7 @@ class hr_timesheet_invoice_create(osv.osv_memory):
|
|||
#
|
||||
# Compute for lines
|
||||
#
|
||||
cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id = ANY (%s) AND product_id=%s and to_invoice=%s", (account.id, data['ids'], product_id, factor_id))
|
||||
cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id = %s AND product_id=%s and to_invoice=%s", (account.id, data['id'], product_id, factor_id))
|
||||
|
||||
line_ids = cr.dictfetchall()
|
||||
note = []
|
||||
|
@ -170,7 +170,7 @@ class hr_timesheet_invoice_create(osv.osv_memory):
|
|||
details.append(line['date'])
|
||||
if data['time']:
|
||||
if line['product_uom_id']:
|
||||
details.append("%s %s" % (line['unit_amount'], pool.get('product.uom').browse(cr, uid, [line['product_uom_id']])[0].name))
|
||||
details.append("%s %s" % (line['unit_amount'], self.pool.get('product.uom').browse(cr, uid, [line['product_uom_id']])[0].name))
|
||||
else:
|
||||
details.append("%s" % (line['unit_amount'], ))
|
||||
if data['name']:
|
||||
|
@ -180,8 +180,8 @@ class hr_timesheet_invoice_create(osv.osv_memory):
|
|||
note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
|
||||
|
||||
curr_line['note'] = "\n".join(map(lambda x: unicode(x) or '',note))
|
||||
pool.get('account.invoice.line').create(cr, uid, curr_line)
|
||||
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id =ANY(%s)" ,(last_invoice, account.id,data['ids']))
|
||||
self.pool.get('account.invoice.line').create(cr, uid, curr_line)
|
||||
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id =%s" ,(last_invoice, account.id,data['id']))
|
||||
|
||||
self.pool.get('account.invoice').button_reset_taxes(cr, uid, [last_invoice], context)
|
||||
|
||||
|
|
|
@ -56,7 +56,10 @@ The validation can be configured in the company:
|
|||
'report/timesheet_report_view.xml',
|
||||
'board_hr_timesheet_view.xml',
|
||||
],
|
||||
'demo_xml': ['hr_timesheet_sheet_demo.xml'],
|
||||
'demo_xml': ['hr_timesheet_sheet_demo.xml',
|
||||
|
||||
],
|
||||
'test':['test/test_hr_timesheet_sheet.yml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0073297700829',
|
||||
|
|
|
@ -151,13 +151,16 @@ class hr_timesheet_sheet(osv.osv):
|
|||
raise osv.except_osv(_('Error !'), _('You can not duplicate a timesheet !'))
|
||||
|
||||
def button_confirm(self, cr, uid, ids, context=None):
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
for sheet in self.browse(cr, uid, ids, context=context):
|
||||
di = sheet.user_id.company_id.timesheet_max_difference
|
||||
|
||||
if (abs(sheet.total_difference) < di) or not di:
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, 'hr_timesheet_sheet.sheet', sheet.id, 'confirm', cr)
|
||||
|
||||
else:
|
||||
raise osv.except_osv(_('Warning !'), _('Please verify that the total difference of the sheet is lower than %.2f !') %(di,))
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
- |
|
||||
In order, to test hr_timesheet_sheet module in OpenERP, I create timesheet and check validation process done by
|
||||
manager.
|
||||
|
||||
- |
|
||||
Now, I create a new employee “Mark Johnson” to test Timesheet.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
address_home_id: base.res_partner_address_1
|
||||
company_id: base.main_company
|
||||
gender: male
|
||||
marital: hr.hr_employee_marital_status_single
|
||||
name: Mark Johnson
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
I create new user "user1".
|
||||
-
|
||||
!record {model: res.users, id: res_users_user0}:
|
||||
company_id: base.main_company
|
||||
context_lang: en_US
|
||||
groups_id:
|
||||
- hr.group_hr_user
|
||||
- hr_attendance.group_hr_attendance
|
||||
- base.group_user
|
||||
- base.group_extended
|
||||
- hr.group_hr_manager
|
||||
login: user1
|
||||
name: user1
|
||||
password: user1
|
||||
|
||||
- |
|
||||
create another employee "Francline" as "user1".
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_fracline0}:
|
||||
address_home_id: base.res_partner_address_8
|
||||
name: Francline
|
||||
parent_id: 'hr_employee_employee0'
|
||||
user_id: 'res_users_user0'
|
||||
|
||||
- |
|
||||
Given that I have Timesheet journal for employee.
|
||||
|
||||
-
|
||||
!record {model: account.analytic.journal, id: analytic_journal}:
|
||||
code: TS
|
||||
name: Timesheet Journal
|
||||
type: general
|
||||
|
||||
- |
|
||||
Given that I have product for "Consultancy - Senior Developer".
|
||||
-
|
||||
!record {model: product.product, id: product_consultant}:
|
||||
categ_id: product.product_category_10
|
||||
default_code: DEV
|
||||
list_price: 75.0
|
||||
name: Consultancy - Senior Developer
|
||||
procure_method: make_to_order
|
||||
purchase_ok: False
|
||||
standard_price: 30.0
|
||||
supply_method: produce
|
||||
type: service
|
||||
uom_id: product.uom_hour
|
||||
uom_po_id: product.uom_hour
|
||||
|
||||
- |
|
||||
I assing product and journal to "Mark Johnson"
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_employee0}:
|
||||
product_id: product_consultant
|
||||
journal_id: analytic_journal
|
||||
- |
|
||||
And also assing product and journal to "francline" employee.
|
||||
-
|
||||
!record {model: hr.employee, id: hr_employee_fracline0}:
|
||||
product_id: product_consultant
|
||||
journal_id: analytic_journal
|
||||
|
||||
- |
|
||||
I connect as "francline" and create my current timesheet.
|
||||
-
|
||||
!record {model: hr_timesheet_sheet.sheet, id: hr_timesheet_sheet_sheet_deddk0}:
|
||||
date_current: '2010-05-26'
|
||||
date_from: '2010-05-01'
|
||||
date_to: '2010-05-31'
|
||||
name: Week-22(2010)
|
||||
state: new
|
||||
user_id: 'res_users_user0'
|
||||
- |
|
||||
Now , When I came in office , I create Attendances and perform "Sign In" action with proper reason.
|
||||
-
|
||||
!record {model: hr.attendance, id: hr_attendance_0}:
|
||||
action: sign_in
|
||||
employee_id: 'hr_employee_fracline0'
|
||||
name: '2010-05-26 10:08:08'
|
||||
|
||||
- |
|
||||
When I left office , I create attendance and perform "Sign Out".
|
||||
-
|
||||
!record {model: hr.attendance, id: hr_attendance_1}:
|
||||
action: sign_out
|
||||
employee_id: 'hr_employee_fracline0'
|
||||
name: '2010-05-26 15:10:55'
|
||||
|
||||
-
|
||||
I create Timesheet Entry for time spend on today work.
|
||||
-
|
||||
|
||||
!record {model: hr_timesheet_sheet.sheet, id: hr_timesheet_sheet.sheet1}:
|
||||
timesheet_ids:
|
||||
- account_id: account.analytic_sednacom
|
||||
date: '05/26/2010'
|
||||
name: 'Develop yaml for hr module'
|
||||
unit_amount: 5.00
|
||||
amount: -90.00
|
||||
product_id: hr_timesheet.product_consultant
|
||||
general_account_id: account.a_expense
|
||||
user_id: res_users_user0
|
||||
journal_id: hr_timesheet.analytic_journal
|
||||
|
||||
- |
|
||||
I confirm my timesheet at end of period by click on "Confirm" button which is signal of workflow.
|
||||
-
|
||||
!python {model: hr_timesheet_sheet.sheet}: |
|
||||
uid = ref('res_users_user0')
|
||||
self.button_confirm(cr, uid, [ref('hr_timesheet_sheet_sheet_deddk0')])
|
||||
- |
|
||||
I check that state is "Confirmed".
|
||||
-
|
||||
!assert {model: hr_timesheet_sheet.sheet, id: hr_timesheet_sheet_sheet_deddk0}:
|
||||
- state == 'confirm'
|
||||
- |
|
||||
"Mark Johnson" check timesheet and time spend on project by "francline" employee.
|
||||
And then accept it request by click on "Accept" button.
|
||||
If "Maximal difference between timesheet and attendances" is more than 1 then manage can "Refuse" his request.
|
||||
-
|
||||
!python {model: hr_timesheet_sheet.sheet}: |
|
||||
#self.write(cr, uid, [ref('hr_timesheet_sheet_sheet_deddk0')], {'state': 'done'})
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
<group colspan="8">
|
||||
<field name="marketing_campaign" />
|
||||
<field name="crm_profiling" />
|
||||
<field name="marketing_campaign_mailchimp" />
|
||||
</group>
|
||||
</data>
|
||||
</field>
|
||||
|
|
|
@ -28,6 +28,8 @@ class marketing_installer(osv.osv_memory):
|
|||
# Generic modules
|
||||
'marketing_campaign':fields.boolean('Marketing Campaigns',
|
||||
help="Helps you to manage marketing campaigns and automate actions and communication steps."),
|
||||
'marketing_campaign_mailchimp':fields.boolean('Mailchimp Integration',
|
||||
help="This modules integrate mailchimp.com's service with OpenERP to automate mass mailings."),
|
||||
'crm_profiling':fields.boolean('Profiling Tools',
|
||||
help="Helps you to perform segmentation within partners and design questionaires.")
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ from dateutil.relativedelta import relativedelta
|
|||
|
||||
from osv import fields, osv
|
||||
import netsvc
|
||||
import tools
|
||||
import tools
|
||||
|
||||
_intervalTypes = {
|
||||
'hours': lambda interval: relativedelta(hours=interval),
|
||||
|
@ -37,10 +37,10 @@ _intervalTypes = {
|
|||
class marketing_campaign(osv.osv): #{{{
|
||||
_name = "marketing.campaign"
|
||||
_description = "Marketing Campaign"
|
||||
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'object_id': fields.many2one('ir.model', 'Objects', required=True,
|
||||
'object_id': fields.many2one('ir.model', 'Object', required=True,
|
||||
help="Choose the Object on which you want \
|
||||
this campaign to be run"),
|
||||
'mode':fields.selection([('test', 'Test'),
|
||||
|
@ -52,17 +52,15 @@ class marketing_campaign(osv.osv): #{{{
|
|||
('running', 'Running'),
|
||||
('done', 'Done'),
|
||||
('cancelled', 'Cancelled'),],
|
||||
'State',),
|
||||
'activity_ids': fields.one2many('marketing.campaign.activity',
|
||||
'State',),
|
||||
'activity_ids': fields.one2many('marketing.campaign.activity',
|
||||
'campaign_id', 'Activities'),
|
||||
'fixed_cost': fields.float('Fixed Cost', help="The fixed cost is cost\
|
||||
you required for the campaign"),
|
||||
|
||||
you required for the campaign"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': lambda *a: 'draft',
|
||||
'mode': lambda *a: 'test',
|
||||
'mode': lambda *a: 'test',
|
||||
}
|
||||
|
||||
def state_running_set(self, cr, uid, ids, *args):
|
||||
|
@ -79,16 +77,16 @@ class marketing_campaign(osv.osv): #{{{
|
|||
('state', '=', 'draft')])
|
||||
self.write(cr, uid, ids, {'state': 'running'})
|
||||
return True
|
||||
|
||||
|
||||
def state_done_set(self, cr, uid, ids, *args):
|
||||
segment_ids = self.pool.get('marketing.campaign.segment').search(cr, uid,
|
||||
[('campaign_id', 'in', ids),
|
||||
('state', '=', 'running')])
|
||||
if segment_ids :
|
||||
raise osv.except_osv("Error", "Camapign cannot be done before all segments are done")
|
||||
raise osv.except_osv("Error", "Camapign cannot be done before all segments are done")
|
||||
self.write(cr, uid, ids, {'state': 'done'})
|
||||
return True
|
||||
|
||||
|
||||
def state_cancel_set(self, cr, uid, ids, *args):
|
||||
self.write(cr, uid, ids, {'state': 'cancelled'})
|
||||
return True
|
||||
|
@ -100,7 +98,7 @@ class marketing_campaign_segment(osv.osv): #{{{
|
|||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64,required=True),
|
||||
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
|
||||
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
|
||||
required=True),
|
||||
'object_id': fields.related('campaign_id','object_id',
|
||||
type='many2one', relation='ir.model',
|
||||
|
@ -114,22 +112,22 @@ class marketing_campaign_segment(osv.osv): #{{{
|
|||
('running', 'Running'),
|
||||
('done', 'Done'),
|
||||
('cancelled', 'Cancelled')],
|
||||
'State',),
|
||||
'State',),
|
||||
'date_run': fields.datetime('Running'),
|
||||
'date_done': fields.datetime('Done'),
|
||||
}
|
||||
|
||||
|
||||
_defaults = {
|
||||
'state': lambda *a: 'draft',
|
||||
'sync_mode': lambda *a: 'create_date',
|
||||
}
|
||||
|
||||
|
||||
def state_running_set(self, cr, uid, ids, *args):
|
||||
segment = self.browse(cr, uid, ids[0])
|
||||
curr_date = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
vals = {'state': 'running'}
|
||||
if not segment.date_run:
|
||||
vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if not segment.sync_last_date:
|
||||
vals['sync_last_date']=curr_date
|
||||
if not segment.date_done:
|
||||
|
@ -137,9 +135,9 @@ class marketing_campaign_segment(osv.osv): #{{{
|
|||
).strftime('%Y-%m-%d %H:%M:%S')
|
||||
self.write(cr, uid, ids, vals)
|
||||
return True
|
||||
|
||||
|
||||
def state_done_set(self, cr, uid, ids, *args):
|
||||
date_done = self.browse(cr, uid, ids[0]).date_done
|
||||
date_done = self.browse(cr, uid, ids[0]).date_done
|
||||
if (date_done > time.strftime('%Y-%m-%d %H:%M:%S')):
|
||||
raise osv.except_osv("Error", "Segment cannot be closed before end date")
|
||||
|
||||
|
@ -147,21 +145,21 @@ class marketing_campaign_segment(osv.osv): #{{{
|
|||
[('state', 'in', ['inprogress', 'todo']),
|
||||
('segment_id', '=', ids[0])])
|
||||
if wi_ids :
|
||||
raise osv.except_osv("Error", "Segment cannot be done before all workitems are processed")
|
||||
raise osv.except_osv("Error", "Segment cannot be done before all workitems are processed")
|
||||
self.write(cr, uid, ids, {'state': 'done'})
|
||||
return True
|
||||
|
||||
|
||||
def state_cancel_set(self, cr, uid, ids, *args):
|
||||
self.write(cr, uid, ids, {'state': 'cancelled'})
|
||||
return True
|
||||
|
||||
|
||||
def process_segment(self, cr, uid, context={}):
|
||||
segment_ids = self.search(cr, uid, [('state', '=', 'running')])
|
||||
action_date = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
last_action_date = (datetime.now() + _intervalTypes['days'](-1) \
|
||||
).strftime('%Y-%m-%d %H:%M:%S')
|
||||
for segment in self.browse(cr, uid, segment_ids):
|
||||
act_ids = self.pool.get('marketing.campaign.activity').search(cr,
|
||||
act_ids = self.pool.get('marketing.campaign.activity').search(cr,
|
||||
uid, [('start', '=', True),
|
||||
('campaign_id', '=', segment.campaign_id.id)])
|
||||
if (segment.sync_last_date and \
|
||||
|
@ -195,23 +193,23 @@ class marketing_campaign_activity(osv.osv): #{{{
|
|||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128, required=True),
|
||||
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
|
||||
'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
|
||||
required = True, ondelete='cascade'),
|
||||
'object_id': fields.related('campaign_id','object_id',
|
||||
type='many2one', relation='ir.model',
|
||||
string='Object'),
|
||||
'start': fields.boolean('Start',help= "Its necessary to start activity \
|
||||
before running campaign"),
|
||||
'condition': fields.char('Condition', size=256, required=True,
|
||||
'condition': fields.char('Condition', size=256, required=True,
|
||||
help="Condition that is to be tested before \
|
||||
action is executed"),
|
||||
action is executed"),
|
||||
'type': fields.selection([('email', 'E-mail'),
|
||||
('paper', 'Paper'),
|
||||
('action', 'Action'),
|
||||
('subcampaign', 'Sub-Campaign')],
|
||||
'Type', required=True),
|
||||
'email_template_id': fields.many2one('email.template','Email Template'),
|
||||
'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
|
||||
'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
|
||||
'report_directory_id': fields.many2one('document.directory','Directory',
|
||||
help="Folder is used to store the generated reports"),
|
||||
'server_action_id': fields.many2one('ir.actions.server', string='Action',
|
||||
|
@ -222,7 +220,7 @@ class marketing_campaign_activity(osv.osv): #{{{
|
|||
'Next Activities'),
|
||||
'from_ids': fields.one2many('marketing.campaign.transition',
|
||||
'activity_to_id',
|
||||
'Previous Activities'),
|
||||
'Previous Activities'),
|
||||
'subcampaign_id': fields.many2one('marketing.campaign', 'Sub-Campaign'),
|
||||
'subcampaign_segment_id': fields.many2one('marketing.campaign.segment',
|
||||
'Sub Campaign Segment'),
|
||||
|
@ -236,7 +234,7 @@ class marketing_campaign_activity(osv.osv): #{{{
|
|||
'object_id' : lambda obj, cr, uid, context : context.get('object_id',False),
|
||||
}
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=None, order=None,
|
||||
def search(self, cr, uid, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
if context == None:
|
||||
context = {}
|
||||
|
@ -247,14 +245,14 @@ class marketing_campaign_activity(osv.osv): #{{{
|
|||
for activity in segment_obj.campaign_id.activity_ids:
|
||||
act_ids.append(activity.id)
|
||||
return act_ids
|
||||
return super(marketing_campaign_activity, self).search(cr, uid, args,
|
||||
return super(marketing_campaign_activity, self).search(cr, uid, args,
|
||||
offset, limit, order, context, count)
|
||||
|
||||
def process(self, cr, uid, act_id, wi_id, context={}):
|
||||
activity = self.browse(cr, uid, act_id)
|
||||
workitem_obj = self.pool.get('marketing.campaign.workitem')
|
||||
workitem = workitem_obj.browse(cr, uid, wi_id)
|
||||
|
||||
|
||||
if activity.type == 'paper' :
|
||||
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
|
||||
(report_data, format) = service.create(cr, uid, [], {}, {})
|
||||
|
@ -298,7 +296,7 @@ class marketing_campaign_activity(osv.osv): #{{{
|
|||
server_obj = self.pool.get('ir.actions.server')
|
||||
server_obj.run(cr, uid, [activity.server_action_id.id], context)
|
||||
#???
|
||||
return True
|
||||
return True
|
||||
marketing_campaign_activity()#}}}
|
||||
|
||||
class marketing_campaign_transition(osv.osv): #{{{
|
||||
|
@ -309,10 +307,10 @@ class marketing_campaign_transition(osv.osv): #{{{
|
|||
_columns = {
|
||||
'activity_from_id': fields.many2one('marketing.campaign.activity',
|
||||
'Source Activity'),
|
||||
'activity_to_id': fields.many2one('marketing.campaign.activity',
|
||||
'activity_to_id': fields.many2one('marketing.campaign.activity',
|
||||
'Destination Activity'),
|
||||
'interval_nbr': fields.integer('Interval No.'),
|
||||
'interval_type': fields.selection([('hours', 'Hours'), ('days', 'Days'),
|
||||
'interval_type': fields.selection([('hours', 'Hours'), ('days', 'Days'),
|
||||
('months', 'Months'),
|
||||
('years','Years')],'Interval Type')
|
||||
}
|
||||
|
@ -323,32 +321,46 @@ class marketing_campaign_transition(osv.osv): #{{{
|
|||
if context.has_key('type_id'):
|
||||
value[context['type_id']] = context['activity_id']
|
||||
return value
|
||||
|
||||
|
||||
marketing_campaign_transition() #}}}
|
||||
|
||||
class marketing_campaign_workitem(osv.osv): #{{{
|
||||
_name = "marketing.campaign.workitem"
|
||||
_description = "Campaign Workitem"
|
||||
|
||||
def _res_name_get(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.res_id:
|
||||
try:
|
||||
res[obj.id] = self.pool.get(obj.object_id.model).name_get(cr, uid, [obj.res_id], context=context)[0][1]
|
||||
except:
|
||||
res[obj.id] = '/'
|
||||
else:
|
||||
res[obj.id] = '/'
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'segment_id': fields.many2one('marketing.campaign.segment', 'Segment',
|
||||
required=True),
|
||||
required=True),
|
||||
'activity_id': fields.many2one('marketing.campaign.activity','Activity',
|
||||
required=True),
|
||||
'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
|
||||
type='many2one', relation='ir.model',
|
||||
string='Object'),
|
||||
'res_id': fields.integer('Results'),
|
||||
required=True),
|
||||
'campaign_id': fields.related('segment_id', 'campaign_id',
|
||||
type='many2one', relation='marketing.campaign', string='Campaign', readonly=True),
|
||||
'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
|
||||
type='many2one', relation='ir.model', string='Object'),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'res_name': fields.function(_res_name_get, method=True, string='Resource Name', type="char", size=64),
|
||||
'date': fields.datetime('Execution Date'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner',required=True),
|
||||
'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
|
||||
'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
|
||||
('exception', 'Exception'), ('done', 'Done'),
|
||||
('cancelled', 'Cancelled')], 'State'),
|
||||
|
||||
'error_msg' : fields.text('Error Message')
|
||||
}
|
||||
}
|
||||
_defaults = {
|
||||
'state': lambda *a: 'draft',
|
||||
'state': lambda *a: 'todo',
|
||||
}
|
||||
|
||||
def process_chain(self, cr, uid, workitem_id, context={}):
|
||||
|
@ -369,11 +381,17 @@ class marketing_campaign_workitem(osv.osv): #{{{
|
|||
'state': 'todo',
|
||||
}
|
||||
self.create(cr, uid, workitem_vals)
|
||||
|
||||
|
||||
def button_cancel(self, cr, uid, workitem_ids, context={}):
|
||||
for wi in self.browse(cr, uid, workitem_ids):
|
||||
if wi.state in ('todo','exception'):
|
||||
self.write(cr, uid, [wi.id], {'state':'cancelled'}, context=context)
|
||||
return True
|
||||
|
||||
def process(self, cr, uid, workitem_ids, context={}):
|
||||
for wi in self.browse(cr, uid, workitem_ids):
|
||||
if wi.state == 'todo':# we searched the wi which are in todo state
|
||||
#then y v keep this filter again
|
||||
if wi.state == 'todo':# we searched the wi which are in todo state
|
||||
#then y v keep this filter again
|
||||
eval_context = {
|
||||
'pool': self.pool,
|
||||
'cr': cr,
|
||||
|
@ -390,45 +408,44 @@ class marketing_campaign_workitem(osv.osv): #{{{
|
|||
if res :
|
||||
self.write(cr, uid, wi.id, {'state': 'done'})
|
||||
self.process_chain(cr, uid, wi.id, context)
|
||||
else :
|
||||
else :
|
||||
self.write(cr, uid, wi.id, {'state': 'exception',
|
||||
'error_msg': res['error_msg']})
|
||||
except Exception,e:
|
||||
self.write(cr, uid, wi.id, {'state': 'exception'})
|
||||
else :
|
||||
self.write(cr, uid, wi.id, {'state': 'cancelled'})
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def process_all(self, cr, uid, context={}):
|
||||
workitem_ids = self.search(cr, uid, [('state', '=', 'todo'),
|
||||
('date','<=', time.strftime('%Y-%m-%d %H:%M:%S'))])
|
||||
if workitem_ids:
|
||||
self.process(cr, uid, workitem_ids, context)
|
||||
|
||||
marketing_campaign_workitem() #}}}
|
||||
|
||||
marketing_campaign_workitem() #}}}
|
||||
|
||||
class email_template(osv.osv):
|
||||
_inherit = "email.template"
|
||||
|
||||
_defaults = {
|
||||
'object_name': lambda obj, cr, uid, context: context.get('object_id',False),
|
||||
}
|
||||
email_template()
|
||||
email_template()
|
||||
|
||||
class report_xml(osv.osv):
|
||||
|
||||
_inherit = 'ir.actions.report.xml'
|
||||
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
|
||||
if not context:
|
||||
context = {}
|
||||
if context and 'object_id' in context and context['object_id']:
|
||||
model = self.pool.get('ir.model').browse(cr, uid,
|
||||
model = self.pool.get('ir.model').browse(cr, uid,
|
||||
context['object_id']).model
|
||||
args.append(('model', '=', model))
|
||||
return super(report_xml, self).search(cr, uid, args, offset, limit, order, context, count)
|
||||
|
||||
report_xml()
|
||||
|
||||
report_xml()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -14,75 +14,67 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Campaign">
|
||||
<group colspan="4">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field name="object_id" select="1"/>
|
||||
<field name="mode"/>
|
||||
<field name="fixed_cost"/>
|
||||
</group>
|
||||
<field name="activity_ids" nolabel = "1" colspan="4" default_get="{'object_id':object_id}">
|
||||
<form string="Activities">
|
||||
<field name="name" select="1" />
|
||||
<field name="object_id" readonly="True"/>
|
||||
<field name="variable_cost" select="1"/>
|
||||
<field name="start"/>
|
||||
<field name="condition" colspan="4"/>
|
||||
<form string="Activities">
|
||||
<group colspan="4" col="6">
|
||||
<separator string="Activity Definition" colspan="4"/>
|
||||
<separator string="Cost Control" colspan="2"/>
|
||||
<field name="name" select="1" />
|
||||
<field name="start"/>
|
||||
<field name="variable_cost" select="1"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Condition" colspan="2"/>
|
||||
<field name="condition"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Action" colspan="2"/>
|
||||
<field name="type" colspan="4"/>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
|
||||
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
|
||||
<field name="report_id" attrs="{'required':[('type','=','paper')]}"/>
|
||||
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
|
||||
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
|
||||
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
</group>
|
||||
</group>
|
||||
<newline/>
|
||||
<field name="type" colspan="4"/>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
|
||||
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
|
||||
<field name="report_id" attrs="{'required':[('type','=','paper')]}"/>
|
||||
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
|
||||
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
|
||||
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
</group>
|
||||
<field name="to_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
|
||||
<form string="Out Transitions" >
|
||||
<field name="activity_from_id" readonly="True"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</form>
|
||||
<tree string="Out Transitions" editable="bottom">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="from_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
|
||||
<form string="In Transitions" >
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id" readonly="True"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</form>
|
||||
<tree string="In Transitions" editable="bottom">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group colspan="4" col="4">
|
||||
<separator string="Transitions" colspan="4"/>
|
||||
<field name="to_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
|
||||
<tree string="Outgoing Transitions" editable="bottom">
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="from_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
|
||||
<tree string="Incoming Transitions" editable="bottom">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</form>
|
||||
<tree string="Activities">
|
||||
<field name="name" select="1"/>
|
||||
<field name="object_id"/>
|
||||
<field name="name"/>
|
||||
<field name="start"/>
|
||||
<field name="condition"/>
|
||||
<field name="variable_cost" select="1"/>
|
||||
<field name="type"/>
|
||||
<field name="report_id"/>
|
||||
<field name="to_ids"/>
|
||||
<field name="subcampaign_id"/>
|
||||
<field name="subcampaign_segment_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
<separator string="Status" colspan="4" />
|
||||
|
@ -105,7 +97,6 @@
|
|||
<field name="name" select="1"/>
|
||||
<field name="object_id" select="1"/>
|
||||
<field name="mode"/>
|
||||
<field name="fixed_cost"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -122,13 +113,13 @@
|
|||
<field name="type"/>
|
||||
<field name="start" invisible="1"/>
|
||||
<field name="condition"/>
|
||||
</node>
|
||||
<arrow object="marketing.campaign.transition" source="activity_from_id" destination="activity_to_id" label="['interval_type']">
|
||||
</node>
|
||||
<arrow object="marketing.campaign.transition" source="activity_from_id" destination="activity_to_id" label="['interval_type']">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</arrow>
|
||||
<field name="interval_type"/>
|
||||
</arrow>
|
||||
</diagram>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -183,21 +174,23 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Segments">
|
||||
<group colspan="4">
|
||||
<field name="name" select="1" colspan="4"/>
|
||||
<newline/>
|
||||
<group colspan="4" col="6">
|
||||
<field name="name"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
<field name="object_id" select="1" readonly="True"/>
|
||||
<newline/>
|
||||
<field name="ir_filter_id" select="1"/>
|
||||
<newline/>
|
||||
<field name="object_id" invisible="1" readonly="True"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Synchronization" colspan="2"/>
|
||||
<field name="sync_last_date"/>
|
||||
<field name="sync_mode" required="True"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Dates" colspan="2"/>
|
||||
<field name="date_run" attrs="{'readonly':[('date_run','!=',False),('state','=','running')]}"/>
|
||||
<field name="date_done"/>
|
||||
<separator string="Synchronization" colspan="4" />
|
||||
<field name="sync_last_date"/>
|
||||
<field name="sync_mode" required="True"/>
|
||||
</group>
|
||||
<separator string="Status" colspan="4" />
|
||||
<separator string="Status" colspan="4"/>
|
||||
<group col="10" colspan="4">
|
||||
<field name="state" readonly="1" select="2" nolabel="1"/>
|
||||
<button name="state_running_set" string="Run" states="draft" icon="gtk-apply"/>
|
||||
|
@ -214,13 +207,11 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Segments">
|
||||
<field name="name" select="1"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
<field name="object_id" select="1" />
|
||||
<field name="name"/>
|
||||
<field name="campaign_id"/>
|
||||
<field name="object_id"/>
|
||||
<field name="date_run"/>
|
||||
<field name="date_done"/>
|
||||
<field name="sync_last_date" string="Sync Date"/>
|
||||
<field name="sync_mode" string="Sync Mode"/>
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -277,54 +268,55 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Activities">
|
||||
<field name="name" select="1" />
|
||||
<field name="start"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
<field name="object_id" readonly="True"/>
|
||||
|
||||
<group colspan="4" col="6">
|
||||
<separator string="Activity Definition" colspan="4"/>
|
||||
<separator string="Cost Control" colspan="2"/>
|
||||
<field name="name" select="1" />
|
||||
<field name="start"/>
|
||||
<field name="variable_cost" select="1"/>
|
||||
<field name="object_id" invisible="1"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Condition" colspan="2"/>
|
||||
<field name="condition"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Action"/>
|
||||
<field name="type" colspan="4"/>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
|
||||
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
|
||||
<field name="report_id" attrs="{'required':[('type','=','paper')]}"/>
|
||||
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
|
||||
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
|
||||
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
</group>
|
||||
</group>
|
||||
<newline/>
|
||||
<field name="type"/>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
|
||||
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
|
||||
<group colspan="4" col="4">
|
||||
<separator string="Transitions" colspan="4"/>
|
||||
<field name="to_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
|
||||
<tree string="Outgoing Transitions" editable="bottom">
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="from_ids" nolabel="1" colspan="2" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
|
||||
<tree string="Incoming Transitions" editable="bottom">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
|
||||
<field name="report_id" attrs="{'required':[('type','=','paper')]}" />
|
||||
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
|
||||
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
|
||||
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
|
||||
</group>
|
||||
<field name="to_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_from_id','activity_id':active_id or False}">
|
||||
<form string="Out Transitions" >
|
||||
<field name="activity_from_id" readonly="True"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</form>
|
||||
<tree string="Out Transitions" editable="bottom">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="from_ids" nolabel="1" colspan="4" mode="tree" default_get="{'type_id':'activity_to_id','activity_id':active_id or False}">
|
||||
<form string="In Transitions" >
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id" readonly="True"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</form>
|
||||
<tree string="In Transitions" editable="bottom">
|
||||
<field name="activity_from_id"/>
|
||||
<field name="activity_to_id"/>
|
||||
<field name="interval_nbr"/>
|
||||
<field name="interval_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -338,13 +330,8 @@
|
|||
<field name="name" select="1"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
<field name="start"/>
|
||||
<field name="object_id"/>
|
||||
<field name="condition"/>
|
||||
<field name="type"/>
|
||||
<field name="report_id"/>
|
||||
<field name="to_ids" />
|
||||
<field name="subcampaign_id"/>
|
||||
<field name="subcampaign_segment_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -374,11 +361,12 @@
|
|||
<tree string="Workitems">
|
||||
<field name="segment_id"/>
|
||||
<field name="activity_id" />
|
||||
<field name="object_id"/>
|
||||
<field name="partner_id" select="1"/>
|
||||
<field name="res_id" />
|
||||
<field name="res_name" />
|
||||
<field name="partner_id"/>
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
<button string="Process" states="todo" name="process" type="object" icon="gtk-ok"/>
|
||||
<button string="Cancel" states="todo" name="button_cancel" type="object" icon="gtk-cancel"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -389,14 +377,31 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Workitem">
|
||||
<field name="segment_id" select="1"/>
|
||||
<field name="activity_id" context="{'segment_id':segment_id}" select="1"/>
|
||||
<field name="object_id" readonly="True"/>
|
||||
<field name="partner_id" select="1"/>
|
||||
<field name="res_id"/>
|
||||
<field name="date" select="1"/>
|
||||
<group colspan="4" col="6">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Campaign Step" colspan="2"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
<field name="segment_id" select="1"/>
|
||||
<field name="activity_id" context="{'segment_id':segment_id}" select="1"/>
|
||||
</group><group colspan="2" col="2">
|
||||
<separator string="Related Resource" colspan="2"/>
|
||||
<field name="object_id" readonly="True"/>
|
||||
<field name="res_name"/>
|
||||
<field name="res_id"/>
|
||||
<field name="partner_id" select="1"/>
|
||||
</group><group colspan="2" col="2">
|
||||
<separator string="Date" colspan="2"/>
|
||||
<field name="date"/>
|
||||
<label string="" colspan="1"/>
|
||||
<button string="Preview" states="todo" name="preview" icon="gtk-apply"/>
|
||||
</group>
|
||||
</group>
|
||||
<separator string="Status" colspan="4"/>
|
||||
<field name="state" nolabel="1" colspan="4" readonly="True" select="1"/>
|
||||
<group colspan="4" col="11">
|
||||
<field name="state" nolabel="1" readonly="True" select="1"/>
|
||||
<button string="Process" states="todo" name="process" type="object" icon="gtk-ok"/>
|
||||
<button string="Cancel" states="todo" name="button_cancel" type="object" icon="gtk-cancel"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
Loading…
Reference in New Issue