Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.0][ADD] Migrated business_requirement_deliverable_cost module from v8 to v9 #30

136 changes: 136 additions & 0 deletions business_requirement_deliverable_cost/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3


=============================================
Business Requirement Deliverable Cost Control
=============================================

Introduction
============

This module is part of a set of modules (`Business Requirements
<https://github.com/OCA/business-requirement/blob/9.0/README.md>`_)

This module improves the cost control of the original module with the following:

* Estimation sales price on resource lines. It provides a simple way to
calculate the sales price of the deliverable based on the necessary
resources lines (see usage).
* Adds ACL for sales price and resource cost confidentiality.
* Creates a tab Cost control in the Business Requirement for simple Gross Profit
control.
* Multi-currency compatible: sales price is valued at currency Pricelist and
converted back to the reporting company currency for the cost control.

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

Users
-----

* **Business Requirement Sales Estimates**: Can See the sales prices in DL and
RL (ideal for sales/presales)
* **Business Requirement Cost Control**: Can See the cost prices for project
profit control (Manager/Finance dept)

Without Sales Estimate nor Cost Control rights:

.. figure:: /business_requirement_deliverable_cost/static/img/bus_req_acl1.png
:width: 600 px
:alt: No access to sales or cost control information (Simple user)

Without Cost Control rights:

.. figure:: /business_requirement_deliverable_cost/static/img/bus_req_acl2.png
:width: 600 px
:alt: Access to sales price with no cost control (Salesmen)


With both Sales Estimate and Cost Control rights:

.. figure:: /business_requirement_deliverable_cost/static/img/bus_req_acl3.png
:width: 600 px
:alt: Full access to sales price and cost control (Financial dept)


Estimation Pricelist
--------------------

You can define the Estimation price list in the Master Project which will be
used in deliverable lines and sales price for the resource lines.


Usage
=====

The pricelist stored in the Project/Estimation pricelist field will be used to
help the calculation of the expected revenue of a Deliverable based on the sum
of related RL.

#. In the BR, you can add as many deliverable lines as necessary. You can keep
the price empty at that stage.

#. Once the deliverable lines are created you can create as many resources lines
as necessary in each DL.

#. in RL, the estimation sales price will be display per resource.

#. The total Revenue from the resources (sum of the sales estimation for all RL)
can be manually added back to the deliverable line.

#. you can review the cost control tab of your BR as followed (only available for
ACL Cost Control)

#. Eventually you can manually update the price of all resource clicking on the
Update button.

.. figure:: /business_requirement_deliverable_cost/static/img/bus_req_control.png
:width: 600 px
:alt: Control your cost for the BR


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

Known issues / Roadmap
======================

* Display the currency in the cost control panel and deliverable

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/business-requirement/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
------------

* Eric Caudal <eric.caudal@elico-corp.com>
* Alex Duan <alex.duan@elico-corp.com>
* Xie XiaoPeng <xie.xiaopeng@elico-corp.com>
* Luke Zheng <luke.zheng@elico-corp.com>
* Victor Martin <victor.martin@elico-corp.com>
* Sudhir P. Arya <sudhir.arya@serpentcs.com>

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.
5 changes: 5 additions & 0 deletions business_requirement_deliverable_cost/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import models
28 changes: 28 additions & 0 deletions business_requirement_deliverable_cost/__openerp__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# © 2016 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Business Requirement Deliverable Cost Control",
"summary": "Control the cost of your Business Requirements",
"version": "9.0.1.0.1",
'category': 'Business Requirement Management',
"website": "www.elico-corp.com",
"author": "Elico Corp, Odoo Community Association (OCA)",
"license": "AGPL-3",
"depends": [
"business_requirement_deliverable",
],
'image': [
'static/description/icon.png',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add icon image

'static/img/bus_req_acl1.png',
'static/img/bus_req_acl2.png',
'static/img/bus_req_acl3.png',
'static/img/bus_req_control.png'
],
"data": [
"security/business_requirement_deliverable_security.xml",
"views/business.xml",
],
"application": False,
"installable": True,
}
5 changes: 5 additions & 0 deletions business_requirement_deliverable_cost/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Elico Corp (https://www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import business
207 changes: 207 additions & 0 deletions business_requirement_deliverable_cost/models/business.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# -*- coding: utf-8 -*-
# © 2016 Elico Corp (https://www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, fields, models


class BusinessRequirementResource(models.Model):
_inherit = "business.requirement.resource"

sale_price_unit = fields.Float(
string='Sales Price',
groups='business_requirement_deliverable_cost.'
'group_business_requirement_estimation',
)
sale_price_total = fields.Float(
compute='_compute_sale_price_total',
string='Total Revenue',
groups='business_requirement_deliverable_cost.'
'group_business_requirement_estimation',
)
unit_price = fields.Float(
string='Cost Price',
groups='business_requirement_deliverable_cost.'
'group_business_requirement_cost_control',
)
price_total = fields.Float(
store=False,
compute='_compute_get_price_total',
string='Total Cost',
groups='business_requirement_deliverable_cost.'
'group_business_requirement_cost_control',
)
partner_id = fields.Many2one(
'res.partner',
related='business_requirement_deliverable_id.'
'business_requirement_id.partner_id',
string='Parter ID Related',
readonly=True,
)

@api.multi
@api.depends('unit_price', 'qty')
def _compute_get_price_total(self):
for resource in self:
resource.price_total = resource.unit_price * resource.qty

@api.multi
@api.depends('sale_price_unit', 'qty')
def _compute_sale_price_total(self):
for resource in self:
resource.sale_price_total = resource.sale_price_unit * resource.qty

@api.multi
def _get_pricelist(self):
self.ensure_one()
partner = self.partner_id
if partner:
if partner.property_product_pricelist:
return partner.property_product_pricelist
else:
return False

@api.multi
@api.onchange('product_id')
def product_id_change(self):
super(BusinessRequirementResource, self).product_id_change()
unit_price = self.product_id.standard_price
pricelist_id = self._get_pricelist()
partner = self.partner_id
sale_price_unit = self.product_id.list_price
if pricelist_id and partner and self.uom_id:
product = self.product_id.with_context(
lang=partner.lang,
partner=partner.id,
quantity=self.qty,
pricelist=pricelist_id.id,
uom=self.uom_id.id,
)
sale_price_unit = product.list_price
unit_price = product.standard_price

self.unit_price = unit_price
self.sale_price_unit = sale_price_unit

@api.multi
@api.onchange('uom_id', 'qty')
def product_uom_change(self):
qty_uom = 0
unit_price = self.unit_price
sale_price_unit = self.product_id.list_price
pricelist = self._get_pricelist()
partner = self.partner_id
product_uom = self.env['product.uom']

if self.qty != 0:
qty_uom = product_uom._compute_qty(
self.uom_id.id,
self.qty,
self.product_id.uom_id.id
) / self.qty

if pricelist:
product = self.product_id.with_context(
lang=partner.lang,
partner=partner.id,
quantity=self.qty,
pricelist=pricelist.id,
uom=self.uom_id.id,
)
unit_price = product.standard_price
sale_price_unit = product.list_price

self.unit_price = unit_price * qty_uom
self.sale_price_unit = sale_price_unit * qty_uom


class BusinessRequirementDeliverable(models.Model):
_inherit = "business.requirement.deliverable"

unit_price = fields.Float(
groups='business_requirement_deliverable_cost.'
'group_business_requirement_estimation',
)
price_total = fields.Float(
groups='business_requirement_deliverable_cost.'
'group_business_requirement_estimation',
)

@api.multi
def action_button_update_estimation(self):
for deliverable in self:
if deliverable.resource_ids:
for resource in deliverable.resource_ids:
pricelist_id = resource._get_pricelist()
partner = resource.partner_id
resource.sale_price_unit = resource.product_id.lst_price
if pricelist_id and partner and resource.uom_id:
product = resource.product_id.with_context(
lang=partner.lang,
partner=partner.id,
quantity=resource.qty,
pricelist=pricelist_id.id,
uom=resource.uom_id.id,
)
resource.sale_price_unit = product.price


class BusinessRequirement(models.Model):
_inherit = "business.requirement"

total_revenue = fields.Float(
store=False,
groups='business_requirement_deliverable_cost.'
'group_business_requirement_estimation',
)
resource_task_total = fields.Float(
compute='_compute_resource_task_total',
string='Total tasks',
store=False,
groups='business_requirement_deliverable_cost.'
'group_business_requirement_cost_control',
)
resource_procurement_total = fields.Float(
compute='_compute_resource_procurement_total',
string='Total procurement',
store=False,
groups='business_requirement_deliverable_cost.'
'group_business_requirement_cost_control',
)
gross_profit = fields.Float(
string='Estimated Gross Profit',
compute='_compute_gross_profit',
groups='business_requirement_deliverable_cost.'
'group_business_requirement_cost_control',
)

@api.multi
@api.depends('deliverable_lines')
def _compute_resource_task_total(self):
for br in self:
if br.deliverable_lines:
br.resource_task_total = sum(
br.mapped('deliverable_lines').mapped(
'resource_ids').filtered(
lambda r: r.resource_type == 'task').mapped(
'price_total'))

@api.multi
@api.depends('deliverable_lines')
def _compute_resource_procurement_total(self):
for br in self:
if br.deliverable_lines:
br.resource_procurement_total = sum(
br.mapped('deliverable_lines').mapped(
'resource_ids').filtered(
lambda r: r.resource_type == 'procurement').mapped(
'price_total'))

@api.multi
@api.depends(
'total_revenue',
'resource_task_total',
'resource_procurement_total')
def _compute_gross_profit(self):
for br in self:
br.gross_profit = br.total_revenue - \
br.resource_task_total - br.resource_procurement_total
Loading