{# Harvest plan-builder tile + re-rendered queue. Inputs: plan: HarvestPlan rows: list[HarvestOpportunity] (full pool) tax_saved_by_key: dict[(symbol, account_label), Decimal] selected_keys: set[(symbol, account_label)] (rows currently checked) mode: "auto" | "manual" | "custom" (current budget mode) custom_budget: str (last custom value or "") exclude_locked: bool has_tax_config: bool #}
Harvest plan
Selected: {{ plan.selected|length }} of {{ rows|length }} candidates · −${{ "%.2f"|format(plan.total_loss_harvested|float|abs) }} loss harvested {% if has_tax_config %} · tax saved (est.): ${{ "%.2f"|format(plan.estimated_tax_saved|float) }} {% else %} · configure tax rates to see tax-saved estimates {% endif %}
Offsets gains: ${{ "%.2f"|format(plan.gain_offset_used|float) }} · against ordinary income (capped $3K): ${{ "%.2f"|format(plan.ordinary_offset_used|float) }}
{% if rows %} {% for row in rows_page %} {% set _checked = (row.symbol, row.account_label) in selected_keys %} {% endfor %}
Symbol Loss LT/ST Account Lockout-clear Tax saved (est.) Actions
{{ row.symbol }} −${{ "%.2f"|format(row.loss|abs) }} {{ row.lt_st }} {{ row.account_label }} {% if row.lockout_clear %} {{ row.lockout_clear }} {% else %} clear {% endif %} {% if has_tax_config %} {% set _ts = tax_saved_by_key[(row.symbol, row.account_label)] %} ${{ "%.2f"|format(_ts|float) }} {% else %} {% endif %} Simulate harvest
{% if pagination is defined and pagination.total_pages > 1 %}
Showing {{ ((pagination.page - 1) * pagination.page_size) + 1 }}–{{ [pagination.page * pagination.page_size, pagination.total_rows]|min }} of {{ pagination.total_rows }}
{# Reconstruct the picks query string so pagination doesn't drop the user's manual selections. #} {% set pick_qs = '' %} {% if picks %}{% for p in picks %}{% set pick_qs = pick_qs + '&pick=' + (p|urlencode) %}{% endfor %}{% endif %} {% if pagination.page > 1 %} ← Prev {% else %} ← Prev {% endif %} Page {{ pagination.page }} / {{ pagination.total_pages }} {% if pagination.page < pagination.total_pages %} Next → {% else %} Next → {% endif %}
{% endif %} {% else %}

No harvestable candidates right now.

{% endif %}