[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
This commit is contained in:
parent
4f8081e1fd
commit
6d19450457
|
@ -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):
|
||||
|
|
|
@ -11,5 +11,18 @@
|
|||
<field eval="'cron_account_analytic_account'" name="function"/>
|
||||
<field eval="'()'" name="args"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.cron" id="account_analytic_cron_for_invoice">
|
||||
<field name="name">Recurrent Report for Invoice</field>
|
||||
<field eval="True" name="active" />
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="'account.analytic.account'" name="model" />
|
||||
<field eval="'cron_create_invoice'" name="function" />
|
||||
<field eval="'(False,)'" name="args" />
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -138,6 +138,59 @@
|
|||
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<separator string="Recurrency"/>
|
||||
<label for="recurring_invoices"/>
|
||||
<field name="recurring_invoices" on_change="onchange_recurring_invoices(date_start, parent_id)"/>
|
||||
<group attrs="{'invisible': [('recurring_invoices','=',False)]}">
|
||||
<label for="interval"/>
|
||||
<div>
|
||||
<field name="interval" attrs="{'required': [('recurring_invoices','==',True)]}" class="oe_inline"/>
|
||||
<field name="rrule_type" attrs="{'required': [('recurring_invoices','==',True)]}" class="oe_inline"/>
|
||||
</div>
|
||||
<label for="next_date"/>
|
||||
<div>
|
||||
<field name="next_date" attrs="{'required': [('recurring_invoices','==',True)]}" class="oe_inline"/>
|
||||
</div>
|
||||
</group>
|
||||
<table class="oe_form_analytic_account" attrs="{'invisible': [('recurring_invoices','=',False)]}">
|
||||
<tr>
|
||||
<th class="oe_timesheet_grey" width="100px"><label string="Product"/></th>
|
||||
<th class="oe_timesheet_grey" width="100px"><label string="Description"/></th>
|
||||
<th class="oe_timesheet_grey" width="100px"><label string="Quantity"/></th>
|
||||
<th class="oe_timesheet_grey" width="100px"><label string="UOM"/></th>
|
||||
<th class="oe_timesheet_grey" width="100px"><label string="Unit Price"/></th>
|
||||
<th class="oe_timesheet_grey" width="100px"><label string="Sub total"/></th>
|
||||
<th width="30px"></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100px">
|
||||
<field name="product_id" class="oe_inline"/>
|
||||
</td>
|
||||
<td width="100px">
|
||||
<field name="descriptions" class="oe_inline"/>
|
||||
</td>
|
||||
<td width="100px">
|
||||
<field name="qty" class="oe_inline"/>
|
||||
</td>
|
||||
<td width="100px">
|
||||
<field name="uom" class="oe_inline"/>
|
||||
</td>
|
||||
<td width="100px">
|
||||
<field name="unit_price" class="oe_inline"/>
|
||||
</td>
|
||||
<td width="100px">
|
||||
<field name="sub_total" class="oe_inline"/>
|
||||
</td>
|
||||
<td width="30px"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<field name="amount_tax" widget="monetary" options="{'currency_field': 'currency_id'}" class="oe_subtotal_footer oe_right,oe_inline"/>
|
||||
<field name="amount_total" class="oe_subtotal_footer_separator,oe_inline" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
</tr>
|
||||
</table>
|
||||
<button name="cron_create_invoice1" string="INVOICE" type="object" class="oe_highlight"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
from mako.template import Template
|
||||
import time
|
||||
import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
try:
|
||||
import cStringIO as StringIO
|
||||
except ImportError:
|
||||
|
@ -74,6 +77,60 @@ class analytic_account(osv.osv):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
def cron_create_invoice(self, cr, uid, 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')
|
||||
print "\n000000000000 ids 0000000000000>",contract_ids
|
||||
|
||||
a = self.pool.get('hr.timesheet.invoice.create.final').do_create(cr, uid, contract_ids, context=None)
|
||||
print"\n\n====================================================>",a
|
||||
contracts = self.browse(cr, uid, contract_ids, context=context)
|
||||
for contract in contracts:
|
||||
# journal_ids = journal_obj.search(cr, uid, [('type', '=','sale'),('company_id', '=', contract.company_id.id)], limit=1)
|
||||
# if not journal_ids:
|
||||
# raise osv.except_osv(_('Error!'),
|
||||
# _('Define sale journal for this company: "%s" (id:%d).') % (contract.company_id.name, contract.company_id.id))
|
||||
# inv_data = {}
|
||||
# inv_data = {
|
||||
# 'name': contract.name,
|
||||
# 'reference': contract.name,
|
||||
# 'account_id': contract.partner_id.property_account_receivable.id or contract.partner_id.property_account_receivable or False,
|
||||
# 'type': 'in_invoice',
|
||||
# 'partner_id': contract.partner_id.id,
|
||||
# 'currency_id': contract.partner_id.property_product_pricelist.id,
|
||||
# 'journal_id': len(journal_ids) and journal_ids[0] or False,
|
||||
# 'invoice_line': [(6, 0, inv_lines)],
|
||||
# 'date_invoice': contract.next_date,
|
||||
# 'origin': contract.name,
|
||||
# 'company_id': contract.company_id.id,
|
||||
# 'contract_id': contract.id,
|
||||
# }
|
||||
# inv_id = inv_obj.create(cr, uid, inv_data, context=context)
|
||||
# inv_obj.button_compute(cr, uid, [inv_id], context=context, set_total=True)
|
||||
next_date = datetime.datetime.strptime(contract.next_date, "%Y-%m-%d")
|
||||
interval = contract.interval
|
||||
print"STRAT...................."
|
||||
# # compute the invoice
|
||||
# res.append(inv_id)
|
||||
|
||||
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)
|
||||
|
||||
print"==========res=============>",contract.next_date,contract.interval,contract.rrule_type,new_date
|
||||
# Link this new invoice to related contract
|
||||
contract.write({'next_date':new_date}, context=context)
|
||||
print"\n\n========11111==res=========FINISH.====>",res
|
||||
return True
|
||||
|
||||
analytic_account()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -43,7 +43,7 @@ class final_invoice_create(osv.osv_memory):
|
|||
}
|
||||
|
||||
def do_create(self, cr, uid, ids, context=None):
|
||||
data = self.read(cr, uid, ids, [], context=context)[0]
|
||||
data = self.read(cr, uid, ids, [], context=context) or None
|
||||
# hack for fixing small issue (context should not propagate implicitly between actions)
|
||||
if 'default_type' in context:
|
||||
del context['default_type']
|
||||
|
|
Loading…
Reference in New Issue