Fix astapowerproject import to ifc which seemed mostly broken for some reason

This commit is contained in:
Dion Moult
2022-11-11 11:37:56 +11:00
parent ff984f62af
commit a7febaa9b0
2 changed files with 125 additions and 141 deletions
+99 -116
View File
@@ -1,6 +1,7 @@
print("In module products __package__, __name__ ==", __package__)
print(__name__)
import sys
import sys
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)
sys.path.append(sys.path[0])
@@ -16,20 +17,20 @@ from .common import ScheduleIfcGenerator
import time
list_of_tables = [
'BAR',
'EXPANDED_TASK',
'PERMANENT_RESOURCE',
'CONSUMABLE_RESOURCE',
'TASK',
'PROJECT_SUMMARY',
'WBS_ENTRY'
"BAR",
"EXPANDED_TASK",
"PERMANENT_RESOURCE",
"CONSUMABLE_RESOURCE",
"TASK",
"PROJECT_SUMMARY",
"WBS_ENTRY",
]
class PP2Ifc:
def __init__(self):
self.pp = None
self.file = None
self.work_plan = None
@@ -41,30 +42,14 @@ class PP2Ifc:
self.relationships = {}
self.resources = {}
self.output = None
self.day_map = {
"Monday": 1,
"Tuesday": 2,
"Wednesday": 3,
"Thursday": 4,
"Friday": 5,
"Saturday": 6,
"Sunday": 7,
}
self.relationship_map = {
0: "FINISH_START",
1: "FINISH_FINISH",
2: "START_START",
3: "START_FINISH"
}
self.relationship_map = {0: "FINISH_START", 1: "FINISH_FINISH", 2: "START_START", 3: "START_FINISH"}
def get_json(self, table_name):
self.cur.execute("select * from " + table_name)
self.cur.execute("select * from " + table_name)
r = [dict((self.cur.description[i][0], value) for i, value in enumerate(row)) for row in self.cur.fetchall()]
return r
def get_json_with_filter(self, table_name, attr_name, attr_value):
self.cur.execute("select * from " + table_name + " where " + attr_name + " = " + str(attr_value))
r = [dict((self.cur.description[i][0], value) for i, value in enumerate(row)) for row in self.cur.fetchall()]
@@ -75,19 +60,19 @@ class PP2Ifc:
self.cur = self.con.cursor()
self.parse_pp()
settings = {
"work_plan":self.work_plan,
"work_plan": self.work_plan,
"project": self.project,
"calendars": self.calendars,
"wbs": self.wbs,
"root_activities": self.root_activites,
"activities": self.activities,
"relationships": self.relationships,
"resources": self.resources
"resources": self.resources,
}
start = time.time()
ifcCreator = ScheduleIfcGenerator(self.file, self.output, settings)
end = time.time()
ifcCreator.create_ifc()
end2 = time.time()
print("Parsing time is", end - start)
@@ -96,34 +81,35 @@ class PP2Ifc:
# self.create_ifc()
def parse_pp(self):
project = self.get_json("PROJECT_SUMMARY")[0]
self.project["Name"] = project["SHORT_NAME"]
self.parse_calendar_pp()
self.parse_wbs_pp()
self.parse_activity_pp()
self.parse_bar()
self.parse_relationship_pp(project)
def parse_calendar_pp(self):
calendars = self.get_json("CALENDAR")
wp_data = self.get_json("WORK_PATTERN")
work_types = self.get_json("EXCEPTIONN")
work_type_ids = [wt['ID'] for wt in work_types if wt['EXCEPTION_TYPE'] == 0]
work_type_ids = [wt["ID"] for wt in work_types if wt["EXCEPTION_TYPE"] == 0]
for calendar in calendars:
calendar_id = calendar["ID"]
calendar_wp = calendar["DOMINANT_WORK_PATTERN"]
wp_data = self.get_json_with_filter("WORK_PATTERN", "ID", calendar_wp)
wp = AstaCalendarWorkPattern(wp_data[0]['SHIFTS'], work_type_ids)
wp = AstaCalendarWorkPattern(wp_data[0]["SHIFTS"], work_type_ids)
exceptions = {}
timex = []
for times in wp.dict_wp:
work_times = timedelta(hours=0)
for daily in times['WorkTimes']:
fin = daily['Finish']
strt = daily['Start']
work_times += timedelta(hours=fin.hour, minutes=fin.minute) - timedelta(hours=strt.hour, minutes=strt.minute)
timex.append(work_times.total_seconds() /(60*60))
for daily in times["WorkTimes"]:
fin = daily["Finish"]
strt = daily["Start"]
work_times += timedelta(hours=fin.hour, minutes=fin.minute) - timedelta(
hours=strt.hour, minutes=strt.minute
)
timex.append(work_times.total_seconds() / (60 * 60))
self.calendars[calendar_id] = {
"Name": calendar["NAME"],
@@ -132,87 +118,84 @@ class PP2Ifc:
"StandardWorkWeek": wp.dict_wp,
"HolidayOrExceptions": exceptions,
}
#print(self.calendars[calendar_id])
# print(self.calendars[calendar_id])
def parse_wbs_pp(self):
def parse_bar(self):
bars = self.get_json("BAR")
extended_tasks = self.get_json("EXPANDED_TASK")
expanded_tasks = {t["BAR"]: t for t in self.get_json("EXPANDED_TASK")}
tasks = {t["BAR"]: t for t in self.get_json("TASK")}
milestones = {m["BAR"]: m for m in self.get_json("MILESTONE")}
schedule_task = None
bar_tasks = {}
wbs_activities = {}
for bar in bars:
self.wbs[bar["ID"]] = {
"Name": bar["NAME"],
"Code": bar["ID"],
"ParentObjectId": bar["EXPANDED_TASK"] if bar["EXPANDED_TASK"]> 0 else None,
"ifc": None,
"rel": None,
"activities": [],
}
for bar in extended_tasks:
self.wbs[bar["ID"]] = {
"Name": bar["NAME"],
"Code": bar["ID"],
"ParentObjectId": bar["BAR"] if bar["BAR"]> 0 else None,
"ifc": None,
"rel": None,
"activities": [],
}
#print(self.wbs)
extra_type = None
extra_data = None
bar_id = None
def parse_activity_pp(self):
activities = self.get_json("TASK")
milestones = self.get_json("MILESTONE")
for activity in activities:
activity_type = "TASK"
activity_id = activity["ID"]
if 'PLANNED_DURATION' in activity.keys():
activity_duration = float(activity["PLANNED_DURATION"].split(",")[-2].replace("<","").replace(">",""))
elif 'GIVEN_DURATION' in activity.keys():
activity_duration = float(activity["GIVEN_DURATION"].split(",")[-2].replace("<","").replace(">",""))
if bar["ID"] in expanded_tasks:
extra_type = "EXPANDED_TASK"
extra_data = expanded_tasks[bar["ID"]]
elif bar["ID"] in tasks:
extra_type = "TASK"
extra_data = tasks[bar["ID"]]
elif bar["ID"] in milestones:
extra_type = "MILESTONE"
extra_data = milestones[bar["ID"]]
else:
activity_duration = 0.0
# Not sure where this might be the case
continue
wbs_id = activity["BAR"]
if wbs_id:
self.wbs[wbs_id]["activities"].append(activity_id)
name = bar["NAME"]
if extra_data["NAME"]:
name += f" - {extra_data['NAME']}"
bar_tasks[extra_data["ID"]] = {"bar": bar, "extra_type": extra_type, "extra_data": extra_data}
if extra_type == "EXPANDED_TASK":
self.wbs[extra_data["ID"]] = {
"Name": name,
"Code": extra_data["ID"],
"ParentObjectId": bar["EXPANDED_TASK"] if bar["EXPANDED_TASK"] > 0 else None,
"ifc": None,
"rel": None,
"activities": [],
}
else:
self.root_activites.append(activity_id)
self.activities[activity_id] = {
"Name": activity["NAME"],
"Identification": activity["ID"],
"StartDate": datetime.datetime.fromisoformat(activity["LINKABLE_START"]),
"FinishDate": datetime.datetime.fromisoformat(activity["LINKABLE_FINISH"]),
"PlannedDuration": activity_duration,
"Status": "PLANNED",
"CalendarObjectId": activity["CALENDAR"],
"ifc": None,
}
for activity in milestones:
activity_type = "MILESTONE"
activity_id = activity["ID"]
wbs_id = activity["BAR"]
if wbs_id:
self.wbs[wbs_id]["activities"].append(activity_id)
else:
self.root_activites.append(activity_id)
self.activities[activity_id] = {
"Name": activity["NAME"],
"Identification": activity["ID"],
"StartDate": datetime.datetime.fromisoformat(activity["LINKABLE_START"]),
"FinishDate": datetime.datetime.fromisoformat(activity["LINKABLE_FINISH"]),
"PlannedDuration": 0.0,
"Status": "PLANNED",
"CalendarObjectId": activity["CALENDAR"],
"ifc": None,
}
#print("***ACTIVITIES", self.activities[activity_id])
if "PLANNED_DURATION" in extra_data.keys():
activity_duration = float(
extra_data["PLANNED_DURATION"].split(",")[-2].replace("<", "").replace(">", "")
)
elif "GIVEN_DURATION" in extra_data.keys():
activity_duration = float(
extra_data["GIVEN_DURATION"].split(",")[-2].replace("<", "").replace(">", "")
)
else:
activity_duration = 0.0
self.activities[extra_data["ID"]] = {
"Name": name,
"Identification": extra_data["ID"],
"StartDate": datetime.datetime.fromisoformat(extra_data["LINKABLE_START"]),
"FinishDate": datetime.datetime.fromisoformat(extra_data["LINKABLE_FINISH"]),
"PlannedDuration": activity_duration,
"Status": "PLANNED",
"CalendarObjectId": extra_data["CALENDAR"],
"ifc": None,
}
wbs_activities.setdefault(bar["EXPANDED_TASK"], []).append(extra_data["ID"])
for wbs, activities in wbs_activities.items():
self.wbs[wbs]["activities"] = activities
def parse_relationship_pp(self, project):
relations = self.get_json('LINK')
print(relations)
relations = self.get_json("LINK")
# print(relations)
for relationship in relations:
predecessor = relationship['START_TASK']
successor = relationship['END_TASK']
predecessor = relationship["START_TASK"]
successor = relationship["END_TASK"]
if predecessor not in self.activities:
print(f"Linked predecessor task {predecessor} cannot be found.")
continue
@@ -222,6 +205,6 @@ class PP2Ifc:
self.relationships[relationship["ID"]] = {
"PredecessorActivity": predecessor,
"SuccessorActivity": successor,
"Type": self.relationship_map[relationship['LINK_KIND']],
"Lag": float(relationship['END_LAG_TIME'].split(",")[-2].replace("<","").replace(">","")),
"Type": self.relationship_map[relationship["LINK_KIND"]],
"Lag": float(relationship["END_LAG_TIME"].split(",")[-2].replace("<", "").replace(">", "")),
}
+26 -25
View File
@@ -10,28 +10,27 @@ import re
from datetime import time, datetime
class AstaCalendarWorkPattern:
def get_keys(self, s):
regex = r"\<(\".+?\")\>(\w|\d|)+?"
matches=re.finditer(regex, s)
matches = re.finditer(regex, s)
matcs = []
for matchNum, match in enumerate(matches, start=1):
matcs.append(match.group(1))
return matcs
return matcs
def get_values(self, s):
rx2 = r"<\"[^<>]+\">"
data = re.split('<[^<>]+>', s)
data = re.split("<[^<>]+>", s)
return data
def __init__(self, string, work_type_ids):
self.string = string
self.Days = {
'en': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
'sv': ['Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag'],
"en": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"sv": ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"],
"de": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
}
self.keys = self.get_keys(string)
self.values = self.get_values(string)
@@ -40,29 +39,31 @@ class AstaCalendarWorkPattern:
for d, m in zip(self.values[1:], self.keys):
splt_data = d.strip().split(",")
workhours = []
if len(splt_data)>=7:
if len(splt_data) >= 7:
number_of_work_slots = splt_data[1]
for i in range(int(number_of_work_slots)):
if int(splt_data[2+i*3]) in work_type_ids:
st1_1 = datetime.strptime(splt_data[2+i*3+1].ljust(5,'0'), "%H%M%S")
st1_2 = datetime.strptime(splt_data[2+i*3+2].ljust(5,'0'), "%H%M%S")
st = {"Start":time(st1_1.hour, st1_1.minute), "Finish": time(st1_2.hour, st1_2.minute), "ifc": None}
if int(splt_data[2 + i * 3]) in work_type_ids:
st1_1 = datetime.strptime(splt_data[2 + i * 3 + 1].ljust(5, "0"), "%H%M%S")
st1_2 = datetime.strptime(splt_data[2 + i * 3 + 2].ljust(5, "0"), "%H%M%S")
st = {
"Start": time(st1_1.hour, st1_1.minute),
"Finish": time(st1_2.hour, st1_2.minute),
"ifc": None,
}
workhours.append(st)
self.dict_wp.append({'DayOfWeek': m.replace("\"",""),
'WorkTimes': workhours, "ifc": None})
self.dict_wp.append({"DayOfWeek": m.replace('"', ""), "WorkTimes": workhours, "ifc": None})
# Translate day names to english
for index, day in enumerate(self.Days['en']):
d = self.dict_wp[-1]['DayOfWeek']
for index, day in enumerate(self.Days["en"]):
d = self.dict_wp[-1]["DayOfWeek"]
for lang in self.Days.keys():
if lang == 'en':
if lang == "en":
continue
self.dict_wp[-1]['DayOfWeek'] = d.replace(self.Days[lang][index], self.Days['en'][index])
for day in self.Days['en']:
if not len(list(filter(lambda d: d['DayOfWeek']== day , self.dict_wp))) > 0:
self.dict_wp[-1]["DayOfWeek"] = d.replace(self.Days[lang][index], self.Days["en"][index])
for day in self.Days["en"]:
if not len(list(filter(lambda d: d["DayOfWeek"] == day, self.dict_wp))) > 0:
print("MISSING", day)
self.dict_wp.append({'DayOfWeek': day,
'WorkTimes': [], "ifc": None})
self.dict_wp.append({"DayOfWeek": day, "WorkTimes": [], "ifc": None})
print("final", self.dict_wp)