bemade-addons/st_laurent_portal_vendor/controllers/portal.py
2025-05-05 10:29:07 -04:00

441 lines
20 KiB
Python

# -*- coding: utf-8 -*-
import base64
import werkzeug
from odoo import http, _
from odoo.http import request
from odoo.exceptions import AccessError, ValidationError, MissingError
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager, get_records_pager
class VendorRequestPortal(CustomerPortal):
"""
Contrôleur pour gérer les demandes de vendeur dans le portail
"""
@http.route(['/my/vendor/request/new'], type='http', auth="user", website=True)
def vendor_request_form(self, **kw):
"""
Affiche le formulaire de demande pour devenir vendeur
"""
user = request.env.user
partner = user.partner_id
# Vérifier que l'utilisateur n'est pas déjà un vendeur
if hasattr(partner, 'is_vendor') and partner.is_vendor:
return request.redirect('/my/home')
# Vérifier qu'il n'y a pas déjà une demande en attente
if hasattr(partner, 'has_pending_vendor_request') and partner.has_pending_vendor_request:
return request.redirect('/my/vendor/requests')
# Récupérer les pays et états autorisés selon la configuration
config_settings = request.env['res.config.settings'].sudo()
countries = config_settings.get_allowed_countries()
states = config_settings.get_allowed_states()
# Déterminer le pays par défaut (Canada si dispo)
default_country = None
for country in countries:
if country.code == 'CA':
default_country = country
break
# Si l'utilisateur a déjà sélectionné un pays, le garder, sinon mettre Canada par défaut
company_country_id = int(kw.get('company_country_id')) if kw.get('company_country_id') and str(kw.get('company_country_id')).isdigit() else (default_country.id if default_country else False)
company_state_id = int(kw.get('company_state_id')) if kw.get('company_state_id') and str(kw.get('company_state_id')).isdigit() else False
# Préremplir les champs société avec le parent si présent
parent = partner.parent_id or partner.commercial_partner_id if partner.commercial_partner_id != partner else None
if parent:
if not kw.get('company_name'):
kw['company_name'] = parent.name
if not kw.get('company_street'):
kw['company_street'] = parent.street
if not kw.get('company_street2'):
kw['company_street2'] = parent.street2
if not kw.get('company_zip'):
kw['company_zip'] = parent.zip
if not kw.get('company_city'):
kw['company_city'] = parent.city
if not kw.get('company_state_id'):
kw['company_state_id'] = parent.state_id.id if parent.state_id else False
if not kw.get('company_country_id'):
kw['company_country_id'] = parent.country_id.id if parent.country_id else False
if not kw.get('company_email'):
kw['company_email'] = parent.email
if not kw.get('company_phone'):
kw['company_phone'] = parent.phone
if not kw.get('company_website'):
kw['company_website'] = parent.website
if not kw.get('company_vat'):
kw['company_vat'] = parent.vat
values = {
'page_name': 'vendor_request_new',
'countries': countries,
'states': states,
'partner': partner,
'company_country_id': company_country_id,
'company_state_id': company_state_id,
'error': kw.get('error'),
'error_message': kw.get('error_message'),
# Champs préremplis
'company_name': kw.get('company_name'),
'company_street': kw.get('company_street'),
'company_street2': kw.get('company_street2'),
'company_zip': kw.get('company_zip'),
'company_city': kw.get('company_city'),
'company_state_id': kw.get('company_state_id'),
'company_country_id': kw.get('company_country_id'),
'company_email': kw.get('company_email'),
'company_phone': kw.get('company_phone'),
'company_website': kw.get('company_website'),
'company_vat': kw.get('company_vat'),
'description': kw.get('description'),
}
return request.render("st_laurent_portal_vendor.portal_vendor_request_form", values)
@http.route(['/my/vendor/request/submit'], type='http', auth="user", website=True, methods=['POST'], csrf=True)
def vendor_request_submit(self, **kw):
"""
Traite la soumission du formulaire de demande pour devenir vendeur
"""
user = request.env.user
partner = user.partner_id
# Vérifier que l'utilisateur n'est pas déjà un vendeur
if hasattr(partner, 'is_vendor') and partner.is_vendor:
return request.redirect('/my/home')
# Vérifier qu'il n'y a pas déjà une demande en attente
if hasattr(partner, 'has_pending_vendor_request') and partner.has_pending_vendor_request:
return request.redirect('/my/vendor/requests')
# Valider les données du formulaire
if not kw.get('company_name'):
return self.vendor_request_form(error="missing", error_message=_("Le nom de l'entreprise est obligatoire."))
# Créer la demande
try:
vals = {
'company_name': kw.get('company_name', ''),
'company_street': kw.get('company_street', ''),
'company_street2': kw.get('company_street2', ''),
'company_zip': kw.get('company_zip', ''),
'company_city': kw.get('company_city', ''),
'company_state_id': int(kw.get('company_state_id', '0')) if kw.get('company_state_id') and str(kw.get('company_state_id')).isdigit() else False,
'company_country_id': int(kw.get('company_country_id', '0')) if kw.get('company_country_id') and str(kw.get('company_country_id')).isdigit() else False,
'company_email': kw.get('company_email', ''),
'company_phone': kw.get('company_phone', ''),
'company_website': kw.get('company_website', ''),
'company_vat': kw.get('company_vat', ''),
'description': kw.get('description', ''),
}
vendor_request = request.env['vendor.request'].sudo().create(vals)
# Soumettre la demande
vendor_request.action_submit()
return request.redirect('/my/vendor/requests')
except Exception as e:
return self.vendor_request_form(error="error", error_message=str(e))
def _prepare_home_portal_values(self, counters):
"""
Ajoute le compteur de demandes de vendeur aux valeurs du portail
"""
values = super(VendorRequestPortal, self)._prepare_home_portal_values(counters)
if 'vendor_request_count' in counters:
partner = request.env.user.partner_id
vendor_request_count = request.env['vendor.request'].sudo().search_count([
('partner_id', '=', partner.id)
])
values['vendor_request_count'] = vendor_request_count
return values
@http.route(['/my/vendor/requests'], type='http', auth="user", website=True)
def vendor_requests(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
"""
Affiche la liste des demandes de vendeur de l'utilisateur
"""
values = self._prepare_portal_layout_values()
partner = request.env.user.partner_id
VendorRequest = request.env['vendor.request'].sudo()
# Domaine de recherche
domain = [('partner_id', '=', partner.id)]
# Tri par défaut
if not sortby:
sortby = 'date'
sort_order = 'create_date desc'
# Comptage pour la pagination
request_count = VendorRequest.search_count(domain)
# Pager
pager = portal_pager(
url="/my/vendor/requests",
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
total=request_count,
page=page,
step=self._items_per_page
)
# Récupérer les demandes avec pagination
vendor_requests = VendorRequest.search(
domain,
order=sort_order,
limit=self._items_per_page,
offset=pager['offset']
)
values.update({
'page_name': 'vendor_requests',
'pager': pager,
'vendor_requests': vendor_requests,
'default_url': '/my/vendor/requests',
})
return request.render("st_laurent_portal_vendor.portal_vendor_requests", values)
@http.route(['/my/vendor/request/<int:request_id>'], type='http', auth="user", website=True)
def vendor_request_detail(self, request_id, access_token=None, **kw):
"""
Affiche le détail d'une demande de vendeur
"""
try:
# Utiliser la méthode standard de CustomerPortal pour vérifier l'accès
vendor_request_sudo = self._document_check_access('vendor.request', request_id, access_token)
except (AccessError, MissingError):
return request.redirect('/my/vendor/requests')
# Préparer les valeurs pour le template
values = self._prepare_portal_layout_values()
values.update({
'page_name': 'vendor_request_detail',
'vendor_request': vendor_request_sudo,
'default_url': f'/my/vendor/request/{request_id}',
})
# Ajouter les valeurs pour la navigation entre demandes
history = request.session.get('my_vendor_requests_history', [()])
values.update(get_records_pager(history, vendor_request_sudo))
return request.render("st_laurent_portal_vendor.portal_vendor_request_detail", values)
@http.route(['/my/vendor/request/<int:request_id>/edit'], type='http', auth="user", website=True)
def vendor_request_edit(self, request_id, access_token=None, **kw):
"""
Affiche le formulaire d'édition d'une demande de vendeur
"""
try:
# Utiliser la méthode standard de CustomerPortal pour vérifier l'accès
vendor_request_sudo = self._document_check_access('vendor.request', request_id, access_token)
except (AccessError, MissingError):
return request.redirect('/my/vendor/requests')
# Vérifier que la demande est en état 'pending' (en attente)
if hasattr(vendor_request_sudo, 'state') and vendor_request_sudo.state != 'pending':
return request.redirect(f'/my/vendor/request/{request_id}')
# Récupérer les pays et états autorisés selon la configuration
config_settings = request.env['res.config.settings'].sudo()
countries = config_settings.get_allowed_countries()
states = config_settings.get_allowed_states()
# Préparer les valeurs pour le template
values = self._prepare_portal_layout_values()
values.update({
'page_name': 'vendor_request_edit',
'vendor_request': vendor_request_sudo,
'countries': countries,
'states': states,
'error': kw.get('error'),
'error_message': kw.get('error_message'),
})
return request.render("st_laurent_portal_vendor.portal_vendor_request_edit", values)
@http.route(['/my/vendor/request/<int:request_id>/update'], type='http', auth="user", website=True, methods=['POST'], csrf=True)
def vendor_request_update(self, request_id, **kw):
"""
Traite la mise à jour d'une demande de vendeur
"""
try:
# Utiliser la méthode standard de CustomerPortal pour vérifier l'accès
vendor_request_sudo = self._document_check_access('vendor.request', request_id)
except (AccessError, MissingError):
return request.redirect('/my/vendor/requests')
# Vérifier que la demande est en état 'pending' (en attente)
if hasattr(vendor_request_sudo, 'state') and vendor_request_sudo.state != 'pending':
return request.redirect(f'/my/vendor/request/{request_id}')
# Valider les données du formulaire
if not kw.get('company_name'):
return self.vendor_request_edit(request_id, error="missing", error_message="Le nom de l'entreprise est obligatoire.")
# Mettre à jour la demande
try:
vals = {
'company_name': kw.get('company_name', ''),
'company_street': kw.get('company_street', ''),
'company_street2': kw.get('company_street2', ''),
'company_zip': kw.get('company_zip', ''),
'company_city': kw.get('company_city', ''),
'company_state_id': int(kw.get('company_state_id', '0')) if kw.get('company_state_id') and str(kw.get('company_state_id')).isdigit() else False,
'company_country_id': int(kw.get('company_country_id', '0')) if kw.get('company_country_id') and str(kw.get('company_country_id')).isdigit() else False,
'company_email': kw.get('company_email', ''),
'company_phone': kw.get('company_phone', ''),
'company_website': kw.get('company_website', ''),
'company_vat': kw.get('company_vat', ''),
'description': kw.get('description', ''),
}
vendor_request_sudo.write(vals)
# Soumettre à nouveau la demande si nécessaire
if kw.get('submit', False) and hasattr(vendor_request_sudo, 'action_submit'):
vendor_request_sudo.action_submit()
return request.redirect(f'/my/vendor/request/{request_id}')
except Exception as e:
return self.vendor_request_edit(request_id, error="error", error_message=str(e))
class VendorProductEcommercePortal(http.Controller):
"""
Contrôleur pour gérer les fonctionnalités e-commerce du portail vendeur
"""
@http.route(['/my/vendor'], type='http', auth="user", website=True)
def vendor_portal_home(self, **kw):
"""
Affiche la page d'accueil de l'espace vendeur
"""
# Vérifier que l'utilisateur est un vendeur
partner = request.env.user.partner_id
if not partner.is_vendor:
return request.redirect('/my/home')
# Récupérer les produits du vendeur
vendor_products = request.env['vendor.product'].sudo().search(
[('partner_id', '=', partner.commercial_partner_id.id)]
)
values = {
'page_name': 'vendor_home',
'vendor_products': vendor_products,
}
return request.render("st_laurent_portal_vendor.portal_vendor_home", values)
@http.route(['/my/products/<model("vendor.product"):product_id>/image'], type='http', auth="user", website=True)
def vendor_product_image_form(self, product_id=None, **kw):
"""
Affiche le formulaire d'upload d'image pour un produit vendeur
"""
try:
if not product_id:
return request.redirect('/my/products')
product_sudo = product_id.sudo()
# Vérifier que l'utilisateur a accès à ce produit
if product_sudo.partner_id.id != request.env.user.partner_id.commercial_partner_id.id:
return request.redirect('/my/products')
values = {
'vendor_product': product_sudo,
'page_name': _('Upload Product Image'),
'error': kw.get('error'),
'success': kw.get('success'),
}
return request.render("st_laurent_portal_vendor.vendor_product_image_form", values)
except AccessError:
return request.redirect('/my/products')
@http.route(['/my/products/update_image'], type='http', auth="user", website=True, methods=['POST'], csrf=True)
def vendor_product_update_image(self, **kw):
"""
Traite l'upload d'image pour un produit vendeur
"""
product_id = kw.get('product_id')
if not product_id:
return request.redirect('/my/products')
try:
product = request.env['vendor.product'].sudo().browse(int(product_id))
# Vérifier que l'utilisateur a accès à ce produit
if product.partner_id.id != request.env.user.partner_id.commercial_partner_id.id:
return request.redirect('/my/products')
# Vérifier si une image recadrée a été fournie
cropped_image = kw.get('cropped_image')
if cropped_image and cropped_image.startswith('data:image/'):
# Traiter l'image recadrée (format base64 data URL)
try:
# Extraire les données base64 de l'URL data
image_format, image_data = cropped_image.split(';base64,')
image_data = base64.b64decode(image_data)
# Mettre à jour l'image du produit
product.write({
'image_1920': base64.b64encode(image_data),
'website_published': True, # Publier automatiquement le produit
'success': _("L'image recadrée a été mise à jour avec succès.")
})
# Rediriger vers la page du produit
return request.redirect('/my/products/%s' % product.id)
except Exception as e:
return self.vendor_product_image_form(
product_id=product,
error=_("Une erreur est survenue lors du traitement de l'image recadrée: %s") % str(e)
)
# Si pas d'image recadrée, utiliser l'image uploadée normalement
image_data = kw.get('product_image')
if not image_data and not cropped_image:
return self.vendor_product_image_form(product_id=product, error=_("Aucune image n'a été fournie."))
# Traiter l'image normale
if image_data:
try:
image_data = image_data.read()
if len(image_data) > 5 * 1024 * 1024: # 5 MB max
return self.vendor_product_image_form(
product_id=product,
error=_("L'image est trop volumineuse. La taille maximale est de 5 Mo.")
)
# Mettre à jour l'image du produit
product.write({
'image_1920': base64.b64encode(image_data),
'website_published': True, # Publier automatiquement le produit
'success': _("L'image a été mise à jour avec succès.")
})
# Rediriger vers la page du produit
return request.redirect('/my/products/%s' % product.id)
except Exception as e:
return self.vendor_product_image_form(
product_id=product,
error=_("Une erreur est survenue lors du traitement de l'image: %s") % str(e)
)
# Si on arrive ici, c'est qu'il y a eu un problème
return self.vendor_product_image_form(
product_id=product,
error=_("Aucune image valide n'a été fournie.")
)
except (AccessError, ValidationError) as e:
return request.redirect('/my/products')
except Exception as e:
return request.redirect('/my/products')