[WIP] Pms: show folio details in portal

This commit is contained in:
Sara Lago
2021-03-04 12:15:37 +01:00
parent cca52a0db2
commit b3ce037840
4 changed files with 469 additions and 31 deletions

View File

@@ -1,34 +1,68 @@
from odoo import http from odoo import http
from odoo.addons.portal.controllers.portal import CustomerPortal
from odoo.exceptions import AccessError, MissingError from odoo.exceptions import AccessError, MissingError
from odoo.http import request, route from odoo.http import request
from odoo.addons.portal.controllers.portal import CustomerPortal
class PortalFolio(CustomerPortal): class PortalFolio(CustomerPortal):
def _prepare_home_portal_values(self, counters): def _prepare_home_portal_values(self, counters):
partner = request.env.user.partner_id partner = request.env.user.partner_id
values = super()._prepare_home_portal_values(counters) values = super()._prepare_home_portal_values(counters)
Folio = request.env['pms.folio'] Folio = request.env["pms.folio"]
if 'folio_count' in counters: if "folio_count" in counters:
values['folio_count'] = Folio.search_count([ values["folio_count"] = (
# ('partner_id', '=', partner.id), Folio.search_count(
]) if Folio.check_access_rights('read', raise_exception=False) else 0 [
("partner_id", "child_of", partner.id),
]
)
if Folio.check_access_rights("read", raise_exception=False)
else 0
)
return values return values
@http.route(['/my/folios'], type='http', auth="user", website=True) def _folio_get_page_view_values(self, folio, access_token, **kwargs):
def portal_my_folios(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw): values = {"folio": folio, "token": access_token}
return self._get_page_view_values(
folio, access_token, values, "my_folios_history", False, **kwargs
)
@http.route(["/my/folios"], type="http", auth="user", website=True)
def portal_my_folios(
self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw
):
partner = request.env.user.partner_id
values = self._prepare_portal_layout_values() values = self._prepare_portal_layout_values()
values['folios'] = request.env['pms.folio'].sudo().search([]) values["folios"] = (
request.env["pms.folio"]
.sudo()
.search(
[
("partner_id", "child_of", partner.id),
]
)
)
return request.render("pms.portal_my_folio", values) return request.render("pms.portal_my_folio", values)
@http.route(['/my/folios/<int:folio_id>'], type='http', auth="user", website=True) @http.route(["/my/folios/<int:folio_id>"], type="http", auth="user", website=True)
def portal_my_folio_detail(self, folio_id, access_token=None, report_type=None, download=False, **kw): def portal_my_folio_detail(
self, folio_id, access_token=None, report_type=None, download=False, **kw
):
try: try:
folio_sudo = self._document_check_access('pms_folio', folio_id, access_token=access_token) folio_sudo = self._document_check_access(
"pms.folio",
folio_id,
access_token="9a6f4fc8-59f6-4f50-ae45-5af6492e7aba",
)
except (AccessError, MissingError): except (AccessError, MissingError):
return request.redirect('/my') return request.redirect("/my")
if report_type in ('html', 'pdf', 'text'): if report_type in ("html", "pdf", "text"):
return self._show_report(model=folio_sudo, report_type=report_type, report_ref='pms.report_folio_document', download=download) return self._show_report(
values = self._invoice_get_page_view_values(folio_sudo, access_token, **kw) model=folio_sudo,
return request.render("pms.report_folio_document", values) report_type=report_type,
report_ref="action_report_folio",
download=download,
)
values = self._folio_get_page_view_values(folio_sudo, access_token, **kw)
return request.render("pms.folio_portal_template", values)

View File

@@ -60,4 +60,4 @@ user_access_folio_make_invoice_advance,user_access_folio_make_invoice_advance,mo
user_access_pms_invoice_filter_days,user_access_pms_invoice_filter_days,model_pms_invoice_filter_days,pms.group_pms_user,1,1,1,1 user_access_pms_invoice_filter_days,user_access_pms_invoice_filter_days,model_pms_invoice_filter_days,pms.group_pms_user,1,1,1,1
user_access_pms_invoice_filter_days_items,user_access_pms_invoice_filter_days_items,model_pms_invoice_filter_days_items,pms.group_pms_user,1,1,1,1 user_access_pms_invoice_filter_days_items,user_access_pms_invoice_filter_days_items,model_pms_invoice_filter_days_items,pms.group_pms_user,1,1,1,1
user_access_wizard_payment_folio,user_access_wizard_payment_folio,model_wizard_payment_folio,pms.group_pms_user,1,1,1,1 user_access_wizard_payment_folio,user_access_wizard_payment_folio,model_wizard_payment_folio,pms.group_pms_user,1,1,1,1
user_access_pms_folio_portal,user_access_pms_folio_portal,model_pms_folio,base.group_portal,1,0,0,0 user_access_pms_folio_portal,user_access_pms_folio_portal,model_pms_folio,base.group_portal,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
60 user_access_pms_invoice_filter_days user_access_pms_invoice_filter_days model_pms_invoice_filter_days pms.group_pms_user 1 1 1 1
61 user_access_pms_invoice_filter_days_items user_access_pms_invoice_filter_days_items model_pms_invoice_filter_days_items pms.group_pms_user 1 1 1 1
62 user_access_wizard_payment_folio user_access_wizard_payment_folio model_wizard_payment_folio pms.group_pms_user 1 1 1 1
63 user_access_pms_folio_portal user_access_pms_folio_portal model_pms_folio base.group_portal 1 0 0 0

View File

@@ -225,10 +225,10 @@
</record> </record>
<record id="pms_folio_rule_portal" model="ir.rule"> <record id="pms_folio_rule_portal" model="ir.rule">
<field name="name">Portal Personal Folios</field> <field name="name">Portal Personal Folios</field>
<field name="model_id" ref="model_pms_folio"/> <field name="model_id" ref="model_pms_folio" />
<field name="domain_force">[]</field> <field name="domain_force">[]</field>
<field name="groups" eval="[(4, ref('base.group_portal'))]"/> <field name="groups" eval="[(4, ref('base.group_portal'))]" />
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True" />
</record> </record>
</data> </data>
</odoo> </odoo>

View File

@@ -1,10 +1,16 @@
<odoo> <odoo>
<template id="portal_my_folios" name="Folios" inherit_id="portal.portal_my_home" customize_show="True" priority="30"> <template
id="portal_my_folios"
name="Folios"
inherit_id="portal.portal_my_home"
customize_show="True"
priority="30"
>
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside"> <xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
<t t-call="portal.portal_docs_entry"> <t t-call="portal.portal_docs_entry">
<t t-set="title">Folios</t> <t t-set="title">Folios</t>
<t t-set="url" t-value="'/my/folios'"/> <t t-set="url" t-value="'/my/folios'" />
<t t-set="placeholder_count" t-value="'folio_count'"/> <t t-set="placeholder_count" t-value="'folio_count'" />
</t> </t>
</xpath> </xpath>
</template> </template>
@@ -12,7 +18,7 @@
<template id="portal_my_folio" name="My Folios"> <template id="portal_my_folio" name="My Folios">
<t t-call="portal.portal_layout"> <t t-call="portal.portal_layout">
<t t-set="breadcrumbs_searchbar" t-value="True"/> <t t-set="breadcrumbs_searchbar" t-value="True" />
<t t-call="portal.portal_searchbar"> <t t-call="portal.portal_searchbar">
<t t-set="title">Folios</t> <t t-set="title">Folios</t>
@@ -32,16 +38,414 @@
<t t-foreach="folios" t-as="folio"> <t t-foreach="folios" t-as="folio">
<tr> <tr>
<td> <td>
<a t-att-href="folio.get_portal_url()" t-att-title="folio.name"> <a
<t t-esc="folio.name"/> t-att-href="folio.get_portal_url()"
t-att-title="folio.name"
>
<t t-esc="folio.name" />
</a> </a>
</td> </td>
<td><span t-field="folio.date_order"/></td> <td><span t-field="folio.date_order" /></td>
<td class="text-right"><span t-field="folio.amount_total"/></td> <td class="text-right"><span
t-field="folio.amount_total"
/></td>
</tr> </tr>
</t> </t>
</tbody> </tbody>
</t> </t>
</t> </t>
</template> </template>
<template
id="folio_portal_template"
name="Folio Portal Template"
inherit_id="portal.portal_sidebar"
primary="True"
>
<xpath expr="//div[hasclass('o_portal_sidebar')]" position="inside">
<div class="row mt16 o_portal_sale_sidebar">
<!-- Sidebar -->
<t t-call="portal.portal_record_sidebar">
<t t-set="classes" t-value="'col-lg-auto d-print-none'" />
<t t-set="title">
<h2 class="mb-0"><b t-field="folio.amount_total" /> </h2>
</t>
<t t-set="entries">
<ul
class="list-group list-group-flush flex-wrap flex-row flex-lg-column"
>
<li class="list-group-item flex-grow-1">
<div class="o_download_pdf btn-toolbar flex-sm-nowrap">
<div class="btn-group flex-grow-1 mr-1 mb-1">
<a
class="btn btn-secondary btn-block o_download_btn"
t-att-href="folio.get_portal_url(report_type='pdf', download=True)"
title="Download"
><i class="fa fa-download" /> Download</a>
</div>
<div class="btn-group flex-grow-1 mb-1">
<a
class="btn btn-secondary btn-block o_print_btn o_portal_invoice_print"
t-att-href="folio.get_portal_url(report_type='pdf')"
id="print_folio_report"
title="Print"
target="_blank"
><i class="fa fa-print" /> Print</a>
</div>
</div>
</li>
<li
class="navspy list-group-item pl-0 flex-grow-1"
t-ignore="true"
role="complementary"
>
<ul class="nav flex-column bs-sidenav" />
</li>
<li
t-if="folio.user_id.name"
class="list-group-item flex-grow-1"
>
<div class="small mb-1"><strong
class="text-muted"
>Salesperson</strong></div>
<div class="row flex-nowrap">
<!--<div class="col flex-grow-0 pr-2">
<img class="rounded-circle mr4 float-left o_portal_contact_img" t-if="folio.user_id.image_1024" t-att-src="image_data_uri(sale_order.user_id.image_1024)" alt="Contact"/>
<img class="rounded-circle mr4 float-left o_portal_contact_img" t-if="not folio.user_id.image_1024" src="/web/static/src/img/placeholder.png" alt="Contact"/>
</div>-->
<div class="col pl-0" style="min-width: 150px">
<span
t-field="folio.user_id"
t-options='{"widget": "contact", "fields": ["name", "phone"], "no_marker": True}'
/>
<a href="#discussion" class="small"><i
class="fa fa-comment"
/> Send message</a>
</div>
</div>
</li>
</ul>
</t>
</t>
<!-- main content -->
<div
t-attf-class="card #{'pb-5' if report_type == 'html' else ''}"
id="portal_folio_content"
>
<div t-call="pms.folio_portal_content" />
</div>
<!-- chatter -->
<div id="folio_communication" class="mt-4">
<h2>History</h2>
<t t-call="portal.message_thread">
<t t-set="object" t-value="folio" />
</t>
</div>
</div>
</xpath>
</template>
<!--
Sales Order content : intro, informations, order lines, remarks, descriptions ....
This template should contains all the printable element of the SO. This is the
template rendered in PDF with the report engine.
-->
<template id="folio_portal_content" name="Folio Portal Content">
<!--<t t-call="web.external_layout">-->
<t t-set="address">
<div class="row">
<div class="col-xs-6">
<t t-if="folio.partner_invoice_id != folio.partner_id">
<div
t-field="folio.partner_invoice_id"
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'
/>
</t>
</div>
<div class="col-xs-5 col-xs-offset-1">
<div
t-field="folio.partner_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'
/>
<p t-if="folio.partner_id.vat">
<t t-esc="folio.company_id.country_id.vat_label or 'TIN'" />
:
<span t-field="folio.partner_id.vat" />
</p>
</div>
</div>
</t>
<div class="page">
<div class="oe_structure" />
<h2 class="mt16">
<span t-if="folio.state not in ['draft','sent']">Order #</span>
<span t-if="folio.state in ['draft','sent']">Quotation #</span>
<span t-field="folio.name" />
</h2>
<div class="row mt32 mb32" id="informations">
<div t-if="folio.client_order_ref" class="col-auto col-3 mw-100 mb-2">
<strong>Your Reference:</strong>
<p class="m-0" t-field="folio.client_order_ref" />
</div>
<div
t-if="folio.date_order and folio.state not in ['draft','sent']"
class="col-auto col-3 mw-100 mb-2"
>
<strong>Order Date:</strong>
<p class="m-0" t-field="folio.date_order" />
</div>
<div
t-if="folio.date_order and folio.state in ['draft','sent']"
class="col-auto col-3 mw-100 mb-2"
>
<strong>Quotation Date:</strong>
<p
class="m-0"
t-field="folio.date_order"
t-options='{"widget": "date"}'
/>
</div>
<div t-if="folio.user_id.name" class="col-auto col-3 mw-100 mb-2">
<strong>Salesperson:</strong>
<p class="m-0" t-field="folio.user_id" />
</div>
</div>
<!-- Is there a discount on at least one line? -->
<t
t-set="display_discount"
t-value="any(l.discount for l in folio.sale_line_ids)"
/>
<table class="table table-sm o_main_table">
<!-- In case we want to repeat the header, remove "display: table-row-group" -->
<thead style="display: table-row-group">
<tr>
<th name="th_description" class="text-left">Description</th>
<th name="th_quantity" class="text-right">Quantity</th>
<th name="th_priceunit" class="text-right">Unit Price</th>
<th
name="th_discount"
t-if="display_discount"
class="text-right"
>
<span>Disc.%</span>
</th>
<th name="th_taxes" class="text-right">Taxes</th>
<th name="th_subtotal" class="text-right">
<span
groups="account.group_show_line_subtotals_tax_excluded"
>Amount</span>
<span
groups="account.group_show_line_subtotals_tax_included"
>Total Price</span>
</th>
</tr>
</thead>
<tbody class="sale_tbody">
<t t-set="current_subtotal" t-value="0" />
<t t-foreach="folio.sale_line_ids" 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">
<t t-set="price" t-value="line.price_unit" />
<t t-if="line.reservation_id">
<t
t-set="print_board_service"
t-value="line.reservation_id.board_service_room_id.pms_board_service_id.show_detail_report"
/>
<t t-if="not print_board_service">
<t
t-foreach="line.reservation_id.service_ids"
t-as="service"
>
<t t-if="service.is_board_service">
<t
t-set="price"
t-value="service.product_qty/line.product_uom_qty*service.price_unit*(1-(service.discount or 0.0)*0.01) + price"
/>
</t>
</t>
</t>
</t>
<t
t-if="not(not print_board_service and line.service_id.is_board_service)"
>
<td name="td_name"><span
t-field="line.name"
/></td>
<td name="td_quantity" class="text-right">
<span t-field="line.product_uom_qty" />
<span
t-field="line.product_uom"
groups="uom.group_uom"
/>
</td>
<td name="td_priceunit" class="text-right">
<span
t-esc="price"
t-options='{"widget": "monetary", "display_currency": folio.pricelist_id.currency_id}'
/>
</td>
<td t-if="display_discount" class="text-right">
<span t-field="line.discount" />
</td>
<td name="td_taxes" class="text-right">
<span
t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_ids))"
/>
</td>
<td
name="td_subtotal"
class="text-right o_price_total"
>
<span
t-esc="price*(1-(line.discount or 0.0)*0.01)* line.product_uom_qty"
groups="account.group_show_line_subtotals_tax_excluded"
t-options='{"widget": "monetary", "display_currency": folio.pricelist_id.currency_id}'
/>
<span
t-esc="price *(1-(line.discount or 0.0)*0.01)* line.product_uom_qty"
groups="account.group_show_line_subtotals_tax_included"
t-options='{"widget": "monetary", "display_currency": folio.pricelist_id.currency_id}'
/>
</td>
</t>
</t>
<t t-if="line.display_type == 'line_section'">
<td name="td_section_line" 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 name="td_note_line" colspan="99">
<span t-field="line.name" />
</td>
</t>
</tr>
<t
t-if="current_section and (line_last or folio.sale_line_ids[line_index+1].display_type == 'line_section')"
>
<tr class="is-subtotal text-right">
<td name="td_section_subtotal" colspan="99">
<strong class="mr16">Subtotal</strong>
<span
t-esc="current_subtotal"
t-options='{"widget": "monetary", "display_currency": folio.pricelist_id.currency_id}'
/>
</td>
</tr>
</t>
</t>
</tbody>
</table>
<div class="clearfix" name="so_total_summary">
<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 name="td_amount_untaxed_label"><strong
>Subtotal</strong></td>
<td name="td_amount_untaxed" class="text-right">
<span t-field="folio.amount_untaxed" />
</td>
</tr>
<t
t-foreach="folio._get_tax_amount_by_group()"
t-as="amount_by_group"
>
<tr style="">
<t
t-if="amount_by_group[3] == 1 and folio.amount_untaxed == amount_by_group[2]"
>
<td name="td_amount_by_group_label_3">
<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": folio.pricelist_id.currency_id}'
/></span>
</td>
<td
name="td_amount_by_group_3"
class="text-right o_price_total"
>
<span
t-esc="amount_by_group[1]"
t-options='{"widget": "monetary", "display_currency": folio.pricelist_id.currency_id}'
/>
</td>
</t>
<t t-else="">
<td name="td_amount_by_group_label">
<span t-esc="amount_by_group[0]" />
</td>
<td
name="td_amount_by_group"
class="text-right o_price_total"
>
<span
t-esc="amount_by_group[1]"
t-options='{"widget": "monetary", "display_currency": folio.pricelist_id.currency_id}'
/>
</td>
</t>
</tr>
</t>
<tr class="border-black o_total">
<td name="td_amount_total_label"><strong
>Total</strong></td>
<td name="td_amount_total" class="text-right">
<span t-field="folio.amount_total" />
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="oe_structure" />
<p t-field="folio.note" />
<p t-if="folio.payment_term_id.note">
<span t-field="folio.payment_term_id.note" />
</p>
<p
id="fiscal_position_remark"
t-if="folio.fiscal_position_id and folio.fiscal_position_id.sudo().note"
>
<strong>Fiscal Position Remark:</strong>
<span t-field="folio.fiscal_position_id.sudo().note" />
</p>
</div>
<!--</t>-->
</template>
</odoo> </odoo>