Odoo Sale Order and Quotation Tutorials

Add a menu item to Sales section

This menu below will appear under Sales > Orders

<record id="act_export_sale" model="ir.actions.act_window">
    <field name="name">Export Sales</field>
    <field name="res_model">wizard.sale.export.sale</field>
    <field name="view_mode">form</field>
    <field name="view_id" ref="export_sale_form_view"/>
    <field name="target">new</field>
</record>

<menuitem id="menu_sale_export" parent="sale.sale_order_menu" name="Export Sales" sequence="0" action="act_export_sale"/>

You need to write export_sale_form_view based on your need.

Inherit and Override Sale Report Document

Create a view file called custom_report_sale.xml then add it to manifest. You can add custom field or modify existing values in this view.

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>
        <template id="custom_report_sale" inherit_id="sale.report_saleorder_document">
            <xpath expr="//div[@class='page']" position="replace">
                <div class="page">
            <div class="oe_structure"/>

            <h2>
                <t t-if="not (env.context.get('proforma', False) or is_pro_forma)">
                    <span t-if="doc.state not in ['draft','sent']">Order # </span>
                    <span t-if="doc.state in ['draft','sent']">Quotation # </span>
                </t>
                <t t-if="env.context.get('proforma', False) or is_pro_forma">
                    <span>Pro-Forma Invoice # </span>
                </t>
                <span t-field="doc.name"/>
            </h2>

            <div class="row mt32 mb32" id="informations">
                <div t-if="doc.client_order_ref" class="col-auto mw-100 mb-2">
                    <strong>Your Reference:</strong>
                    <p class="m-0" t-field="doc.client_order_ref"/>
                </div>
                <div t-if="doc.confirmation_date and doc.state not in ['draft','sent']" class="col-auto mw-100 mb-2">
                    <strong>Date Ordered:</strong>
                    <p class="m-0" t-field="doc.confirmation_date"/>
                </div>
                <div t-if="doc.date_order and doc.state in ['draft','sent']" class="col-auto mw-100 mb-2">
                    <strong>Quotation Date:</strong>
                    <p class="m-0" t-field="doc.date_order"/>
                </div>
                <div t-if="doc.user_id.name" class="col-auto mw-100 mb-2">
                    <strong>Salesperson:</strong>
                    <p class="m-0" t-field="doc.user_id"/>
                </div>
                <div name="payment_term" t-if="doc.payment_term_id" class="col-auto mw-100 mb-2">
                    <strong>Payment Terms:</strong>
                    <p class="m-0" t-field="doc.payment_term_id"/>
                </div>
                <div t-if="doc.validity_date and doc.state in ['draft', 'sent']" class="col-auto mw-100 mb-2">
                    <strong>Expiration Date:</strong>
                    <p class="m-0" t-field="doc.validity_date"/>
                </div>
            </div>

            <!-- Is there a discount on at least one line? -->
            <t t-set="display_discount" t-value="any([l.discount for l in doc.order_line])"/>

            <table class="table table-sm o_main_table">
                <thead>
                    <tr>
                        <!-- TODO: remove in master -->
                        <t t-set="colspan" t-value="5"/>
                        <th class="text-left">Description</th>
                        <th class="text-right">Quantity</th>
                        <th class="text-right">Unit Price</th>
                        <th class="text-right">Taxes</th>
                        <th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">
                            <span>Disc.(%)</span>
                            <!-- TODO: remove in master -->
                            <t t-set="colspan" t-value="colspan+1"/>
                        </th>                        
                        <th class="text-right">
                            <t groups="account.group_show_line_subtotals_tax_excluded">Amount</t>
                            <t groups="account.group_show_line_subtotals_tax_included">Total Price</t>
                        </th>
                    </tr>
                </thead>
                <tbody class="sale_tbody">

                    <t t-set="current_subtotal" t-value="0"/>

                    <t t-foreach="doc.order_line" t-as="line">

                        <t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
                        <t t-set="current_subtotal" t-value="current_subtotal + line.price_total" groups="account.group_show_line_subtotals_tax_included"/>

                        <tr t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''">
                            <t t-if="not line.display_type">
                                <td><span t-field="line.name"/></td>
                                <td class="text-right">
                                    <span t-field="line.product_uom_qty"/>
                                    <span t-field="line.product_uom" groups="uom.group_uom"/>
                                </td>
                                <td class="text-right">
                                    <span t-field="line.price_unit"/>
                                </td>
                                <td class="text-right">
                                    <span t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_id))"/>
                                </td>
                                <td t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">
                                    <span t-field="line.discount"/>
                                </td>                                
                                <td class="text-right o_price_total">
                                    <span t-field="line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/>
                                    <span t-field="line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
                                </td>
                            </t>
                            <t t-if="line.display_type == 'line_section'">
                                <td colspan="99">
                                    <span t-field="line.name"/>
                                </td>
                                <t t-set="current_section" t-value="line"/>
                                <t t-set="current_subtotal" t-value="0"/>
                            </t>
                            <t t-if="line.display_type == 'line_note'">
                                <td colspan="99">
                                    <span t-field="line.name"/>
                                </td>
                            </t>
                        </tr>

                        <t t-if="current_section and (line_last or doc.order_line[line_index+1].display_type == 'line_section')">
                            <tr class="is-subtotal text-right">
                                <td colspan="99">
                                    <strong class="mr16">Subtotal</strong>
                                    <span
                                        t-esc="current_subtotal"
                                        t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'
                                    />
                                </td>
                            </tr>
                        </t>
                    </t>
                </tbody>
            </table>

            <div class="clearfix">
                <div id="total" class="row" name="total">
                    <div t-attf-class="#{'col-4' if report_type != 'html' else 'col-sm-7 col-md-5'} ml-auto">
                        <table class="table table-sm">
                            <tr class="border-black o_subtotal" style="">
                                <td><strong>Subtotal</strong></td>
                                <td class="text-right">
                                    <span t-field="doc.amount_untaxed"/>
                                </td>
                            </tr>
                            <t t-foreach="doc.amount_by_group" t-as="amount_by_group">
                                <tr style="">
                                    <t t-if="amount_by_group[3] == 1 and doc.amount_untaxed == amount_by_group[2]">
                                        <td>
                                            <span t-esc="amount_by_group[0]"/>
                                            <span>&amp;nbsp;<span>on</span>&amp;nbsp;<t t-esc="amount_by_group[2]" t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/></span>
                                        </td>
                                        <td class="text-right o_price_total">
                                            <span t-esc="amount_by_group[1]"
                                                t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
                                        </td>
                                    </t>
                                    <t t-else ="">
                                        <td>
                                            <span t-esc="amount_by_group[0]"/>
                                        </td>
                                        <td class="text-right o_price_total">
                                            <span t-esc="amount_by_group[1]"
                                                t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
                                        </td>
                                    </t>
                                </tr>
                            </t>
                            <tr class="border-black o_total">
                                <td><strong>Total</strong></td>
                                <td class="text-right">
                                    <span t-field="doc.amount_total"/>
                                </td>
                            </tr>
                        </table>
                    </div>
                </div>
            </div>

            <p t-field="doc.note" />
            <p t-if="doc.payment_term_id.note">
                <span t-field="doc.payment_term_id.note"/>
            </p>
            <p id="fiscal_position_remark" t-if="doc.fiscal_position_id and doc.fiscal_position_id.sudo().note">
                <strong>Fiscal Position Remark:</strong>
                <span t-field="doc.fiscal_position_id.sudo().note"/>
            </p>

            <div t-if="doc.signature" class="mt32 ml16 mr16" name="signature">
                <div class="offset-8">
                    <strong>Signature</strong>
                </div>
                <div class="offset-8">
                    <img t-att-src="image_data_uri(doc.signature)" style="max-height: 4cm; max-width: 8cm;"/>
                </div>
                <div class="offset-8 text-center">
                    <p t-field="doc.signed_by"/>
                </div>
            </div>

            <div class="oe_structure"/>
        </div>
            </xpath>
        </template>

    </data>
</openerp>

Add custom field to Sale Order form view

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

    my_custom_field = fields.Char(string='My Field')
<record id="view_sale_order_form_custom_inherit" model="ir.ui.view">
    <field name="name">sale.order.form.inherit</field>
    <field name="model">sale.order</field>
    <field name="inherit_id" ref="sale.view_order_form"/>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='partner_shipping_id']" position="after">
            <field name="my_custom_field"/>            
        </xpath>
    </field>
</record>

Add custom field to Sale Order tree

<record model="ir.ui.view" id="view_sale_order_tree_custom_inherit">
    <field name="name">sale.order.tree.with.onboarding.inherit</field>
    <field name="model">sale.order</field>
    <field name="inherit_id" ref="sale.view_quotation_tree_with_onboarding"/>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='amount_total']" position="after">
            <field name="my_custom_field"/>
        </xpath>
    </field>
</record>

Leave a Comment

Your email address will not be published. Required fields are marked *

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close