{% extends "base.html" %} {% load crm_tags static erp_tags labels tz %} {% block title %}{{ engagement.number }} — {% label "crm.engagement" %}{% endblock %} {% block chat_context %} {% endblock %} {% block stylesheets %} {% endblock %} {% block content %} {% timezone viewer_tz %} {% if open_quotes_banner %}
This {% label "crm.engagement" case="lower" %} is won, but {{ open_quotes|length }} of its {% label "orders.quote" plural=True case="lower" %} {% if open_quotes|length == 1 %}is{% else %}are{% endif %} still open: {% for q in open_quotes %}{{ q.quote_number }}{% if not forloop.last %}, {% endif %}{% endfor %}. Nothing was canceled for you.
{% endif %} {# Header #}

{% label "crm.engagement" %} {{ engagement.number }}

{{ engagement.title }}

{% if engagement.party %}{{ engagement.party.display_name }} {% else %}No counterparty{% endif %} · Owner: {{ engagement.owner|profile_name }}{% if engagement.owner_team %} · {{ engagement.owner_team.name }}{% if not engagement.owner_team.is_active %} (archived team){% endif %}{% endif %}

{% if engagement.status == "lost" %}Lost: {{ loss_label }}{% else %}{{ engagement.get_status_display }}{% endif %} {% if stale_days is not None %}Stale · {{ stale_days }} d{% endif %}
{% if engagement.status == "open" %} Move {% label "crm.stage" case="lower" %}
{% csrf_token %}
Lose {% elif can_reopen %}
{% csrf_token %}
{% endif %} {% if engagement.status != "lost" %} New {% label "orders.quote" case="lower" %} {% endif %} Edit
{# 1. Next action #}

{% if engagement.status == "open" and not next_task %}No next action{% else %}Next action{% endif %}

{% if engagement.status == "open" %} {% if next_task %}

{{ next_task.title }}

{% if next_task.due_at %} {% if next_task.overdue %}Overdue: {% else %}Due {% endif %} {% if next_task.all_day %}{{ next_task.due_at|date:"D M j" }} (end of day){% else %}{{ next_task.due_at|date:"D M j, H:i" }}{% endif %} {% if next_task.set_in %}· set in {{ next_task.set_in }}{% endif %} {% else %}No due date{% endif %}

{{ next_task.kind_label }} · {{ next_task.get_priority_display }} priority · {{ next_task.assignee|profile_name }}

{% csrf_token %}
{% csrf_token %}
{% csrf_token %} {{ reassign_form.assignee|add_class:"form-control form-control-sm" }}
{% endif %} {% if other_open_tasks and engagement.status == "open" %}

{% if next_task %}Also open{% else %}Open {% label "crm.task" plural=True case="lower" %}{% endif %}

    {% for task in other_open_tasks %}
  • {{ task.title }}{% if task.due_at %} · {{ task.due_at|date:"M j" }}{% endif %} · {{ task.assignee|profile_name }}
    {% csrf_token %}
  • {% endfor %}
{% endif %} {% if not next_task or whats_next %} {% if whats_next and next_task %}

What's next?

{% elif not next_task %}

Nothing is planned on this {% label "crm.engagement" case="lower" %}. Set the next action.

{% endif %}
{% csrf_token %}
{{ task_form.title|add_class:"form-control form-control-sm" }}
{{ task_form.due_date|add_class:"form-control form-control-sm" }}
{{ task_form.assignee|add_class:"form-control form-control-sm" }}
{{ task_form.kind|add_class:"form-control form-control-sm" }}
{{ task_form.due_time|add_class:"form-control form-control-sm" }}
{{ task_form.priority|add_class:"form-control form-control-sm" }}
{% if task_form.definition_sections or task_form.hidden_definitions %}
{% include "erp/_definition_fieldsets.html" with form=task_form %}
{% endif %}
{% endif %} {% elif open_tasks %}

This {% label "crm.engagement" case="lower" %} is closed and still has open tasks: complete, cancel or keep them.

    {% for task in open_tasks %}
  • {{ task.title }}{% if task.due_at %} · {{ task.due_at|date:"M j" }}{% endif %}
    {% csrf_token %}
  • {% endfor %}
{% csrf_token %}
{% else %}

Closed{% if engagement.closed_at %} on {{ engagement.closed_at|date:"M j, Y" }}{% endif %}. No open tasks.

{% endif %}
{# 2. Deal facts #}

Deal

{% if engagement.status == "open" %}

{% label "crm.pipeline" %}: {{ engagement.pipeline.name }}

    {% for stage in stepper %}
  1. {% if stage.pk == engagement.stage_id %} {{ stage.name }} {% else %}
    {% csrf_token %}
    {% endif %}
  2. {% endfor %}
{% if other_pipeline_stages %}
{% csrf_token %}
{% endif %} {% endif %}
{% label "crm.stage" %}
{{ engagement.stage.name|default:"—" }}{% if engagement.status == "open" and engagement.stage_entered_at %} · {{ engagement.stage_entered_at|timesince }} in {% label "crm.stage" case="lower" %}{% endif %}
Expected value
{% if engagement.expected_value is not None %}{{ engagement.expected_value|money:engagement.currency }}{% else %}—{% endif %}
Probability
{% if probability is not None %}{{ probability }}%{% if probability_inherited %} (from {% label "crm.stage" case="lower" %}){% endif %}{% else %}—{% endif %}
Weighted value
{% if weighted_value is not None %}{{ weighted_value|money:engagement.currency }}{% else %}—{% endif %}
Expected close
{{ engagement.expected_close_date|date:"M j, Y"|default:"—" }}{% if close_date_past %} (past){% endif %}
Source
{{ source_label|default:"Unknown" }}
First touch
{% if engagement.first_touch %}{{ engagement.first_touch.channel|default:engagement.first_touch.utm_source|default:"—" }}{% if engagement.first_touch.utm_campaign %} · {{ engagement.first_touch.utm_campaign }}{% endif %} {{ engagement.first_touch.occurred_at|date:"M j, Y" }}{% else %}—{% endif %}
Last touch
{% if engagement.last_touch %}{{ engagement.last_touch.channel|default:engagement.last_touch.utm_source|default:"—" }}{% if engagement.last_touch.utm_campaign %} · {{ engagement.last_touch.utm_campaign }}{% endif %} {{ engagement.last_touch.occurred_at|date:"M j, Y" }}{% else %}—{% endif %}
{% label "crm.pipeline" %}
{{ engagement.pipeline.name }}
{% if engagement.status == "lost" and engagement.loss_competitor %}
Lost to
{{ engagement.loss_competitor }}
{% endif %} {% if engagement.status == "lost" and engagement.loss_notes %}
Loss notes
{{ engagement.loss_notes }}
{% endif %}
{% include "erp/_definition_groups.html" with groups=definition_groups %} {% if engagement.status == "open" %}
Close this {% label "crm.engagement" case="lower" %} {% if confirm_close == "won" %}

The {% label "crm.stage" case="lower" %} proposes a win. Confirm it, or leave the {% label "crm.engagement" case="lower" %} open.

{% endif %}
{% csrf_token %}
{% csrf_token %}
{{ lose_form.loss_reason|add_class:"form-control form-control-sm" }}
{{ lose_form.loss_competitor|add_class:"form-control form-control-sm" }}
{{ lose_form.loss_notes|add_class:"form-control form-control-sm" }}
{% if open_tasks %}

Open tasks stay open when you close: you choose what happens to them.

{% endif %}
{% endif %}
{# 3. Timeline #}
Log a call, meeting, email or note here
{% include "erp/crm/_log_form.html" with form=log_form %}
{% include "erp/crm/_timeline.html" %}
{# Side column #}

Contacts

    {% for c in contacts %}
  • {{ c.party.display_name }} {% if c.is_primary %}Primary{% endif %} Email marketing: {{ c.consent|capfirst }}
    {{ c.role }} {% if c.contact_id %}
    {% csrf_token %}
    {% endif %}
    {% if c.party.primary_email_normalized %}
    {{ c.party.primary_email_normalized }}
    {% endif %} {% if c.party.primary_phone_e164 %}
    {{ c.party.primary_phone_e164 }}
    {% endif %}
  • {% empty %}
  • No contacts.
  • {% endfor %}
Add a contact
{% csrf_token %}
{{ contact_form.party|add_class:"form-control form-control-sm" }}
{% include "erp/crm/_new_party_link.html" with party_kind="person" %}
{{ contact_form.role|add_class:"form-control form-control-sm" }}
{{ contact_form.is_primary }}

Documents

    {% for chain in quote_chains %}
  • {{ chain.head.quote_number }}{% if chain.revisions > 1 %} v{{ chain.head.revision_number }} of {{ chain.revisions }}{% endif %} · {{ chain.head.get_status_display }} · {{ chain.head.grand_total|money:chain.head.currency }}
  • {% endfor %} {% for order in orders %}
  • {{ order.order_number }} · {{ order.get_status_display }} · {{ order.grand_total|money:order.currency }}
  • {% endfor %} {% for invoice in invoices %}
  • {{ invoice.invoice_number }} · {% if invoice.status == "paid" %}Paid{% else %}{{ invoice.get_status_display }}{% endif %} · {{ invoice.grand_total|money:invoice.order.currency }}
  • {% endfor %} {% if not quote_chains and not orders and not invoices %}
  • No {% label "orders.quote" plural=True case="lower" %} or {% label "orders.order" plural=True case="lower" %} yet.
  • {% endif %}

{% label "crm.stage" %} history

{{ stage_history|length }} change{{ stage_history|length|pluralize }}
    {% for change in stage_history %}
  • {{ change.changed_at|date:"M j, Y H:i" }} · {% if change.from_stage %}{{ change.from_stage.name }}{% else %}{{ change.from_status|default:"new" }}{% endif %} → {% if change.to_stage %}{{ change.to_stage.name }}{% endif %}{% if change.to_status != "open" %} ({{ change.to_status }}){% endif %}{% if change.changed_by %} by {{ change.changed_by.display_name }}{% endif %}{% if change.is_reconstructed %} reconstructed · {{ change.get_source_display|lower }}{% endif %}
  • {% endfor %}
{% if leads %}

{% label "crm.lead" plural=True %}

    {% for lead in leads %}
  • {{ lead.lead_number }} · {{ lead.get_source_display }} {{ lead.created_at|date:"M j, Y" }}
  • {% endfor %}
{% endif %} {% include "erp/_other_data.html" with other=other_data %} {% if identifiers or engagement.tags %}

Identifiers and tags

    {% for ref in identifiers %}
  • {{ ref.source }} · {{ ref.object_type }}: {{ ref.source_id }}
  • {% endfor %}
{% for tag in engagement.tags %}{{ tag }}{% endfor %}
{% endif %}
{% endtimezone %} {% endblock %} {% block javascripts %} {% include "erp/_party_search_js.html" %} {% endblock %}