diff --git a/addons/account/project/project_view.xml b/addons/account/project/project_view.xml
index 8590ee286d4..175a227a9ea 100644
--- a/addons/account/project/project_view.xml
+++ b/addons/account/project/project_view.xml
@@ -18,6 +18,7 @@
+
diff --git a/addons/account_analytic_analysis/__init__.py b/addons/account_analytic_analysis/__init__.py
index 9aae723c5cf..be5a6e43f73 100644
--- a/addons/account_analytic_analysis/__init__.py
+++ b/addons/account_analytic_analysis/__init__.py
@@ -20,7 +20,6 @@
##############################################################################
import account_analytic_analysis
-import cron_account_analytic_account
import res_config
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_analysis/__openerp__.py b/addons/account_analytic_analysis/__openerp__.py
index 5ff15c09076..99e4353afa1 100644
--- a/addons/account_analytic_analysis/__openerp__.py
+++ b/addons/account_analytic_analysis/__openerp__.py
@@ -38,7 +38,6 @@ Adds menu to show relevant information to each manager.You can also view the rep
'security/ir.model.access.csv',
'security/account_analytic_analysis_security.xml',
'account_analytic_analysis_view.xml',
- 'account_analytic_analysis_menu.xml',
'account_analytic_analysis_cron.xml',
'res_config_view.xml',
],
diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index 23d8faaffce..2238a9179fc 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -18,6 +18,8 @@
# along with this program. If not, see .
#
##############################################################################
+import datetime
+import time
from openerp.osv import osv, fields
from openerp.osv.orm import intersect, except_orm
@@ -484,7 +486,41 @@ class account_analytic_account(osv.osv):
res['value']['to_invoice'] = template.to_invoice.id
res['value']['pricelist_id'] = template.pricelist_id.id
return res
-account_analytic_account()
+
+ def cron_account_analytic_account(self, cr, uid, context=None):
+ remind = {}
+
+ def fill_remind(key, domain, write_pending=False):
+ base_domain = [
+ ('partner_id', '!=', False),
+ ('manager_id', '!=', False),
+ ('manager_id.email', '!=', False),
+ ]
+ base_domain.extend(domain)
+ accounts_ids = self.search(cr, uid, base_domain, context=context, order='name asc')
+ accounts = self.browse(cr, uid, accounts_ids, context=context)
+ for account in accounts:
+ if write_pending:
+ account.write({'state' : 'pending'}, context=context)
+ remind_user = remind.setdefault(account.manager_id.id, {})
+ remind_type = remind_user.setdefault(key, {})
+ remind_partner = remind_type.setdefault(account.partner_id, []).append(account)
+
+ # Already expired
+ fill_remind("old", [('state', 'in', ['pending'])])
+
+ # Expires now
+ fill_remind("new", [('state', 'in', ['draft', 'open']), '|', '&', ('date', '!=', False), ('date', '<=', time.strftime('%Y-%m-%d')), ('is_overdue_quantity', '=', True)], True)
+
+ # Expires in less than 30 days
+ fill_remind("future", [('state', 'in', ['draft', 'open']), ('date', '!=', False), ('date', '<', (datetime.datetime.now() + datetime.timedelta(30)).strftime("%Y-%m-%d"))])
+
+ template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_analytic_analysis', 'account_analytic_cron_email_template')[1]
+ for user_id, data in remind.items():
+ context["data"] = data
+ self.pool.get('email.template').send_mail(cr, uid, template_id, user_id, context=context)
+
+ return True
class account_analytic_account_summary_user(osv.osv):
_name = "account_analytic_analysis.summary.user"
@@ -538,8 +574,6 @@ class account_analytic_account_summary_user(osv.osv):
lu.user_id as "user",
unit_amount
from lu, mu)''')
-
-account_analytic_account_summary_user()
class account_analytic_account_summary_month(osv.osv):
_name = "account_analytic_analysis.summary.month"
@@ -600,6 +634,4 @@ class account_analytic_account_summary_month(osv.osv):
'GROUP BY d.month, d.account_id ' \
')')
-
-account_analytic_account_summary_month()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_cron.xml b/addons/account_analytic_analysis/account_analytic_analysis_cron.xml
index 8564b1606eb..39da3caa0a3 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis_cron.xml
+++ b/addons/account_analytic_analysis/account_analytic_analysis_cron.xml
@@ -1,15 +1,77 @@
+
+
+ Contract expiration reminder
+ ${user.email or ''}
+ Contract expiration reminder ${user.company_id.name}
+ ${object.email}
+ ${object.lang}
+
+
+
+
+ | Customer |
+ Contract |
+ Dates |
+ Prepaid Units |
+ Contact |
+
+ % for partner, accounts in values:
+ % for account in accounts:
+
+ | ${partner.name} |
+ ${account.name} |
+ ${account.date_start} to ${account.date and account.date or '???'} |
+
+ % if account.quantity_max != 0.0:
+ ${account.quantity}/${account.quantity_max} hours
+ % endif
+ |
+ ${account.partner_id.phone or ''}, ${account.partner_id.email or ''} |
+
+ % endfor
+ % endfor
+
+% endmacro
+
+% if "new" in ctx["data"]:
+ The following contracts just expired:
+ ${account_table(ctx["data"]["new"].iteritems())}
+% endif
+
+% if "old" in ctx["data"]:
+ The following expired contracts are still not processed:
+ ${account_table(ctx["data"]["old"].iteritems())}
+% endif
+
+% if "future" in ctx["data"]:
+ The following contracts will expire in less than one month:
+ ${account_table(ctx["data"]["future"].iteritems())}
+% endif
+
+
+
+ ]]>
+
+
+
- Analytic Account Report for Sales
+ Contract expiration reminder
1
weeks
-1
-
-
-
-
+
+
+
+
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_menu.xml b/addons/account_analytic_analysis/account_analytic_analysis_menu.xml
deleted file mode 100644
index 75f06614124..00000000000
--- a/addons/account_analytic_analysis/account_analytic_analysis_menu.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
-
- Time & Materials to Invoice
- account.analytic.line
- form
- tree,form
- [('invoice_id','=',False)]
- {'search_default_to_invoice': 1, 'search_default_sales': 1}
-
-
-
- You will find here timesheets and purchases you did for
- contracts that can be reinvoiced to the customer. If you want
- to record new activities to invoice, you should use the timesheet
- menu instead.
-
-
-
-
-
-
- account.analytic.account.search
- account.analytic.account
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Contracts to Renew
- account.analytic.account
- form
- tree,form
- {'search_default_manager_id':uid, 'search_default_pending':1, 'search_default_renew':1}
- [('type','=','contract')]
-
-
-
- Click to define a new contract.
-
- You will find here the contracts to be renewed because the
- end date is passed or the working effort is higher than the
- maximum authorized one.
-
- OpenERP automatically sets contracts to be renewed in a pending
- state. After the negociation, the salesman should close or renew
- pending contracts.
-
-
-
-
-
-
- Contracts
- account.analytic.account
- form
- tree,form
- {'default_type':'contract', 'search_default_open':1, 'search_default_pending':1, 'default_manager_id':uid}
- [('type','=','contract')]
-
-
-
- Click to create a new contract.
-
- Use contracts to follow tasks, issues, timesheets or invoicing based on
- work done, expenses and/or sales orders. OpenERP will automatically manage
- the alerts for the renewal of the contracts to the right salesperson.
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
index f8f718882af..dfbded83baa 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml
+++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
@@ -1,17 +1,13 @@
-
-
-
Sales Orders
sale.order
account.analytic.account
+
account.analytic.account.invoice.form.inherit
account.analytic.account
@@ -142,19 +138,7 @@
-
- account.analytic.account.tree
- account.analytic.account
-
-
-
-
-
-
-
-
-
-
+
account.analytic.account.form.template.required
account.analytic.account
@@ -167,6 +151,130 @@
+
+
+ account.analytic.account.list.contract
+ account.analytic.account
+
+
+
+
+
+
+
+
+
+
+
+
+ account.analytic.account.search
+ account.analytic.account
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contracts
+ account.analytic.account
+ form
+ tree,form
+ {'default_type':'contract', 'search_default_open':1, 'search_default_pending':1, 'default_manager_id':uid}
+ [('type','=','contract')]
+
+
+
+ Click to create a new contract.
+
+ Use contracts to follow tasks, issues, timesheets or invoicing based on
+ work done, expenses and/or sales orders. OpenERP will automatically manage
+ the alerts for the renewal of the contracts to the right salesperson.
+
+
+
+
+
+
+
+
+ Time & Materials to Invoice
+ account.analytic.line
+ form
+ tree,form
+ [('invoice_id','=',False)]
+ {'search_default_to_invoice': 1, 'search_default_sales': 1}
+
+
+
+ You will find here timesheets and purchases you did for
+ contracts that can be reinvoiced to the customer. If you want
+ to record new activities to invoice, you should use the timesheet
+ menu instead.
+
+
+
+
+
+
+
+
+ Contracts to Renew
+ account.analytic.account
+ form
+ tree,form
+ {'search_default_manager_id':uid, 'search_default_pending':1, 'search_default_renew':1}
+ [('type','=','contract')]
+
+
+
+ Click to define a new contract.
+
+ You will find here the contracts to be renewed because the
+ end date is passed or the working effort is higher than the
+ maximum authorized one.
+
+ OpenERP automatically sets contracts to be renewed in a pending
+ state. After the negociation, the salesman should close or renew
+ pending contracts.
+
+
+
+
+
+
Contract Template
ir.actions.act_window
@@ -184,8 +292,8 @@
terms and conditions of the contract.
-
+
diff --git a/addons/account_analytic_analysis/cron_account_analytic_account.py b/addons/account_analytic_analysis/cron_account_analytic_account.py
deleted file mode 100644
index 6e2ce4a47b3..00000000000
--- a/addons/account_analytic_analysis/cron_account_analytic_account.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-from mako.template import Template
-import time
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-
-from openerp import tools
-from openerp.osv import osv
-
-MAKO_TEMPLATE = u"""Hello ${user.name},
-
-Here is a list of contracts that have to be renewed for two
-possible reasons:
- - the end of contract date is passed
- - the customer consumed more hours than expected
-
-Can you contact the customer in order to sell a new or renew its contract.
-The contract has been set with a pending state, can you update the status
-of the analytic account following this rule:
- - Set Done: if the customer does not want to renew
- - Set Open: if the customer purchased an extra contract
-
-Here is the list of contracts to renew:
-% for partner, accounts in partners.iteritems():
- * ${partner.name}
- % for account in accounts:
- - Name: ${account.name}
- % if account.quantity_max != 0.0:
- - Quantity: ${account.quantity}/${account.quantity_max} hours
- % endif
- - Dates: ${account.date_start} to ${account.date and account.date or '???'}
- - Contacts:
- ${account.partner_id.name}, ${account.partner_id.phone or ''}, ${account.partner_id.email or ''}
-
- % endfor
-% endfor
-
-You can use the report in the menu: Sales > Invoicing > Overdue Accounts
-
-Regards,
-
---
-OpenERP
-"""
-
-class analytic_account(osv.osv):
- _inherit = 'account.analytic.account'
-
- def cron_account_analytic_account(self, cr, uid, context=None):
- domain = [
- ('name', 'not ilike', 'maintenance'),
- ('partner_id', '!=', False),
- ('user_id', '!=', False),
- ('user_id.email', '!=', False),
- ('state', 'in', ('draft', 'open')),
- '|', ('date', '<', time.strftime('%Y-%m-%d')), ('date', '=', False),
- ]
-
- account_ids = self.search(cr, uid, domain, context=context, order='name asc')
- accounts = self.browse(cr, uid, account_ids, context=context)
-
- users = dict()
- for account in accounts:
- users.setdefault(account.user_id, dict()).setdefault(account.partner_id, []).append(account)
-
- account.write({'state' : 'pending'}, context=context)
-
- for user, data in users.iteritems():
- subject = '[OPENERP] Reporting: Analytic Accounts'
- body = Template(MAKO_TEMPLATE).render_unicode(user=user, partners=data)
- tools.email_send('noreply@openerp.com', [user.email, ], subject, body)
-
- return True
-
-analytic_account()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py
index 005afa5d544..af5fc2f3890 100644
--- a/addons/analytic/analytic.py
+++ b/addons/analytic/analytic.py
@@ -196,7 +196,7 @@ class account_analytic_account(osv.osv):
'date_start': fields.date('Start Date'),
'date': fields.date('Date End', select=True),
'company_id': fields.many2one('res.company', 'Company', required=False), #not required because we want to allow different companies to use the same chart of account, except for leaf accounts.
- 'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'), ('cancelled', 'Cancelled'),('pending','To Renew'),('close','Closed')], 'Status', required=True, track_visibility='onchange'),
+ 'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'),('pending','To Renew'),('close','Closed'),('cancelled', 'Cancelled')], 'Status', required=True, track_visibility='onchange'),
'currency_id': fields.function(_currency, fnct_inv=_set_company_currency, #the currency_id field is readonly except if it's a view account and if there is no company
store = {
'res.company': (_get_analytic_account, ['currency_id'], 10),
@@ -349,6 +349,4 @@ class account_analytic_line(osv.osv):
(_check_no_view, 'You cannot create analytic line on view account.', ['account_id']),
]
-account_analytic_line()
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: