Set profile.allowed_manual_input as False even for charge based portal users

Resolved 💬 3 comments Opened Nov 30, 2025 by rafalitos123 Closed Jan 29, 2026

Overview

We need to change the semantic meaning of the allowed_manual_input flag to be consistent across all portal types.

Current Behavior

  • Ledger-based portals: allowed_manual_input = whether user can change their rent amount
  • Charge-based portals (TurboTenant, Innago): allowed_manual_input = whether user can edit specific charge amounts (after removing the option to manually input charges entirely)

Problem

Since we removed the option for users to manually input charges for TurboTenant and Innago, the flag's meaning is now inconsistent. For charge-based users, we should return allowed_manual_input=False when they don't have manual input permissions, just like ledger-based users.

Solution

Update the logic to return allowed_manual_input=False for charge-based portal users (TurboTenant, Innago) when they don't have manual input permissions enabled, making the flag consistently represent: "Can this user change/override their rent amount?"

Relevant Code Locations

Core Logic - Flag Calculation

  • File: libs/manual_input/utils.py:50-82
  • Function: is_allowed_manual_input(user: User, db: Session) -> bool
  • Contains the main decision logic that needs to be updated to handle charge-based portals consistently

API Endpoint Returning The Flag

  • File: services/api/src/api_v8/logic/user_logic.py:923-926
  • Function: profile()
  • Calculates allowed_manual_input and adds it to ProfileResponse (line 974)
  • This is where the flag gets sent to the frontend

Supporting Functions

  • File: libs/manual_input/utils.py:31-47
  • Function: get_partial_payments_allowed_from_scan()
  • Checks if partial payments are allowed in portal scan
  • File: libs/manual_input/utils.py:106-112
  • Function: get_max_payment_allowed_in_portal()
  • Contains special handling for CHARGE_BASED vs other billing types
  • File: libs/tenant_portals/utils.py
  • Function: get_billing_type(user) - returns portal billing type
  • Function: is_user_from_portal_with_manual_input_enabled() - checks if portal supports manual input

Validation Endpoints

  • File: services/api/src/api_v8/api/payments.py:905-910
  • Endpoint: post_manual_rent_data()
  • Validates allowed_manual_input before allowing manual input
  • File: services/api/src/api_v9/logic/payments.py:191-211
  • Function: create_loan_params_and_validate_rent_amount()
  • Similar validation logic

Frontend Implications

The frontend uses this flag in:

  • lib/models/extensions/user_ext.dart - User extension checks isManualInputAllowed
  • lib/screens/home/month_views/shared_components/button_or_rejected_message.dart:75 - Navigation logic
  • lib/screens/home/month_views/shared_components/editable_price_home_square/demonstration_price_square.dart:72,75 - Edit CTA visibility

Expected Impact

  • Charge-based portal users without manual input permissions will see allowed_manual_input=False
  • Frontend will hide edit CTAs for these users (consistent with ledger-based behavior)
  • No impact on users who do have manual input permissions
  • Simplifies the semantic meaning of the flag across all portal types

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗