diff --git a/wrike_monitor.py b/wrike_monitor.py index 97da710..a8252f7 100644 --- a/wrike_monitor.py +++ b/wrike_monitor.py @@ -415,40 +415,106 @@ class WrikeMonitor: return task["id"] return None - def create_deliverable_task(self, project_id, job_details): - """Create deliverable task (skip if exists)""" - task_title = job_details.get("Title", "Untitled Task") + def find_deliverable_by_omg_number(self, parent_project_id, omg_number): + """Find deliverable (project) with matching OMG number""" + if not omg_number: + return None + + # Get folder tree + result = self.make_wrike_request("GET", f"/folders/{parent_project_id}/folders?fields=[\"customFields\",\"project\"]") + + if result and "data" in result: + # Find parent folder with childIds + parent_folder = None + for item in result["data"]: + if item["id"] == parent_project_id: + parent_folder = item + break + + if parent_folder: + child_ids = parent_folder.get("childIds", []) + # Search only in direct children that are projects + for item in result["data"]: + if item["id"] in child_ids and "project" in item: + custom_fields = item.get("customFields", []) + for field in custom_fields: + if field.get("id") == Config.CUSTOM_FIELDS["omg_number"]: + if field.get("value") == omg_number: + return item["id"] + return None + + def generate_omg_url(self, omg_number): + """Generate OMG URL from OMG number (subtract 999999)""" + try: + omg_int = int(omg_number) + job_id = omg_int - 999999 + return f"https://bissell.omg.oliver.solutions/jobs/{job_id}" + except (ValueError, TypeError): + return None + + def create_deliverable_project(self, parent_project_id, job_details): + """Create deliverable as a project (not a task) - skip if exists""" + deliverable_title = job_details.get("Title", "Untitled Deliverable") job_number = job_details.get("Number", "") - # Check if exists + # Check if exists by searching for existing deliverable with same OMG# if job_number: - existing_task_id = self.find_task_by_omg_number(project_id, job_number) - if existing_task_id: - self.logger.info(f"⊙ Task already exists: {task_title} (#{job_number}) - skipping") - return existing_task_id, True # Return (task_id, skipped=True) + existing_deliverable_id = self.find_deliverable_by_omg_number(parent_project_id, job_number) + if existing_deliverable_id: + self.logger.info(f"⊙ Deliverable already exists: {deliverable_title} (#{job_number}) - skipping") + return existing_deliverable_id, True # Return (deliverable_id, skipped=True) - # Parse dates - due_date = self.parse_date(job_details.get("DueDate")) + # Parse dates - use BriefDate as start, LiveDate (or DueDate) as end brief_date = self.parse_date(job_details.get("BriefDate")) + live_date = self.parse_date(job_details.get("LiveDate")) or self.parse_date(job_details.get("DueDate")) - # Create task - task_data = { - "title": task_title, - "description": job_details.get("Notes", ""), + # Build description + description_parts = [] + if job_details.get("Notes"): + description_parts.append(job_details["Notes"]) + if job_details.get("Type"): + description_parts.append(f"Type: {job_details['Type']}") + if job_details.get("MediaType"): + description_parts.append(f"Media: {job_details['MediaType']}") + + deliverable_description = " | ".join(description_parts) if description_parts else "" + + # Create deliverable as a project (subfolder) + deliverable_data = { + "title": deliverable_title, + "description": deliverable_description } - if due_date: - task_data["dates"] = {"due": due_date} - if brief_date: - task_data["dates"]["start"] = brief_date + result = self.make_wrike_request("POST", f"/folders/{parent_project_id}/folders", deliverable_data) - result = self.make_wrike_request("POST", f"/folders/{project_id}/tasks", task_data) if result and "data" in result and len(result["data"]) > 0: - task_id = result["data"][0]["id"] + deliverable_id = result["data"][0]["id"] + + # Convert to project with dates + project_data = {"project": {}} + if brief_date: + project_data["project"]["startDate"] = brief_date + if live_date: + project_data["project"]["endDate"] = live_date # Add custom fields custom_fields = [] + # For deliverables: OMG# field gets the URL, not just the number + if job_number: + omg_url = self.generate_omg_url(job_number) + if omg_url: + custom_fields.append({ + "id": Config.CUSTOM_FIELDS["omg_number"], + "value": omg_url + }) + else: + # Fallback to just the number if URL generation fails + custom_fields.append({ + "id": Config.CUSTOM_FIELDS["omg_number"], + "value": job_number + }) + job_category = job_details.get("JobCategory", job_details.get("MediaType", "")) if job_category: custom_fields.append({ @@ -456,12 +522,6 @@ class WrikeMonitor: "value": job_category }) - if job_number: - custom_fields.append({ - "id": Config.CUSTOM_FIELDS["omg_number"], - "value": job_number - }) - notes_parts = [] if job_details.get("Type"): notes_parts.append(f"Type: {job_details['Type']}") @@ -474,10 +534,13 @@ class WrikeMonitor: }) if custom_fields: - self.make_wrike_request("PUT", f"/tasks/{task_id}", {"customFields": custom_fields}) + project_data["customFields"] = custom_fields - self.logger.info(f"Created task: {task_title} (#{job_number})") - return task_id, False # Return (task_id, skipped=False) + # Update with project dates and custom fields + self.make_wrike_request("PUT", f"/folders/{deliverable_id}", project_data) + + self.logger.info(f"✓ Created deliverable (as project): {deliverable_title} (#{job_number})") + return deliverable_id, False # Return (deliverable_id, skipped=False) return None, False @@ -514,10 +577,10 @@ class WrikeMonitor: if not project_id: raise ValueError(f"Failed to create project: {project_title}") - # Create task - task_id, skipped = self.create_deliverable_task(project_id, job_details) - if not task_id: - raise ValueError("Failed to create task") + # Create deliverable (as project) + deliverable_id, skipped = self.create_deliverable_project(project_id, job_details) + if not deliverable_id: + raise ValueError("Failed to create deliverable") processing_time = time.time() - start_time