[ADD]mandates_bank_accounts_portal
This commit is contained in:
2
partner_bank_account_portal/.gitignore
vendored
Normal file
2
partner_bank_account_portal/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.*~
|
||||
*pyc
|
49
partner_bank_account_portal/README.rst
Normal file
49
partner_bank_account_portal/README.rst
Normal file
@@ -0,0 +1,49 @@
|
||||
===============
|
||||
partner_bank_account_portal
|
||||
===============
|
||||
|
||||
Provide portal pages and forms to manage partner's contract, bank accounts and mandates from portal home space.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Use Odoo normal module installation procedure to install
|
||||
``partner_bank_account_portal``.
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Provide portal pages and forms to manage partner's bank accounts and mandates from portal home space.
|
||||
Also add the mandate in contract portal view
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
None yet.
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `our issues website <https://github.com/elabore-coop/partner-tools/issues>`_. In case of
|
||||
trouble, please check there if your issue has already been
|
||||
reported. If you spotted it first, help us smashing it by providing a
|
||||
detailed and welcomed feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Laetitia Da Costa
|
||||
|
||||
Funders
|
||||
-------
|
||||
|
||||
The development of this module has been financially supported by:
|
||||
* Elabore (https://elabore.coop)
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
This module is maintained by Elabore.
|
3
partner_bank_account_portal/__init__.py
Normal file
3
partner_bank_account_portal/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
48
partner_bank_account_portal/__manifest__.py
Normal file
48
partner_bank_account_portal/__manifest__.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright 2022 Stéphan Sainléger (Elabore)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "Mandates and bank accounts portal",
|
||||
"version": "16.0.1.0.0",
|
||||
"author": "Elabore",
|
||||
"website": "https://elabore.coop",
|
||||
"maintainer": "Laetitia Da Costa",
|
||||
"license": "AGPL-3",
|
||||
"category": "Tools",
|
||||
"summary": "Provide portal pages and forms to manage partner's bank accounts and mandates from portal home space.",
|
||||
# any module necessary for this one to work correctly
|
||||
"depends": [
|
||||
"base",
|
||||
"account",
|
||||
"portal",
|
||||
"website",
|
||||
"account_banking_mandate",
|
||||
"contract",
|
||||
"account_payment_order",
|
||||
"contract_mandate",
|
||||
],
|
||||
"qweb": [],
|
||||
"external_dependencies": {
|
||||
"python": [],
|
||||
},
|
||||
# always loaded
|
||||
"data": [
|
||||
"security/members_security.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"views/portal_my_home_template.xml",
|
||||
"views/portal_my_bank_accounts_template.xml",
|
||||
"views/portal_my_bank_account_template.xml",
|
||||
"views/portal_my_mandates_template.xml",
|
||||
"views/portal_my_mandate_template.xml",
|
||||
"views/portal_my_contract_template_inherit.xml",
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"demo": [],
|
||||
"js": [],
|
||||
"css": [],
|
||||
"installable": True,
|
||||
# Install this module automatically if all dependency have been previously
|
||||
# and independently installed. Used for synergetic or glue modules.
|
||||
"auto_install": False,
|
||||
"application": False,
|
||||
}
|
4
partner_bank_account_portal/controllers/__init__.py
Normal file
4
partner_bank_account_portal/controllers/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from . import portal_my_bank_accounts
|
||||
from . import portal_my_bank_account
|
||||
from . import portal_my_mandates
|
||||
from . import portal_my_mandate
|
@@ -0,0 +1,159 @@
|
||||
# Copyright 2020 Lokavaluto ()
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import base64
|
||||
from odoo import http, tools, _
|
||||
from odoo.exceptions import AccessError, MissingError
|
||||
from odoo.http import request
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal
|
||||
|
||||
|
||||
class CustomerPortalBankAccount(CustomerPortal):
|
||||
|
||||
def _bank_account_get_page_view_values(self, bank_account, access_token, **kwargs):
|
||||
values = {
|
||||
"page_name": "bank_account",
|
||||
"bank_account": bank_account,
|
||||
}
|
||||
return self._get_page_view_values(
|
||||
bank_account, access_token, values, "my_bank_accounts_history", False, **kwargs
|
||||
)
|
||||
|
||||
def _details_bank_account_form_validate(self, data, bank_account_id):
|
||||
error = dict()
|
||||
error_message = []
|
||||
# public name uniqueness
|
||||
if data.get("public_name") and request.env["res.partner"].sudo().search(
|
||||
[
|
||||
("name", "=", data.get("public_name")),
|
||||
("is_public_profile", "=", True),
|
||||
("contact_id", "!=", bank_account_id),
|
||||
]
|
||||
):
|
||||
error["public_name"] = "error"
|
||||
error_message.append(
|
||||
_("This public name is already used, please find an other idea.")
|
||||
)
|
||||
|
||||
# email validation
|
||||
if data.get("email") and not tools.single_email_re.match(data.get("email")):
|
||||
error["email"] = "error"
|
||||
error_message.append(
|
||||
_("Invalid Email! Please enter a valid email address.")
|
||||
)
|
||||
return error, error_message
|
||||
|
||||
def _get_bank_account_fields(self):
|
||||
fields = [
|
||||
"acc_number",
|
||||
"acc_holder_name",
|
||||
]
|
||||
return fields
|
||||
|
||||
def _get_id_fields(self):
|
||||
fields = [
|
||||
"bank_id",
|
||||
]
|
||||
return fields
|
||||
|
||||
def _get_main_boolean_bank_account_fields(self):
|
||||
'''Provides the fields for which we must check the presence
|
||||
in form's kw to know the value to save in the partner field.
|
||||
All of them MUST start with "main_".'''
|
||||
fields = []
|
||||
return fields
|
||||
|
||||
def _transform_res_partner_fields(self, kw, bank_account_fields, prefix=""):
|
||||
'''Transforms kw's values in res_partner fields and values'''
|
||||
return {key[len(prefix):]: kw[key] for key in bank_account_fields if key in kw}
|
||||
|
||||
def _cast_id_fields(self, kw, id_fields):
|
||||
'''Cast ids fields in kw's values into a integer'''
|
||||
result = {}
|
||||
for key in id_fields:
|
||||
if key in kw:
|
||||
if kw[key] == '':
|
||||
result[key] = None
|
||||
elif not isinstance(kw[key], int):
|
||||
result[key] = int(kw[key])
|
||||
else:
|
||||
result[key] = kw[key]
|
||||
return result
|
||||
|
||||
def _add_boolean_values(self, values, kw, boolean_fields, prefix=""):
|
||||
for key in boolean_fields:
|
||||
values.update(
|
||||
{
|
||||
key[len(prefix):]: kw.get(key, "off") == "on",
|
||||
}
|
||||
)
|
||||
return values
|
||||
|
||||
def _get_page_saving_bank_account_values(self, kw):
|
||||
bank_account_fields = self._get_bank_account_fields()
|
||||
values = self._transform_res_partner_fields(kw, bank_account_fields)
|
||||
if kw["bank_id"] == '':
|
||||
bank_id = None
|
||||
else:
|
||||
bank_id = int(kw["bank_id"])
|
||||
values.update({"bank_id":bank_id})
|
||||
return values
|
||||
|
||||
@http.route(
|
||||
["/my/bank_account/<int:bank_account_id>", "/my/bank_account/save"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
def portal_my_bank_account(
|
||||
self,bank_account_id=None, access_token=None, redirect=None, **kw
|
||||
):
|
||||
# The following condition is to transform profile_id to an int, as it is sent as a string from the templace "portal_my_profile"
|
||||
# TODO: find a better way to retrieve the profile_id at form submit step
|
||||
if not isinstance(bank_account_id, int):
|
||||
bank_account_id = int(bank_account_id)
|
||||
|
||||
# Check that the user has the right to see this profile
|
||||
try:
|
||||
bank_account_sudo = self._document_check_access(
|
||||
"res.partner.bank", bank_account_id, access_token
|
||||
)
|
||||
except (AccessError, MissingError):
|
||||
return request.redirect("/my/bank_accounts")
|
||||
|
||||
PartnerBankAccount = request.env["res.partner.bank"]
|
||||
user = request.env.user
|
||||
bank_account = PartnerBankAccount.browse(bank_account_id)
|
||||
|
||||
values = self._bank_account_get_page_view_values(bank_account_sudo, access_token, **kw)
|
||||
values.update(
|
||||
{
|
||||
"error": {},
|
||||
"error_message": [],
|
||||
}
|
||||
)
|
||||
if kw and request.httprequest.method == "POST":
|
||||
# the user has clicked in the Save button to save new data
|
||||
error, error_message = self._details_bank_account_form_validate(kw, bank_account_id)
|
||||
values.update({"error": error, "error_message": error_message})
|
||||
values.update(kw)
|
||||
if not error:
|
||||
# Update main profile
|
||||
new_values = self._get_page_saving_bank_account_values(kw)
|
||||
bank_account.sudo().write(new_values)
|
||||
if redirect:
|
||||
return request.redirect(redirect)
|
||||
return request.redirect("/my/bank_accounts")
|
||||
|
||||
# This is just the form page opening. We send all the data needed for the form fields
|
||||
can_edit_bank_account = user.partner_id == bank_account.partner_id
|
||||
banks = request.env["res.bank"].sudo().search([])
|
||||
|
||||
values.update(
|
||||
{
|
||||
"bank_account_id": bank_account_id, # Sent in order to retrieve it at submit time
|
||||
"can_edit_bank_account": can_edit_bank_account,
|
||||
"banks": banks,
|
||||
"redirect": "/my/bank_account/" + str(bank_account_id) + "?success=True"
|
||||
}
|
||||
)
|
||||
return request.render("partner_bank_account_portal.portal_my_bank_account", values) #TODO créer le template portal_my_bank_account.xml
|
@@ -0,0 +1,92 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import http, _
|
||||
from odoo.osv import expression
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
|
||||
from odoo.exceptions import AccessError, MissingError
|
||||
from collections import OrderedDict
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class CustomerPortalBankAccounts(CustomerPortal):
|
||||
|
||||
def _prepare_home_portal_values(self, counters):
|
||||
values = super()._prepare_home_portal_values(counters)
|
||||
if 'bank_account_count' in counters:
|
||||
bank_account_count = request.env['res.partner.bank'].search_count([])
|
||||
values['bank_account_count'] = bank_account_count
|
||||
return values
|
||||
|
||||
def _get_account_searchbar_sortings(self):
|
||||
res = super()._get_account_searchbar_sortings()
|
||||
res['acc_number'] = {'label': _('IBAN'), 'order': 'acc_number'}
|
||||
return res
|
||||
|
||||
|
||||
|
||||
@http.route(['/my/bank_accounts', '/my/bank_accounts/page/<int:page>'], type='http', auth="user", website=True)
|
||||
def portal_my_bank_accounts(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw):
|
||||
values = self._prepare_my_bank_accounts_values(page, date_begin, date_end, sortby, filterby)
|
||||
|
||||
# pager
|
||||
pager = portal_pager(**values['pager'])
|
||||
|
||||
# content according to pager and archive selected
|
||||
bank_accounts = values['bank_accounts'](pager['offset'])
|
||||
request.session['bank_accounts_history'] = bank_accounts.ids[:100]
|
||||
|
||||
values.update({
|
||||
'bank_accounts': bank_accounts,
|
||||
'pager': pager,
|
||||
})
|
||||
return request.render("partner_bank_account_portal.portal_my_bank_accounts", values)
|
||||
|
||||
def _get_bank_accounts_domain(self):
|
||||
return [('active', '=', True)]
|
||||
|
||||
|
||||
def _prepare_my_bank_accounts_values(self, page, date_begin, date_end, sortby, filterby, domain=None, url="/my/bank_accounts"):
|
||||
values = self._prepare_portal_layout_values()
|
||||
res_partner_bank = request.env['res.partner.bank']
|
||||
|
||||
domain = expression.AND([
|
||||
domain or [],
|
||||
self._get_bank_accounts_domain(),
|
||||
])
|
||||
|
||||
searchbar_sortings = self._get_account_searchbar_sortings()
|
||||
# default sort by order
|
||||
if not sortby:
|
||||
sortby = 'acc_number'
|
||||
order = searchbar_sortings[sortby]['order']
|
||||
|
||||
# default filter by value
|
||||
if not filterby:
|
||||
filterby = 'all'
|
||||
|
||||
if date_begin and date_end:
|
||||
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
|
||||
|
||||
values.update({
|
||||
'date': date_begin,
|
||||
# content according to pager and archive selected
|
||||
# lambda function to get the invoices recordset when the pager will be defined in the main method of a route
|
||||
'bank_accounts': lambda pager_offset: (
|
||||
res_partner_bank.search(domain, order=order, limit=self._items_per_page, offset=pager_offset)
|
||||
if res_partner_bank.check_access_rights('read', raise_exception=False) else
|
||||
res_partner_bank
|
||||
),
|
||||
'page_name': 'bank_accounts',
|
||||
'pager': { # vals to define the pager.
|
||||
"url": url,
|
||||
"url_args": {'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
|
||||
"total": res_partner_bank.search_count(domain) if res_partner_bank.check_access_rights('read', raise_exception=False) else 0,
|
||||
"page": page,
|
||||
"step": self._items_per_page,
|
||||
},
|
||||
'default_url': url,
|
||||
'sortby': sortby,
|
||||
'filterby': filterby,
|
||||
})
|
||||
return values
|
152
partner_bank_account_portal/controllers/portal_my_mandate.py
Normal file
152
partner_bank_account_portal/controllers/portal_my_mandate.py
Normal file
@@ -0,0 +1,152 @@
|
||||
# Copyright 2020 Lokavaluto ()
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import base64
|
||||
from odoo import http, tools, _
|
||||
from odoo.exceptions import AccessError, MissingError
|
||||
from odoo.http import request
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal
|
||||
|
||||
|
||||
class CustomerPortalMandate(CustomerPortal):
|
||||
|
||||
def _mandate_get_page_view_values(self, mandate, access_token, **kwargs):
|
||||
values = {
|
||||
"page_name": "mandate",
|
||||
"mandate": mandate,
|
||||
}
|
||||
return self._get_page_view_values(
|
||||
mandate, access_token, values, "my_mandates_history", False, **kwargs
|
||||
)
|
||||
|
||||
def _details_mandate_form_validate(self, data, mandate_id):
|
||||
error = dict()
|
||||
error_message = []
|
||||
# public name uniqueness
|
||||
if data.get("public_name") and request.env["res.partner"].sudo().search(
|
||||
[
|
||||
("name", "=", data.get("public_name")),
|
||||
("is_public_profile", "=", True),
|
||||
("contact_id", "!=", mandate_id),
|
||||
]
|
||||
):
|
||||
error["public_name"] = "error"
|
||||
error_message.append(
|
||||
_("This public name is already used, please find an other idea.")
|
||||
)
|
||||
|
||||
# email validation
|
||||
if data.get("email") and not tools.single_email_re.match(data.get("email")):
|
||||
error["email"] = "error"
|
||||
error_message.append(
|
||||
_("Invalid Email! Please enter a valid email address.")
|
||||
)
|
||||
return error, error_message
|
||||
|
||||
def _get_mandate_fields(self):
|
||||
fields = [
|
||||
"unique_mandate_reference",
|
||||
"signature_date",
|
||||
"last_debit_date",
|
||||
"state",
|
||||
]
|
||||
return fields
|
||||
|
||||
def _get_main_boolean_mandate_fields(self):
|
||||
'''Provides the fields for which we must check the presence
|
||||
in form's kw to know the value to save in the partner field.
|
||||
All of them MUST start with "main_".'''
|
||||
fields = []
|
||||
return fields
|
||||
|
||||
def _transform_in_res_partner_fields(self, kw, mandate_fields, prefix=""):
|
||||
'''Transforms kw's values in res_partner fields and values'''
|
||||
return {key[len(prefix):]: kw[key] for key in mandate_fields if key in kw}
|
||||
|
||||
def _add_boolean_values(self, values, kw, boolean_fields, prefix=""):
|
||||
for key in boolean_fields:
|
||||
values.update(
|
||||
{
|
||||
key[len(prefix):]: kw.get(key, "off") == "on",
|
||||
}
|
||||
)
|
||||
return values
|
||||
|
||||
def _get_page_saving_mandate_values(self, kw):
|
||||
mandate_fields = self._get_mandate_fields()
|
||||
values = self._transform_in_res_partner_fields(kw, mandate_fields)
|
||||
# boolean_fields = self._get_main_boolean_bank_account_fields()
|
||||
# values = self._add_boolean_values(values, kw, boolean_fields)
|
||||
return values
|
||||
|
||||
def _get_page_opening_values(self):
|
||||
# Just retrieve the values to display for Selection fields
|
||||
countries = request.env["res.country"].sudo().search([])
|
||||
values = {
|
||||
"countries": countries,
|
||||
}
|
||||
return values
|
||||
|
||||
@http.route(
|
||||
["/my/mandate/<int:mandate_id>", "/my/mandate/save"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
)
|
||||
def portal_my_mandate(
|
||||
self,mandate_id=None, access_token=None, redirect=None, **kw
|
||||
):
|
||||
# The following condition is to transform profile_id to an int, as it is sent as a string from the templace "portal_my_profile"
|
||||
# TODO: find a better way to retrieve the profile_id at form submit step
|
||||
if not isinstance(mandate_id, int):
|
||||
mandate_id = int(mandate_id)
|
||||
|
||||
# Check that the user has the right to see this profile
|
||||
try:
|
||||
mandate_sudo = self._document_check_access(
|
||||
"account.banking.mandate", mandate_id, access_token
|
||||
)
|
||||
except (AccessError, MissingError):
|
||||
return request.redirect("/my/mandates")
|
||||
|
||||
Mandate = request.env["account.banking.mandate"]
|
||||
user = request.env.user
|
||||
mandate = Mandate.browse(mandate_id)
|
||||
|
||||
values = self._mandate_get_page_view_values(mandate_sudo, access_token, **kw)
|
||||
values.update(
|
||||
{
|
||||
"error": {},
|
||||
"error_message": [],
|
||||
}
|
||||
)
|
||||
if kw and request.httprequest.method == "POST":
|
||||
# the user has clicked in the Save button to save new data
|
||||
error, error_message = self._details_mandate_form_validate(kw, mandate_id)
|
||||
values.update({"error": error, "error_message": error_message})
|
||||
values.update(kw)
|
||||
if not error:
|
||||
# Update main profile
|
||||
new_values = self._get_page_saving_mandate_values(kw)
|
||||
mandate.sudo().write(new_values)
|
||||
# Update public profile
|
||||
# new_values = self._get_page_saving_public_structure_values(kw)
|
||||
# public_profile.sudo().write(new_values)
|
||||
# Update position profile
|
||||
# new_values = self._get_page_saving_position_structure_values(kw)
|
||||
# position_profile.sudo().write(new_values)
|
||||
# End of updates
|
||||
if redirect:
|
||||
return request.redirect(redirect)
|
||||
return request.redirect("/my/mandates")
|
||||
|
||||
# This is just the form page opening. We send all the data needed for the form fields
|
||||
can_edit_mandate = user.partner_id == mandate.partner_id
|
||||
values.update(self._get_page_opening_values())
|
||||
values.update(
|
||||
{
|
||||
"mandate_id": mandate_id, # Sent in order to retrieve it at submit time
|
||||
"can_edit_mandate": can_edit_mandate,
|
||||
"redirect": "/my/mandate/" + str(mandate_id) + "?success=True"
|
||||
}
|
||||
)
|
||||
return request.render("partner_bank_account_portal.portal_my_mandate", values) #TODO créer le template portal_my_bank_account.xml
|
@@ -0,0 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import http, _
|
||||
from odoo.osv import expression
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
|
||||
from odoo.exceptions import AccessError, MissingError
|
||||
from collections import OrderedDict
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class CustomerPortalMandates(CustomerPortal):
|
||||
|
||||
def _prepare_home_portal_values(self, counters):
|
||||
values = super()._prepare_home_portal_values(counters)
|
||||
if 'mandate_count' in counters:
|
||||
mandate_count = request.env['account.banking.mandate'].search_count([])
|
||||
values['mandate_count'] = mandate_count
|
||||
return values
|
||||
|
||||
@http.route(['/my/mandates', '/my/mandates/page/<int:page>'], type='http', auth="user", website=True)
|
||||
def portal_mandates(self, page=1, date_begin=None, date_end=None, filterby=None, **kw):
|
||||
values = self._prepare_my_mandates_values(page, date_begin, date_end)
|
||||
|
||||
# pager
|
||||
pager = portal_pager(**values['pager'])
|
||||
|
||||
# content according to pager and archive selected
|
||||
mandates = values['mandates'](pager['offset'])
|
||||
request.session['mandates_history'] = mandates.ids[:100]
|
||||
|
||||
values.update({
|
||||
'mandates': mandates,
|
||||
'pager': pager,
|
||||
})
|
||||
return request.render("partner_bank_account_portal.portal_my_mandates", values)
|
||||
|
||||
def _get_mandate_domain(self):
|
||||
return []
|
||||
|
||||
def _prepare_my_mandates_values(self, page, date_begin, date_end, domain=None, url="/my/mandates"):
|
||||
values = self._prepare_portal_layout_values()
|
||||
Mandate = request.env['account.banking.mandate']
|
||||
|
||||
domain = expression.AND([
|
||||
domain or [],
|
||||
self._get_mandate_domain(),
|
||||
])
|
||||
|
||||
if date_begin and date_end:
|
||||
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
|
||||
|
||||
values.update({
|
||||
'date': date_begin,
|
||||
# content according to pager and archive selected
|
||||
# lambda function to get the invoices recordset when the pager will be defined in the main method of a route
|
||||
'mandates': lambda pager_offset: (
|
||||
Mandate.search(domain, limit=self._items_per_page, offset=pager_offset)
|
||||
if Mandate.check_access_rights('read', raise_exception=False) else
|
||||
Mandate
|
||||
),
|
||||
'page_name': 'mandates',
|
||||
'pager': { # vals to define the pager.
|
||||
"url": url,
|
||||
"url_args": {'date_begin': date_begin, 'date_end': date_end},
|
||||
"total": Mandate.search_count(domain) if Mandate.check_access_rights('read', raise_exception=False) else 0,
|
||||
"page": page,
|
||||
"step": self._items_per_page,
|
||||
},
|
||||
'default_url': url,
|
||||
})
|
||||
return values
|
192
partner_bank_account_portal/i18n/fr.po
Normal file
192
partner_bank_account_portal/i18n/fr.po
Normal file
@@ -0,0 +1,192 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * partner_bank_account_portal
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-08-05 13:58+0000\n"
|
||||
"PO-Revision-Date: 2024-08-05 13:58+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
msgid "1 registration"
|
||||
msgstr "1 enregistrement"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandate
|
||||
msgid "<i class=\"fa fa-fw fa-check-circle\"/> Data saved!"
|
||||
msgstr "Données enregistrées!"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
msgid "<span class=\"fa fa-arrow-left\"/> Back to my bank accounts list"
|
||||
msgstr "<span class=\"fa fa-arrow-left\"/> Retour à la liste des comptes bancaires"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandate
|
||||
msgid "<span class=\"fa fa-arrow-left\"/> Back to my mandates list"
|
||||
msgstr "<span class=\"fa fa-arrow-left\"/> Retour à la liste des mandats"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Associed IBAN"
|
||||
msgstr "IBAN associé"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model:ir.model.fields,field_description:partner_bank_account_portal.field_account_setup_bank_manual_config__associated_mandate_count
|
||||
#: model:ir.model.fields,field_description:partner_bank_account_portal.field_res_partner_bank__associated_mandate_count
|
||||
msgid "Associated mandate count"
|
||||
msgstr "Décompte de mandats associés au compte bancaire"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model:ir.model,name:partner_bank_account_portal.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr "Comptes bancaires"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_home_bank_accounts
|
||||
msgid "Bank accounts"
|
||||
msgstr "Comptes bancaires"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Contact name"
|
||||
msgstr "Nom du contact"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
msgid "Contact name:"
|
||||
msgstr "Nom du contact : "
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Format"
|
||||
msgstr ""
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandate
|
||||
msgid "Format :"
|
||||
msgstr ""
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#. odoo-python
|
||||
#: code:addons/partner_bank_account_portal/controllers/portal_my_bank_accounts.py:0
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
#, python-format
|
||||
msgid "IBAN"
|
||||
msgstr ""
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
msgid "IBAN :"
|
||||
msgstr ""
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#. odoo-python
|
||||
#: code:addons/partner_bank_account_portal/controllers/portal_my_bank_account.py:0
|
||||
#: code:addons/partner_bank_account_portal/controllers/portal_my_mandate.py:0
|
||||
#, python-format
|
||||
msgid "Invalid Email! Please enter a valid email address."
|
||||
msgstr "Email invalide ! Entrez une adresse email valide."
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Last debit date"
|
||||
msgstr "Date du dernier débit"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_home_bank_accounts
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_home_menu_contract
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Mandates"
|
||||
msgstr "Mandats"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
msgid "My bank account Details"
|
||||
msgstr "Détails du compte bancaire"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandate
|
||||
msgid "My mandate details"
|
||||
msgstr "Details du mandat"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
msgid "Name of IBAN holder if different"
|
||||
msgstr "Nom du titulaire de l'IBAN si différent :"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
msgid "Name of IBAN holder if different :"
|
||||
msgstr "Nom du titulaire de l'IBAN si différent :"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
msgid "No registrations"
|
||||
msgstr "Pas d'enregistrement"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
msgid "Number of associated mandates"
|
||||
msgstr "Nombre de mandats associés"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Reference"
|
||||
msgstr "Référence"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandate
|
||||
msgid "Reference :"
|
||||
msgstr "Référence :"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_account
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandate
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Signature date"
|
||||
msgstr "Date de signature"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "Status"
|
||||
msgstr "Statut"
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
msgid "There are currently no bank accounts for your account."
|
||||
msgstr "Aucun compte bancaire n'est accessible depuis votre compte."
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_mandates
|
||||
msgid "There are currently no mandates for your account."
|
||||
msgstr "Aucun mandat n'est accessible depuis votre compte."
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#. odoo-python
|
||||
#: code:addons/partner_bank_account_portal/controllers/portal_my_bank_account.py:0
|
||||
#: code:addons/partner_bank_account_portal/controllers/portal_my_mandate.py:0
|
||||
#, python-format
|
||||
msgid "This public name is already used, please find an other idea."
|
||||
msgstr "Ce nom est déjà utilisé, veuillez trouver un autre nom."
|
||||
|
||||
#. module: partner_bank_account_portal
|
||||
#: model_terms:ir.ui.view,arch_db:partner_bank_account_portal.portal_my_bank_accounts
|
||||
msgid "records"
|
||||
msgstr "enregistrements"
|
2
partner_bank_account_portal/models/__init__.py
Normal file
2
partner_bank_account_portal/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import res_partner_bank
|
17
partner_bank_account_portal/models/res_partner_bank.py
Normal file
17
partner_bank_account_portal/models/res_partner_bank.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2022 Elabore (https://elabore.coop)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
class res_partner_bank(models.Model):
|
||||
_inherit = "res.partner.bank"
|
||||
|
||||
#count all mandate linked to the IBAN, even draft or canceled mandates
|
||||
associated_mandate_count = fields.Integer("Associated mandate count", compute="_compute_associated_mandate_count")
|
||||
|
||||
def _compute_associated_mandate_count(self):
|
||||
for record in self:
|
||||
count = self.env["account.banking.mandate"].search_count(
|
||||
[("partner_bank_id", "=", record.id)]
|
||||
)
|
||||
record.associated_mandate_count = count
|
4
partner_bank_account_portal/security/ir.model.access.csv
Normal file
4
partner_bank_account_portal/security/ir.model.access.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
"access_res_partner_bank_group_portal","res_partner_bank group_portal","base.model_res_partner_bank","base.group_portal",1,0,0,0
|
||||
"access_res_bank_group_portal","res_bank group_portal","base.model_res_bank","base.group_portal",1,0,0,0
|
||||
"access_account_banking_mandate_group_portal","account_banking_mandate group_portal","account_banking_mandate.model_account_banking_mandate","base.group_portal",1,0,0,0
|
|
34
partner_bank_account_portal/security/members_security.xml
Normal file
34
partner_bank_account_portal/security/members_security.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record model="ir.rule" id="res_partner_portal_members_bank_accounts_read_rule">
|
||||
<field name="name">res_partner: portal: read access on my bank accounts</field>
|
||||
<field name="model_id" ref="base.model_res_partner_bank" />
|
||||
<field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]" />
|
||||
<field name="perm_read" eval="True" />
|
||||
<field name="perm_write" eval="False" />
|
||||
<field name="perm_create" eval="False" />
|
||||
<field name="perm_unlink" eval="False" />
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="res_partner_portal_bank_read_rule">
|
||||
<field name="name">res_partner: portal: read access on my banks</field>
|
||||
<field name="model_id" ref="base.model_res_bank" />
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]" />
|
||||
<field name="perm_read" eval="True" />
|
||||
<field name="perm_write" eval="False" />
|
||||
<field name="perm_create" eval="False" />
|
||||
<field name="perm_unlink" eval="False" />
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="res_partner_portal_mandate_read_rule">
|
||||
<field name="name">res_partner: portal: read access on my mandates</field>
|
||||
<field name="model_id" ref="account_banking_mandate.model_account_banking_mandate" />
|
||||
<field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal'))]" />
|
||||
<field name="perm_read" eval="True" />
|
||||
<field name="perm_write" eval="False" />
|
||||
<field name="perm_create" eval="False" />
|
||||
<field name="perm_unlink" eval="False" />
|
||||
</record>
|
||||
</odoo>
|
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_bank_account" name="Bank account details">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="additional_title">My bank account Details</t>
|
||||
<form action="/my/bank_account/save" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<div class="row o_portal_details">
|
||||
<div class="col-lg-12">
|
||||
<br />
|
||||
<div t-if="success" class="alert alert-success py-1 mb-2">
|
||||
<i class="fa fa-fw fa-check-circle" /> Data saved! </div>
|
||||
<div t-if="error_message" role="alert" class="col-lg-12 alert alert-danger">
|
||||
<t t-foreach="error_message" t-as="err">
|
||||
<t t-out="err" />
|
||||
<br />
|
||||
</t>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="iban"
|
||||
t-attf-class="form-group #{error.get('acc_number') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="acc_number">IBAN : </label>
|
||||
<label class="text-danger"> *</label>
|
||||
<input t-if="can_edit_bank_account" type="text" name="acc_number"
|
||||
required="True"
|
||||
t-attf-class="form-control #{error.get('acc_number') and 'is-invalid' or ''}"
|
||||
t-att-value="acc_number or bank_account.acc_number" />
|
||||
<span t-if="not can_edit_bank_account" t-field="bank_account.acc_number" />
|
||||
</div>
|
||||
<div id="partner_id"
|
||||
t-attf-class="form-group #{error.get('partner_id') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="partner_id">Contact name: </label>
|
||||
<input t-if="can_edit_bank_account" type="text" name="partner_id"
|
||||
required="False"
|
||||
readonly="True"
|
||||
t-attf-class="form-control #{error.get('partner_id') and 'is-invalid' or ''}"
|
||||
t-att-value="partner_id or bank_account.partner_id.name" />
|
||||
<span t-if="not can_edit_bank_account" t-field="bank_account.partner_id.name" />
|
||||
</div>
|
||||
<div id="iban_holder_name_if_different"
|
||||
t-attf-class="form-group #{error.get('acc_holder_name') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="bank_id">Name of IBAN holder if different : </label>
|
||||
<input t-if="can_edit_bank_account" type="text" name="acc_holder_name"
|
||||
t-attf-class="form-control #{error.get('acc_holder_name') and 'is-invalid' or ''}"
|
||||
t-att-value="acc_holder_name or bank_account.acc_holder_name" />
|
||||
<span t-if="not can_edit_bank_account" t-field="bank_account.acc_holder_name" />
|
||||
</div>
|
||||
<div id="bank_id"
|
||||
t-attf-class="form-group #{error.get('bank_id') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="bank_id">Banque name : </label>
|
||||
<select t-if="can_edit_bank_account" type="text" name="bank_id"
|
||||
t-attf-class="form-control #{error.get('bank_id') and 'is-invalid' or ''}">
|
||||
<option value="">My bank is not in the list</option>
|
||||
<t t-foreach="banks or []" t-as="bank">
|
||||
<option t-att-value="bank.id" t-att-selected="bank.id == bank_account.bank_id.id">
|
||||
<t t-esc="bank.name" />
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
<span t-if="not can_edit_bank_account" t-field="bank_account.acc_holder_name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<input type="hidden" name="bank_account_id" t-att-value="bank_account_id" />
|
||||
<input type="hidden" name="redirect" t-att-value="redirect" />
|
||||
<div style="text-align:right;">
|
||||
<button type="submit"
|
||||
class="btn btn-primary ">Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div style="text-align:right">
|
||||
<br />
|
||||
<a href="/my/bank_accounts">
|
||||
<span class="fa fa-arrow-left" /> Back to my bank accounts list </a>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_bank_accounts" name="My bank accounts">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True" />
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Bank accounts</t>
|
||||
</t>
|
||||
<t t-if="not bank_accounts">
|
||||
<p>There are currently no bank accounts for your account.</p>
|
||||
</t>
|
||||
<t t-if="bank_accounts" t-call="portal.portal_table">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<th>IBAN</th>
|
||||
<th>Contact name</th>
|
||||
<th>Name of IBAN holder if different</th>
|
||||
<th>Number of associated mandates</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="bank_accounts" t-as="bank_account">
|
||||
<tr>
|
||||
<td>
|
||||
<a
|
||||
t-attf-href="/my/bank_account/#{bank_account.id}?{{ keep_query() }}">
|
||||
<span t-field="bank_account.acc_number" />
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="bank_account.partner_id.name" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="bank_account.acc_holder_name" />
|
||||
</td>
|
||||
<td>
|
||||
<t t-if="bank_account.associated_mandate_count == 0">
|
||||
No registrations
|
||||
</t>
|
||||
<t t-if="bank_account.associated_mandate_count == 1">
|
||||
1 registration
|
||||
</t>
|
||||
<t t-if="bank_account.associated_mandate_count > 1">
|
||||
<t t-esc="bank_account.associated_mandate_count" />
|
||||
records </t>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_contract_page_inherit_mandate" name="My Contract inherit mandate"
|
||||
inherit_id="contract.portal_contract_page" customize_show="True" priority="100">
|
||||
<xpath expr="//div[@id='product_information']/div" position="inside">
|
||||
<div t-if="contract.mandate_id" class="row mb-2 mb-sm-1">
|
||||
<div class="col-12 col-sm-4">
|
||||
<strong>Direct Debit Mandate</strong>
|
||||
</div>
|
||||
<div class="col-12 col-sm-8">
|
||||
<span
|
||||
t-field="contract.mandate_id"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template
|
||||
id="portal_my_home_menu_contract"
|
||||
name="Portal layout : Mandate menu entries"
|
||||
inherit_id="portal.portal_breadcrumbs"
|
||||
priority="35"
|
||||
>
|
||||
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
|
||||
<li
|
||||
t-if="page_name == 'Mandates'"
|
||||
t-attf-class="breadcrumb-item #{'active ' if not contract else ''}"
|
||||
>
|
||||
<a
|
||||
t-if="mandate"
|
||||
t-attf-href="/my/mandates?{{ keep_query() }}"
|
||||
>Mandates</a>
|
||||
<t t-else="">Mandates</t>
|
||||
</li>
|
||||
<li t-if="mandate" class="breadcrumb-item active">
|
||||
<t t-esc="mandate.reference" />
|
||||
</li>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="portal_my_home_bank_accounts" name="Bank accounts"
|
||||
inherit_id="portal.portal_my_home" customize_show="True" priority="100">
|
||||
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
|
||||
<t t-call="portal.portal_docs_entry">
|
||||
<t t-set="title">Bank accounts</t>
|
||||
<t t-set="url" t-value="'/my/bank_accounts'" />
|
||||
<t t-set="placeholder_count" t-value="'bank_account_count'" />
|
||||
</t>
|
||||
<t t-call="portal.portal_docs_entry">
|
||||
<t t-set="title">Mandates</t>
|
||||
<t t-set="url" t-value="'/my/mandates'" />
|
||||
<t t-set="placeholder_count" t-value="'mandate_count'"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</odoo>
|
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_mandate" name="Mandate details">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="additional_title">My mandate details</t>
|
||||
<form action="/my/mandate/save" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<div class="row o_portal_details">
|
||||
<div class="col-lg-12">
|
||||
<br />
|
||||
<div t-if="success" class="alert alert-success py-1 mb-2">
|
||||
<i class="fa fa-fw fa-check-circle" /> Data saved! </div>
|
||||
<div t-if="error_message" role="alert" class="col-lg-12 alert alert-danger">
|
||||
<t t-foreach="error_message" t-as="err">
|
||||
<t t-out="err" />
|
||||
<br />
|
||||
</t>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="reference"
|
||||
t-attf-class="form-group #{error.get('unique_mandate_reference') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="unique_mandate_reference">Reference : </label>
|
||||
<label class="text-danger"> *</label>
|
||||
<input t-if="can_edit_mandate" type="text" name="unique_mandate_reference"
|
||||
required="True"
|
||||
t-attf-class="form-control #{error.get('unique_mandate_reference') and 'is-invalid' or ''}"
|
||||
t-att-value="unique_mandate_reference or mandate.unique_mandate_reference" />
|
||||
<span t-if="not can_edit_mandate" t-field="mandate.unique_mandate_reference" />
|
||||
</div>
|
||||
<div id="format"
|
||||
t-attf-class="form-group #{error.get('format') and 'o_has_error' or ''} col-xl-12">
|
||||
<label class="col-form-label" for="format">Format : </label>
|
||||
<label class="text-danger"> *</label>
|
||||
<input t-if="can_edit_mandate" type="text" name="format"
|
||||
required="True"
|
||||
t-attf-class="form-control #{error.get('format') and 'is-invalid' or ''}"
|
||||
t-att-value="format or mandate.format" />
|
||||
<span t-if="not can_edit_mandate" t-field="mandate.format" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<input type="hidden" name="mandate_id" t-att-value="mandate_id" />
|
||||
<input type="hidden" name="redirect" t-att-value="redirect" />
|
||||
<div style="text-align:right;">
|
||||
<button type="submit"
|
||||
class="btn btn-primary ">Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div style="text-align:right">
|
||||
<br />
|
||||
<a href="/my/mandates">
|
||||
<span class="fa fa-arrow-left" /> Back to my mandates list </a>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_mandates" name="My mandates">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True" />
|
||||
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Mandates</t>
|
||||
</t>
|
||||
<t t-if="not mandates">
|
||||
<p>There are currently no mandates for your account.</p>
|
||||
</t>
|
||||
<t t-if="mandates" t-call="portal.portal_table">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<th>Reference</th>
|
||||
<th>Format</th>
|
||||
<th>Contact name</th>
|
||||
<th>Signature date</th>
|
||||
<th>Last debit date</th>
|
||||
<th>Status</th>
|
||||
<th>Associed IBAN</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="mandates" t-as="mandate">
|
||||
<tr>
|
||||
<td>
|
||||
<span t-field="mandate.unique_mandate_reference" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="mandate.format" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="mandate.partner_id" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="mandate.last_debit_date" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="mandate.signature_date" />
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="mandate.state" />
|
||||
</td>
|
||||
<td>
|
||||
<a t-attf-href="/my/bank_account/#{mandate.partner_bank_id.id}?{{ keep_query() }}">
|
||||
<span t-field="mandate.partner_bank_id.acc_number" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
Reference in New Issue
Block a user