mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
Fix import error bugs when importing P6XML to enterprise environments
This commit is contained in:
+50
-19
@@ -34,6 +34,8 @@ class Ifc2P6:
|
||||
self.element_map = {}
|
||||
self.hours_per_day = 8
|
||||
self.project_tasks = []
|
||||
self.starts = []
|
||||
self.finishes = []
|
||||
# P6XML does not understand patterns in holiday dates. Instead, it
|
||||
# expects a list of every day that is a holiday between a date range.
|
||||
# This allows you to specify the date range where the export should
|
||||
@@ -51,8 +53,8 @@ class Ifc2P6:
|
||||
|
||||
self.schedule = self.file.by_type("IfcWorkSchedule")[0]
|
||||
|
||||
self.create_obs()
|
||||
self.create_calendars()
|
||||
# It seems as though OBSes aren't necessary and cause permission issues on P6 enterprise setups
|
||||
# self.create_obs()
|
||||
self.create_projects()
|
||||
|
||||
tree = ET.ElementTree(self.root)
|
||||
@@ -65,14 +67,23 @@ class Ifc2P6:
|
||||
ET.SubElement(obs, "Id").text = element.Name or "X"
|
||||
ET.SubElement(obs, "Name").text = element.LongName or "Unnamed"
|
||||
|
||||
def create_calendars(self):
|
||||
def create_calendars(self, work_schedule):
|
||||
for calendar in self.file.by_type("IfcWorkCalendar"):
|
||||
self.create_calendar(calendar)
|
||||
self.create_calendar(calendar, work_schedule)
|
||||
|
||||
def create_calendar(self, calendar):
|
||||
el = ET.SubElement(self.root, "Calendar")
|
||||
def create_calendar(self, calendar, work_schedule):
|
||||
el = ET.SubElement(self.element_map[work_schedule], "Calendar")
|
||||
ET.SubElement(el, "Name").text = calendar.Name or "Unnamed"
|
||||
self.link_element(calendar, el)
|
||||
ET.SubElement(el, "BaseCalendarObjectId")
|
||||
ET.SubElement(el, "HoursPerDay").text = "8"
|
||||
ET.SubElement(el, "HoursPerMonth").text = "172"
|
||||
ET.SubElement(el, "HoursPerWeek").text = "40"
|
||||
ET.SubElement(el, "HoursPerYear").text = "2000"
|
||||
ET.SubElement(el, "IsDefault").text = "0"
|
||||
ET.SubElement(el, "IsPersonal").text = "0"
|
||||
ET.SubElement(el, "ProjectObjectId").text = self.id_map[work_schedule]
|
||||
ET.SubElement(el, "Type").text = "Project"
|
||||
|
||||
working_week = self.auto_detect_working_week(calendar)
|
||||
|
||||
@@ -81,13 +92,17 @@ class Ifc2P6:
|
||||
|
||||
work_week = ET.SubElement(el, "StandardWorkWeek")
|
||||
|
||||
for day, time_periods in working_week.items():
|
||||
for day in ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]:
|
||||
work_hours = ET.SubElement(work_week, "StandardWorkHours")
|
||||
day = ET.SubElement(work_hours, "DayOfWeek").text = day
|
||||
for time_period in time_periods:
|
||||
work_time = ET.SubElement(work_hours, "WorkTime")
|
||||
ET.SubElement(work_time, "Start").text = time_period["Start"]
|
||||
ET.SubElement(work_time, "Finish").text = time_period["Finish"]
|
||||
ET.SubElement(work_hours, "DayOfWeek").text = day
|
||||
if day in working_week:
|
||||
print(working_week)
|
||||
for time_period in working_week[day]:
|
||||
work_time = ET.SubElement(work_hours, "WorkTime")
|
||||
ET.SubElement(work_time, "Start").text = time_period["Start"]
|
||||
ET.SubElement(work_time, "Finish").text = time_period["Finish"]
|
||||
else:
|
||||
ET.SubElement(work_hours, "WorkTime")
|
||||
|
||||
holidays = ET.SubElement(el, "HolidayOrExceptions")
|
||||
for holiday in self.auto_detect_holidays(calendar):
|
||||
@@ -152,24 +167,34 @@ class Ifc2P6:
|
||||
def create_project(self, work_schedule):
|
||||
project = ET.SubElement(self.root, "Project")
|
||||
self.link_element(work_schedule, project)
|
||||
|
||||
ET.SubElement(project, "ActivityDefaultCalendarObjectId").text = self.id_map[
|
||||
self.file.by_type("IfcWorkCalendar")[0]
|
||||
]
|
||||
activity_calendar = ET.SubElement(project, "ActivityDefaultCalendarObjectId")
|
||||
ET.SubElement(project, "Name").text = work_schedule.Name or "Unnamed"
|
||||
ET.SubElement(project, "Id").text = work_schedule.Identification or "X"
|
||||
ET.SubElement(project, "OBSObjectId").text = self.id_map[self.file.by_type("IfcProject")[0]]
|
||||
data_date = ET.SubElement(project, "DataDate")
|
||||
planned_start_date = ET.SubElement(project, "PlannedStartDate")
|
||||
# ET.SubElement(project, "OBSObjectId").text = self.id_map[self.file.by_type("IfcProject")[0]]
|
||||
|
||||
# Note: order matters for P6 enterprise imports.
|
||||
# Root elements like Name must come first. Then calendar, WBS, activities, and relationships.
|
||||
# Changing the order will result in import failures (but not for all P6 versions, it seems?)
|
||||
self.create_calendars(work_schedule)
|
||||
self.project_tasks = []
|
||||
self.activities = []
|
||||
self.create_wbs(self.get_subtasks(work_schedule), work_schedule)
|
||||
self.create_activities()
|
||||
self.create_relationships(self.project_tasks, work_schedule)
|
||||
|
||||
activity_calendar.text = self.id_map[self.file.by_type("IfcWorkCalendar")[0]]
|
||||
start_date = sorted(self.starts)[0]
|
||||
data_date.text = start_date
|
||||
planned_start_date.text = start_date
|
||||
|
||||
def create_wbs(self, tasks, work_schedule, parent=None):
|
||||
self.project_tasks.extend(tasks)
|
||||
for task in tasks:
|
||||
subtasks = self.get_subtasks(task)
|
||||
if not subtasks:
|
||||
self.create_activity(task, work_schedule, parent=parent)
|
||||
self.activities.append({"task": task, "work_schedule": work_schedule, "parent": parent})
|
||||
continue
|
||||
wbs = ET.SubElement(self.element_map[work_schedule], "WBS")
|
||||
self.link_element(task, wbs)
|
||||
@@ -181,6 +206,10 @@ class Ifc2P6:
|
||||
ET.SubElement(wbs, "ProjectObjectId").text = self.id_map[work_schedule]
|
||||
self.create_wbs(subtasks, work_schedule, parent=task)
|
||||
|
||||
def create_activities(self):
|
||||
for activity in self.activities:
|
||||
self.create_activity(activity["task"], activity["work_schedule"], parent=activity["parent"])
|
||||
|
||||
def create_activity(self, task, work_schedule, parent=None):
|
||||
if not parent:
|
||||
return
|
||||
@@ -198,9 +227,11 @@ class Ifc2P6:
|
||||
if task.TaskTime.ScheduleStart:
|
||||
ET.SubElement(activity, "PlannedStartDate").text = task.TaskTime.ScheduleStart
|
||||
ET.SubElement(activity, "StartDate").text = task.TaskTime.ScheduleStart
|
||||
self.starts.append(task.TaskTime.ScheduleStart)
|
||||
if task.TaskTime.ScheduleFinish:
|
||||
ET.SubElement(activity, "PlannedFinishDate").text = task.TaskTime.ScheduleFinish
|
||||
ET.SubElement(activity, "FinishDate").text = task.TaskTime.ScheduleFinish
|
||||
self.finishes.append(task.TaskTime.ScheduleFinish)
|
||||
ET.SubElement(activity, "ProjectObjectId").text = self.id_map[work_schedule]
|
||||
ET.SubElement(activity, "ActualDuration").text = "0"
|
||||
ET.SubElement(activity, "ActualFinishDate")
|
||||
@@ -218,7 +249,7 @@ class Ifc2P6:
|
||||
"RemainingLateFinishDate": task.TaskTime.LateFinish,
|
||||
}
|
||||
for key, value in data_map.items():
|
||||
el = ET.SubElement(activity, "RemainingEarlyStartDate")
|
||||
el = ET.SubElement(activity, key)
|
||||
if value:
|
||||
el.text = value
|
||||
|
||||
|
||||
Reference in New Issue
Block a user