Skip to content

Commit

Permalink
[9.0][NEW] sale_timesheet_invoice_description: New module (OCA#154)
Browse files Browse the repository at this point in the history
[ADD] sale_timesheet_invoice_description: New module
  • Loading branch information
carlosdauden authored and Jasper Jumelet committed Mar 14, 2023
1 parent 11acbbc commit fc504d9
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 0 deletions.
77 changes: 77 additions & 0 deletions sale_timesheet_invoice_description/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3

=========================
Timesheet details invoice
=========================

Add timesheet details in invoice line to invoices related with timesheets.

Configuration
=============

To configure this module, you need to:

#. Go to *Sales -> Configuration -> Settings -> Quotations & Sales* and set
Default Timesheet Invoice Description.


Usage
=====

To use this module, you need to:

#. Go to *Sales -> Sales Orders* and create a new Sales Orders.
#. Add line selecting a product with

- *Invoicing Policy* -> **Delivered quantities**

- *Track Service* -> **Timesheets on contract**

e.g. *Support Contract (on timesheet)*
#. Confirm Sale
#. Go to *Timesheets -> Activities* and create line with same project of SO
#. Go to Sales Orders and select *Other Information* -> **Timesheet invoice
description**
#. *Create Invoice*


.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/95/9.0


Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/OCA/account-invoicing/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.


Credits
=======

Contributors
------------

* Carlos Dauden <[email protected]>
* Pedro M. Baeza <[email protected]>


Maintainer
----------

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

This module is maintained by the OCA.

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

To contribute to this module, please visit https://odoo-community.org.
3 changes: 3 additions & 0 deletions sale_timesheet_invoice_description/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import models
19 changes: 19 additions & 0 deletions sale_timesheet_invoice_description/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
'name': 'Timesheet details invoice',
'summary': 'Add timesheet details in invoice line',
'version': '9.0.1.0.0',
'category': 'Sales Management',
'license': 'AGPL-3',
'author': 'Tecnativa, Odoo Community Association (OCA)',
'website': 'https://www.tecnativa.com',
'depends': ['sale_timesheet'],
'data': [
'views/sale_view.xml',
'views/res_config_view.xml',
],
'installable': True,
}
4 changes: 4 additions & 0 deletions sale_timesheet_invoice_description/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

from . import sale
from . import res_config
34 changes: 34 additions & 0 deletions sale_timesheet_invoice_description/models/res_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from openerp import api, fields, models


class SaleConfiguration(models.TransientModel):
_inherit = 'sale.config.settings'

default_timesheet_invoice_description = fields.Selection(
'_get_timesheet_invoice_description',
"Timesheet Invoice Description")

@api.model
def _get_timesheet_invoice_description(self):
return self.env['sale.order']._get_timesheet_invoice_description()

@api.model
def get_default_sale_config(self, fields):
default_timesheet_inv_desc = self.env['ir.values'].get_default(
'sale.order', 'timesheet_invoice_description') or '111'
return {
'default_timesheet_invoice_description':
default_timesheet_inv_desc,
}

@api.multi
def set_sale_defaults(self):
self.ensure_one()
self.env['ir.values'].sudo().set_default(
'sale.order', 'timesheet_invoice_description',
self.default_timesheet_invoice_description)
res = super(SaleConfiguration, self).set_sale_defaults()
return res
63 changes: 63 additions & 0 deletions sale_timesheet_invoice_description/models/sale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from openerp import api, fields, models, _
from openerp.tools import config


class SaleOrder(models.Model):
_inherit = 'sale.order'

timesheet_invoice_description = fields.Selection(
'_get_timesheet_invoice_description', default='000')

@api.model
def _get_timesheet_invoice_description(self):
return [
('000', _('None')),
('111', _('Date - Time spent - Description')),
('101', _('Date - Description')),
('001', _('Description')),
('011', _('Time spent - Description')),
]


class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'

@api.multi
def _prepare_invoice_line_details(self, line, desc_rule):
details = []
if desc_rule[0] == '1':
details.append(line.date)
if desc_rule[1] == '1':
details.append(
"%s %s" % (line.unit_amount, line.product_uom_id.name))
if desc_rule[2] == '1':
details.append(line.name)
return details

@api.multi
def _prepare_invoice_line(self, qty):
res = super(SaleOrderLine, self)._prepare_invoice_line(qty)
desc_rule = self.order_id.timesheet_invoice_description
if not desc_rule or desc_rule == '000':
return res
note = []
domain = [('so_line', '=', self.id)]
last_invoice = self.invoice_lines.sorted(lambda x: x.create_date)[-1:]
if last_invoice:
domain.append(('create_date', '>', last_invoice.create_date))
for line in self.env['account.analytic.line'].search(
domain, order='date, id'):
details = self._prepare_invoice_line_details(line, desc_rule)
note.append(
u' - '.join(map(lambda x: unicode(x) or '', details)))
# This is for not breaking possible tests that expects to create the
# invoices lines the standard way
if note and (not config['test_enable'] or self.env.context.get(
'timesheet_description')):
res['name'] += "\n" + (
"\n".join(map(lambda x: unicode(x) or '', note)))
return res
3 changes: 3 additions & 0 deletions sale_timesheet_invoice_description/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import test_sale_timesheet_description
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from openerp.addons.sale.tests.test_sale_common import TestSale


class TestSaleTimesheetDescription(TestSale):
def test_sale_timesheet_description(self):
""" Test invoice description """
self.SaleConfigSetting = self.env['sale.config.settings']
inv_obj = self.env['account.invoice']
# intial sale order
prod_ts = self.env.ref('product.product_product_2')
sale_order_vals = {
'partner_id': self.partner.id,
'partner_invoice_id': self.partner.id,
'partner_shipping_id': self.partner.id,
'pricelist_id': self.env.ref('product.list0').id,
'timesheet_invoice_description': '111',
'order_line': [(0, 0, {
'name': prod_ts.name,
'product_id': prod_ts.id,
'product_uom_qty': 5,
'product_uom': prod_ts.uom_id.id,
'price_unit': prod_ts.list_price})],
}
sale_order = self.env['sale.order'].create(sale_order_vals)
sale_order.action_confirm()
# let's log some timesheets
self.env['account.analytic.line'].create({
'name': 'Test description 1234567890',
'account_id': sale_order.project_id.id,
'unit_amount': 10.5,
'user_id': self.manager.id,
'is_timesheet': True,
})
invoice_id = sale_order.with_context(
timesheet_description=True).action_invoice_create()
invoice = inv_obj.browse(invoice_id)
description = invoice.invoice_line_ids[0].name
self.assertIn('Test description 1234567890', description)

self.default_timesheet_invoice_description = (
self.SaleConfigSetting.create({}))

self.default_timesheet_invoice_description.execute()
15 changes: 15 additions & 0 deletions sale_timesheet_invoice_description/views/res_config_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <[email protected]>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>
<record id="view_sales_config_inherit_timesheet_invoice_description" model="ir.ui.view">
<field name="name">sale settings</field>
<field name="model">sale.config.settings</field>
<field name="inherit_id" ref="sale.view_sales_config"/>
<field name="arch" type="xml">
<field name="group_sale_delivery_address" position="after">
<field name="default_timesheet_invoice_description"/>
</field>
</field>
</record>
</odoo>
15 changes: 15 additions & 0 deletions sale_timesheet_invoice_description/views/sale_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <[email protected]>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>
<record id="view_order_form_description" model="ir.ui.view">
<field name="name">sale.order.form.invoice.description</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="fiscal_position_id" position="after">
<field name="timesheet_invoice_description"/>
</field>
</field>
</record>
</odoo>

0 comments on commit fc504d9

Please sign in to comment.