[IMP] Sales: Invoicing project milestones
closes odoo/documentation#15545 Signed-off-by: Felicia Kuan (feku) <feku@odoo.com> Co-authored-by: theRealThagomizer <96515928+theRealThagomizer@users.noreply.github.com>
@@ -2,235 +2,111 @@
|
||||
Invoice project milestones
|
||||
==========================
|
||||
|
||||
Invoicing based on project milestones can be used for expensive or large-scale projects with
|
||||
discrete, measurable deliverables. The series of milestones in a project represent a clear sequence
|
||||
of work that will inevitably result in the completion of a project and/or contract.
|
||||
.. |SO| replace:: :abbr:`SO (Sales Order)`
|
||||
.. |SOs| replace:: :abbr:`SOs (Sales Orders)`
|
||||
|
||||
This method of invoicing ensures the company gets a consistent flow of money throughout the lifetime
|
||||
of the project. Customers can closely monitor every phase of the project's development as it
|
||||
happens, in addition to paying a large bill in several installments, instead of all at once.
|
||||
Milestone-based invoicing is designed for companies that deliver work in clearly defined phases.
|
||||
Instead of invoicing an entire service upfront or at the very end, businesses can bill customers
|
||||
progressively as each stage of work is completed. This approach provides customers clearer
|
||||
visibility into progress and value delivered over time.
|
||||
|
||||
In Odoo, milestone invoicing is configured at the product level in the **Sales** app, with milestone
|
||||
progress and completion managed in the **Projects** app. When a milestone is marked as reached, the
|
||||
delivered quantity on the sales order (SO) is updated and can be invoiced.
|
||||
|
||||
How milestone invoicing works
|
||||
=============================
|
||||
|
||||
Milestone invoicing follows a clear workflow involving multiple applications in Odoo:
|
||||
|
||||
- A product is created in the **Sales** application, configured to be invoiced based on milestones.
|
||||
- A |SO| is created with the product.
|
||||
- A project in the **Projects** app is created with multiple milestones included.
|
||||
- A milestone is reached, and marked complete, causing the *Delivered* quantity on the |SO| line to
|
||||
update.
|
||||
- An invoice is created for the completed milestone, which can be sent to the customer.
|
||||
|
||||
.. important::
|
||||
This document covers the **Sales** app configuration and invoicing flow for invoicing based on
|
||||
project milestones. For more information on creating, managing, and marking milestones as
|
||||
complete, and how to link them to tasks, see :doc:`Project milestones
|
||||
<../../../services/project/project_management/project_milestones>`.
|
||||
|
||||
Create milestone products
|
||||
=========================
|
||||
|
||||
In Odoo, each milestone of a project is considered as an individual product.
|
||||
To begin, a service product must be configured specifically for milestone-based invoicing. Navigate
|
||||
to :menuselection:`Sales app --> Products --> Products` and click :guilabel:`New`. Enter the
|
||||
necessary information, including the product title and :guilabel:`Sales Price`.
|
||||
|
||||
To create and/or configure products to work like this, first navigate to :menuselection:`Sales app
|
||||
--> Products --> Products`. Then, click on a product, or create a new one by clicking
|
||||
:guilabel:`New`.
|
||||
|
||||
The option to invoice based on milestones is only available for certain product types.
|
||||
|
||||
On the product form, under the :guilabel:`General Information` tab, the :guilabel:`Product Type`
|
||||
field *must* be set on any of the following options: :guilabel:`Service`, :guilabel:`Event Ticket`,
|
||||
:guilabel:`Event Booth`, or :guilabel:`Course`.
|
||||
|
||||
.. image:: milestone/product-type-field.png
|
||||
:align: center
|
||||
:alt: The invoicing policy field drop-down menu with options on product form.
|
||||
|
||||
With any of those :guilabel:`Product Type` options selected, choose :guilabel:`Based on Milestones`
|
||||
from the :guilabel:`Invoicing Policy` drop-down menu.
|
||||
|
||||
.. image:: milestone/invoicing-policy-field.png
|
||||
:align: center
|
||||
:alt: The invoicing policy field drop-down menu with options on product form.
|
||||
|
||||
Beneath that is the :guilabel:`Create on Order` field.
|
||||
|
||||
To ensure workflows are as seamless as possible, it is recommended that an option in the
|
||||
:guilabel:`Create on Order` field is selected.
|
||||
For the :guilabel:`Product Type`, select :guilabel:`Service`. Doing so reveals the :guilabel:`Create
|
||||
on Order` field. Select either :guilabel:`Project`, :guilabel:`Project and Task`, or
|
||||
:guilabel:`Task`, depending on how the product is to be tracked in the **Project** app.
|
||||
|
||||
.. note::
|
||||
Leaving it on the default :guilabel:`Nothing` option won't negatively affect the desired
|
||||
workflow. However, a project *must* then be created directly from a sales order form with that
|
||||
specific product. Once a project is created *then* milestones and tasks can be created and
|
||||
configured.
|
||||
A :guilabel:`Project Template` can also be selected for the product. See :doc:`Project templates
|
||||
<../../../services/project/project_management/project_templates>` for more information. Project
|
||||
templates can have milestones defined, however, the *Quantity (%)* field must be manually updated
|
||||
on each newly created project.
|
||||
|
||||
When the :guilabel:`Create on Order` default option of :guilabel:`Nothing` is clicked, a drop-down
|
||||
menu is revealed with the following options:
|
||||
For the :guilabel:`Invoicing Policy`, select :guilabel:`Based on Milestones`. This option ensures
|
||||
that the product's delivered quantities update automatically once a milestone is completed.
|
||||
|
||||
- :guilabel:`Task`: Odoo creates a task related to this milestone product in the *Projects* app when
|
||||
this specific product is ordered.
|
||||
- :guilabel:`Project \& Task`: Odoo creates a project and task related to this milestone product in
|
||||
the *Projects* app when this specific product is ordered.
|
||||
- :guilabel:`Project`: Odoo creates a project related to this milestone product in the *Projects*
|
||||
app when this specific product is ordered.
|
||||
.. important::
|
||||
*Based on Milestones* is only available if there is at least one project with *Milestones*
|
||||
enabled.
|
||||
|
||||
When :guilabel:`Task` is selected, a :guilabel:`Project` field appears. In this field, select to
|
||||
which existing project in the *Projects* app this created task should be connected.
|
||||
|
||||
.. image:: milestone/task-option-project-field.png
|
||||
:align: center
|
||||
:alt: The Project field appears when the Task option is selected in Create on Order field.
|
||||
|
||||
When :guilabel:`Project \& Task` or :guilabel:`Project` is selected, two new fields appear:
|
||||
:guilabel:`Project Template` and :guilabel:`Workspace Template`.
|
||||
|
||||
.. image:: milestone/project-task-option-project-workspace-fields.png
|
||||
:align: center
|
||||
:alt: The Project template and workspace template fields that appear on milestone product.
|
||||
|
||||
The :guilabel:`Project Template` field provides template options to use for the project that will be
|
||||
created when this specific product is ordered.
|
||||
|
||||
The :guilabel:`Workspace Template` field provides template options to use for the workspace (for the
|
||||
*Documents* app, not the *Projects* app) that will be automatically generated for the project when
|
||||
this specific product is ordered.
|
||||
|
||||
.. tip::
|
||||
For organizational purposes, click the :guilabel:`Sales` tab on the product form, and enter a
|
||||
custom 'Milestone' related descriptor in the :guilabel:`Sales Description` field. This
|
||||
information appears in the :guilabel:`Description` column on the :guilabel:`Order Lines` tab of
|
||||
the sales order.
|
||||
|
||||
Or, directly edit/modify the :guilabel:`Description` field on the :guilabel:`Order Lines` tab of
|
||||
the sales order.
|
||||
|
||||
This is *not* a requirement.
|
||||
|
||||
Invoice milestones
|
||||
==================
|
||||
Defining milestones
|
||||
-------------------
|
||||
|
||||
.. note::
|
||||
The following flow features a trio of milestone products that have :guilabel:`Service` set as
|
||||
their :guilabel:`Product Type`, and :guilabel:`Task` set on their :guilabel:`Create on Order`
|
||||
field.
|
||||
This document focuses on the process of selling and invoicing a milestone product in the
|
||||
**Sales** app. For more information on creating milestones in the **Project** app, see
|
||||
:doc:`Project milestones <../../../services/project/project_management/project_milestones>`.
|
||||
|
||||
.. image:: milestone/settings-for-workflow.png
|
||||
:align: center
|
||||
:alt: Product with Service "Product Type" and "Task" in the Create on Order field on form.
|
||||
After the milestone product has been sold, a *Milestones* smart button is added to the |SO|. Click
|
||||
the smart button to view, edit, or create new milestones.
|
||||
|
||||
Those tasks are then attached to a pre-existing :guilabel:`Project`, which, in this case, is
|
||||
titled, :guilabel:`Rebranding Projects`.
|
||||
From here, the :guilabel:`Delivered %` can be altered. This amount equates to the total cost of the
|
||||
|SO| that is billed when the milestone is reached.
|
||||
|
||||
To invoice milestones, create a sales order with the milestone product(s). To do that, go to
|
||||
:menuselection:`Sales app --> New`. Doing so reveals a blank quotation form.
|
||||
.. example::
|
||||
A company that provides pool installation services bills based on predefined milestones as the
|
||||
work is completed. Each milestone equates to 25% of the total services:
|
||||
|
||||
From this quotation form, add a :guilabel:`Customer`. Then, click :guilabel:`Add a product` in the
|
||||
:guilabel:`Order Lines` tab. Next, add the milestone product(s) to the :guilabel:`Order Lines` tab.
|
||||
- Site Preparation & Excavation
|
||||
- Structural Installation
|
||||
- Plumbing & Equipment Installation
|
||||
- Finishing & Final Inspection
|
||||
|
||||
Once the corresponding milestone product(s) have been added, click :guilabel:`Confirm` to confirm
|
||||
the order, which turns the quotation into a sales order.
|
||||
.. image:: milestone/view-milestones.png
|
||||
:alt: The milestones for a sales order line.
|
||||
|
||||
When the order is confirmed, new smart buttons appear at the top of the sales order based on what
|
||||
was selected in the :guilabel:`Create on Order` field on the product form.
|
||||
The team uses a project template, called *Pool installation*, with these milestones defined. A
|
||||
new project is created whenever a |SO| with the *Pool installation services* product is
|
||||
confirmed.
|
||||
|
||||
From the sales order, click the :guilabel:`Milestones` smart button. Doing so reveals a blank
|
||||
:guilabel:`Milestones` page. Click :guilabel:`New` to add milestones.
|
||||
Invoicing a completed milestone
|
||||
===============================
|
||||
|
||||
.. image:: milestone/adding-milestones.png
|
||||
:align: center
|
||||
:alt: Adding milestones to a sales order with milestone products.
|
||||
Milestones can be tracked through the **Project** app (see :ref:`Using milestones
|
||||
<project/using-milestones>`). Additionally, a milestone can be marked complete by navigating to the
|
||||
|SO|, and clicking the :guilabel:`Milestones` smart button. On the *Milestones* page, enable the
|
||||
checkbox in the :guilabel:`Reached` column for the milestone.
|
||||
|
||||
Enter a :guilabel:`Name` for the milestone. Next, apply it to the corresponding :guilabel:`Sales
|
||||
Order Item`. Lastly, assign a :guilabel:`Deadline` to the milestone, if desired.
|
||||
Then, click :guilabel:`View Sales Order` or use the breadcrumbs to return to the |SO|. The
|
||||
:guilabel:`Delivered` column will be updated to reflect the *Delivered %* for the milestone reached.
|
||||
|
||||
Repeat that process for all milestone sales order items.
|
||||
These steps can be repeated as additional milestones are reached until the |SO| has been fulfilled.
|
||||
|
||||
Then, return to the sales order, via the breadcrumbs. From the sales order, click the
|
||||
:guilabel:`Tasks` smart button. Doing so reveals a :guilabel:`Tasks` page with a task for each sales
|
||||
order item with that option designated in the :guilabel:`Create on Order` field.
|
||||
.. important::
|
||||
Reaching a milestone does *not* automatically create an invoice. Instead, it updates the |SO| to
|
||||
reflect the amount of the total that is ready for invoicing.
|
||||
|
||||
.. image:: milestone/tasks-page.png
|
||||
:align: center
|
||||
:alt: Sample tasks page accessed via the smart button from a sales order with milestone products.
|
||||
Once one or more milestones have been reached, navigate to the |SO|, and confirm the
|
||||
:guilabel:`Delivered` column has updated correctly. Then, click :guilabel:`Create Invoice`.
|
||||
|
||||
To manually assign a configured milestone to a task, click the desired task, which reveals the task
|
||||
form. On the task form, select the appropriate milestone to which this task should be connected, in
|
||||
the :guilabel:`Milestone` field.
|
||||
|
||||
.. image:: milestone/milestone-field-on-task-form.png
|
||||
:align: center
|
||||
:alt: The milestone field on the task form when dealing with milestone products in Odoo Sales.
|
||||
|
||||
Repeat this process for all milestone tasks.
|
||||
|
||||
With those tasks properly configured, employees log in their progress as they work on the task, in
|
||||
addition to adding any notes related to the task.
|
||||
|
||||
Then, when that task is complete, that means that milestone has been reached. At that point, it is
|
||||
time to invoice that milestone.
|
||||
|
||||
To invoice a milestone, first return to the sales order — either via the breadcrumb links, or by
|
||||
navigating to :menuselection:`Sales app --> Orders --> Orders` and picking the appropriate sales
|
||||
order.
|
||||
|
||||
Back on the sales order form, click the :guilabel:`Milestones` smart button, and check the box in
|
||||
the :guilabel:`Reached` column for that particular task.
|
||||
|
||||
.. image:: milestone/reached-milestone.png
|
||||
:align: center
|
||||
:alt: What it looks like to mark a milestone as reached via the milestone smart button.
|
||||
|
||||
Next, return to the sales order — either by clicking :guilabel:`View Sales Order` on the
|
||||
:guilabel:`Milestones` page, or via the breadcrumb links.
|
||||
|
||||
Back on the sales order, the line item for the milestone that's been reached has its
|
||||
:guilabel:`Delivered` column filled. That's because the milestone has been reached, and therefore
|
||||
delivered.
|
||||
|
||||
.. image:: milestone/delivered-milestone-product-sales-order.png
|
||||
:align: center
|
||||
:alt: A milestone product that's been reached marked as delivered on the sales order in Odoo.
|
||||
|
||||
Click :guilabel:`Create Invoice` in the upper-left corner. Doing so reveals a :guilabel:`Create
|
||||
invoices` pop-up window.
|
||||
|
||||
.. image:: milestone/create-invoices-pop-up.png
|
||||
:align: center
|
||||
:alt: The create invoices pop-up window that appears when create invoice button is clicked.
|
||||
|
||||
On the :guilabel:`Create invoices` pop-up window, leave the :guilabel:`Create Invoice` option on the
|
||||
default :guilabel:`Regular Invoice` selection, and click the :guilabel:`Create Draft Invoice`
|
||||
button.
|
||||
|
||||
Upon clicking :guilabel:`Create Draft Invoice`, Odoo reveals the :guilabel:`Customer Invoice Draft`,
|
||||
*only* showing that reached milestone in the :guilabel:`Invoice Lines` tab.
|
||||
|
||||
.. image:: milestone/invoice-draft-milestone.png
|
||||
:align: center
|
||||
:alt: A customer invoice draft showing only the milestone product that's been reached.
|
||||
|
||||
From this invoice page, click the :guilabel:`Confirm` button to confirm the invoice. Then, when the
|
||||
customer has paid for this milestone, click :guilabel:`Register Payment`.
|
||||
|
||||
When :guilabel:`Register Payment` is clicked, a :guilabel:`Register Payment` pop-up window appears.
|
||||
|
||||
.. image:: milestone/register-payment-pop-up.png
|
||||
:align: center
|
||||
:alt: The Register Payment pop-up window that appears when Register Payment is clicked.
|
||||
|
||||
On this pop-up window, confirm the accuracy of the auto-populated fields, then click
|
||||
:guilabel:`Create Payment`.
|
||||
|
||||
When clicked, the pop-up window disappears, and Odoo returns to the invoice for that milestone,
|
||||
which now has a green :guilabel:`In Payment` banner in the upper-right corner. This banner signifies
|
||||
the invoice has been paid.
|
||||
|
||||
.. image:: milestone/in-payment-invoice.png
|
||||
:align: center
|
||||
:alt: An invoice with a milestone product that has been paid with an In Payment banner.
|
||||
|
||||
Then, return to the sales order, via the breadcrumb links. Back on the sales order, in the
|
||||
:guilabel:`Order Lines` tab, the reached milestone that's been invoiced and paid for, now has its
|
||||
:guilabel:`Invoiced` column filled.
|
||||
|
||||
.. image:: milestone/invoiced-column-filled-milestone.png
|
||||
:align: center
|
||||
:alt: The Invoiced column of a milestone product that's been paid for is filled.
|
||||
|
||||
There is also a new :guilabel:`Invoices` smart button at the top of the sales order. Clicking that
|
||||
reveals all the invoices that are connected to this sales order.
|
||||
|
||||
.. image:: milestone/invoices-smart-button.png
|
||||
:align: center
|
||||
:alt: The invoices smart button that appears at the top of a sales order with milestones.
|
||||
|
||||
Simply repeat the above process for each milestone as it is worked on, and subsequently, completed.
|
||||
|
||||
Continue that process until the entire project has been completed, each milestone has been invoiced,
|
||||
and the entire order has been paid for in full.
|
||||
Additional milestones can be invoiced as they are completed, until all services are complete.
|
||||
|
||||
.. seealso::
|
||||
- :doc:`time_materials`
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 27 KiB |
@@ -45,6 +45,8 @@ marked as :guilabel:`Reached` in the :menuselection:`Project --> Settings --> Mi
|
||||
also check the :guilabel:`Reached` box manually whenever the milestone is reached. Manual checking
|
||||
of the box will not impact the tasks linked to the milestone.
|
||||
|
||||
.. _project/using-milestones:
|
||||
|
||||
Using milestones
|
||||
================
|
||||
|
||||
|
||||