[ADD]mandates_bank_accounts_portal

This commit is contained in:
2024-09-16 17:16:39 +02:00
committed by Stéphan Sainléger
parent 31b9c39f8c
commit 37142bfa98
20 changed files with 1142 additions and 0 deletions

View 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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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