第二章 门户销售

在门户销售订单中添加图片预览

使用[Mommy_Portal_Sale]模块来完成这个工作。

Odoo原生实现了附件预览的功能,但是没有在门户端实现。我们先来看一下后端如何使用图片预览的功能:

门户订单分组

原生odoo在门户订单列表中只提供了过滤和筛选选项,并未提供分组功能。下面我们来看一下,如何在门户中自定义分组功能。

自定义分组字段

由于所有门户模型都继承自CustomerPortal类,因此分组功能其实已经内置了,只不过我们需要把相关的条件通过代码配置出来。

首先我们要理解门户页面的工作流程,由controller组织数据,然后使用QWeb的render方法将页面渲染出来。因此,我们的改造就要基于Render方法。对于门户销售模块来说,这个方法是_prepare_sale_portal_rendering_values。

def _prepare_sale_portal_rendering_values(
        self,
        page=1,
        date_begin=None,
        date_end=None,
        sortby=None,
        quotation_page=False,
        search_in=None,
        search=None,
        groupby="none",
        filterby=None,
        **kwargs,
    ):
    ...
    def get_group_orders():
        groupby_mapping = self._get_groupby_mapping()
        field = groupby_mapping.get(groupby, None)
        orderby = "%s, %s" % (field, sort_order) if field else sort_order
        if field:
            if groupby == "date":
                group_orders = SaleOrder.read_group(
                    domain,
                    ["amount_total:sum", "ids:array_agg(id)"],
                    ["date_order:day"],
                    orderby=orderby,
                )
                grouped_orders = [
                    SaleOrder.sudo().browse(group["ids"]) for group in group_orders
                ]
            else:
                grouped_orders = [
                    SaleOrder.concat(*g)
                    for k, g in groupbyelem(orders, itemgetter(field))
                ]
                # group_orders = SaleOrder.sudo().read_group(domain, [field, 'amount_total:sum'], [field])
            return grouped_orders

    grouped_orders = get_group_orders() or [orders]
    ...

想要获取分组后的数据,我们在传递给templates就需要将数据根据我们的分组条件分组好。上面的内置方法get_group_orders就是实现此功能。如果分组的条件是None,那么我们将没有分组的orders作为一个数组传递给页面。

values.update(
    {
        "date": date_begin,
        "grouped_orders": grouped_orders,
        "quotations": orders.sudo() if quotation_page else SaleOrder,
        "orders": orders.sudo() if not quotation_page else SaleOrder,
        "page_name": "quote" if quotation_page else "order",
        "pager": pager_values,
        "default_url": url,
        "searchbar_filters": OrderedDict(sorted(searchbar_filters.items())),
        "searchbar_groupby": self._sale_get_searchbar_groupby(),
        "searchbar_inputs": self._sale_get_searchbar_inputs(),
        "searchbar_sortings": searchbar_sortings,
        "sortby": sortby,
        "groupby": groupby,
        "search_in": search_in,
        "search": search,
        "filterby": filterby,
    }
)

return values

我们在返回给页面数据时,groups_orders就是我们分组以后的订单数据,searchbar_groupby代表我们自定义的分组条件。groupby是我们要分组的字段。

分组条件

在门户页面中,分组条件不像后台那样简单写个xml配置就可以,而是需要额外的代码配置。接下来,我们来看一下如何自定义分组条件。

以上面的门户销售为例:

def _sale_get_searchbar_groupby(self):
    """
    groupby orders in portal
    """
    return {
        "none": {"input": "none", "label": _("None")},
        "date": {"input": "date_order", "label": _("Date")},
        "partner_id": {"input": "partner_id", "label": _("Customer")},
        "user_id": {"input": "state", "label": _("Salesperson")},
        "team_id": {"input": "team_id", "label": _("Sales Team")},
    }

门户的分组过滤功能配置由一个字典组成。外层的KEY代表的是分组的关键字,值代表的是在页面显示的label和输入参数input。

input会在_get_groupby_mapping方法中匹配到对应的分组字段值。

def _get_groupby_mapping(self):
    """
    group by mapping
    """

    return {
        "date": "date_order",
        "partner_id": "partner_id",
        "user_id": "user_id",
        "team_id": "team_id",
    }

比如,分组条件中的partner_id,匹配到的字段是partner_id, 也就是使用partner_id进行分组。

分组条件的页面配置

最后,我们需要在页面中对分组的条件进行配置。

<t t-set="grouped_invoices_colspan" t-value="12"/>
    <t t-if="grouped_invoices" t-call="portal.portal_table">
        <t t-foreach="grouped_invoices" t-as="invoices">
            <thead>
                <tr t-if="groupby != 'none'" class="table-light">
                <t t-set="invoice" t-value="invoices[0].sudo()" t-if="invoices" />
                    <th t-if="invoice and groupby == 'invoice_date'" t-attf-colspan="">
                        <em class="font-weight-normal text-muted">Invoice Date:</em>
                        <span t-field="invoice.invoice_date" />
                    </th>
                    <th t-if="invoice and groupby == 'partner_id'" t-attf-colspan="">
                        <em class="font-weight-normal text-muted">Partner:</em>
                        <span t-field="invoice.partner_id" />
                    </th>
                    <th t-if="invoice and groupby == 'user_id'" t-attf-colspan="">
                        <em class="font-weight-normal text-muted">Salesperson:</em>
                        <span t-field="invoice.user_id" />
                    </th>
                </tr>
                <tr t-if="groupby=='none'" class="active">
                    <th>Invoice #</th>
                    <th>Invoice Date</th>
                    <th class='d-none d-md-table-cell'>Due Date</th>
                    <th class="text-center">Status</th>
                    <th class="text-end">Amount Due</th>
                </tr>
            </thead>
            <tbody>
                ...
            </tbody>
        </t>
    </t>
</t>

在页面中,我们根据分组后的订单grouped_orders,进行循环遍历。

  • 如果分组条件是None,那么就进行额外输出,直接讲分组单据使用原格式输出。
  • 如果分组条件不为None,那么将相应的分组条件显示在每个分组订单行的上面。输出格式为: 条件:分组值。

results matching ""

    No results matching ""