ppm_milestone_achieve
Mark a milestone as achieved and record the current date as the actual completion date.
Instructions
Mark a milestone as achieved; records today as the actual date.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| milestone_id | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/qod_ppm_mcp/server.py:51-55 (handler)The handler function for the ppm_milestone_achieve MCP tool. It takes a milestone_id integer, calls the Odoo server action 'action_achieve' on 'ppm.milestone' via the OdooClient, and returns the updated milestone state fields (name, state, date_planned, date_actual, project_id).
@mcp.tool() def ppm_milestone_achieve(milestone_id: int) -> dict[str, Any]: """Mark a milestone as achieved; records today as the actual date.""" client().call_action("ppm.milestone", "action_achieve", [milestone_id]) return _read_state("ppm.milestone", milestone_id, _MILESTONE_FIELDS) - src/qod_ppm_mcp/server.py:41-41 (helper)The constant _MILESTONE_FIELDS defining the fields read back after a milestone state transition: name, state, date_planned, date_actual, project_id.
_MILESTONE_FIELDS = ["name", "state", "date_planned", "date_actual", "project_id"] - src/qod_ppm_mcp/server.py:44-44 (registration)The @mcp.tool() decorator on line 44 (for ppm_milestone_start) shows the registration pattern; the same decorator is used on line 51 for ppm_milestone_achieve.
@mcp.tool() - src/qod_ppm_mcp/client.py:122-124 (helper)The OdooClient.call_action helper method used by ppm_milestone_achieve to invoke the 'action_achieve' server method on the Odoo model 'ppm.milestone'.
def call_action(self, model: str, method: str, ids: list[int]) -> Any: """Invoke an `action_*` button method on the given record ids.""" return self.execute_kw(model, method, [ids]) - src/qod_ppm_mcp/client.py:113-120 (helper)The OdooClient.read helper method used by _read_state to retrieve the updated milestone fields after the action.
def read( self, model: str, ids: list[int], fields: list[str] | None = None, ) -> list[dict[str, Any]]: kwargs = {"fields": fields} if fields else {} return self.execute_kw(model, "read", [ids], kwargs)