Source code for django_webapps_fullstack.dashboard.views

"""
This module implements the core business functionality of the dingx logistics platform, providing users
with a comprehensive dashboard to manage their physical belongings across different locations. It handles
product visualization, basket operations for logistics orders, and complete user profile and address
management, all synchronized with the Odoo ERP backend.

**Business Context:**

The dashboard app is the central workspace where users interact with their registered objects (products).
The platform tracks physical belongings across four primary locations:

- **Storage:** Items in long-term storage facilities
- **Home:** Items currently at user's residence
- **Disposal:** Items marked for disposal or donation
- **Transfer:** Items currently in transit between locations

Users can view their inventory with multi-perspective product images, create transfer orders through
drag-and-drop basket functionality, edit product details, and manage their account profile and delivery/
invoice addresses. The system provides two dashboard layouts (pictures and rows) for different user
preferences.

**Key Business Workflows:**

1. **Product Overview & Filtering:**

- :func:`overview`: Main dashboard displays all user products with location-based filtering
    - Visual product cards with images, names, descriptions, and location badges
    - Color-coded system for instant location identification
    - Product count per location displayed in real-time
    - Caching for optimal performance

- :func:`pictures`: Switch to picture grid layout

- :func:`rows`: Switch to row list layout

2. **Basket Operations (Logistics Orders):**

- Users drag products to destination location cards

- :func:`basket_elements`: AJAX handler for adding products to basket

- :func:`basket`: Basket collects selected products for transfer and displays products organized by destination location

- :func:`remove_basket_element`: AJAX handler for removing items from basket before finalizing

- AJAX-based interactions for smooth UX

3. **Product Editing:**

- :func:`edit_object_element`: AJAX handler for edit object selection

- :func:`edit_object`: Edit product name and description
    - View multi-perspective images (front, right, back, left)
    - See product attributes (volume, weight, current location)
    - Undo changes before saving
    - Cache invalidation after updates ensures data consistency

4. **User Profile Management:**

- :func:`account_profile`: Edit name, email, login, title, language
    - International phone number support
    - Multi-language interface with dynamic form field labels
    - Real-time validation against Odoo database
    - Language preference affects entire platform

5. **Address Management:**

- :func:`account_address`: Manage separate delivery and invoice addresses
    - Country and state/canton selection with localization
    - Swiss cantons supported with multi-language names
    - Integration with Odoo partner address system

- :func:`account_billing`: Billing information (placeholder)

**Technical Features:**

- **Caching Strategy:** Django cache framework for product lists per partner and location
- **AJAX Operations:** JSON responses for basket and product selection
- **Multi-language Support:** Dynamic language activation via Django i18n
- **Color Coding:** Bootstrap-based color scheme from parameter_design.ini
- **Image Handling:** Base64-encoded images from Odoo with fallback to dummy images
- **Session Management:** User context (partner_id, language, layout, place) stored in session
- **Error Handling:** Try-catch blocks with detailed logging for debugging
- **Cache Invalidation:** Smart cache clearing after product updates

**Integration:**

All views communicate with the Odoo ERP backend via XMLRPC through dashboard forms,
ensuring synchronized inventory management, order processing, and user profile data across
the entire dingx ecosystem.

**Security:**

- Session-based authentication required for all views
- Partner-specific data isolation
- Redirect to login if session invalid
- Cache cleared per partner_id for data privacy
"""

# Initialize Django settings if running standalone (e.g., in Thonny IDE)
# This allows the module to be imported for inspection without running Django server
import sys
import os
if __name__ == "__main__" or 'django.conf.settings' not in sys.modules or not hasattr(sys.modules.get('django.conf.settings', None), 'configured'):
    import django
    from django.conf import settings
    if not settings.configured:
        # Add the project root to Python path
        project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        if project_root not in sys.path:
            sys.path.insert(0, project_root)
        # Set the Django settings module
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.settings')
        # Setup Django
        django.setup()

from django.shortcuts         import redirect, render
from django.urls              import reverse
from django.http              import JsonResponse
from django.conf              import settings
from django.contrib           import messages
from django.core.exceptions   import ValidationError
# used for internationalization (i18n) and localization (l10n)
from django.utils             import translation
# for the use of the gettext function to mark text for translation
from django.utils.translation import gettext as _
# set the desired language for templates
from django.utils.translation import activate, deactivate
# remove all HTML tags from a string, leaving only the plain text content
from django.utils.html import strip_tags

# use these forms for handling user input, validation, and rendering it in this view
# Handle both relative imports (normal Django) and absolute imports (standalone/Thonny)
try:
    from .forms                   import BasketForm
    from .forms                   import OverviewForm
    from .forms                   import Edit_ObjectForm
    from .forms                   import Account_ProfileForm
    from .forms                   import Delivery_AddressForm
    from .forms                   import Invoice_AddressForm
except ImportError:
    # Fallback for standalone execution (e.g., in Thonny IDE)
    from dashboard.forms          import BasketForm
    from dashboard.forms          import OverviewForm
    from dashboard.forms          import Edit_ObjectForm
    from dashboard.forms          import Account_ProfileForm
    from dashboard.forms          import Delivery_AddressForm
    from dashboard.forms          import Invoice_AddressForm

# for the conversion of a string to a list of integers
import ast
# for the logging of errors
import logging
logger = logging.getLogger(__name__)
# handle and debug exceptions by capturing and printing the full stack trace
import traceback



[docs] def remove_basket_element(request): """ Remove an element from the basket elements list. Call the 'basket' page with the updated list. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) if request.method == 'POST': # Retrieve data from the AJAX request product_id = int(request.POST.get('product_id')) BasketElements = request.session.get('BasketElements') # convert the single string to a list to use it in the loop if not isinstance(BasketElements, list): BasketElements = ast.literal_eval(BasketElements) # remove the element from the list if product_id in BasketElements: BasketElements.remove(product_id) # save the updated list in the session key request.session["BasketElements"] = BasketElements # call the 'basket' page to show the updated list try: # set the URL of the 'basket' HTML page basket_url = request.build_absolute_uri('/dashboard/basket') # Return the basket URL as a JSON response return JsonResponse({'basket_url': basket_url}) except Exception as e: # Log the error for debugging return JsonResponse({'error': 'An error occurred'}, status=500) return JsonResponse({'error': 'Invalid request'}, status=400)
[docs] def basket_elements(request, place): """ Get the place and the elements from the HTML page for preparing the basket. Call the 'basket' page to show the ordered elements. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) if request.method == 'POST': basketPlace = request.POST.get('basketPlace') BasketElements = request.POST.get('BasketElements') # save the values in session keys request.session['basketPlace'] = basketPlace request.session['BasketElements'] = BasketElements # send the URL of the 'basket' HTML page basket_data = { 'basket_url': request.build_absolute_uri('/dashboard/basket'), } return JsonResponse(basket_data)
[docs] def basket(request): """ Prepare the basket page with all the objects to be ordered. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) # get the place from the session if request.session['place']: # if a place exit: get the place from the session place = request.session.get('place') else: place = "all" try: if (request.session['basketPlace'] and request.session['BasketElements']): # get the basket place and basket elements from the session basketPlace = request.session.get('basketPlace') BasketElements = request.session.get('BasketElements') # get the background color of the header corresponding to the selected Basket Place # from the 'OverviewForm' class basketPlace = basketPlace.lower() form = OverviewForm(place=basketPlace) try: header_background_color = form.get_header_background_color(basketPlace) except AttributeError as e: logger.error(f"Failed to get header background color for place {basketPlace}: {e}") form = BasketForm(basketPlace=basketPlace, BasketElements=BasketElements) try: products = form.get_ordered_products(basketPlace, BasketElements) except AttributeError as e: logger.error(f"Failed to get ordered elements for place {place}: {e}") # prepare the content for the HTML page context = { 'basketPlace' : basketPlace, 'products' : products, 'place' : place, 'header_background_color' : header_background_color, } # render the HTML page 'dashboard_basket' return render(request, 'dashboard_basket.html', context) else: # back to dashboard return redirect("overview", place) except Exception as e: print("An error occurred:", e) traceback.print_exc() # return to dashboard with all objects return redirect('overview', place = "all")
[docs] def edit_object_element(request, place): """ Get the element from the HTML page for preparing to edit the element. Return the URL of the 'edit element' page. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) if request.method == 'POST': product_id = request.POST.get('product_id') # save the value in a session key request.session['product_id'] = product_id # send the URL of the 'edit_object' HTML page edit_object_data = { 'edit_object_url': request.build_absolute_uri('/dashboard/edit_object'), } return JsonResponse(edit_object_data)
[docs] def edit_object(request): """ Prepare the page for editing an object. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) try: if request.session['partner_id'] and ['product_id']: # get the id of the partner of the selected product from the session partner_id = request.session.get('partner_id') # get the id of the selected product from the session product_id = request.session.get('product_id') # prepare the form form = Edit_ObjectForm() # get the values of the selected product product = form.get_product(product_id) # get the pictures of the selected product picture_string_dict = form.get_product_pictures(product_id) # prepare the content for the HTML page including the values of the product context = { 'name' : product.get('name', ''), 'description' : strip_tags(product.get('description', '')), 'volume' : product.get('volume', ''), 'weight' : product.get('weight', ''), 'x_place' : product.get('x_place', ''), 'badgecolor' : product.get('badgecolor', ''), 'image_front' : picture_string_dict.get('front', ''), 'image_right' : picture_string_dict.get('right', ''), 'image_back' : picture_string_dict.get('back', ''), 'image_left' : picture_string_dict.get('left', ''), } # prepare the form with the values of the product form = Edit_ObjectForm(request.POST or None, initial=context) if request.method == "POST": # Detect which button was pressed action = request.POST.get("action") if action == "back": # redirect to the dashboard without saving if request.session['place']: # if a place exit: get the place from the session place = request.session.get('place') # dashboard with that place return redirect("overview", place) else: # dashboard over all places return redirect("overview", "all") elif action == "undo": # Reload product with the initial values and reset the form form = Edit_ObjectForm(initial=context) elif action == "save" and form.is_valid(): name = form.cleaned_data['name'] description = form.cleaned_data['description'] # Update the product with the changed values result = form.update(partner_id, product_id, name, description) if result != True: error_message = ValidationError messages.error(request, error_message) # prepare the content for the HTML page including the values of the product # name and description directly come as the updated values context = { 'name' : name, 'description' : strip_tags(description), 'volume' : product.get('volume', ''), 'weight' : product.get('weight', ''), 'x_place' : product.get('x_place', ''), 'badgecolor' : product.get('badgecolor', ''), 'image_front' : picture_string_dict.get('front', ''), 'image_right' : picture_string_dict.get('right', ''), 'image_back' : picture_string_dict.get('back', ''), 'image_left' : picture_string_dict.get('left', ''), } # Reset the form with the updated values form = Edit_ObjectForm(initial=context) else: # back to dashboard with all objects return redirect('overview', place = "all") except Exception as e: print("An error occurred:", e) traceback.print_exc() # back to dashboard with all objects return redirect('overview', place = "all") return render(request, 'edit_object.html', {'form': form})
[docs] def overview(request, place): """ Prepare the overview page which shows the products of a user. If a user is logged in, than the overview page will be called. Otherwise the landung page will be called. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) # Attach the 'CSS' classes to the diferrent places. if place in ("all", "storage", "home", "disposal", "transfer"): # These are the possible places. # save the place in a session key for future use request.session['place'] = place # prepare the form with the place form = OverviewForm(place=place) try: # user is logged in if request.session['partner_id']: # get all products of the place from the user # these products will be shown in the dashboard partner_id = request.session.get('partner_id', None) try: products = form.get_product_list(partner_id, place) except AttributeError as e: logger.error(f"Failed to get product list for place {place}: {e}") # get the 'CSS' classes for the different places (= card_place) # and also the number of articles at that place card_place = "storage" try: card_classes_storage = form.get_card_classes(card_place, place) except AttributeError as e: logger.error(f"Failed to get card class color for place {place}: {e}") count_article_storage = form.count_product_place(partner_id, card_place) card_place = "home" try: card_classes_home = form.get_card_classes(card_place, place) except AttributeError as e: logger.error(f"Failed to get card class color for place {place}: {e}") count_article_home = form.count_product_place(partner_id, card_place) card_place = "disposal" try: card_classes_disposal = form.get_card_classes(card_place, place) except AttributeError as e: logger.error(f"Failed to get card class color for place {place}: {e}") count_article_disposal = form.count_product_place(partner_id, card_place) card_place = "transfer" try: card_classes_transfer = form.get_card_classes(card_place, place) except AttributeError as e: logger.error(f"Failed to get card class color for place {place}: {e}") count_article_transfer = form.count_product_place(partner_id, card_place) # get the background color of the header corresponding to the selected place try: header_background_color = form.get_header_background_color(place) except AttributeError as e: logger.error(f"Failed to get card background color for place {place}: {e}") # prepare the content for the HTML page including the classes with the css styles context = { 'place' : place.capitalize(), 'products' : products, 'header_background_color' : header_background_color, 'card_classes_storage' : card_classes_storage, 'card_classes_home' : card_classes_home, 'card_classes_disposal' : card_classes_disposal, 'card_classes_transfer' : card_classes_transfer, 'count_article_storage' : count_article_storage, 'count_article_home' : count_article_home, 'count_article_disposal' : count_article_disposal, 'count_article_transfer' : count_article_transfer, } # according to the 'layout' session parameter call the corresponding dashboard page # if no 'layout' session exist: call 'pictures' as a default try: if request.session['layout'] == 'rows': return render(request, 'dashboard_rows.html', context) else: return render(request, 'dashboard_pictures.html', context) except: return render(request, 'dashboard_pictures.html', context) except Exception as e: print("An error occurred:", e) traceback.print_exc() return redirect(reverse("login")) else: # in case of a wrong place return render(request, 'error_404.html', status=404)
[docs] def pictures(request, place): """ Call the dashboard page with pictures layout. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) request.session['layout'] = 'pictures' return redirect('overview', place = place)
[docs] def rows(request, place): """ Call the dashboard page with rows layout. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) request.session['layout'] = 'rows' return redirect('overview', place = place)
[docs] def account_profile(request): """ Prepare the account profile page to show and update the account profile values of a user. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) partner_id = request.session.get('partner_id', None) try: if request.session['partner_id']: # get the user_id and the language from the session key user_id = request.session.get('user_id', None) # if session key does not exit take the default language (must be converted) user_language_code = request.session.get('language', None) or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()])) # prepare the form and get the user profile values form = Account_ProfileForm(user_language_code=user_language_code) result = form.get_user_profile_values(user_id) if result[0] == 'True': # prepare first name and last name from the full name full_name = result[3] # Split the full_name into two parts names = full_name.split(" ", 1) if len(names) == 2: first_name, last_name = names else: first_name = "" last_name = full_name # prepare code and name of the language languages = result[5] if languages: language_code = str(languages[0]['code']) language_name = str(languages[0]['name']) else: language_code = '' language_name = '' # prepare the content for the HTML page including the values of the user context = { 'login' : result[1], 'email' : result[2], 'first_name' : first_name, 'last_name' : last_name, 'title' : result[4], 'language' : (language_code, language_name), 'phone_number' : result[6], 'mobile_number' : result[7],} form = Account_ProfileForm(request.POST or None, user_language_code=user_language_code, initial=context) if form.is_valid(): # build the complete name from first name and last name # If both are present, concatenate with a space if first_name: complete_name = first_name + " " + last_name else: complete_name = last_name login = form.cleaned_data['login'] email = form.cleaned_data['email'] first_name = form.cleaned_data['first_name'] last_name = form.cleaned_data['last_name'] name = complete_name title = form.cleaned_data['title'] language = form.cleaned_data['language'] phone_number = form.cleaned_data['phone_number'] mobile_number = form.cleaned_data['mobile_number'] result = form.update(user_id, login, email, name, title, language, phone_number, mobile_number) if result != True: error_message = ValidationError messages.error(request, error_message) # update the session key for the user language code request.session['language'] = language # Redirect to the same page after successful update return redirect('account_profile') else: return redirect('overview', place = "all") except Exception as e: print("An error occurred:", e) traceback.print_exc() return redirect(reverse("login")) return render(request, 'account_profile.html', {'form': form})
[docs] def account_address(request): """ Prepare the account address page to show and update the account address values of a user. """ # set the language for the template; if session key does not exit take the default language(must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) try: if request.session['user_id']: # get the partner_id and the language from the session key partner_id = request.session.get('partner_id', None) # if language session key does not exit take the default language(must be converted) user_language_code = request.session.get('language', None) or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()])) # prepare the form and get the user address values form = Delivery_AddressForm(partner_id=partner_id, user_language_code=user_language_code) result = form.get_user_address_values(partner_id) if result != 'False': # prepare the address values of the user address_data = result # get the address values for address type = 'delivery' delivery_address_items = [item for item in address_data if item['type'] == 'delivery'] # get the address values for address type = 'invoice' invoice_address_items = [item for item in address_data if item['type'] == 'invoice'] # prepare the address values for address type = 'delivery' # if the array is not empty if delivery_address_items: if delivery_address_items[0]['street']: delivery_street = delivery_address_items[0]['street'] else: delivery_street = '' if delivery_address_items[0]['street2']: delivery_street_2 = delivery_address_items[0]['street2'] else: delivery_street_2 = '' if delivery_address_items[0]['zip']: delivery_zip = delivery_address_items[0]['zip'] else: delivery_zip = '' if delivery_address_items[0]['city']: delivery_city = delivery_address_items[0]['city'] else: delivery_city = '' # prepare id and name of the delivery state if delivery_address_items[0]['state_id'] != '': delivery_state_item = delivery_address_items[0]['state_id'] delivery_state_id = str(delivery_state_item[0]) delivery_state_name = str(delivery_state_item[1]) else: delivery_state_id = '' delivery_state_name = '' # prepare id and name of the delivery country if delivery_address_items[0]['country_id'] != '': delivery_country_item = delivery_address_items[0]['country_id'] delivery_country_id = str(delivery_country_item[0]) delivery_country_name = str(delivery_country_item[1]) else: delivery_country_id = '' delivery_country_name = '' else: delivery_street = '' delivery_street_2 = '' delivery_zip = '' delivery_city = '' delivery_state_id = '' delivery_state_name = '' delivery_country_id = '' delivery_country_name = '' # prepare the address values for address type = 'invoice' # if the array is not empty if invoice_address_items: if invoice_address_items[0]['street']: invoice_street = invoice_address_items[0]['street'] else: invoice_street = '' if invoice_address_items[0]['street2']: invoice_street_2 = invoice_address_items[0]['street2'] else: invoice_street_2 = '' if invoice_address_items[0]['zip']: invoice_zip = invoice_address_items[0]['zip'] else: invoice_zip = '' if invoice_address_items[0]['city']: invoice_city = invoice_address_items[0]['city'] else: invoice_city = '' # prepare id and name of the invoice state if invoice_address_items[0]['state_id'] != '': invoice_state_item = invoice_address_items[0]['state_id'] invoice_state_id = str(invoice_state_item[0]) invoice_state_name = str(invoice_state_item[1]) else: invoice_state_id = '' invoice_state_name = '' # prepare id and name of the invoice country if invoice_address_items[0]['country_id'] != '': invoice_country_item = invoice_address_items[0]['country_id'] invoice_country_id = str(invoice_country_item[0]) invoice_country_name = str(invoice_country_item[1]) else: invoice_country_id = '' invoice_country_name = '' else: invoice_street = '' invoice_street_2 = '' invoice_zip = '' invoice_city = '' invoice_state_id = '' invoice_state_name = '' invoice_country_id = '' invoice_country_name = '' # prepare the content for the HTML page including the values of the user context_delivery = {'delivery_street' : delivery_street, 'delivery_street_2' : delivery_street_2, 'delivery_zip' : delivery_zip, 'delivery_city' : delivery_city, 'delivery_state' : (delivery_state_id, delivery_state_name), 'delivery_country' : (delivery_country_id, delivery_country_name), } context_invoice = {'invoice_street' : invoice_street, 'invoice_street_2' : invoice_street_2, 'invoice_zip' : invoice_zip, 'invoice_city' : invoice_city, 'invoice_state' : (invoice_state_id, invoice_state_name), 'invoice_country' : (invoice_country_id, invoice_country_name), } if request.method == 'POST': # Identify which form was submitted form_type = request.POST.get("form_type") # Initialize forms form_delivery = Delivery_AddressForm(request.POST if form_type == "form_type_delivery" else None, prefix="form_delivery", partner_id=partner_id, user_language_code=user_language_code, initial=context_delivery) form_invoice = Invoice_AddressForm (request.POST if form_type == "form_type_invoice" else None, prefix="form_invoice", partner_id=partner_id, user_language_code=user_language_code, initial=context_invoice) # if 'form_delivery' was submitted if form_delivery.is_valid(): delivery_street = form_delivery.cleaned_data['delivery_street'] delivery_street_2 = form_delivery.cleaned_data['delivery_street_2'] delivery_zip = form_delivery.cleaned_data['delivery_zip'] delivery_city = form_delivery.cleaned_data['delivery_city'] delivery_state = form_delivery.cleaned_data['delivery_state'] delivery_country = form_delivery.cleaned_data['delivery_country'] # update the address values including set the address type as delivery type = 'delivery' result = form_delivery.update(partner_id, type, delivery_street, delivery_street_2, delivery_zip, delivery_city, delivery_state, delivery_country) if result != True: error_message = ValidationError messages.error(request, error_message) # Redirect to the same page after successful update return redirect('account_address') # if 'form_invoice' was submitted if form_invoice.is_valid(): invoice_street = form_invoice.cleaned_data['invoice_street'] invoice_street_2 = form_invoice.cleaned_data['invoice_street_2'] invoice_zip = form_invoice.cleaned_data['invoice_zip'] invoice_city = form_invoice.cleaned_data['invoice_city'] invoice_state = form_invoice.cleaned_data['invoice_state'] invoice_country = form_invoice.cleaned_data['invoice_country'] # update the address values including set the address type as invoice type = 'invoice' result = form_invoice.update(partner_id, type, invoice_street, invoice_street_2, invoice_zip, invoice_city, invoice_state, invoice_country) if result != True: error_message = ValidationError messages.error(request, error_message) # Redirect to the same page after successful update return redirect('account_address') else: form_delivery = Delivery_AddressForm(request.GET or None, partner_id=partner_id, user_language_code=user_language_code, initial=context_delivery, prefix="form_delivery") form_invoice = Invoice_AddressForm (request.GET or None, partner_id=partner_id, user_language_code=user_language_code, initial=context_invoice, prefix="form_invoice") else: # go to dashoard and show all objects in the dashboard (= 'overview') return redirect('overview', place = "all") except Exception as e: print(f"Exception: {e}") traceback.print_exc() # Print the traceback to the console return redirect(reverse("login")) return render(request, 'account_address.html', {"form_delivery": form_delivery, "form_invoice": form_invoice})
[docs] def account_billing(request): """ Prepare the account billing page to show and update the account billing values of a user. """ # set the language for the template; if session key does not exit take the default language (must be converted) activate(request.session.get('language') or ("_".join([settings.LANGUAGE_CODE[:2].lower(), settings.LANGUAGE_CODE[3:].upper()]))) if request.method == "GET": return render(request, 'account_billing.html') elif request.method == "POST": # go to dashoard and show all objects in the dashboard (= 'overview') return redirect('overview', place = "all") return render(request, 'account_billing.html', {'form': form})