Lead update Required result
Lost, no reason Reject
Lost, reason “Other,” no notes Reject
Lost, reason “Other,” notes supplied Accept these fields
Open, no reason Do not require a lost reason

Frappe CRM’s lead validator enforces these conditions. A Perch rule can check whether a later edit preserves them. Other validation can still reject the update.

Add the workflow requirement

The rule below is based on that implementation; this example does not claim a new defect or a completed scan of Frappe CRM.

Source checkout

git clone --filter=blob:none https://github.com/frappe/crm.git crm-example
cd crm-example
git checkout 08f8fb5227494835a65024717fe41126cdac8358

Perch can read the source without a running CRM instance. Testing the complete workflow requires Frappe and the project’s application test environment.

Behavior rule

Save this in the clone’s root perch.yaml:

- name: lost-lead-requires-reason
  where: crm/fcrm/doctype/crm_lead/crm_lead.py
  each: method
  ensure: >-
    If this method validates a lead's lost reason, it rejects
    a status of type Lost when lost_reason is empty. When
    lost_reason is Other, it also rejects empty lost_notes.
    It does not require a lost reason for an Open status.
    Silently filling in a reason or checking only the reason
    while accepting missing Other notes breaks this rule.
    Methods unrelated to lost-reason validation satisfy it.
perch check crm/fcrm/doctype/crm_lead/crm_lead.py::CRMLead.validate_lost_reason \
  --rules lost-lead-requires-reason

For a committed edit, scan the file with the custom rules:

perch scan --paths crm/fcrm/doctype/crm_lead/crm_lead.py --filter type=lint

Rule controls

In a disposable local copy, remove the branch requiring notes for “Other” and run the same check. Restore the branch and compare the result. This tests whether the question distinguishes the specific regression from the original implementation.

The current method looks up the status’s type rather than assuming every status named “Lost” has identical configuration. Keep that distinction in the rule and test data when adapting it to your CRM.

Workflow tests

Run the scenario table through the application’s save path. This also checks that the framework invokes the validation method and rolls back rejected updates. A method-level review alone cannot establish either behavior.

The same pattern works for approval workflows: state the allowed transition, required role, and required data, then keep each Perch rule scoped to the method that enforces one requirement. Use integration tests for transaction boundaries and external effects.