From 80118df2c59b9d7cbb862ac1e6ecb1690aa4f93b Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Sat, 10 Jul 2010 10:46:19 +0530 Subject: [PATCH 01/17] [IMP] procurement : If product type service and project_mrp not installed then set procurement state exception bzr revid: sbh@tinyerp.com-20100710051619-g42mmwlq3cyc4tbu --- addons/procurement/procurement.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index b098d279d78..34a5c029d51 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -228,7 +228,14 @@ class procurement_order(osv.osv): return False def check_produce_service(self, cr, uid, procurement, context=[]): - return True + """ Checks project_mrp install or not. + @return: True or False""" + obj_module = self.pool.get('ir.module.module') + module_id = obj_module.search(cr, uid, [('name', '=', 'project_mrp'),('state', '=', 'installed')]) + if module_id: + return True + cr.execute('update procurement_order set message=%s where id=%s', (_('Project_mrp module not installed !'), procurement.id)) + return False def check_produce_product(self, cr, uid, procurement, context=[]): """ Finds BoM of a product if not found writes exception message. @@ -344,6 +351,10 @@ class procurement_order(osv.osv): return True def _check_make_to_stock_service(self, cr, uid, procurement, context={}): + """ + This method may be overrided by objects that override procurement.order + for computing their own purpose + @return: True""" return True def _check_make_to_stock_product(self, cr, uid, procurement, context={}): From 71fc32abc75c5da504036979b6ab59594a19d4db Mon Sep 17 00:00:00 2001 From: "rpa (Open ERP)" Date: Sat, 10 Jul 2010 11:37:54 +0530 Subject: [PATCH 02/17] [IMP]: crm: Improvement in statistics report and crm board bzr revid: rpa@tinyerp.com-20100710060754-u9wqiqkta9lloala --- addons/crm/board_crm_statistical_view.xml | 6 +++--- addons/crm/board_crm_view.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/crm/board_crm_statistical_view.xml b/addons/crm/board_crm_statistical_view.xml index b23fdeac1cd..01d0472c21e 100644 --- a/addons/crm/board_crm_statistical_view.xml +++ b/addons/crm/board_crm_statistical_view.xml @@ -36,7 +36,7 @@ - + @@ -60,7 +60,7 @@ - Number of Opportunities by stage + Planned revenue by user and stage crm.lead.report form graph,tree,form @@ -93,7 +93,7 @@ diff --git a/addons/crm/board_crm_view.xml b/addons/crm/board_crm_view.xml index ed6044a6fd6..ccaf0f7e35c 100644 --- a/addons/crm/board_crm_view.xml +++ b/addons/crm/board_crm_view.xml @@ -51,7 +51,7 @@ form graph,tree,form - ['&', ('user_id','=',uid), '!' , '&', ('state', '=', 'done'), ('date_closed','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))] + ['&', '&', ('user_id','=',uid), ('type', '=', 'opportunity'), '!' , '&', ('state', '=', 'done'), ('date_closed','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%Y-%m-%d'))] @@ -84,11 +84,11 @@ From 1e839d87977dd845d70d5633acf70bb08a16ce41 Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Sat, 10 Jul 2010 12:00:54 +0530 Subject: [PATCH 03/17] [Fix] sale: fix the argument name of product_id_change bzr revid: sbh@tinyerp.com-20100710063054-cezdzk6yj8lo2ktz --- addons/sale/wizard/sale_make_invoice_advance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index 82a5f1c2d16..19c23eca13f 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -64,7 +64,7 @@ class sale_advance_payment_inv(osv.osv_memory): _("You cannot make an advance on a sale order \ that is defined as 'Automatic Invoice after delivery'.")) val = obj_lines.product_id_change(cr, uid, [], sale_adv_obj.product_id.id, - uom = False, partner_id = sale.partner_id.id, fiscal_position = sale.fiscal_position.id) + uom = False, partner_id = sale.partner_id.id, fposition_id = sale.fiscal_position.id) line_id =obj_lines.create(cr, uid, { 'name': val['value']['name'], 'account_id': val['value']['account_id'], From 60de30c62feb3ee2bff5e700d55efece75a47975 Mon Sep 17 00:00:00 2001 From: "ATP (OpenERP)" <> Date: Sat, 10 Jul 2010 13:55:32 +0530 Subject: [PATCH 04/17] [Fix]: project_retro_planning: Fix the problem of dateformat in yml bzr revid: sbh@tinyerp.com-20100710082532-suz4vr7ir9xate1e --- .../test/deadline_change.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/project_retro_planning/test/deadline_change.yml b/addons/project_retro_planning/test/deadline_change.yml index 717dccd5d97..b5f65d5b6eb 100644 --- a/addons/project_retro_planning/test/deadline_change.yml +++ b/addons/project_retro_planning/test/deadline_change.yml @@ -3,10 +3,9 @@ - !record {model: project.project, id: project_project_retroplanning0}: company_id: base.main_company - date: '2010-06-10' + date: !eval time.strftime('%Y-%m-%d') name: Retro Planning - - Create task 'Plan all projects' - @@ -19,12 +18,11 @@ project_id: project_project_retroplanning0 remaining_hours: 24.0 state: draft - - Check if task deadline_date and start_date changes upon changing its project's end_date - !python {model: project.project}: | - from datetime import datetime, date + from datetime import datetime, date, timedelta import time data_project = self.browse(cr,uid,[ref("project_project_retroplanning0")]) prj = data_project[0] @@ -32,17 +30,19 @@ if prj.date: old_end_date = date(*time.strptime(prj.date,'%Y-%m-%d')[:3]) if old_end_date: - new_end_date = date(*time.strptime('2010-06-10','%Y-%m-%d')[:3]) + new_end_date = date.today()+timedelta(1) res={} for task in prj.tasks: start_dt = (datetime(*time.strptime(task.date_start,'%Y-%m-%d %H:%M:%S')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d %H:%M:%S') deadline_dt='' if task.date_deadline: - deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d') + deadline_dt = (datetime(*time.strptime(task.date_deadline,'%Y-%m-%d')[:6])+(new_end_date-old_end_date)).strftime('%Y-%m-%d') res[task.id]=[start_dt,deadline_dt] - self.write(cr, uid, [ref("project_project_retroplanning0")], {'date':'2010-06-10'}) + self.write(cr, uid, [ref("project_project_retroplanning0")], {'date' : (datetime.datetime.now()+datetime.timedelta(1)).strftime('%Y-%m-%d') +}) data_project = self.browse(cr,uid,[ref("project_project_retroplanning0")]) prj = data_project[0] + for task in prj.tasks: assert task.date_start == res[task.id][0], "task start date differs, expected %s, got %s"%(res[task.id][0], task.date_start) assert task.date_deadline == res[task.id][1], "task deadline date differs, expected %s, got %s"%(res[task.id][1], task.date_deadline) \ No newline at end of file From 6102a64b4fa0bcf03e792d331b32b90c9efcb4a1 Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Sat, 10 Jul 2010 13:58:03 +0530 Subject: [PATCH 05/17] [ADD] purchase: Add the yml of procument bzr revid: sbh@tinyerp.com-20100710082803-jsyzlbttjqdmfo7x --- addons/purchase/purchase_workflow.xml | 1 + addons/purchase/test/procurement_buy.yml | 109 +++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 addons/purchase/test/procurement_buy.yml diff --git a/addons/purchase/purchase_workflow.xml b/addons/purchase/purchase_workflow.xml index a194cd16713..d14530e5f48 100644 --- a/addons/purchase/purchase_workflow.xml +++ b/addons/purchase/purchase_workflow.xml @@ -103,6 +103,7 @@ + purchase_approve diff --git a/addons/purchase/test/procurement_buy.yml b/addons/purchase/test/procurement_buy.yml new file mode 100644 index 00000000000..011e70d0cdc --- /dev/null +++ b/addons/purchase/test/procurement_buy.yml @@ -0,0 +1,109 @@ +- + In order to test the procurement with product type buy in OpenERP, I will create product + and then I will create procurement for this product. +- + I create product. +- + !record {model: product.product, id: product_product_cddrive0}: + categ_id: product.product_category_3 + cost_method: standard + mes_type: fixed + name: CD drive + procure_method: make_to_order + supply_method: buy + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit + valuation: manual_periodic + volume: 0.0 + warranty: 0.0 + weight: 0.0 + weight_net: 0.0 + seller_ids: + - delay: 1 + name: base.res_partner_asus + qty: 5.0 +- + I create procurement order. +- + !record {model: procurement.order, id: procurement_order_testcase0}: + company_id: base.main_company + date_planned: '2010-07-07 15:38:53' + location_id: stock.stock_location_stock + name: Test Case + priority: '1' + procure_method: make_to_order + product_id: product_product_cddrive0 + product_qty: 5.0 + product_uom: product.product_uom_unit + product_uos: product.product_uom_unit + product_uos_qty: 0.0 + state: draft +- + I confirm on procurement order. +- + !workflow {model: procurement.order, action: button_confirm, ref: procurement_order_testcase0} +- + I run the scheduler. +- + !workflow {model: procurement.order, action: button_check, ref: procurement_order_testcase0} +- + I check that purchase order is generated. +- + !python {model: procurement.order}: | + from tools.translate import _ + proc_ids = self.browse(cr, uid, [ref('procurement_order_testcase0')])[0] + assert(proc_ids.purchase_id), _('Purchase Order is not Created!') +- + I check the state is running. +- + !python {model: procurement.order}: | + from tools.translate import _ + proc_ids = self.browse(cr, uid, [ref('procurement_order_testcase0')])[0] + assert(proc_ids.state == 'running'), _('Exception') +- + I confirm and Approve the purchase order. +- + !python {model: purchase.order}: | + procurement_obj = self.pool.get('procurement.order') + proc_ids = procurement_obj.browse(cr, uid, [ref('procurement_order_testcase0')])[0] + import netsvc + wf_service = netsvc.LocalService("workflow") + wf_service.trg_validate(uid, 'purchase.order',proc_ids.purchase_id.id,'purchase_confirm', cr) + wf_service.trg_validate(uid, 'purchase.order',proc_ids.purchase_id.id,'purchase_approve', cr) +- + I receive the order of the supplier ASUStek from the Incoming Shipments menu. +- + !python {model: stock.picking }: | + import time + procurement_obj = self.pool.get('procurement.order') + proc_ids = procurement_obj.browse(cr, uid, [ref('procurement_order_testcase0')])[0] + picking_id = self.search(cr, uid, [('origin', '=', proc_ids.purchase_id.name)]) + if picking_id: + pick=self.browse(cr,uid,picking_id[0]) + move =pick.move_lines[0] + partial_datas = { + 'partner_id':pick.address_id.partner_id.id, + 'address_id': pick.address_id.id, + 'delivery_date' : time.strftime('%Y-%m-%d') + } + partial_datas['move%s'%(move.id)]= { + 'product_id': move.product_id, + 'product_qty': move.product_qty, + 'product_uom': move.product_uom.id, + } + self.do_partial(cr, uid, picking_id,partial_datas) +- + I confirm the Reservation. +- + !python {model: stock.move }: | + procurement_obj = self.pool.get('procurement.order') + proc_ids = procurement_obj.browse(cr, uid, [ref('procurement_order_testcase0')])[0] + self.action_done(cr,uid,[proc_ids.move_id.id]) +- + I check the state is Done. +- + !python {model: procurement.order}: | + from tools.translate import _ + proc_ids = self.browse(cr, uid, [ref('procurement_order_testcase0')])[0] + assert(proc_ids.state == 'done'), _('Order is not in done state') From 2128bb753a14157a7afaa7976e7e28ed3268f9d5 Mon Sep 17 00:00:00 2001 From: "Vir (Open ERP)" Date: Sat, 10 Jul 2010 14:46:49 +0530 Subject: [PATCH 06/17] [Fix] Event : problem badge and product are fixed bzr revid: vir@tinyerp.com-20100710091649-qxgphaf6v4dwy029 --- addons/event/event.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/event/event.py b/addons/event/event.py index 73ff7f6755a..8efa132477b 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -454,7 +454,7 @@ and users by email"), contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact) data['badge_name'] = contact_id.name - data['badge_title'] = contact_id.title + data['badge_title'] = contact_id.title.name if partner: partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', partner)]) job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id', '=', contact), ('address_id', 'in', partner_addresses)]) @@ -471,7 +471,9 @@ and users by email"), data_event = self.pool.get('event.event').browse(cr, uid, event_id) context['currency_id'] = data_event.currency_id.id - + if data_event.user_id.id: + return {'value': {'user_id':data_event.user_id.id}} + if data_event.product_id: if not partner_invoice_id: unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id] @@ -516,6 +518,7 @@ and users by email"), data_event = self.pool.get('event.event').browse(cr, uid, event_id) if data_event.product_id: + data['event_product']=data_event.product_id.name if not partner_invoice_id: data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id] return {'value': data} From dc0b929b09a10ec5d06f14e8e0f0dc7cbbe38f80 Mon Sep 17 00:00:00 2001 From: "rpa (Open ERP)" Date: Sat, 10 Jul 2010 15:30:16 +0530 Subject: [PATCH 07/17] [ADD]: crm: * Added new objects for custom crm case and sections * Added a wizard to create Menus for custom cases bzr revid: rpa@tinyerp.com-20100710100016-n1tjsrvfnjgmifig --- addons/crm/__openerp__.py | 2 + addons/crm/crm.py | 82 ++++++ addons/crm/crm_view.xml | 257 ++++++++++++++++++ addons/crm/wizard/__init__.py | 2 + addons/crm/wizard/crm_custom_create_menu.py | 78 ++++++ .../wizard/crm_custom_create_menu_view.xml | 40 +++ 6 files changed, 461 insertions(+) create mode 100644 addons/crm/wizard/crm_custom_create_menu.py create mode 100644 addons/crm/wizard/crm_custom_create_menu_view.xml diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py index a490a800beb..f23b61df5ea 100644 --- a/addons/crm/__openerp__.py +++ b/addons/crm/__openerp__.py @@ -85,6 +85,8 @@ Create dashboard for CRM that includes: 'wizard/crm_forward_to_partner_view.xml', 'wizard/crm_send_email_view.xml', + 'wizard/crm_custom_create_menu_view.xml', + 'crm_view.xml', 'crm_action_rule_view.xml', diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 575c2a8a3e3..9dd021183f4 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -639,4 +639,86 @@ class res_partner(osv.osv): } res_partner() + +class crm_case_section_custom(osv.osv): + _name = "crm.case.section.custom" + _description = 'Custom CRM Case Section' + + _columns = { + 'name': fields.char('Case Section',size=64, required=True, translate=True), + 'code': fields.char('Section Code',size=8), + 'active': fields.boolean('Active'), + 'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"), + 'sequence': fields.integer('Sequence'), + 'user_id': fields.many2one('res.users', 'Responsible User'), + '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 section"), + 'parent_id': fields.many2one('crm.case.section', 'Parent Section'), + 'note': fields.text('Notes'), + } + + _defaults = { + 'active': 1, + 'allow_unlink': 1, + } + + _sql_constraints = [ + ('code_uniq', 'unique (code)', 'The code of the section must be unique !') + ] + + def _check_recursion(self, cr, uid, ids): + level = 100 + while len(ids): + cr.execute('SELECT DISTINCT parent_id FROM crm_case_section '\ + 'WHERE id IN %s', + (tuple(ids),)) + ids = filter(None, map(lambda x:x[0], cr.fetchall())) + if not level: + return False + level -= 1 + return True + _constraints = [ + (_check_recursion, 'Error ! You cannot create recursive sections.', ['parent_id']) + ] + +crm_case_section_custom() + + +class crm_case_custom(osv.osv, crm_case): + _name = 'crm.case.custom' + _inherit = 'mailgate.thread' + _description = "Custom CRM Case" + + _columns = { + 'id': fields.integer('ID', readonly=True), + 'name': fields.char('Name',size=64,required=True), + 'priority': fields.selection(AVAILABLE_PRIORITIES, 'Priority'), + 'active': fields.boolean('Active'), + 'description': fields.text('Description'), + 'section_id': fields.many2one('crm.case.section.custom', 'Section', required=True, select=True), + 'probability': fields.float('Probability (%)'), + 'email_from': fields.char('Partner Email', size=128), + 'email_cc': fields.char('CC', size=252), + 'partner_id': fields.many2one('res.partner', 'Partner'), + 'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"), + 'date': fields.datetime('Date'), + 'create_date': fields.datetime('Created' ,readonly=True), + 'date_deadline': fields.datetime('Deadline'), + 'date_closed': fields.datetime('Closed', readonly=True), + 'user_id': fields.many2one('res.users', 'Responsible'), + 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True), + 'ref' : fields.reference('Reference', selection=_links_get, size=128), + 'date_action_last': fields.datetime('Last Action', readonly=1), + 'date_action_next': fields.datetime('Next Action', readonly=1), + } + + _defaults = { + 'active': 1, + 'state': 'draft', + 'priority': AVAILABLE_PRIORITIES[2][0], + 'date': time.strftime('%Y-%m-%d %H:%M:%S'), + } + +crm_case_custom() + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/crm/crm_view.xml b/addons/crm/crm_view.xml index 74786ad91f6..e42a3db0584 100644 --- a/addons/crm/crm_view.xml +++ b/addons/crm/crm_view.xml @@ -428,5 +428,262 @@ + + + + + crm.case.section.custom.form + crm.case.section.custom + form + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + crm.case.section.custom.tree + crm.case.section.custom + tree + + + + + + + + + + + + + Custom Cases - Tree + crm.case.custom + tree + + + + + + + + + + + + + + + + + Custom Cases - Form + crm.case.custom + form + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +