From 6d19450457ded5b9a57cb88b7eb4dc6d90dfff02 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 18 Feb 2013 18:21:17 +0530 Subject: [PATCH] [IMP]account_analytic_analysis: Add Recurrent virtual invoice functionality Try to set cron job but and test it's function with temp invoice btn bzr revid: dbr@tinyerp.com-20130218125117-4sqbhxb1vro2nzhp --- .../account_analytic_analysis.py | 96 ++++++++++++++++++- .../account_analytic_analysis_cron.xml | 13 +++ .../account_analytic_analysis_view.xml | 53 ++++++++++ .../cron_account_analytic_account.py | 57 +++++++++++ .../hr_timesheet_final_invoice_create.py | 2 +- 5 files changed, 219 insertions(+), 2 deletions(-) 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 @@ + + + Recurrent Report for Invoice + + + 1 + minutes + -1 + + + + + diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml index f8f718882af..104e66d5d47 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml +++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml @@ -138,6 +138,59 @@ attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/> + +