Skip to content

[WI-000978][WI-000977][WI-000976][WI-001005][ Contract Workflow - Inactivation Email][Contracts Workflow Update][Contract Lifecycle - Inactivation Process & End Date Modification][Doctype Update regarding Contracts Day Off Visibility in Contracts]#6208

Merged
Talleyrand333 merged 3 commits into
stagingfrom
WI-000978_WI-000977_WI-000976_WI-001005
Jun 9, 2026

Conversation

@samdanikouser

Copy link
Copy Markdown
Contributor

Is this a Feature, Chore or Bug?

  • Feature
  • Chore
  • Bug

Clearly and concisely describe the feature, chore or bug.

This PR implements 4 contract-related user stories for the Contracts DocType:

1. Automating Contract Inactivation Process

Adds a full inactivation/activation lifecycle — when Finance Manager clicks "Set Inactive", a date prompt captures the new Contract End Date. If the date is today or past, the contract immediately transitions to Inactive. If the date is future, the contract stays Active and a daily scheduler job (auto_deactivate_contracts) transitions it automatically when the end date arrives. "Set as Active" prompts for new start/end dates and transitions back to Draft.

2. Updating Contracts Workflow Transition

Adds the "Set as Active" workflow transition (Inactive → Draft) for the Sales Manager role, allowing re-activation of inactive contracts back through the full lifecycle.

3. Updating Contract Days Off Visibility

Updates the depends_on conditions on the "Off Type" and related days-off fields in the Contract Items Operation child table to show them for both "Monthly" and "Hourly" rate types (previously only visible for "Monthly"). Fields remain hidden for "Daily" rate type.

4. Contract Inactivation Email Notification

Sends an automated email to per-contract notification members when a contract is set to Inactive. A new "Contract Notification Member" child table allows mapping specific users (e.g. Fayaad, Mariam, Abbas, Supriya) per contract. The email includes Contract ID, Client Name, and updated Contract End Date, wrapped in the standard ONE FM branded template.

Analysis and design (optional)

  • Task 1: Implementation Plan | Walkthrough
  • Task 4: Implementation Plan | Walkthrough

Solution description

Task 1 — Automating Contract Inactivation Process

Server-side (contracts.py):

  • set_contract_inactive(contract_name, contract_end_date) — whitelisted method, Finance Manager only. Updates end_date, unchecks is_auto_renewal, transitions to Inactive immediately or defers to scheduler based on date
  • set_contract_active(contract_name, new_start_date, new_end_date) — whitelisted method, Sales Manager only. Validates dates, updates start/end, transitions to Draft
  • auto_deactivate_contracts() — daily scheduler job. Queries Active contracts with end_date < today() and transitions each to Inactive with per-contract error handling

Client-side (contracts.js):

  • Intercepts "Set Inactive" workflow button → shows frappe.prompt for Contract End Date
  • Intercepts "Set as Active" workflow button → shows frappe.prompt for New Start Date / New End Date

Scheduler (hooks.py):

  • Added auto_deactivate_contracts to the daily scheduler events

Task 2 — Updating Contracts Workflow Transition

Workflow (contracts.json workflow):

  • Added transition: Inactive → Draft via "Set as Active", allowed for Sales Manager
  • This transition was already defined in the workflow JSON — verified present at idx 14

Task 3 — Updating Contract Days Off Visibility

DocType JSON (contract_items_operation.json):

  • Updated depends_on for off_type and related days-off fields from eval:doc.rate_type == "Monthly" to eval:doc.rate_type == "Monthly" || doc.rate_type == "Hourly"
  • Fields remain hidden for "Daily" and other rate types

Task 4 — Contract Inactivation Email Notification

New DocType (contract_notification_member/):

  • Contract Notification Member — child table (istable: 1) with user (Link → User) and full_name (fetched from User)

DocType update (contracts.json):

  • Added collapsible "Notification Members" section with notification_members Table field

Email template (contract_inactivation.html):

  • Jinja template rendering Contract ID (linked), Client Name, and End Date in a styled table

Controller (contracts.py):

  • on_update() detects workflow_state change to "Inactive" → calls send_inactivation_email()
  • send_inactivation_email() fetches recipients from notification_members, renders template, sends via sendemail() from one_fm.processor

Is there a business logic within a doctype?

  • Yes
  • No

Business logic in Contracts controller:

  • Inactivation date evaluation (immediate vs deferred transition)
  • Auto-deactivation scheduler job
  • Inactivation email trigger on workflow state change
  • Days-off field visibility based on rate type

Output screenshots (optional)

N/A — UI changes are workflow button prompts (date dialogs) and a new "Notification Members" section on the Contracts form. Manual verification recommended.

Areas affected and ensured

Area Impact
Contracts DocType New notification_members child table field, new send_inactivation_email() method, updated on_update()
Contracts form (JS) Workflow button interceptors for "Set Inactive" and "Set as Active"
Contract Items Operation depends_on updated for days-off fields (Hourly + Monthly)
hooks.py New daily scheduler: auto_deactivate_contracts
Email templates New contract_inactivation.html
New child table DocType Contract Notification Member

Is there any existing behavior change of other features due to this code change?

Yes.

  • "Set Inactive" workflow action now shows a date prompt instead of executing the default workflow transition directly. The end date is updated and auto-renewal is disabled before the state change.
  • "Set as Active" workflow action now shows a date prompt for new start/end dates instead of the default workflow transition.
  • Contract Items Operation — "Off Type" and related days-off fields are now visible for "Hourly" rate type in addition to "Monthly" (previously hidden for Hourly).
  • Active contracts past their end date will now be automatically set to Inactive by the daily scheduler job.

Did you test with the following dataset?

  • Existing Data
  • New Data

Was child table created?

  • Yes — Contract Notification Member (child table for per-contract email recipients)
    • is attachment required?
      N/A — no attachments in this child table

Did you delete custom field?

  • Yes
  • No

Is patch required?

  • Yes
  • No

No data migration patch needed. The new child table and field are additive — existing contracts will simply have an empty notification_members table. The auto_deactivate_contracts scheduler job is registered via hooks.py and picks up on next bench migrate.

Which browser(s) did you use for testing?

  • Chrome
  • Safari
  • Firefox
Screen.Recording.2026-06-09.at.8.49.04.AM.mov
Screen.Recording.2026-06-09.at.9.06.45.AM.mov
Screen.Recording.2026-06-09.at.9.19.03.AM.mov

Copilot AI review requested due to automatic review settings June 9, 2026 06:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements several contract-lifecycle enhancements in the ONE FM Operations module: adding a controlled Contract inactivation/reactivation flow (with scheduler support), introducing per-contract notification recipients and an inactivation email, and adjusting Contract Items Operation day-off field visibility for Hourly rate types.

Changes:

  • Adds server-side lifecycle methods (set_contract_inactive, set_contract_active, auto_deactivate_contracts) plus client-side workflow-action interceptors to capture dates before transitioning.
  • Introduces “Contract Notification Member” child table + a Contracts form section and an inactivation email template triggered when workflow state becomes Inactive.
  • Updates workflow transition (Inactive → Draft via “Set as Active”), registers a daily scheduler, and expands days-off field visibility rules to include Hourly rate type.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
one_fm/templates/emails/contract_inactivation.html Adds the email body used for contract inactivation notifications.
one_fm/patches/v15_0/update_contracts_workflow_inactive_to_draft.py Adds a migration patch to recreate the Contracts workflow with updated transition rules.
one_fm/patches.txt Registers the new workflow update patch for execution during migrate.
one_fm/operations/doctype/contracts/contracts.py Adds inactivation email trigger + lifecycle methods + daily auto-deactivation job.
one_fm/operations/doctype/contracts/contracts.json Adds a “Notification Members” section and table field to Contracts.
one_fm/operations/doctype/contracts/contracts.js Intercepts workflow actions to prompt for dates and call new server methods.
one_fm/operations/doctype/contract_notification_member/contract_notification_member.py Adds the DocType controller for the new child table.
one_fm/operations/doctype/contract_notification_member/contract_notification_member.json Defines the new “Contract Notification Member” child table schema.
one_fm/operations/doctype/contract_notification_member/init.py Initializes the new doctype module.
one_fm/operations/doctype/contract_items_operation/contract_items_operation.json Updates depends_on rules so days-off fields also show for Hourly rate type.
one_fm/hooks.py Registers auto_deactivate_contracts in daily scheduler events.
one_fm/custom/workflow/contracts.json Updates workflow transition “Set as Active” to go Inactive → Draft and be allowed for Sales Manager.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread one_fm/operations/doctype/contracts/contracts.py
Comment thread one_fm/operations/doctype/contracts/contracts.py
Comment thread one_fm/operations/doctype/contracts/contracts.py Outdated
Comment thread one_fm/patches.txt
Comment thread one_fm/operations/doctype/contracts/contracts.py
@Talleyrand333 Talleyrand333 merged commit a8244c6 into staging Jun 9, 2026
1 of 6 checks passed
@Talleyrand333 Talleyrand333 deleted the WI-000978_WI-000977_WI-000976_WI-001005 branch June 9, 2026 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants