[MERGE]: Merge with lp:openobject-trunk-dev-addons2
bzr revid: ksa@tinyerp.co.in-20100428050233-4muruzwlrdyulgxq
This commit is contained in:
@@ -28,7 +28,7 @@ If you don't think you need any of these right now, you can easily install them
|
||||
<field name="account"/> <field name="purchase"/>
|
||||
<field name="hr"/> <field name="point_of_sale"/>
|
||||
<field name="marketing"/> <field name="misc_tools"/>
|
||||
<field name="report_designer"/>
|
||||
<field name="report_designer"/> <field name="thunderbird"/>
|
||||
<separator string="Vertical Modules" colspan="4"/>
|
||||
<field name="profile_association"/>
|
||||
<field name="profile_training"/>
|
||||
|
||||
@@ -73,6 +73,7 @@ class base_setup_installer(osv.osv_memory):
|
||||
'report_designer':fields.boolean('Advanced Reporting',
|
||||
help="Lets you install various tools to simplify and enhance "
|
||||
"OpenERP's report creation."),
|
||||
'thunderbird' :fields.boolean('Thunderbird'),
|
||||
# Vertical modules
|
||||
'profile_association':fields.boolean('Associations',
|
||||
help="Installs a preselected set of OpenERP "
|
||||
|
||||
@@ -109,6 +109,7 @@ between mails and Open ERP.""",
|
||||
'process/crm_configuration_process.xml',
|
||||
],
|
||||
'demo_xml': [
|
||||
'test/test_crm_meeting.yml',
|
||||
'crm_demo.xml',
|
||||
'crm_claims_demo.xml',
|
||||
'crm_fund_demo.xml',
|
||||
@@ -118,6 +119,13 @@ between mails and Open ERP.""",
|
||||
'crm_opportunity_demo.xml',
|
||||
'crm_phonecall_demo.xml'
|
||||
],
|
||||
'test': ['test/test_crm_lead.yml',
|
||||
'test/test_crm_opportunity.yml',
|
||||
'test/test_crm_phonecall.yml',
|
||||
'test/test_crm_fund.yml',
|
||||
'test/test_crm_claim.yml',
|
||||
'test/test_crm_helpdesk.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0079056041421',
|
||||
|
||||
+7
-5
@@ -59,6 +59,7 @@ class crm_case_section(osv.osv):
|
||||
true, it will allow you to hide the sales team without removing it."),
|
||||
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
|
||||
'user_id': fields.many2one('res.users', 'Responsible User'),
|
||||
'member_ids':fields.many2many('res.users', 'sale_member_rel', 'section_id', 'member_id', 'Team Members'),
|
||||
'reply_to': fields.char('Reply-To', size=64, help="The email address put \
|
||||
in the 'Reply-To' of all emails sent by Open ERP about cases in this sales team"),
|
||||
'parent_id': fields.many2one('crm.case.section', 'Parent Team'),
|
||||
@@ -66,6 +67,7 @@ class crm_case_section(osv.osv):
|
||||
'resource_calendar_id': fields.many2one('resource.calendar', "Resource's Calendar"),
|
||||
'server_id':fields.many2one('email.smtpclient', 'Server ID'),
|
||||
'note': fields.text('Description'),
|
||||
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -79,14 +81,14 @@ class crm_case_section(osv.osv):
|
||||
|
||||
def _check_recursion(self, cr, uid, ids):
|
||||
"""
|
||||
Checks for recursion level for sections
|
||||
Checks for recursion level for sales team
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of section ids
|
||||
@param ids: List of Sales team ids
|
||||
"""
|
||||
level = 100
|
||||
|
||||
|
||||
while len(ids):
|
||||
cr.execute('select distinct parent_id from crm_case_section where id =ANY(%s)', (ids,))
|
||||
ids = filter(None, map(lambda x: x[0], cr.fetchall()))
|
||||
@@ -97,7 +99,7 @@ class crm_case_section(osv.osv):
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error ! You cannot create recursive sections.', ['parent_id'])
|
||||
(_check_recursion, 'Error ! You cannot create recursive Sales team.', ['parent_id'])
|
||||
]
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
@@ -105,7 +107,7 @@ class crm_case_section(osv.osv):
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of section ids
|
||||
@param ids: List of sales team ids
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
+10
-8
@@ -11,7 +11,7 @@
|
||||
<field name="model">crm.case.section</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Case Section">
|
||||
<form string="Sales Team">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1" colspan="4"/>
|
||||
<field name="code" select="1"/>
|
||||
@@ -19,22 +19,24 @@
|
||||
<field name="resource_calendar_id" select="2"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Case section">
|
||||
<group col="2" colspan="2">
|
||||
<page string="Sales Team">
|
||||
<group col="2" colspan="1">
|
||||
<separator string="Responsible" colspan="2"/>
|
||||
<field name="parent_id" select="2" widget="selection"/>
|
||||
<field name="user_id" select="2"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<group col="2" colspan="1">
|
||||
<separator string="Contact Information" colspan="2"/>
|
||||
<field name="server_id" select="2"/>
|
||||
<field name="reply_to" select="2"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Section Property" colspan="2"/>
|
||||
<group col="2" colspan="1">
|
||||
<separator string="Sales Team Property" colspan="2"/>
|
||||
<field name="active" select="2"/>
|
||||
<field name="allow_unlink" select="2"/>
|
||||
</group>
|
||||
<separator string="Members List" colspan="4"/>
|
||||
<field name="member_ids" nolabel="1" colspan="4"/>
|
||||
<separator string="Note" colspan="4"/>
|
||||
<field name="note" select="1" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
@@ -51,7 +53,7 @@
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Case Section">
|
||||
<tree string="Sales Team">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
@@ -62,7 +64,7 @@
|
||||
<!-- Case Sections Action -->
|
||||
|
||||
<record id="crm_case_section_act" model="ir.actions.act_window">
|
||||
<field name="name">Sections</field>
|
||||
<field name="name">Sales Team</field>
|
||||
<field name="res_model">crm.case.section</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_case_section_view_tree"/>
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
<act_window domain="[('section_id', '=', active_id)]"
|
||||
id="act_crm_case_section_2_report_crm_case_categ"
|
||||
name="Monthly cases by section" res_model="crm.case.report"
|
||||
name="Monthly cases by Sales Team" res_model="crm.case.report"
|
||||
src_model="crm.case.section" />
|
||||
|
||||
<!-- Closed & Open CRM Case view for Random Activities dashboard Tree View -->
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
- |
|
||||
Now I check claims which contain customer claim information about document
|
||||
related problem, product related problem.
|
||||
- |
|
||||
I start by creating new claims for Damaged product as Value Claims with priority High and specify
|
||||
date of claim at which claim is created.
|
||||
-
|
||||
!record {model: crm.claim, id: crm_claim_damagedproduct0}:
|
||||
categ_id: crm.categ_claim2
|
||||
date: '2010-04-21 20:13:00'
|
||||
email_from: info@balmerinc.be
|
||||
name: 'Damaged product '
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
priority: '2'
|
||||
section_id: crm.section_sales_department
|
||||
|
||||
- |
|
||||
I check that the claims is in 'draft' state.
|
||||
-
|
||||
!assert {model: crm.claim, id: crm_claim_damagedproduct0}:
|
||||
- state == 'draft'
|
||||
- |
|
||||
Now I make sure that claim is at "Accepted" stage.
|
||||
-
|
||||
!record {model: crm.claim, id: crm.crm_claim_damagedproduct0}:
|
||||
stage_id: crm.stage_claim1
|
||||
- |
|
||||
I can change that stage by next button right on it
|
||||
-
|
||||
!python {model: crm.claim}: |
|
||||
self.stage_next(cr, uid, [ref('crm_claim_damagedproduct0')])
|
||||
- |
|
||||
I make this claim as Open
|
||||
-
|
||||
!python {model: crm.claim}: |
|
||||
self.case_open(cr, uid, [ref('crm_claim_damagedproduct0')])
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
- |
|
||||
Now I start test Fund Raising which contain information about Donation or charity
|
||||
given by user.
|
||||
- |
|
||||
I start by creating new Funds entry for donation for books to poor school children
|
||||
with cost 500000.00 and category as "Learning And Education"
|
||||
I make payment by Cheque so I make sure that the mode on fund is selected as cheque
|
||||
-
|
||||
!record {model: crm.fundraising, id: crm_fundraising_donationforbookstopoorschoolchildren0}:
|
||||
categ_id: crm.categ_fund2
|
||||
email_from: info@balmerinc.be
|
||||
name: Donation for books to poor school children
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
planned_cost: 500000.0
|
||||
section_id: crm.section_sales_department
|
||||
type_id: crm.type_fund2
|
||||
- |
|
||||
I check that the Funds is in 'draft' state.
|
||||
-
|
||||
!assert {model: crm.fundraising, id: crm_fundraising_donationforbookstopoorschoolchildren0}:
|
||||
- state == 'draft'
|
||||
- |
|
||||
Now I open Funds by click on "Open" button
|
||||
-
|
||||
!python {model: crm.fundraising}: |
|
||||
self.case_open(cr, uid, [ref('crm_fundraising_donationforbookstopoorschoolchildren0')])
|
||||
- |
|
||||
I can close Funds by click on "Done" button.
|
||||
-
|
||||
!python {model: crm.fundraising}: |
|
||||
self.case_close(cr, uid, [ref('crm_fundraising_donationforbookstopoorschoolchildren0')])
|
||||
@@ -0,0 +1,38 @@
|
||||
-
|
||||
|
|
||||
I start by creating New helpdesk request regarding some functional questions.
|
||||
I select Date at which helpdesk request is created.
|
||||
-
|
||||
!record {model: crm.helpdesk, id: crm_helpdesk_somefunctionalquestion0}:
|
||||
date: '2010-04-22 10:17:00'
|
||||
email_from: info@balmerinc.be
|
||||
name: Some functional question.
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
section_id: crm.section_sales_department
|
||||
|
||||
- |
|
||||
I check that the Helpdesk request is in 'Draft' state.
|
||||
-
|
||||
!assert {model: crm.helpdesk, id: crm_helpdesk_somefunctionalquestion0}:
|
||||
- state == 'draft'
|
||||
- |
|
||||
In order to make this helpdesk request to be considered I make it "Open"
|
||||
-
|
||||
!python {model: crm.helpdesk}: |
|
||||
self.case_open(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])
|
||||
- |
|
||||
I can see that "Send Reminder" button is visible, which is used to send reminder to partner from
|
||||
responsible person or send reminder to responsible person from partner.
|
||||
-
|
||||
#this is not work for yaml.
|
||||
-
|
||||
# !python {model: crm.helpdesk}: |
|
||||
# self.remind_user(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')], context={}, attach=False, destination=True)
|
||||
- |
|
||||
After a proper communication for the request via email I make sure that the request is fulfilled and
|
||||
I close this HelpDesk Request by clicking on "Close" button.
|
||||
-
|
||||
!python {model: crm.helpdesk}: |
|
||||
self.case_close(cr, uid, [ref('crm_helpdesk_somefunctionalquestion0')])
|
||||
-
|
||||
@@ -0,0 +1,113 @@
|
||||
- |
|
||||
In order to test the CRM in OpenERP,
|
||||
I will do a customer qualification process that
|
||||
starts with a fist contact with a customer (a lead), which will be converted to a
|
||||
business opportunity and a partner.
|
||||
- |
|
||||
In order to test the flow, I create a two new users "user_crm" and
|
||||
I assign the group "salesman".
|
||||
-
|
||||
!record {model: res.users, id: res_users_usercrm0}:
|
||||
company_id: base.main_company
|
||||
context_lang: en_US
|
||||
context_section_id: crm.section_sales_department
|
||||
groups_id:
|
||||
- crm.group_crm_user
|
||||
login: user_crm
|
||||
name: user_crm
|
||||
password: user_crm
|
||||
|
||||
|
||||
- |
|
||||
I start by creating a new lead "New Customer" and I provide an address to this
|
||||
new customer, as well as an email "info@mycustomer.com".
|
||||
-
|
||||
!record {model: crm.lead, id: crm_lead_newcustomer0}:
|
||||
email_from: info@mycustomer.com
|
||||
name: New Customer
|
||||
partner_name: Sandip zala
|
||||
phone: (855) 924-4364
|
||||
mobile: (333) 715-1450
|
||||
section_id: crm.section_sales_department
|
||||
referred: False
|
||||
title: M.
|
||||
- |
|
||||
I check that the lead is in 'draft' state,
|
||||
-
|
||||
!assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in Draft}:
|
||||
- state == "draft"
|
||||
-
|
||||
I open lead by click on "Open" button,
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
self.case_open(cr, uid, [ref("crm_lead_newcustomer0")])
|
||||
|
||||
- |
|
||||
As the lead seems to be a real business opportunity, I will convert it to a
|
||||
partner
|
||||
and a business opportunity by clicking on the "Convert" button.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
lead = self.browse(cr, uid, ref('crm_lead_newcustomer0'))
|
||||
if not lead.partner_id:
|
||||
self.convert_opportunity(cr, uid, [ref("crm_lead_newcustomer0")], {'active_ids': [ref("crm_lead_newcustomer0")]})
|
||||
-
|
||||
|
|
||||
Now, select "create a new partner" option in this wizard.
|
||||
-
|
||||
!record {model: crm.lead2opportunity.partner, id: crm_lead2opportunity_partner_create_0}:
|
||||
action: 'create'
|
||||
-
|
||||
I click on "Continue" button of this wizard.
|
||||
-
|
||||
!python {model: crm.lead2opportunity.partner}: |
|
||||
self.make_partner(cr, uid, [ref("crm_lead2opportunity_partner_create_0")], {'active_ids': [ref("crm_lead_newcustomer0")]})
|
||||
-
|
||||
Now, I give value to this wizard field.
|
||||
-
|
||||
!record {model: crm.lead2opportunity, id: crm_lead2opportunity_stonage_0}:
|
||||
name: Sandip zala
|
||||
planned_revenue: 0.00
|
||||
probability: 0.00
|
||||
-
|
||||
Then, Click on "Create Opportunity" button of this wizard.
|
||||
-
|
||||
!python {model: crm.lead2opportunity}: |
|
||||
self.action_apply(cr, uid, [ref('crm_lead2opportunity_stonage_0')], {'active_id': ref('crm_lead_newcustomer0')})
|
||||
|
||||
- |
|
||||
I can check that a lead and a business opportunity is now assigned to this
|
||||
lead.
|
||||
-
|
||||
# !python {model: crm.lead, id: crm_lead_newcustomer0}:
|
||||
# - opportunity_id.id != False
|
||||
|
||||
- |
|
||||
I check that the partner associated to this lead as the same country, phone number
|
||||
and name than the opportunity.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
lead = self.browse(cr, uid, ref("crm_lead_newcustomer0"))
|
||||
print "lead", lead.partner_name
|
||||
obj_opportunity = self.pool.get('crm.opportunity')
|
||||
ids = obj_opportunity.search(cr, uid, [('name', '=', lead.partner_name)])
|
||||
opportunity = obj_opportunity.browse(cr, uid, ids)[0]
|
||||
assert lead.partner_name == opportunity.partner_id.name
|
||||
assert lead.phone == opportunity.phone
|
||||
-
|
||||
|
|
||||
# yaml is also not working smpt server and send new email.
|
||||
|
||||
- |
|
||||
I configure with smtp server.
|
||||
- |
|
||||
And I communicate with lead through send New mail to Lead using it email address from user which are loged.
|
||||
- |
|
||||
I check that communication history generated when send email to lead.
|
||||
- |
|
||||
Then, I add a cc which receive copy of future communication between partner and users by mail.
|
||||
|
||||
- |
|
||||
I Reply to last Email to lead with some document attached.and check that communication history generated or not.
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
- |
|
||||
Now I will test Meetings which may be customer meeting or phonecall meeting or
|
||||
internal Meeting.
|
||||
- |
|
||||
I start by creating a new Meeting.
|
||||
-
|
||||
!record {model: crm.meeting, id: crm_meeting_regardingpresentation0}:
|
||||
categ_id: crm.categ_meet2
|
||||
date: '2010-04-21 16:04:00'
|
||||
date_deadline: '2010-04-22 00:04:00'
|
||||
duration: 8.0
|
||||
email_from: info@balmerinc.be
|
||||
location: Ahmedabad
|
||||
name: Regarding Presentation
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
rrule_type: weekly
|
||||
section_id: crm.section_sales_department
|
||||
- |
|
||||
I check that the Meetings is in 'UnConfirmed' state.
|
||||
-
|
||||
!assert {model: crm.meeting, id: crm_meeting_regardingpresentation0}:
|
||||
- state == "draft"
|
||||
- |
|
||||
I can set reminder on meeting if I put reminder "40 minutes before"
|
||||
- |
|
||||
For that, I first create alarm.
|
||||
-
|
||||
!record {model: res.alarm, id: res_alarm_minituesbefore0}:
|
||||
name: 40 minutes before
|
||||
trigger_duration: 40
|
||||
trigger_interval: minutes
|
||||
trigger_occurs: before
|
||||
trigger_related: start
|
||||
- |
|
||||
Now I will assign this reminder.
|
||||
|
||||
- !python {model: crm.meeting}: |
|
||||
self.write(cr, uid, [ref('crm_meeting_regardingpresentation0')], {'alarm_id': ref("res_alarm_minituesbefore0")})
|
||||
- |
|
||||
In order to check recurrence on meetings I will set Recurrency to Custom
|
||||
and I set the fields so that the meeting will occure weekly on Monday and Friday 10 times
|
||||
-
|
||||
!python {model: crm.meeting}: |
|
||||
self.write(cr, uid, [ref("crm_meeting_regardingpresentation0")], {'fr': 1, 'mo': 1, 'th': 1, 'tu': 1, 'we':1, 'count':10, 'interval': 1, 'freq': 'weekly', 'rrule_type': 'custom'})
|
||||
|
||||
- |
|
||||
I can see from the calendar view that the meeting is scheduled on Monday and Friday
|
||||
for 10 times,
|
||||
|
||||
-
|
||||
!python {model: crm.meeting}: |
|
||||
self.fields_view_get(cr, uid, False, 'calendar', context)
|
||||
- |
|
||||
I will search for one of the recurrent event and count the number of meeting.
|
||||
-
|
||||
!python {model: crm.meeting}: |
|
||||
ids = self.search(cr, uid, [('date', '>=', '2010-05-21 00:00:00'), ('date', '<=', '2010-04-21 00:00:00')] )
|
||||
assert len(ids) == 9
|
||||
|
||||
- |
|
||||
Now If I want to edit meetings information for all occurence I click on "Edit All" button.
|
||||
-
|
||||
!python {model: crm.meeting}: |
|
||||
self.open_meeting(cr, uid, [ref('crm_meeting_regardingpresentation0')])
|
||||
- |
|
||||
I can see that new meeting form is opened with same value
|
||||
I change some data for meeting and save it
|
||||
I can see from meeting's calendar view that all meeting occurences are changed accordingly
|
||||
-
|
||||
!record {model: crm.meeting, id: crm.crm_meeting_regardingpresentation0}:
|
||||
alarm_id: base_calendar.alarm9
|
||||
rrule_type: weekly
|
||||
|
||||
- |
|
||||
In order to invite people for this meetings, I click on "Invite People" button
|
||||
I can invite internal user.
|
||||
-
|
||||
!record {model: base_calendar.invite.attendee, id: base_calendar_invite_attendee_0}:
|
||||
type: internal
|
||||
partner_id: base.res_partner_9
|
||||
user_ids:
|
||||
- base.user_demo
|
||||
- |
|
||||
If I set Send mail boolean as True I can see that an email is send to
|
||||
specified email address with proper meeting information.
|
||||
-
|
||||
#This is not working for send mail boolean as True.
|
||||
-
|
||||
I click on "Invite" button of "Invite attendee" wizard.
|
||||
-
|
||||
!python {model: base_calendar.invite.attendee}: |
|
||||
self.do_invite(cr, uid, [ref('base_calendar_invite_attendee_0')], {'active_id': ref('crm_meeting_regardingpresentation0'), 'model' : 'crm.meeting', 'attendee_field':'attendee_ids'})
|
||||
|
||||
- |
|
||||
After direct/indirect confirmation for meetings I can confirm meeting
|
||||
-
|
||||
!python {model: crm.meeting}: |
|
||||
self.case_open(cr, uid, [ref('crm_meeting_regardingpresentation0')])
|
||||
@@ -0,0 +1,81 @@
|
||||
- |
|
||||
I start by creating a new Opportunity. And I select partner for opportunity.
|
||||
I can see that after selecting partner his contact and email is automatically filled.
|
||||
-
|
||||
!record {model: crm.opportunity, id: crm_opportunity_abcfuelcounits0}:
|
||||
email_from: info@balmerinc.be
|
||||
name: 'ABC FUEL CO 829264 - 10002 units '
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
probability: 1.0
|
||||
stage_id: crm.stage_oppor1
|
||||
categ_id: crm.categ_oppor2
|
||||
section_id: crm.section_sales_department
|
||||
|
||||
- |
|
||||
I check that the opportunity is in 'New' state.
|
||||
-
|
||||
!assert {model: crm.opportunity, id: crm_opportunity_abcfuelcounits0}:
|
||||
- state == "draft"
|
||||
- |
|
||||
I open opportunity by click on "Open" button,
|
||||
-
|
||||
!python {model: crm.opportunity}: |
|
||||
self.case_open(cr, uid, [ref("crm_opportunity_abcfuelcounits0")])
|
||||
|
||||
- |
|
||||
I schedule Meeting on this current opportunity by clicking on "schedule
|
||||
Meeting".
|
||||
-
|
||||
!python {model: crm.opportunity}: |
|
||||
self.action_makeMeeting(cr, uid, [ref("crm_opportunity_abcfuelcounits0")])
|
||||
|
||||
- |
|
||||
I can see that Meeting's calendar view is shown.
|
||||
then I click on the date on which I want schedule meeting.
|
||||
I fill proper data for that meeting and save it
|
||||
-
|
||||
!record {model: crm.meeting, id: crm_meeting_abcfuelcounits0}:
|
||||
alarm_id: base_calendar.alarm3
|
||||
date: '2010-04-16 00:00:00'
|
||||
date_deadline: '2010-04-16 08:00:00'
|
||||
duration: 8.0
|
||||
email_from: info@balmerinc.be
|
||||
name: 'ABC FUEL CO 829264 - 10002 units '
|
||||
opportunity_id: 'crm_opportunity_abcfuelcounits0'
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
rrule_type: weekly
|
||||
section_id: crm.section_sales_department
|
||||
state: open
|
||||
- |
|
||||
In order to schedule a phonecall to the partner
|
||||
I click on "schedule call" button and select planned date for the call.
|
||||
-
|
||||
!record {model: crm.opportunity2phonecall, id: crm_opportunity2phonecall_abcfuelcounits0}:
|
||||
date: '2010-04-17 11:15:00'
|
||||
name: 'ABC FUEL CO 829264 - 10002 units '
|
||||
section_id: crm.section_sales_department
|
||||
user_id: base.user_demo
|
||||
- |
|
||||
schedule phonecall by apply (action_apply)function of opportunity2phoncall wizard
|
||||
-
|
||||
!python {model: crm.opportunity2phonecall}: |
|
||||
self.action_apply(cr, uid, [ref('crm_opportunity2phonecall_abcfuelcounits0')], {'active_ids': [ref("crm_opportunity_abcfuelcounits0")]})
|
||||
- |
|
||||
I check that phonecall record is created for that opportunity.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
ids = self.search(cr, uid, [('name', '=', 'ABC FUEL CO 829264 - 10002 units')])
|
||||
assert len(ids)
|
||||
- |
|
||||
I can see phonecall record after click on "Schedule call" wizard.
|
||||
-
|
||||
!record {model: crm.phonecall, id: crm_phonecall_abcfuelcounits0}:
|
||||
date: '2010-04-17 11:15:00'
|
||||
duration: 3.0
|
||||
name: 'ABC FUEL CO 829264 - 10002 units'
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
section_id: crm.section_sales_department
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
- |
|
||||
I start by creating a new phonecall.
|
||||
-
|
||||
!record {model: crm.phonecall, id: crm_phonecall_interviewcall0}:
|
||||
date: '2010-04-21 18:59:00'
|
||||
name: Interview call
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
partner_mobile: (+32)2 211 34 83
|
||||
section_id: crm.section_sales_department
|
||||
|
||||
- |
|
||||
As the success of phonecall seems to be a real business opportunity, I will convert
|
||||
it to opportunity by clicking on the "Convert to Opportunity" button.
|
||||
-
|
||||
# !python {model: crm.phonecall2opportunity}: |
|
||||
# self.action_apply(cr, uid, [1], {'active_id': ref('crm_phonecall_interviewcall0')})
|
||||
|
||||
-
|
||||
# This is not working, find a way to do that in YAML
|
||||
|
||||
- |
|
||||
I can see that a business opportunity is now assigned to this phonecall
|
||||
- |
|
||||
I check that the partner associated to this as the same country, phone number
|
||||
and name than the phonecall.
|
||||
- |
|
||||
In order to avoid the duplication of similar partner, OpenERP should be able to
|
||||
detect if the partner exists or if it should be created from the phonecall during the
|
||||
conversion.
|
||||
- |
|
||||
In order to test this, I log as the user "user_crm2"
|
||||
- |
|
||||
Then, I create the same phonecall than the preceeding one but I change the name
|
||||
of the phonecall. But this customer keeps the same email.
|
||||
- |
|
||||
This time OpenERP should detect that this customer already exists in the
|
||||
partner base and I check that in the wizard, proposes me to link to this existing
|
||||
partner instead of creating another one.
|
||||
- |
|
||||
I confirm the conversion wizard.
|
||||
- |
|
||||
And I check that the phonecall and the newly created business opportunity is linked
|
||||
to the partner
|
||||
- |
|
||||
I schedule Meeting on this current phonecall by clicking on "schedule
|
||||
Meeting"
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.action_make_meeting(cr, uid, [ref('crm_phonecall_interviewcall0')])
|
||||
|
||||
- |
|
||||
I can see that Meeting's calendar view is shown.
|
||||
then I click on the date on which I want schedule meeting.
|
||||
I fill proper data for that meeting and save it
|
||||
-
|
||||
!record {model: crm.meeting, id: crm_meeting_interviewcall0}:
|
||||
alarm_id: base_calendar.alarm3
|
||||
date: '2010-04-20 00:00:00'
|
||||
date_deadline: '2010-04-20 08:00:00'
|
||||
duration: 8.0
|
||||
email_from: info@balmerinc.be
|
||||
name: Interview call
|
||||
partner_address_id: base.res_partner_address_1
|
||||
partner_id: base.res_partner_9
|
||||
phonecall_id: 'crm_phonecall_interviewcall0'
|
||||
rrule_type: weekly
|
||||
state: open
|
||||
|
||||
-
|
||||
#This is not working for yaml
|
||||
- |
|
||||
I can jump to this meeting by "Meetings" shortcut from my phonecall's form view
|
||||
-
|
||||
|
||||
- |
|
||||
In order to schedule other phonecall to the partner
|
||||
I click on "schedule other call" button. and plan for other call
|
||||
I can see that it will open other phonecall view with some data same as current
|
||||
phonecall.
|
||||
-
|
||||
!record {model: crm.phonecall2phonecall, id: crm_phonecall2phonecall_interviewcall0}:
|
||||
date: '2010-04-21 19:49:00'
|
||||
name: Interview call
|
||||
section_id: crm.section_sales_department
|
||||
user_id: base.user_root
|
||||
- |
|
||||
I click on "Schedule" button of this wizard.
|
||||
-
|
||||
!python {model: crm.phonecall2phonecall}: |
|
||||
self.action_apply(cr, uid, [ref('crm_phonecall2phonecall_interviewcall0')], {'active_id': ref('crm_phonecall_interviewcall0')})
|
||||
@@ -46,6 +46,9 @@
|
||||
'report/document_report_view.xml'
|
||||
],
|
||||
'demo_xml': [ 'document_demo.xml',],
|
||||
'test': [
|
||||
'test/document_test.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': None,
|
||||
|
||||
@@ -105,7 +105,11 @@ class document_directory(osv.osv):
|
||||
]
|
||||
def name_get(self, cr, uid, ids, context={}):
|
||||
res = []
|
||||
all_ids = self.search(cr,uid,[])
|
||||
for d in self.browse(cr, uid, ids, context=context):
|
||||
if d.id not in all_ids:
|
||||
continue
|
||||
|
||||
s = ''
|
||||
d2 = d
|
||||
while d2 and d2.parent_id:
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
- |
|
||||
In order to test the Document Management System In OpenERP.
|
||||
-
|
||||
In order to test behaviour of resource Directory I will make one resource Directory "Partner Labels" in OpenERP having type "Other Resources" and Directory mapped to object "Partner"
|
||||
-
|
||||
!record {model: 'document.directory', id: dir_partner_label}:
|
||||
name : "Partner Labels"
|
||||
storage_id : storage_default
|
||||
type : ressource
|
||||
content_ids:
|
||||
- name: "Label"
|
||||
report_id : base.res_partner_address_report
|
||||
-
|
||||
Assign "res.partner" object to ressource_type_id.
|
||||
-
|
||||
!python {model: document.directory}: |
|
||||
ids = self.pool.get('ir.model').search(cr, uid, [('model','=','res.partner')])
|
||||
id = self.write(cr, uid, [ref("dir_partner_label")], {'ressource_type_id' : ids[0]}, context)
|
||||
-
|
||||
In order to check static directory in OpenERP which is the real directory just like system's local folders,
|
||||
First I create a directory in OpenERP named "Directory 1" with storage as "Default File storage" and type as "Static Directory"
|
||||
-
|
||||
!record {model: 'document.directory', id: directory_1}:
|
||||
name : "Directory 1"
|
||||
storage_id : storage_default
|
||||
type : directory
|
||||
-
|
||||
In order to make a directory hierarchy in OpenERP I will make other static directory "Directory 2" and I put its Parent Item as "Directory 1",
|
||||
So I can see the directory hierarchy in OpenERP's client like :- Directory1 -> Directory2
|
||||
-
|
||||
!record {model: 'document.directory', id: directory_2}:
|
||||
name : "Directory 2"
|
||||
storage_id : storage_default
|
||||
type : directory
|
||||
parent_id : directory_1
|
||||
-
|
||||
I am create a one Document Attachment name "My document" and select "Directory 2" as its Directory,
|
||||
And in order to put a File content.
|
||||
-
|
||||
When I am creating the document then "Resource Title" is filled automatic with "My document".
|
||||
-
|
||||
!record {model: 'ir.attachment', id: document_1}:
|
||||
name : "My document"
|
||||
parent_id : directory_2
|
||||
-
|
||||
Attach a pdf file in "My document"
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
import tools
|
||||
import base64
|
||||
file = open(tools.config['addons_path'] + '/document/test/partner.pdf')
|
||||
id = self.write(cr, uid, [ref("document_1")], {'datas' : base64.encodestring(file.read())}, context)
|
||||
@@ -0,0 +1,118 @@
|
||||
%PDF-1.3
|
||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
||||
% 'BasicFonts': class PDFDictionary
|
||||
1 0 obj
|
||||
% The standard fonts dictionary
|
||||
<< /F1 2 0 R
|
||||
/F2 3 0 R
|
||||
/F3 4 0 R >>
|
||||
endobj
|
||||
% 'F1': class PDFType1Font
|
||||
2 0 obj
|
||||
% Font Helvetica
|
||||
<< /BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
/Name /F1
|
||||
/Subtype /Type1
|
||||
/Type /Font >>
|
||||
endobj
|
||||
% 'F2': class PDFType1Font
|
||||
3 0 obj
|
||||
% Font Helvetica-Bold
|
||||
<< /BaseFont /Helvetica-Bold
|
||||
/Encoding /WinAnsiEncoding
|
||||
/Name /F2
|
||||
/Subtype /Type1
|
||||
/Type /Font >>
|
||||
endobj
|
||||
% 'F3': class PDFType1Font
|
||||
4 0 obj
|
||||
% Font Times-Roman
|
||||
<< /BaseFont /Times-Roman
|
||||
/Encoding /WinAnsiEncoding
|
||||
/Name /F3
|
||||
/Subtype /Type1
|
||||
/Type /Font >>
|
||||
endobj
|
||||
% 'Page1': class PDFPage
|
||||
5 0 obj
|
||||
% Page dictionary
|
||||
<< /Contents 9 0 R
|
||||
/MediaBox [ 0
|
||||
0
|
||||
841.8898
|
||||
595.2756 ]
|
||||
/Parent 8 0 R
|
||||
/Resources << /Font 1 0 R
|
||||
/ProcSet [ /PDF
|
||||
/Text
|
||||
/ImageB
|
||||
/ImageC
|
||||
/ImageI ] >>
|
||||
/Rotate 0
|
||||
/Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
% 'R6': class PDFCatalog
|
||||
6 0 obj
|
||||
% Document Root
|
||||
<< /Outlines 10 0 R
|
||||
/PageMode /UseNone
|
||||
/Pages 8 0 R
|
||||
/Type /Catalog >>
|
||||
endobj
|
||||
% 'R7': class PDFInfo
|
||||
7 0 obj
|
||||
<< /Author (Generated by OpenERP, Fabien Pinckaers)
|
||||
/CreationDate (20100421145542)
|
||||
/Keywords ()
|
||||
/Producer (ReportLab http://www.reportlab.com)
|
||||
/Subject (\(unspecified\))
|
||||
/Title (Partner) >>
|
||||
endobj
|
||||
% 'R8': class PDFPages
|
||||
8 0 obj
|
||||
% page tree
|
||||
<< /Count 1
|
||||
/Kids [ 5 0 R ]
|
||||
/Type /Pages >>
|
||||
endobj
|
||||
% 'R9': class PDFStream
|
||||
9 0 obj
|
||||
% page stream
|
||||
<< /Filter [ /ASCII85Decode
|
||||
/FlateDecode ]
|
||||
/Length 524 >>
|
||||
stream
|
||||
Gat=(?#P<K'R_@f5MSc<`6.HPV2s@dQRlarfjrE>3i<Y4(hW<qY=/IHPo2nd;U2u=SpPc46=:icfCoF922oN\83q_*El(+<i)0C.\*qSa'orY`+p(cC^oTpn8t,B-+=I?_Q1#SGXQbKWJ5-M7"aXRSQCBTu'NHJF046Jno-.K&2kW+&Ddh9bXc1q%)-e?DSC(5(4%=lk+ql;XaX3m]F#7K:"]hph/QW?(0_J4kXQiP</;'9K=]Wd,jeGe.Ma6pqJ&iD]r%qkNclhVq5Q/gSmK+r&6mr`*Z[m8(n)Usu)MZo%TNta^h'I^g6m5Vp92+>e[>S,B2ME\)S7:@oo6@nF8`I+h##OY3a-n#Qm!>5jiD.9pQ@E1#Xj$=)27)F3RmD%fbqZh,T`gJd0/,?A3`0:_VVm`"l`>oOf9p&HGF7>WCGVJoD2&_+c#BDb)/&0>>rL5@]KY$9YOA<rrt#g)1a61mS([/:0_[`)!ctOhSA/p@bq]>qZHTJq8k]!o+?4a5\-KbB#NYJC'`~>endstream
|
||||
|
||||
endobj
|
||||
% 'R10': class PDFOutlines
|
||||
10 0 obj
|
||||
<< /Count 0
|
||||
/Type /Outlines >>
|
||||
endobj
|
||||
xref
|
||||
0 11
|
||||
0000000000 65535 f
|
||||
0000000113 00000 n
|
||||
0000000233 00000 n
|
||||
0000000398 00000 n
|
||||
0000000573 00000 n
|
||||
0000000740 00000 n
|
||||
0000001017 00000 n
|
||||
0000001152 00000 n
|
||||
0000001395 00000 n
|
||||
0000001500 00000 n
|
||||
0000002169 00000 n
|
||||
trailer
|
||||
<< /ID
|
||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
||||
[(\210\344\006bE\230CUUi\010[\)Qif) (\210\344\006bE\230CUUi\010[\)Qif)]
|
||||
|
||||
/Info 7 0 R
|
||||
/Root 6 0 R
|
||||
/Size 11 >>
|
||||
startxref
|
||||
2221
|
||||
%%EOF
|
||||
@@ -37,6 +37,9 @@
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
'demo_xml': [],
|
||||
'test': [
|
||||
'test/document_ftp_test.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': None,
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
- |
|
||||
In order to test the document_ftp module in OpenERP, I will try different operation on the FTP interface, and check their impacts on OpenERP's documents and vice-versa.
|
||||
-
|
||||
In order to test behaviour of resource Directory I will make one resource Directory "Labels" in OpenERP having type "Other Resources" and Directory mapped to object "Partner"
|
||||
-
|
||||
!record {model: 'document.directory', id: dir_label}:
|
||||
name : "Labels"
|
||||
storage_id : document.storage_default
|
||||
type : ressource
|
||||
content_ids:
|
||||
- name: "Label"
|
||||
report_id : base.res_partner_address_report
|
||||
-
|
||||
Assign "res.partner" object to ressource_type_id.
|
||||
-
|
||||
!python {model: document.directory}: |
|
||||
ids = self.pool.get('ir.model').search(cr, uid, [('model','=','res.partner')])
|
||||
id = self.write(cr, uid, [ref("dir_label")], {'ressource_type_id' : ids[0]}, context)
|
||||
-
|
||||
In order to check static directory in OpenERP which is the real directory just like system's local folders,
|
||||
First I create a directory in OpenERP named "Directory 1" with storage as "Default File storage" and type as "Static Directory"
|
||||
-
|
||||
!record {model: 'document.directory', id: directory_file}:
|
||||
name : "File"
|
||||
storage_id : document.storage_default
|
||||
type : directory
|
||||
-
|
||||
I am create a one Document name "Document" and select "File" as its Directory,
|
||||
-
|
||||
When I am creating the record then "Resource Title" is filled automatic with "Document".
|
||||
-
|
||||
!record {model: 'ir.attachment', id: document_1}:
|
||||
name : "Document"
|
||||
parent_id : directory_file
|
||||
-
|
||||
In order to connect FTP server and set "File" path.
|
||||
I create one directory "New" in "File" directory from FTP and check its effect in OpenERP
|
||||
-
|
||||
Also Rename the directory name "New" to "New Directory".
|
||||
-
|
||||
Remove directory "New Directory" and remove file "Document".
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from ftplib import FTP
|
||||
from tools.misc import detect_ip_addr
|
||||
from tools import config
|
||||
ftp = FTP()
|
||||
if detect_ip_addr:
|
||||
host = config.get('ftp_server_host', detect_ip_addr())
|
||||
else:
|
||||
host = config.get('ftp_server_host', '127.0.0.1')
|
||||
port = config.get('ftp_server_port','8021')
|
||||
ftp.connect(host,port)
|
||||
user = self.pool.get('res.users').read(cr, uid, uid, context)
|
||||
ftp.login(user.get('login',''),user.get('password',''))
|
||||
ftp.cwd("/" + cr.dbname+"/Documents/File/")
|
||||
ftp.mkd("New")
|
||||
ftp.rename('New','New Directory')
|
||||
ftp.cwd("/" + cr.dbname+"/Documents/File/")
|
||||
ftp.rmd('New Directory')
|
||||
ftp.delete('Document')
|
||||
ftp.quit()
|
||||
-
|
||||
In order to check directory created from FTP is working perfectly
|
||||
-
|
||||
Now I will test the same for Resource directory which is mapped with OpenERP object.
|
||||
When you open this directory from FTP clients, it displays each records of mapped resource object as directory.
|
||||
-
|
||||
Now I test FTP client and Open the "Labels" Directory to check Resource Directory in FTP.
|
||||
I can see that all Label of OpenERP are shown as children of "Labels" in FTP client as Directories
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from ftplib import FTP
|
||||
from tools.misc import detect_ip_addr
|
||||
from tools import config
|
||||
ftp = FTP()
|
||||
if detect_ip_addr:
|
||||
host = config.get('ftp_server_host', detect_ip_addr())
|
||||
else:
|
||||
host = config.get('ftp_server_host', '127.0.0.1')
|
||||
port = config.get('ftp_server_port','8021')
|
||||
ftp.connect(host,port)
|
||||
user = self.pool.get('res.users').read(cr, uid, uid, context)
|
||||
ftp.login(user.get('login',''),user.get('password',''))
|
||||
ftp.cwd("/" + cr.dbname+"/Documents/Labels/")
|
||||
-
|
||||
I make sure that I Open Labels Directory successfully.
|
||||
@@ -43,6 +43,7 @@
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
'demo_xml': [],
|
||||
'test':['test/test_idea.yml'],
|
||||
'installable': True,
|
||||
'certificate': '0071515601309',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
- |
|
||||
In order to test the Idea module in OpenERP,
|
||||
we will create a full flow, from the idea definition up to the votes and discussions on the idea.
|
||||
- |
|
||||
Given that I have an Idea category "Technical".
|
||||
-
|
||||
!record {model: idea.category, id: idea_category_technical0}:
|
||||
name: Technical
|
||||
- |
|
||||
I create a New Idea of "Technical presentation for 1 hours in every day" and specify category "Technical".
|
||||
|
||||
-
|
||||
!record {model: idea.idea, id: idea_idea_0}:
|
||||
category_id: idea_category_technical0
|
||||
description: I want that Technical presentation are arranged for 1 hours in every
|
||||
day.\nso, on that presentation, we can know all things what improvement and development
|
||||
are done in our company.\n\n\n\n\n
|
||||
title: Technical presentation for 1 hours in every day
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
I check that idea on draft state.
|
||||
-
|
||||
!assert {model: idea.idea, id: idea_idea_0}:
|
||||
- state == 'draft'
|
||||
|
||||
- |
|
||||
I open this idea by click on "Open" button.
|
||||
-
|
||||
!workflow {model: idea.idea, action: idea_open, ref: idea_idea_0}
|
||||
|
||||
- |
|
||||
In order to check voting statistics in real systems I will create 2 new Users "user1".
|
||||
-
|
||||
!record {model: res.users, id: res_users_user0}:
|
||||
company_id: base.main_company
|
||||
context_lang: en_US
|
||||
login: user1
|
||||
name: user1
|
||||
password: user1
|
||||
- |
|
||||
And I will also create user2.
|
||||
-
|
||||
!record {model: res.users, id: res_users_user1}:
|
||||
company_id: base.main_company
|
||||
context_lang: en_US
|
||||
login: user2
|
||||
name: user2
|
||||
password: user2
|
||||
|
||||
- |
|
||||
In order to post vote I connect as user1 and open the idea page
|
||||
I click on "Vote" wizard and vote the idea as "Normal"
|
||||
-
|
||||
!record {model: idea.post.vote, id: idea_post_vote_0}:
|
||||
vote: 50
|
||||
- |
|
||||
Now I click on "Post Vote" button of wizard.
|
||||
-
|
||||
!python {model: idea.post.vote}: |
|
||||
uid = ref('res_users_user0')
|
||||
self.do_vote(cr, uid, [ref("idea_post_vote_0")], {'active_id': ref('idea_idea_0')})
|
||||
|
||||
- |
|
||||
To add other vote I connect as user2 and open the idea page
|
||||
I click on "Vote" wizard and vote the idea as "Very Good"
|
||||
|
||||
-
|
||||
!record {model: idea.post.vote, id: idea_post_vote_1}:
|
||||
vote: 100
|
||||
|
||||
- |
|
||||
I click on "Post Vote" button of this wizard.
|
||||
-
|
||||
!python {model: idea.post.vote}: |
|
||||
uid = ref('res_users_user1')
|
||||
self.do_vote(cr, uid, [ref("idea_post_vote_1")], {'active_id': ref('idea_idea_0')})
|
||||
|
||||
- |
|
||||
I can see that the Average score changed in "Average score" field with value 75
|
||||
-
|
||||
!record {model: idea.idea, id: idea_idea_0}:
|
||||
vote_avg: 75
|
||||
|
||||
- |
|
||||
I put one comment "We can learn many things from technical presentation" for the idea.
|
||||
-
|
||||
!record {model: idea.idea, id: idea.idea_idea_0}:
|
||||
comment_ids:
|
||||
- content: We can learn many things from technical presentation
|
||||
idea_id: idea.idea_idea_0
|
||||
user_id: res_users_user1
|
||||
- |
|
||||
I connect as Manager and close this idea by click on "Close" button.
|
||||
-
|
||||
!workflow {model: idea.idea, action: idea_close, ref: idea_idea_0}
|
||||
|
||||
- |
|
||||
I check that the idea's state is now Accepted
|
||||
-
|
||||
!assert {model: idea.idea, id: idea_idea_0}:
|
||||
- state == 'close'
|
||||
|
||||
@@ -47,7 +47,10 @@
|
||||
'lunch_report.xml',
|
||||
#'process/lunch_process.xml'
|
||||
],
|
||||
"demo_xml": ['lunch_demo.xml'],
|
||||
"demo_xml": ['lunch_demo.xml',
|
||||
],
|
||||
"test": ['test/test_lunch.yml'
|
||||
],
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
|
||||
+1
-13
@@ -42,21 +42,9 @@ class lunch_product(osv.osv):
|
||||
_name = 'lunch.product'
|
||||
_description = "Lunch Product"
|
||||
|
||||
def _category_name_get(self, cr, uid, context={}):
|
||||
|
||||
""" Get category name
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param context: A standard dictionary for contextual values"""
|
||||
|
||||
obj = self.pool.get('lunch.category')
|
||||
cat_ids = obj.search(cr, uid, [])
|
||||
res = obj.read(cr, uid, cat_ids, ['name', 'category'])
|
||||
return [(str(r['id']), r['name']) for r in res]+ [('0','')]
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=50, required=True),
|
||||
'category_id': fields.selection(_category_name_get, 'Category', size=32),
|
||||
'category_id': fields.many2one('lunch.category', 'Category'),
|
||||
'description': fields.char('Description', size=128, required=False),
|
||||
'price': fields.float('Price', digits=(16,2)),
|
||||
'active': fields.boolean('Active'),
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Products">
|
||||
<field name="name" select="1"/>
|
||||
<field name="category_id" select="1"/>
|
||||
<field name="category_id" widget='selection' select="1"/>
|
||||
<field name="description" select="1"/>
|
||||
<field name="price" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
- |
|
||||
In order to test the Lunch module in OpenERP,
|
||||
I will create one lunch order and then check the effect on cashboxes and cashmoves
|
||||
|
||||
- |
|
||||
Given that I have a category of lunch products "Burger".
|
||||
-
|
||||
!record {model: lunch.category, id: lunch_category_burger0}:
|
||||
name: Burger
|
||||
- |
|
||||
Given that I have a product "Club1" in this category with a price of "2.75".
|
||||
|
||||
-
|
||||
!record {model: lunch.product, id: lunch_product_club1}:
|
||||
category_id: lunch_category_burger0
|
||||
name: Club1
|
||||
price: 2.75
|
||||
- |
|
||||
Given that I have a cashbox "Employee Cashbox"
|
||||
-
|
||||
!record {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
|
||||
manager: base.user_root
|
||||
name: Employee Cashbox
|
||||
- |
|
||||
I create a lunch order "LU001" for the "Club1" product
|
||||
- |
|
||||
When I select the product "club1", the price of 2.75 is automatically proposed
|
||||
-
|
||||
!record {model: lunch.order, id: lunch_order_0}:
|
||||
date: '2010-04-19'
|
||||
product: 'lunch_product_club1'
|
||||
price: 2.75
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
I check that lunch order is on draft state after having created it.
|
||||
-
|
||||
!assert {model: lunch.order, id: lunch_order_0}:
|
||||
- state == 'draft'
|
||||
- |
|
||||
I confirm the order "LU001" using the "Confirm Order" wizard.
|
||||
-
|
||||
!record {model: lunch.order.confirm, id: lunch_order_confirm_0}:
|
||||
confirm_cashbox: 'lunch_cashbox_cashbox0'
|
||||
-
|
||||
I click on "Confirm Order" button of this wizard.
|
||||
-
|
||||
!python {model: lunch.order.confirm}: |
|
||||
self.confirm(cr, uid, [ref('lunch_order_confirm_0')], {'active_ids': [ref('lunch_order_0')]})
|
||||
|
||||
- |
|
||||
I check that the Cash Moves have been generated with the right box
|
||||
name
|
||||
-
|
||||
!assert {model: lunch.order, id: lunch_order_0}:
|
||||
- cashmove.id != False
|
||||
|
||||
- |
|
||||
I check that the Total on the "Employee Cashbox" is -2.75
|
||||
|
||||
-
|
||||
!assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
|
||||
- sum_remain == -2.75
|
||||
|
||||
- |
|
||||
I create a new lunch order "LU002" for the "Club1" product, at another date.
|
||||
-
|
||||
!record {model: lunch.order, id: lunch_order_1}:
|
||||
date: '2010-04-22'
|
||||
product: 'lunch_product_club1'
|
||||
price: 2.75
|
||||
user_id: base.user_root
|
||||
|
||||
- |
|
||||
I confirm this order.open wizard and select "Employee Cashbox".
|
||||
-
|
||||
!record {model: lunch.order.confirm, id: lunch_order_confirm_1}:
|
||||
confirm_cashbox: 'lunch_cashbox_cashbox0'
|
||||
- |
|
||||
Now I click on "Confirm Order" button of this wizard.
|
||||
-
|
||||
!python {model: lunch.order.confirm}: |
|
||||
self.confirm(cr, uid, [ref('lunch_order_confirm_1')], {'active_ids': [ref('lunch_order_1')]})
|
||||
|
||||
- |
|
||||
I check that the Total on the "Employee Cashbox" is -5.50
|
||||
-
|
||||
!assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
|
||||
- sum_remain == -5.50
|
||||
- |
|
||||
I reset the "Employee Cashbox" to zero using the "Set CashBox to Zero" wizard.
|
||||
-
|
||||
!record {model: lunch.cashbox.clean, id: lunch_cashbox_clean_0}:
|
||||
{}
|
||||
-
|
||||
Now click on "Set to Zero" button of this wizard.
|
||||
-
|
||||
!python {model: lunch.cashbox.clean, id: lunch_cashbox_clean_0}: |
|
||||
self.set_to_zero(cr, uid, [ref('lunch_cashbox_clean_0')], {'active_ids': [ref('lunch_cashbox_cashbox0')]})
|
||||
|
||||
- |
|
||||
I check that the Total on the "Employee Cashbox" is 0.0
|
||||
-
|
||||
!assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
|
||||
- sum_remain == 0.00
|
||||
|
||||
- |
|
||||
I cancel the order "LU002"
|
||||
-
|
||||
!record {model: lunch.order.cancel, id: lunch_order_cancel_0}:
|
||||
{}
|
||||
- |
|
||||
I click on "Yes" button of this wizard for cancel order.
|
||||
|
||||
-
|
||||
!python {model: lunch.order.cancel}: |
|
||||
self.cancel(cr, uid, [ref('lunch_order_cancel_0')], {'active_ids': [ref('lunch_order_1')]})
|
||||
|
||||
- |
|
||||
I test that the Cash Moves revord have been removed for the order LU002.
|
||||
-
|
||||
!assert {model: lunch.order, id: lunch_order_1}:
|
||||
- cashmove.id == False
|
||||
|
||||
- |
|
||||
I check that the Total on the "Employee Cashbox" is -2.75
|
||||
-
|
||||
!assert {model: lunch.cashbox, id: lunch_cashbox_cashbox0}:
|
||||
- sum_remain == -2.75
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
"data/olap_security.xml",
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
"demo_xml" : ["data/olap_demo.xml",
|
||||
"test/olap_test00.yml"],
|
||||
"demo_xml" : ["data/olap_demo.xml"],
|
||||
"test" : ['test/olap_test00.yml'],
|
||||
"active": False,
|
||||
"installable": True
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ class olap_load_column(osv.osv_memory):
|
||||
model_data_ids = self.pool.get('ir.model.data').search(cr, uid, \
|
||||
[('model', '=', 'ir.ui.view'), \
|
||||
('name', '=', 'view_olap_database_columns_form')], context={})
|
||||
print "model_ids", model_data_ids
|
||||
resource_id = self.pool.get('ir.model.data').read(cr, uid, \
|
||||
model_data_ids, fields=['res_id'])[0]['res_id']
|
||||
return {
|
||||
|
||||
@@ -47,4 +47,4 @@
|
||||
##############################################################################
|
||||
|
||||
import partner
|
||||
|
||||
import installer
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
Select a section for which you want to create case.''',
|
||||
"init_xml" : [],
|
||||
"demo_xml" : [],
|
||||
"update_xml" : ['security/ir.model.access.csv'],
|
||||
"update_xml" : ['thunderbird_installer.xml',
|
||||
'security/ir.model.access.csv'],
|
||||
"active": False,
|
||||
"installable": True
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields
|
||||
from osv import osv
|
||||
from tools import config
|
||||
|
||||
import base64
|
||||
|
||||
class thunderbird_installer(osv.osv_memory):
|
||||
_name = 'thunderbird.installer'
|
||||
_inherit = 'res.config.installer'
|
||||
|
||||
def process_plugin(self, cr, uid, ids, context):
|
||||
"""
|
||||
Default Attach Thunderbird Plug-in File.
|
||||
"""
|
||||
data = {}
|
||||
file = open(config['addons_path'] + "/thunderbird/plugin/tiny_plugin-2.0.xpi", 'r')
|
||||
data['plugin_file'] = base64.encodestring(file.read())
|
||||
self.write(cr, uid, ids, data)
|
||||
return False
|
||||
|
||||
_columns = {
|
||||
'name':fields.char('File name', size=34, required=True, help='Save Thunderbird plugin file.'),
|
||||
'thunderbird':fields.boolean('Thunderbird Module ', help="Allows you to select an object that you’d like to add to your email and its attachments."),
|
||||
'plugin_file':fields.binary('Thunderbird Plug-in', readonly=True, help="Thunderbird plug-in file. Save as this file and install this plug-in in thunderbir."),
|
||||
|
||||
}
|
||||
_defaults = {
|
||||
'thunderbird' : True,
|
||||
'name' : 'tiny_plugin-2.0.xpi',
|
||||
}
|
||||
|
||||
thunderbird_installer()
|
||||
@@ -92,9 +92,9 @@ class tinythunderbird_partner(osv.osv):
|
||||
partner=add_obj.read(cr,user,partner_ids,['partner_id'])
|
||||
if partner:
|
||||
dictcreate.update({'partner_id':partner[0]['partner_id'][0]})
|
||||
search_id = self.pool.get('res.request.link').search(cr,user,[('object','=',dictcreate['ref'].split(',')[0])])
|
||||
if not search_id:
|
||||
create_link_id = self.pool.get('res.request.link').create(cr,user,{'name':dictcreate['ref'].split(',')[0],'object':dictcreate['ref'].split(',')[0]})
|
||||
# search_id = self.pool.get('res.request.link').search(cr,user,[('object','=',dictcreate['ref'].split(',')[0])])
|
||||
# if not search_id:
|
||||
# create_link_id = self.pool.get('res.request.link').create(cr,user,{'name':dictcreate['ref'].split(',')[0],'object':dictcreate['ref'].split(',')[0]})
|
||||
create_id = self.pool.get(dictcreate.get('object','crm.case')).create(cr, user, dictcreate)
|
||||
cases=case_pool.browse(cr,user,[create_id])
|
||||
case_pool._history(cr, user, cases, _('Archive'), history=True, email=False)
|
||||
@@ -162,12 +162,15 @@ class tinythunderbird_partner(osv.osv):
|
||||
dictcreate = dict(vals)
|
||||
datas = [dictcreate['datas']]
|
||||
name = [dictcreate['name']]
|
||||
f_name = [dictcreate['datas_fname']]
|
||||
if(dictcreate['datas'].__contains__(',')):
|
||||
name = dictcreate['name'].split(',')
|
||||
datas = dictcreate['datas'].split(',')
|
||||
f_name = dictcreate['datas_fname'].split(',')
|
||||
for i in range(0,datas.__len__()):
|
||||
dictcreate['name'] = name[i]
|
||||
dictcreate['datas'] = datas[i]
|
||||
dictcreate['datas_fname'] = f_name[i]
|
||||
create_id = self.pool.get('ir.attachment').create(cr,user,dictcreate)
|
||||
return 0
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,103 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_thunderbird_installer" model="ir.ui.view">
|
||||
<field name="name">thunderbird.installer.view</field>
|
||||
<field name="model">thunderbird.installer</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="base.res_config_installer"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<form position="attributes">
|
||||
<attribute name="string">Thunderbird Module Installation</attribute>
|
||||
</form>
|
||||
<separator string="title" position="attributes">
|
||||
<attribute name="string">Configure Thunderbird Module</attribute>
|
||||
</separator>
|
||||
<xpath expr="//label[@string='description']" position="attributes">
|
||||
<attribute name="string">This module is required for the thuderbird plug-in to work properly.This allows you to select an object that you had like to add to your email and its attachments. You can select a partner, a task, a project, an analytical account, or any other object and attach selected mail as .eml file in attachment of selected record.</attribute>
|
||||
</xpath>
|
||||
<group colspan="8">
|
||||
<separator string="Thunderbird" colspan="4"/>
|
||||
<field name="thunderbird"/>
|
||||
<field name="name" invisible="1"/>
|
||||
<newline/>
|
||||
|
||||
<field name="plugin_file"/>
|
||||
<button name="process_plugin" icon="gtk-execute" string="Get Plugin File" type="object"/>
|
||||
<newline/>
|
||||
<separator string="Thunderbird plugin installation note." colspan="4"/>
|
||||
<label colspan="8" string="Save The thunderbird plugin Follow the following step to install thunderbird plugin ? 1. From Menu Bar, Open Tools > Add ons. 2. Now click on install button and a browser window will appear. 3. Just select the (.xpi) file from thunderbird/plugin directory and click ok, a new software installation window will appear and within a short time Install Now button will be enabled. 4. Click on Install Now and restart Thunderbird. 5. Now Thunderbird plugin is installed."/>
|
||||
</group>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_thunderbird_installer" model="ir.actions.act_window">
|
||||
<field name="name">Thunderbird Module Installation</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">thunderbird.installer</field>
|
||||
<field name="view_id" ref="view_thunderbird_installer"/>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record id="thunderbird_installer_todo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_thunderbird_installer"/>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
|
||||
<!-- Configuration wizard. -->
|
||||
|
||||
<record id="view_thunderbird_wizard" model="ir.ui.view">
|
||||
<field name="name">thunderbird.wizard</field>
|
||||
<field name="model">thunderbird.installer</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string= "Thunderbird Installation">
|
||||
<group colspan="4">
|
||||
<separator string="Configure Thunderbird Module" colspan="4"/>
|
||||
<group colspan="4" col="10">
|
||||
<group colspan="2">
|
||||
<image name="gtk-dialog-info"/>
|
||||
<newline/>
|
||||
<label align="0.0" string="This module is required for the thuderbird plug-in to work properly.This allows you to select an object that you had like to add to your email and its attachments. You can select a partner, a task, a project, an analytical account, or any other object and attach selected mail as .eml file in attachment of selected record." width="200"/>
|
||||
</group>
|
||||
<group colspan="8">
|
||||
<separator string="Thunderbird" colspan="4"/>
|
||||
<field name="thunderbird"/>
|
||||
<field name="name" invisible="1"/>
|
||||
<newline/>
|
||||
<field name="plugin_file"/>
|
||||
<button name="process_plugin" icon="gtk-execute" string="Get Plugin File" type="object"/>
|
||||
<newline/>
|
||||
<separator string="Thunderbird plugin installation note." colspan="4"/>
|
||||
<label colspan="8" string="Save The thunderbird plugin Follow the following step to install thunderbird plugin ? 1. From Menu Bar, Open Tools > Add ons. 2. Now click on install button and a browser window will appear. 3. Just select the (.xpi) file from thunderbird/plugin directory and click ok, a new software installation window will appear and within a short time Install Now button will be enabled. 4. Click on Install Now and restart Thunderbird. 5. Now Thunderbird plugin is installed."/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<separator string="" colspan="4"/>
|
||||
<group colspan="4">
|
||||
<label align="0.0" string="" colspan="3"/>
|
||||
<button colspan="1" icon="gtk-cancel" special="cancel" string="Cancel"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_thunderbird_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Thunderbird Module Installation</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">thunderbird.installer</field>
|
||||
<field name="view_id" ref="view_thunderbird_wizard"/>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_base_config_plugins" name="Plugins" parent="base.menu_base_config" sequence="10" />
|
||||
<menuitem id="menu_base_config_plugins_thunderbird" action="action_thunderbird_wizard" name="Thunderbird" parent="menu_base_config_plugins" sequence="10" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -42,8 +42,8 @@
|
||||
'data/wiki_main.xml',
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
'demo_xml': ['test/wiki_test00.yml'],
|
||||
# 'test': ['test/wiki_test00.yml'],
|
||||
'demo_xml': [],
|
||||
'test': ['test/wiki_test00.yml'],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '0086363630317',
|
||||
|
||||
Reference in New Issue
Block a user