{
	"info": {
		"_postman_id": "9a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
		"name": "Maintenance - Unscheduled (Evaluation) Visits",
		"description": "Collection for testing Unscheduled Visits (Evaluation phase), including asset registration, difficulty assignment, and conversion to Price Offers.",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "Case 1: Happy Path (Evaluation to Quotation)",
			"item": [
				{
					"name": "1. Register Discovered Assets",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Assets Registered Successfully\", function () {",
									"    pm.response.to.have.status(200);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"assets\": [\n        {\n            \"asset_type\": \"Chiller\",\n            \"fault_description\": \"Noisy compressor\",\n            \"brand\": \"York\",\n            \"model\": \"YVAA\",\n            \"serial_number\": \"SN123456\"\n        },\n        {\n            \"asset_type\": \"Package Unit\",\n            \"fault_description\": \"Low refrigerant\",\n            \"brand\": \"Carrier\"\n        }\n    ]\n}"
						},
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/visits/{{visitId}}/report/new-assets",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"visits",
								"{{visitId}}",
								"report",
								"new-assets"
							]
						},
						"description": "Technician registers equipment discovered during the evaluation visit."
					},
					"response": []
				},
				{
					"name": "2. Define Labor Complexity",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Difficulty Updated\", function () {",
									"    pm.response.to.have.status(200);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"difficulty\": \"high\"\n}"
						},
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/visits/{{visitId}}/report/difficulty",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"visits",
								"{{visitId}}",
								"report",
								"difficulty"
							]
						},
						"description": "Set the work difficulty to influence labor pricing in the quotation."
					},
					"response": []
				},
				{
					"name": "3. Apply Inspection Fee",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Fee Applied\", function () {",
									"    pm.response.to.have.status(200);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "PATCH",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"fee\": 500\n}"
						},
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/visits/{{visitId}}/report/inspection-fee",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"visits",
								"{{visitId}}",
								"report",
								"inspection-fee"
							]
						},
						"description": "Set a billable fee for the evaluation visit itself."
					},
					"response": []
				},
				{
					"name": "4. Auto-Generate Quote (Convert to Offer)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Converted to Price Offer\", function () {",
									"    pm.response.to.have.status(200);",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.id).to.not.be.null;",
									"    pm.expect(jsonData.items).to.be.an('array');",
									"    pm.collectionVariables.set(\"offerId\", jsonData.id);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/visits/{{visitId}}/report/convert-to-offer",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"visits",
								"{{visitId}}",
								"report",
								"convert-to-offer"
							]
						},
						"description": "Convert the evaluation findings into a formal Price Offer."
					},
					"response": []
				}
			]
		},
		{
			"name": "Case 2: Constraints & Legacy Data",
			"item": [
				{
					"name": "1. Constraint: Convert Preventive Visit",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Blocked: Only Unscheduled Visits Allowed\", function () {",
									"    pm.expect(pm.response.code).to.be.oneOf([422, 400, 500]);",
									"    pm.expect(pm.response.json().message).to.contain(\"unscheduled\");",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/visits/{{preventiveVisitId}}/report/convert-to-offer",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"visits",
								"{{preventiveVisitId}}",
								"report",
								"convert-to-offer"
							]
						},
						"description": "Attempt to convert a preventive visit report to an offer. Should fail."
					},
					"response": []
				},
				{
					"name": "2. Legacy Data Check",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Handles Legacy Nulls Safely\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.data).to.have.property('work_difficulty');",
									"    pm.expect(jsonData.data).to.have.property('inspection_visit_fee');",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/reports/{{legacyReportId}}",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"reports",
								"{{legacyReportId}}"
							]
						},
						"description": "Ensure the API response returns null for new fields on old reports without crashing."
					},
					"response": []
				}
			]
		},
		{
			"name": "Case 3: Edge Cases & Rejection",
			"item": [
				{
					"name": "1. Block Rejection for Corrective Only",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Blocked: Requires Unscheduled Visit\", function () {",
									"    pm.expect(pm.response.code).to.be.oneOf([400, 422, 500]);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"reason\": \"Customer found it too expensive\"\n}"
						},
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/requests/{{correctiveRequestId}}/reject-quote",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"requests",
								"{{correctiveRequestId}}",
								"reject-quote"
							]
						},
						"description": "Attempt to reject a quote for a request that has no evaluation visits. Should fail."
					},
					"response": []
				},
				{
					"name": "2. Reject Quote (Valid)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Quotation Rejected Successfully\", function () {",
									"    pm.response.to.have.status(200);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"reason\": \"Client decided to postpone the work\"\n}"
						},
						"url": {
							"raw": "{{baseUrl}}/api/maintenance/requests/{{requestId}}/reject-quote",
							"host": [
								"{{baseUrl}}"
							],
							"path": [
								"api",
								"maintenance",
								"requests",
								"{{requestId}}",
								"reject-quote"
							]
						},
						"description": "Reject the offer and automatically cancel the maintenance request."
					},
					"response": []
				}
			]
		}
	],
	"variable": [
		{
			"key": "baseUrl",
			"value": "https://api.example.com"
		},
		{
			"key": "visitId",
			"value": "101"
		},
		{
			"key": "requestId",
			"value": "202"
		},
		{
			"key": "preventiveVisitId",
			"value": "303"
		},
		{
			"key": "legacyReportId",
			"value": "404"
		},
		{
			"key": "correctiveRequestId",
			"value": "505"
		}
	]
}
