[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
Conversation
Contributor
There was a problem hiding this comment.
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.
added 2 commits
June 9, 2026 10:10
Talleyrand333
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Is this a Feature, Chore or 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_onconditions 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)
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. Updatesend_date, unchecksis_auto_renewal, transitions to Inactive immediately or defers to scheduler based on dateset_contract_active(contract_name, new_start_date, new_end_date)— whitelisted method, Sales Manager only. Validates dates, updates start/end, transitions to Draftauto_deactivate_contracts()— daily scheduler job. Queries Active contracts withend_date < today()and transitions each to Inactive with per-contract error handlingClient-side (contracts.js):
frappe.promptfor Contract End Datefrappe.promptfor New Start Date / New End DateScheduler (hooks.py):
auto_deactivate_contractsto thedailyscheduler eventsTask 2 — Updating Contracts Workflow Transition
Workflow (contracts.json workflow):
Task 3 — Updating Contract Days Off Visibility
DocType JSON (contract_items_operation.json):
depends_onforoff_typeand related days-off fields fromeval:doc.rate_type == "Monthly"toeval:doc.rate_type == "Monthly" || doc.rate_type == "Hourly"Task 4 — Contract Inactivation Email Notification
New DocType (contract_notification_member/):
Contract Notification Member— child table (istable: 1) withuser(Link → User) andfull_name(fetched from User)DocType update (contracts.json):
notification_membersTable fieldEmail template (contract_inactivation.html):
Controller (contracts.py):
on_update()detectsworkflow_statechange to "Inactive" → callssend_inactivation_email()send_inactivation_email()fetches recipients fromnotification_members, renders template, sends viasendemail()fromone_fm.processorIs there a business logic within a doctype?
Business logic in
Contractscontroller: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
notification_memberschild table field, newsend_inactivation_email()method, updatedon_update()depends_onupdated for days-off fields (Hourly + Monthly)auto_deactivate_contractscontract_inactivation.htmlContract Notification MemberIs there any existing behavior change of other features due to this code change?
Yes.
Did you test with the following dataset?
Was child table created?
Contract Notification Member(child table for per-contract email recipients)N/A — no attachments in this child table
Did you delete custom field?
Is patch required?
No data migration patch needed. The new child table and field are additive — existing contracts will simply have an empty
notification_memberstable. Theauto_deactivate_contractsscheduler job is registered via hooks.py and picks up on nextbench migrate.Which browser(s) did you use for testing?
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