diff --git a/src/qodev_apollo_api/client.py b/src/qodev_apollo_api/client.py index e862cde..9dd81fa 100644 --- a/src/qodev_apollo_api/client.py +++ b/src/qodev_apollo_api/client.py @@ -420,6 +420,25 @@ async def get_deal(self, deal_id: str) -> Deal: result = await self._get(f"/opportunities/{deal_id}") return Deal.model_validate(result.get("opportunity", {})) + async def create_deal(self, name: str, **fields) -> Deal: + """Create a new deal/opportunity. + + Note: + Apollo requires a **master** API key for this endpoint; a non-master + key returns 403. ``name`` is the only required field. + + Args: + name: Human-readable deal name (required). + **fields: Additional fields (owner_id, account_id, amount, + opportunity_stage_id, closed_date [YYYY-MM-DD], etc.). + + Returns: + The created Deal model. + """ + data = {"name": name, **fields} + result = await self._post("/opportunities", data) + return Deal.model_validate(result.get("opportunity", result)) + # ======================================================================== # PIPELINES & STAGES # ======================================================================== diff --git a/tests/test_client.py b/tests/test_client.py index 6406a78..066a27a 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -533,6 +533,43 @@ async def test_get_deal(client: ApolloClient): client._client.request.assert_called_once_with("GET", "/opportunities/d1") +async def test_create_deal(client: ApolloClient): + """Test POST /opportunities returns the created Deal with name + extra fields in the body.""" + client._client.request.return_value = _make_response( + {"opportunity": {"id": "d9", "name": "New Deal", "amount": "1000"}} + ) + + result = await client.create_deal( + "New Deal", owner_id="o1", account_id="a1", amount=1000, opportunity_stage_id="st1" + ) + + assert isinstance(result, Deal) + assert result.id == "d9" + + call_args = client._client.request.call_args + assert call_args[0] == ("POST", "/opportunities") + assert call_args[1]["json"] == { + "name": "New Deal", + "owner_id": "o1", + "account_id": "a1", + "amount": 1000, + "opportunity_stage_id": "st1", + } + + +async def test_create_deal_name_only(client: ApolloClient): + """Only ``name`` is required; the body carries nothing else.""" + client._client.request.return_value = _make_response( + {"opportunity": {"id": "d10", "name": "Minimal"}} + ) + + result = await client.create_deal("Minimal") + + assert isinstance(result, Deal) + assert result.id == "d10" + assert client._client.request.call_args[1]["json"] == {"name": "Minimal"} + + async def test_get_pipeline(client: ApolloClient): """Test GET /opportunity_pipelines/{id} returns Pipeline.""" client._client.request.return_value = _make_response(