diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py
index 23d8faaffce..809b4e2f3fb 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis.py
+++ b/addons/account_analytic_analysis/account_analytic_analysis.py
@@ -25,7 +25,9 @@ import openerp.tools
from openerp.tools.translate import _
from openerp.addons.decimal_precision import decimal_precision as dp
-
+import time
+import datetime
+from dateutil.relativedelta import relativedelta
class account_analytic_account(osv.osv):
_name = "account.analytic.account"
@@ -391,6 +393,44 @@ class account_analytic_account(osv.osv):
res[account.id]['toinvoice_total'] = self._get_total_toinvoice(account)
return res
+ def _calc_virtual_invoice(self, cr, uid, ids, name, arg, context=None):
+ res = {}
+ analytic_line_obj = self.pool.get('account.analytic.line')
+ product_obj = self.pool.get('product.product')
+ if ids:
+ journal_types = {}
+ timesheets1 = []
+ for account in self.browse(cr, uid, ids, context=context):
+ timesheets1 = analytic_line_obj.search(cr, uid,[('account_id','=', account.id),('invoice_id','=', None)])
+ res[account.id]= {'product_id': 0, 'user_id': 0, 'qty': 0.0 , 'uom': 0, 'description':'', 'unit_price': 0.0, 'sub_total':0.0}
+ for line in analytic_line_obj.browse(cr, uid, timesheets1, context=context):
+ if line.journal_id.type not in journal_types:
+ journal_types[line.journal_id.type] = set()
+ for journal_type in journal_types:
+ cr.execute("""SELECT product_id, user_id, to_invoice, unit_amount, product_uom_id, date
+ FROM account_analytic_line as line LEFT JOIN account_analytic_journal journal ON (line.journal_id = journal.id)
+ WHERE account_id = %s
+ AND invoice_id IS NULL AND journal.type = %s AND to_invoice IS NOT NULL
+ GROUP BY product_id, user_id, to_invoice, unit_amount, product_uom_id, date""", (account.id, journal_type))
+
+ for product_id, user_id, to_invoice, unit_amount, product_uom_id, date in cr.fetchall():
+ product = product_obj.browse(cr, uid, product_id)
+ description = product.description
+ unit_price = product.list_price
+ sub_total = product.list_price * unit_amount
+ print"--------------------------------->",description, unit_price, sub_total
+ res[account.id]['product_id']= product_id,
+ res[account.id]['user_id'] = user_id,
+ res[account.id]['qty'] = unit_amount,
+ res[account.id]['uom'] = product_uom_id,
+ res[account.id]['date'] = date,
+ res[account.id]['descriptions'] = description,
+ res[account.id]['unit_price'] = unit_price,
+ res[account.id]['sub_total'] = sub_total,
+
+ print"\n\n**********************************>",res
+ return res
+
_columns = {
'is_overdue_quantity' : fields.function(_is_overdue_quantity, method=True, type='boolean', string='Overdue Quantity',
store={
@@ -452,6 +492,26 @@ class account_analytic_account(osv.osv):
'invoiced_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total Invoiced"),
'remaining_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total Remaining", help="Expectation of remaining income for this contract. Computed as the sum of remaining subtotals which, in turn, are computed as the maximum between '(Estimation - Invoiced)' and 'To Invoice' amounts"),
'toinvoice_total' : fields.function(_sum_of_fields, type="float",multi="sum_of_all", string="Total to Invoice", help=" Sum of everything that could be invoiced for this contract."),
+ # New Fields added
+ 'recurring_invoices' : fields.boolean('Recurring Invoices'),
+ 'product_id': fields.function(_calc_virtual_invoice, type='many2one',relation="product.product",string='Product(s)', multi="vinvline"),
+ 'user_id': fields.function(_calc_virtual_invoice, type='many2one', relation="res.users",string='User(s)', multi="vinvline"),
+ 'descriptions': fields.function(_calc_virtual_invoice, type='char', string='Description', multi="vinvline"),
+ 'qty': fields.function(_calc_virtual_invoice, type='char', string='Quantity', multi="vinvline"),
+ 'uom': fields.function(_calc_virtual_invoice, type='many2one', string='Unit of Measure', relation="product.uom",multi="vinvline"),
+ 'date': fields.function(_calc_virtual_invoice, type='date', string='Date', multi="vinvline"),
+ 'unit_price':fields.function(_calc_virtual_invoice, type='char', string='Unit Price', multi="vinvline"),
+ 'sub_total':fields.function(_calc_virtual_invoice, type='char', string='Sub Total', multi="vinvline"),
+ 'rrule_type': fields.selection([
+ ('daily', 'Day(s)'),
+ ('weekly', 'Week(s)'),
+ ('monthly', 'Month(s)')
+ ], 'Recurrency', help="Let the event automatically repeat at that interval"),
+ 'interval': fields.integer('Repeat Every', help="Repeat every (Days/Week/Month/Year)"),
+ 'next_date': fields.date('Next Date'),
+ 'amount_tax': fields.float('Tax'),
+ 'amount_total': fields.float('Total'),
+
}
def open_sale_order_lines(self,cr,uid,ids,context=None):
@@ -484,6 +544,40 @@ class account_analytic_account(osv.osv):
res['value']['to_invoice'] = template.to_invoice.id
res['value']['pricelist_id'] = template.pricelist_id.id
return res
+
+ def onchange_recurring_invoices(self, cr, uid, ids, date_start=False, parent_id=False, context=None):
+ result = {}
+ if date_start:
+ result = {'value': {
+ 'next_date': date_start,
+ 'rrule_type':'monthly'
+ }
+ }
+ return result
+
+
+ def cron_create_invoice1(self, cr, uid, ids, context=None):
+ res = {}
+ inv_obj = self.pool.get('account.invoice')
+ journal_obj = self.pool.get('account.journal')
+ inv_lines = []
+
+ contract_ids = self.search(cr, uid, [('next_date','<=',time.strftime("%Y-%m-%d")), ('state','=', 'open'), ('recurring_invoices','=', True)], context=context, order='name asc')
+ context.update({'active_ids':ids})
+ contracts = self.browse(cr, uid, contract_ids, context=context)
+ for contract in contracts:
+ next_date = datetime.datetime.strptime(contract.next_date, "%Y-%m-%d")
+ interval = contract.interval
+ if contract.rrule_type == 'monthly':
+ new_date = next_date+relativedelta(months=+interval)
+ if contract.rrule_type == 'daily':
+ new_date = next_date+relativedelta(days=+interval)
+ if contract.rrule_type == 'weekly':
+ new_date = next_date+relativedelta(weeks=+interval)
+ # Need to Link this new invoice to related contract
+ contract.write({'next_date':new_date}, context=context)
+ return self.pool.get('hr.timesheet.invoice.create.final').do_create(cr, uid, contract_ids, context=context)
+
account_analytic_account()
class account_analytic_account_summary_user(osv.osv):
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_cron.xml b/addons/account_analytic_analysis/account_analytic_analysis_cron.xml
index 8564b1606eb..53ecc0c8c55 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis_cron.xml
+++ b/addons/account_analytic_analysis/account_analytic_analysis_cron.xml
@@ -11,5 +11,18 @@
| + | + | + | + | + | + | + | + |
|---|---|---|---|---|---|---|---|
|
+ |
+
+ |
+
+ |
+
+ |
+
+ |
+
+ |
+ + | + |