Jeevachaithanyan Sivanandan

Odoo - How to Create and Update Workcenter Folders in the Documents App

In Odoo, Programming · 3 min read

When using Odoo, managing folders within the Documents app is a common task. In this guide, we’ll walk through the process of creating a specific folder structure for each Sales Order when it is in the quotation stage. Once the quotation is confirmed, the folders will be moved to a different parent folder under the Sales Order category. Additionally, the subfolders will be organized within a parent folder named after the corresponding quotation or Sales Order.

Let’s dive into the implementation.

Step 1: Inherit documents.folder Model

We’ll start by inheriting the documents.folder model and introducing two boolean fields to designate folders as either a Sales Order or a Quotation. Although parent folders can be created using XML data, using boolean fields offers more flexibility in filtering and managing these folders within the code. Moreover, we’ll enforce that only one folder can be marked as either a Sales Order or Quotation folder at any given time to prevent duplication.

Here’s how you can define the documents.folder model:

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError

class DocumentFolder(models.Model):
    _inherit = 'documents.folder'

    is_sales_folder = fields.Boolean(string="Set As Sales Folder", default=False)
    is_quotation_folder = fields.Boolean(string="Set As Quotation Folder", default=False)

    @api.constrains('is_sales_folder', 'is_quotation_folder')
    def _check_unique_sales_quotation_folder(self):
        if self.is_sales_folder:
            existing_sales_folder = self.search([('is_sales_folder', '=', True), ('id', '!=', self.id)], limit=1)
            if existing_sales_folder:
                raise ValidationError("There can only be one Sales Folder.")

        if self.is_quotation_folder:
            existing_quotation_folder = self.search([('is_quotation_folder', '=', True), ('id', '!=', self.id)], limit=1)
            if existing_quotation_folder:
                raise ValidationError("There can only be one Quotation Folder.")

Step 2: Implement Folder Creation Logic in sale.order Model

Next, we’ll add the logic to the sale.order model. The process involves creating a folder each time a new quotation is generated, creating subfolders within it, and then moving the folder when the quotation is confirmed.

Here is the code to achieve this:

from odoo import api, fields, models
from odoo.exceptions import UserError

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

    def _get_parent_folder(self, is_quotation=True):
        folder = self.env['documents.folder'].search([
            ('is_quotation_folder', '=', True) if is_quotation else ('is_sales_folder', '=', True)
        ], limit=1)
        if not folder:
            raise UserError("Folders for Quotation or Sales Order not found.")
        return folder
   
    def _create_subfolders(self, workspace, folder_structure):
        for folder in folder_structure:
            folder_values = {
                'name': folder['name'] if isinstance(folder, dict) else folder,
                'parent_folder_id': workspace.id,
            }
            self.env['documents.folder'].create(folder_values)
   
    def _create_document_workspace(self, is_quotation=True):
        folder_structure = [
            'custome child folder 1',
            'custome child folder 2',        
        ]

        parent_workspace = self._get_parent_folder(is_quotation)

        workspace = self.env['documents.folder'].create({
            'name': self.name,
            'parent_folder_id': parent_workspace.id,
        })

        self._create_subfolders(workspace, folder_structure)
               
    def _move_workspace_to_sales_order(self):
        quotation_workspace = self.env['documents.folder'].search([
            ('name', '=', self.quotation_reference),  # reference back to quotation
            ('parent_folder_id.is_quotation_folder', '=', True)
        ], limit=1)

        if not quotation_workspace:
            raise UserError("Quotation workspace not found.")

        sales_order_parent_folder = self._get_parent_folder(is_quotation=False)

        # Move the folder to the Sales Order workspace and rename it
        quotation_workspace.write({
            'parent_folder_id': sales_order_parent_folder.id,
            'name': self.name,
        })

Step 3: Override create and action_confirm Methods

We’ll override the create and action_confirm methods to trigger the folder creation and movement at the appropriate times.

@api.model_create_multi
def create(self, vals_list):
    sale_orders = super(SaleOrder, self).create(vals_list)
    for sale_order in sale_orders:
        if sale_order.state in ['draft', 'sent']:
            sale_order._create_document_workspace(is_quotation=True)
    return sale_orders

def action_confirm(self):
    result = super(SaleOrder, self).action_confirm()
    for order in self:
        if order.state == 'sale':
            order._move_workspace_to_sales_order()
    return result

Step 4: Update Documents Settings View

Finally, we need to update the Documents app settings view to include our new boolean fields.

 <?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id="folder_view_form_inherit_custom_module_name" model="ir.ui.view">
        <field name="name">folder.view.form.inherit.custom_module_name</field>
        <field name="model">documents.folder</field>
        <field name="inherit_id" ref="documents.folder_view_form"/>
        <field name="arch" type="xml">
            <field name="parent_folder_id" position="after">
                <field name="is_sales_folder" string="Set as Sales Folder"/>
                <field name="is_quotation_folder" string="Set as Quotation Folder"/>
            </field>
        </field>
    </record>
</odoo>

With these steps, you’ve successfully set up a system in Odoo to manage the creation and organization of folders for Sales Orders and Quotations within the Documents app. This setup ensures that all necessary documents are well-organized and easily accessible as the Sales Order progresses from quotation to confirmation