[IMP] contract useability and invoicing

bzr revid: fp@openerp.com-20121028151537-98wz6qiosmumbqvg
This commit is contained in:
Fabien Pinckaers 2012-10-28 16:15:37 +01:00
parent f721ff1d14
commit 4f0c5bf19c
10 changed files with 50 additions and 31 deletions

View File

@ -61,7 +61,7 @@
</span>
<span attrs="{'invisible': [('fix_price_to_invoice','&lt;&gt;',0.0)]}" class="oe_grey">
No order to invoice, view
No order to invoice, create
</span>
<button name="%(action_sales_order)d" string="Sale Orders"
type="action"
@ -84,7 +84,7 @@
<field class="oe_inline" name="ca_to_invoice" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}"/>
</td><td class="oe_timesheet_action" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}">
<span attrs="{'invisible': [('ca_to_invoice','=',0.0)]}" class="oe_grey">
<button name="%(hr_timesheet_invoice.act_acc_analytic_acc_2_report_acc_analytic_line_to_invoice)d"
<button name="%(hr_timesheet_invoice.action_hr_timesheet_invoice_create_final)d"
type="action"
class="oe_link"
string="⇒ Invoice"/>

View File

@ -141,11 +141,11 @@ class account_analytic_account(osv.osv):
'name': fields.char('Account/Contract Name', size=128, required=True),
'complete_name': fields.function(_complete_name_calc, type='char', string='Full Account Name'),
'code': fields.char('Reference', size=24, select=True),
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True,
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Contract')], 'Type of Account', required=True,
help="If you select the View Type, it means you won\'t allow to create journal entries using that account.\n"\
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
"If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\
"The special type 'Template of Project' allows you to define a template with default data that you can reuse easily."),
"The special type 'Template of Contract' allows you to define a template with default data that you can reuse easily."),
'template_id': fields.many2one('account.analytic.account', 'Template of Contract'),
'description': fields.text('Description'),
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),

View File

@ -195,7 +195,7 @@ class account_analytic_account(osv.osv):
_inherit = 'account.analytic.account'
_description = 'Analytic Account'
_columns = {
'use_timesheets': fields.boolean('Timesheets', help="Check this field if this project manages timesheets"),
'use_timesheets': fields.boolean('Use Timesheets', help="Check this field if this project manages timesheets"),
}
def on_change_template(self, cr, uid, ids, template_id, context=None):

View File

@ -85,6 +85,23 @@
<field name="src_model">account.analytic.account</field>
<field name="view_mode">tree,form</field>
<field name="view_type">form</field>
<field name="help" type="html">
<p>
No activity yet on this contract.
</p><p>
In OpenERP, contracts and projects are implemented using
analytic account. So, you can track costs and revenues to analyse
your margins easily.
</p><p>
Costs will be created automatically when you register supplier
invoices, expenses or timesheets.
</p><p>
Revenues will be created automatically when you create customer
invoices. Customer invoices can be created based on sale orders
(fixed price invoices), on timesheets (based on the work done) or
on expenses (e.g. reinvoicing of travel costs).
</p>
</field>
</record>

View File

@ -16,5 +16,10 @@
<field name="customer_name">50%</field>
<field name="factor">50.0</field>
</record>
<record id="timesheet_invoice_factor4" model="hr_timesheet_invoice.factor">
<field name="name">80%</field>
<field name="customer_name">80%</field>
<field name="factor">20.0</field>
</record>
</data>
</openerp>

View File

@ -9,8 +9,8 @@
<field name="arch" type="xml">
<xpath expr='//separator[@name="description"]' position='before'>
<group string="Invoice on Timesheets Options" name="invoice_on_timesheets" col="4">
<field name="pricelist_id" />
<field name="to_invoice" widget="selection"/>
<field name="pricelist_id" groups="product.group_sale_pricelist"/>
<field name="to_invoice"/>
</group>
</xpath>
<xpath expr="//field[@name='use_timesheets']" position="replace">

View File

@ -36,14 +36,17 @@ class final_invoice_create(osv.osv_memory):
_description = 'Create invoice from timesheet final'
_columns = {
'date': fields.boolean('Date', help='Display date in the history of works'),
'time': fields.boolean('Time spent', help='Display time in the history of works'),
'name': fields.boolean('Name of entry', help='Display detail of work in the invoice line.'),
'time': fields.boolean('Time Spent', help='Display time in the history of works'),
'name': fields.boolean('Log of Activity', help='Display detail of work in the invoice line.'),
'price': fields.boolean('Cost', help='Display cost of the item you reinvoice'),
'product': fields.many2one('product.product', 'Product', help='The product that will be used to invoice the remaining amount'),
}
def do_create(self, cr, uid, ids, context=None):
data = self.read(cr, uid, ids, [], context=context)[0]
# hack for fixing small issue (context should not propagate implicitly between actions)
if 'default_type' in context:
del context['default_type']
ids = self.pool.get('account.analytic.line').search(cr, uid, [('invoice_id','=',False),('to_invoice','<>', False), ('account_id', 'in', context['active_ids'])], context=context)
invs = self.pool.get('account.analytic.line').invoice_cost_create(cr, uid, ids, data, context=context)
mod_obj = self.pool.get('ir.model.data')

View File

@ -169,7 +169,8 @@ class account_analytic_line(osv.osv):
details.append(line['name'])
note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
curr_line['name'] += "\n".join(map(lambda x: unicode(x) or '',note))
if note:
curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
invoice_line_obj.create(cr, uid, curr_line, context=context)
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))

View File

@ -26,13 +26,19 @@
<field name="model">hr.timesheet.invoice.create.final</field>
<field name="arch" type="xml">
<form string="Invoice contract" version="7.0">
<separator string="Do you want to display work details on the invoice?" colspan="4"/>
<field name="date"/>
<field name="time"/>
<field name="name"/>
<field name="price"/>
<separator string="Force to use a special product" colspan="4"/>
<field name="product"/>
<p>Do you want to show details of each activity to your customer?</p>
<group>
<group>
<field name="date"/>
<field name="time"/>
</group><group>
<field name="name"/>
<field name="price"/>
</group>
</group>
<group string="Force to use a special product" groups="base.group_no_one">
<field name="product"/>
</group>
<footer>
<button name="do_create" string="Create Invoice" type="object" class="oe_highlight"/>
or

View File

@ -306,20 +306,6 @@
</group>
</group>
</page>
<page string="History">
<separator string="Invoices"/>
<field name="invoice_ids" context="{'form_view_ref':'account.invoice_form'}">
<tree string="Invoices" colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'">
<field name="date_invoice"/>
<field name="number"/>
<field name="partner_id" string="Customer"/>
<field name="user_id"/>
<field name="date_due"/>
<field name="amount_total"/>
<field name="state"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
@ -360,6 +346,7 @@
<filter string="My Sale Orders" domain="[('user_id','=',uid)]" help="My Sale Orders" icon="terp-personal" name="my_sale_orders_filter"/>
<field name="partner_id"/>
<field name="user_id"/>
<field name="project_id"/>
<group expand="0" string="Group By...">
<filter string="Customer" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Salesperson" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>