Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
I
integrated-scheduling-v3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张晓彤
integrated-scheduling-v3
Commits
93958978
Commit
93958978
authored
Jun 11, 2022
by
z5335534 Ao Guo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
info层修改,table表修改
parent
287a4a43
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
78 deletions
+141
-78
dispatchInfo.cpython-37.pyc
data/__pycache__/dispatchInfo.cpython-37.pyc
+0
-0
dispatchInfo.py
data/dispatchInfo.py
+132
-69
tables.py
tables.py
+9
-9
No files found.
data/__pycache__/dispatchInfo.cpython-37.pyc
View file @
93958978
No preview for this file type
data/dispatchInfo.py
View file @
93958978
...
...
@@ -16,18 +16,20 @@ class DispatchInfo:
"""
class for dispatch group info.
"""
# dispatch groups
group_set
=
set
()
# device group structure
group_dump_dict
=
{}
# team_id -> dict {unload_area_id, unload_area_id, ...}
load_excavator_dict
=
{}
# 装载区id-->>电铲编号的映射
excavator_load_dict
=
{}
# 电铲编号->>装载区id的映射
group_excavator_dict
=
{}
# team_id -> dict {[excavator_id, excavator_id], ...}
load_exactor_dict
=
{}
# 装载区id-->>电铲编号的映射
exactor_load_dict
=
{}
# 电铲编号->>装载区id的映射
group_truck_dict
=
{}
# team_id -> dict # {group_id:[truck_id,truck_id],...}
dump_group_dict
=
{}
# unload_area_id -> team_id
excavator_group_dict
=
{}
# excavator_id -> team_id 问题:多个key值对应一个value值
group_dump_dict
=
{}
# team_id -> dict {unload_area_id, unload_area_id, ...}
dump_group_dict
=
{}
# unload_area_id -> team_id
group_truck_dict
=
{}
# team_id -> dict # {group_id:[truck_id,truck_id],...}
truck_group_dict
=
{}
# truck_id -> team_id
# group feature
...
...
@@ -44,18 +46,34 @@ class DispatchInfo:
@author:maqc
@desc:实例化对象,可直接访问
"""
cls
.
load_excavator_dict
=
{}
cls
.
excavator_load_dict
=
{}
cls
.
group_dump_dict
=
{}
# cls.group_dump_dict.keys() 相当于所有的team_id
cls
.
dump_group_dict
=
{}
# cls.dump_group_dict.keys() 相当于所有的卸载区 unload_area_id
cls
.
group_excavator_dict
=
{}
cls
.
excavator_group_dict
=
{}
cls
.
load_exactor_dict
=
{}
# cls.load_exactor_dict.keys() 相当于所有的装载区 load_area_id
cls
.
exactor_load_dict
=
{}
cls
.
group_dump_dict
=
{}
cls
.
dump_group_dict
=
{}
cls
.
group_truck_dict
=
{}
cls
.
truck_group_dict
=
{}
cls
.
group_mode
=
{}
cls
.
load_distance
=
{}
# to_load_diatance-->>空车模式
cls
.
unload_distance
=
{}
# to_unload_distance-->>重车模式
cls
.
load_distance
=
{}
cls
.
unload_distance
=
{}
# cls.group_dump_dict = {} # cls.group_dump_dict.keys() 相当于所有的team_id
# cls.dump_group_dict = {} # cls.dump_group_dict.keys() 相当于所有的卸载区 unload_area_id
# cls.group_excavator_dict = {}
# cls.excavator_group_dict = {}
# cls.load_excavator_dict = {} # cls.load_excavator_dict.keys() 相当于所有的装载区 load_area_id
# cls.excavator_load_dict = {}
# cls.group_truck_dict = {}
# cls.truck_group_dict = {}
# cls.group_mode = {}
# cls.load_distance = {} # to_load_diatance-->>空车模式
# cls.unload_distance = {} # to_unload_distance-->>重车模式
@classmethod
def
update_device_group_structure
(
cls
):
...
...
@@ -64,48 +82,80 @@ class DispatchInfo:
@author:maqc
@desc:分组与卸载区、挖机、矿卡的映射和反映射
"""
#
建立挖机和装载区映射
#
build excavator group map
logger
=
get_logger
(
"mqc.update_device_group_structure"
)
try
:
for
value
in
session_postgre
.
query
(
DiggingWorkArea
)
.
all
():
cls
.
load_ex
ac
tor_dict
[
value
.
Id
]
=
value
.
ExactorId
cls
.
ex
ac
tor_load_dict
[
value
.
ExactorId
]
=
value
.
Id
cls
.
load_ex
cava
tor_dict
[
value
.
Id
]
=
value
.
ExactorId
cls
.
ex
cava
tor_load_dict
[
value
.
ExactorId
]
=
value
.
Id
except
Exception
as
es
:
logger
.
error
(
"挖机和装载区映射更新异常"
)
logger
.
error
(
es
)
# update excavator<->group and dump<->group map
try
:
# group_dump_dict = {} -->> {team_id:[unload_area_id,unload_area_id],...}
# dump_group_dict = {} # unload_area_id -> team_id
group_code_dict
=
{}
# group_code-->>team_id的映射
for
valve
in
session_mysql
.
query
(
DispatchMatch
)
.
filter_by
(
group_type
=
1
)
.
all
():
group_code_dict
[
valve
.
group_code
]
=
valve
.
team_id
if
valve
.
team_id
not
in
cls
.
group_dump_dict
:
cls
.
group_dump_dict
[
valve
.
team_id
]
=
[
valve
.
unload_area_id
]
# 注意:一个team_id可能对应多个unload_area_id
else
:
cls
.
group_dump_dict
[
valve
.
team_id
]
.
append
(
valve
.
unload_area_id
)
cls
.
dump_group_dict
[
valve
.
unload_area_id
]
=
valve
.
team_id
# 一个unload_area_id只对应一个team_id
# group_excavator_dict = {} -->> {team_id: [excavator_id, excavator_id], ...} # 一个team_id对应一组excavator_id, unload_area_id
# excavator_group_dict = {} -->> excavator_id -> team_id 一个excavator_id只对应一个team_id
for
item
in
session_mysql
.
query
(
DispatchMatch
)
.
filter_by
(
group_type
=
1
)
.
all
():
if
item
.
team_id
in
cls
.
group_excavator_dict
:
cls
.
group_excavator_dict
[
item
.
team_id
]
.
append
(
item
.
exactor_id
)
if
item
.
group_code
not
in
cls
.
group_excavator_dict
.
keys
():
cls
.
group_excavator_dict
[
item
.
group_code
]
=
item
.
excavator_id
else
:
cls
.
group_excavator_dict
[
item
.
team_id
]
=
[
item
.
exactor_id
]
cls
.
excavator_group_dict
[
item
.
exactor_id
]
=
item
.
team_id
# group_truck_dict = {} -->> {team_id:[truck_id,truck_id],...}
# truck_group_dict = {} -->> truck_id -> team_id
for
key
in
session_mysql
.
query
(
DispatchEquipment
)
.
filter_by
(
group_type
=
1
)
.
all
():
if
key
.
group_code
in
group_code_dict
:
if
key
.
group_code
not
in
cls
.
group_truck_dict
:
cls
.
group_truck_dict
[
key
.
group_code
]
=
[
key
.
equipment_id
]
else
:
cls
.
group_truck_dict
[
key
.
group_code
]
.
append
(
key
.
equipment_id
)
cls
.
truck_group_dict
[
key
.
equipment_id
]
=
group_code_dict
[
key
.
group_code
]
cls
.
group_excavator_dict
[
item
.
group_code
]
.
append
(
item
.
excavator_id
)
cls
.
excavator_group_dict
[
item
.
excavator_id
]
=
item
.
group_code
if
item
.
group_code
not
in
cls
.
group_dump_dict
.
keys
():
cls
.
group_dump_dict
[
item
.
group_code
]
=
item
.
dump_area_id
else
:
cls
.
group_dump_dict
[
item
.
group_code
]
.
append
(
item
.
dump_area_id
)
cls
.
dump_group_dict
[
item
.
dump_area_id
]
=
item
.
group_code
except
Exception
as
es
:
logger
.
error
(
"
分组到卸载区的数据
更新异常"
)
logger
.
error
(
"
挖机/卸载区与group_id映射
更新异常"
)
logger
.
error
(
es
)
# update truck<->group map
try
:
for
item
in
session_mysql
.
query
(
DispatchEquipment
)
.
filter_by
(
group_type
=
1
)
.
all
():
if
item
.
group_code
not
in
cls
.
group_truck_dict
.
keys
():
cls
.
group_truck_dict
[
item
.
group_code
]
=
item
.
truck_id
else
:
cls
.
group_truck_dict
[
item
.
group_code
]
.
append
(
item
.
truck_id
)
cls
.
truck_group_dict
[
item
.
truck_id
]
=
item
.
group_code
except
Exception
as
es
:
logger
.
error
(
"矿卡与group_id映射更新异常"
)
logger
.
error
(
es
)
#
# try:
# # group_dump_dict = {} -->> {team_id:[unload_area_id,unload_area_id],...}
# # dump_group_dict = {} # unload_area_id -> team_id
# group_code_dict = {} # group_code-->>team_id的映射
# for valve in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
# group_code_dict[valve.group_code] = valve.team_id
# if valve.team_id not in cls.group_dump_dict:
# cls.group_dump_dict[valve.team_id] = [valve.unload_area_id] # 注意:一个team_id可能对应多个unload_area_id
# else:
# cls.group_dump_dict[valve.team_id].append(valve.unload_area_id)
# cls.dump_group_dict[valve.unload_area_id] = valve.team_id # 一个unload_area_id只对应一个team_id
# # group_excavator_dict = {} -->> {team_id: [excavator_id, excavator_id], ...} # 一个team_id对应一组excavator_id, unload_area_id
# # excavator_group_dict = {} -->> excavator_id -> team_id 一个excavator_id只对应一个team_id
# for item in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
# if item.team_id in cls.group_excavator_dict:
# cls.group_excavator_dict[item.team_id].append(item.excavator_id)
# else:
# cls.group_excavator_dict[item.team_id] = [item.excavator_id]
# cls.excavator_group_dict[item.excavator_id] = item.team_id
# # group_truck_dict = {} -->> {team_id:[truck_id,truck_id],...}
# # truck_group_dict = {} -->> truck_id -> team_id
# for key in session_mysql.query(DispatchEquipment).filter_by(group_type=1).all():
# if key.group_code in group_code_dict:
# if key.group_code not in cls.group_truck_dict:
# cls.group_truck_dict[key.group_code] = [key.equipment_id]
# else:
# cls.group_truck_dict[key.group_code].append(key.equipment_id)
# cls.truck_group_dict[key.equipment_id] = group_code_dict[key.group_code]
#
# except Exception as es:
# logger.error("分组到卸载区的数据更新异常")
# logger.error(es)
@classmethod
def
update_group_mode
(
cls
):
"""
...
...
@@ -113,22 +163,35 @@ class DispatchInfo:
@author:maqc
@desc:处理其它类型的数据
"""
#
新增:team_id-->>group_code;group_code-->>mode_code.结果:team_id-->
>mode_code
#
update group_id-
>mode_code
logger
=
get_logger
(
"mqc.update_group_mode"
)
team_group_dict
=
{}
# team_id-->>group_code的一个映射,格式:{team_id:group_code}
group_mode_dict
=
{}
# group-->>mode_code的一个映射,格式:{group_code:mode_code}
cls
.
group_mode
=
{}
try
:
for
pos
in
session_mysql
.
query
(
DispatchMatch
)
.
filter_by
(
group_type
=
1
)
.
all
():
team_group_dict
[
pos
.
team_id
]
=
pos
.
group_code
for
item
in
session_mysql
.
query
(
DispatchGroup
)
.
filter_by
(
group_type
=
1
)
.
all
():
group_mode_dict
[
item
.
group_code
]
=
item
.
mode_code
for
key
,
value
in
team_group_dict
.
items
():
if
value
in
group_mode_dict
:
cls
.
group_mode
[
key
]
=
group_mode_dict
[
value
]
for
item
in
session_mysql
.
query
(
DispatchGroup
)
.
all
():
mode_id
=
item
.
mode_id
mode_code
=
session_mysql
.
query
(
DispatchMode
)
.
filter_by
(
id
=
mode_id
)
.
first
()
.
mode_code
# mode = session_mysql.query(DispatchMode).filter_by(group_code=).first()
cls
.
group_mode
[
item
.
id
]
=
mode_code
except
Exception
as
es
:
logger
.
error
(
"
派车模式数据
更新异常"
)
logger
.
error
(
"
group_id->mode_code
更新异常"
)
logger
.
error
(
es
)
# 新增:team_id-->>group_code;group_code-->>mode_code.结果:team_id-->>mode_code
# team_group_dict = {} # team_id-->>group_code的一个映射,格式:{team_id:group_code}
# group_mode_dict = {} # group-->>mode_code的一个映射,格式:{group_code:mode_code}
# try:
# for pos in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
# team_group_dict[pos.team_id] = pos.group_code
# for item in session_mysql.query(DispatchGroup).filter_by(group_type=1).all():
# group_mode_dict[item.group_code] = item.mode_code
# for key, value in team_group_dict.items():
# if value in group_mode_dict:
# cls.group_mode[key] = group_mode_dict[value]
# except Exception as es:
# logger.error("派车模式数据更新异常")
# logger.error(es)
# @classmethod
# def dispatch_group_init(cls):
# """
...
...
@@ -137,12 +200,11 @@ class DispatchInfo:
# """
# try:
# for value in session_postgre.query(DiggingWorkArea).all():
# cls.load_ex
ac
tor_dict[value.Id] = value.ExactorId
# cls.ex
ac
tor_load_dict[value.ExactorId] = value.Id
# cls.load_ex
cava
tor_dict[value.Id] = value.ExactorId
# cls.ex
cava
tor_load_dict[value.ExactorId] = value.Id
# except Exception as es:
# logger.error("初始化数据更新异常")
# logger.error(es)
@classmethod
# 距离-->>数据格式:矩阵-->>to_load_distance
def
update_route_distance
(
cls
):
...
...
@@ -176,7 +238,7 @@ class DispatchInfo:
for
i
in
range
(
len
(
unload_nums
)):
for
j
in
range
(
len
(
exactor_nums
)):
id
=
set
(
df
.
loc
[
df
[
1
]
==
str
(
unload_nums
[
i
])]
.
index
.
to_list
())
&
set
(
df
.
loc
[
df
[
0
]
==
str
(
cls
.
ex
ac
tor_load_dict
[
j
])]
.
index
.
to_list
())
# 集合属性
df
.
loc
[
df
[
0
]
==
str
(
cls
.
ex
cava
tor_load_dict
[
j
])]
.
index
.
to_list
())
# 集合属性
unload_exactor_matrix
[
i
][
j
]
=
df
.
iloc
[
list
(
id
)[
0
]][
2
]
except
Exception
as
es
:
logger
.
error
(
"路网距离数据更新异常2"
)
...
...
@@ -185,7 +247,7 @@ class DispatchInfo:
try
:
for
m
in
range
(
len
(
exactor_nums
)):
for
n
in
range
(
len
(
unload_nums
)):
id
=
set
(
df
.
loc
[
df
[
0
]
==
str
(
cls
.
ex
ac
tor_load_dict
[
m
])]
.
index
.
to_list
())
&
set
(
id
=
set
(
df
.
loc
[
df
[
0
]
==
str
(
cls
.
ex
cava
tor_load_dict
[
m
])]
.
index
.
to_list
())
&
set
(
df
.
loc
[
df
[
1
]
==
str
(
unload_nums
[
n
])]
.
index
.
to_list
())
load_exactor_matrix
[
m
][
n
]
=
df
.
iloc
[
list
(
id
)[
0
]][
3
]
except
Exception
as
es
:
...
...
@@ -193,6 +255,7 @@ class DispatchInfo:
logger
.
error
(
es
)
cls
.
load_distance
[
team_id
]
=
unload_exactor_matrix
cls
.
unload_distance
[
team_id
]
=
load_exactor_matrix
except
Exception
as
es
:
logger
.
error
(
"路网距离数据更新异常4"
)
logger
.
error
(
es
)
...
...
@@ -221,16 +284,16 @@ class DispatchInfo:
def
get_to_dump_distance
(
cls
,
group_id
):
return
cls
.
unload_distance
[
group_id
]
@classmethod
def
get_park_to_excavator_distance
(
cls
,
group_id
):
return
cls
.
park_distance
[
group_id
]
#
@classmethod
#
def get_park_to_excavator_distance(cls, group_id):
#
return cls.park_distance[group_id]
@classmethod
def
get_park_to_excavator_distance
(
cls
,
group_id
):
excavators
=
cls
.
group_excavator_dict
[
group_id
]
park_matrix
=
np
.
zeros
((
1
,
len
(
excavators
)))
for
i
in
range
(
excavators
):
load_area_id
=
cls
.
ex
ac
tor_load_dict
[
excavators
[
i
]]
load_area_id
=
cls
.
ex
cava
tor_load_dict
[
excavators
[
i
]]
distance
=
session_postgre
.
query
(
WalkTimePark
)
.
filter_by
(
load_area_id
=
load_area_id
)
.
first
()
park_matrix
[
0
][
i
]
=
distance
return
park_matrix
...
...
@@ -317,9 +380,9 @@ class DispatchInfo:
# # group_excavator_dict = {} -->> {group_id: [excavator_id, unload_area_id], ...} # 一个team_id对应一组excavator_id, unload_area_id
# # excavator_group_dict = {} -->> excavator_id -> team_id 一个excavator_id只对应一个team_id
# for item in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
# # cls.group_excavator_dict[item.team_id] = [item.ex
ac
tor_id, item.unload_area_id]
# cls.group_excavator_dict[item.team_id] = item.ex
ac
tor_id
# cls.excavator_group_dict[item.ex
ac
tor_id] = item.team_id
# # cls.group_excavator_dict[item.team_id] = [item.ex
cava
tor_id, item.unload_area_id]
# cls.group_excavator_dict[item.team_id] = item.ex
cava
tor_id
# cls.excavator_group_dict[item.ex
cava
tor_id] = item.team_id
# # group_truck_dict = {} -->> {group_id:[truck_id,truck_id],...}
# # truck_group_dict = {} -->> truck_id -> team_id
# for key in session_mysql.query(DispatchEquipment).filter_by(group_type=1).all():
...
...
@@ -374,16 +437,16 @@ class DispatchInfo:
# @author:maqc
# @desc:更新路网距离,返回矩阵格式数据
# """
# load_ex
ac
tor_dict = {} # 装载区id-->>电铲编号的映射
# load_ex
cava
tor_dict = {} # 装载区id-->>电铲编号的映射
# logger = get_logger("mqc.update_route_distance")
# try:
# for value in session_postgre.query(DiggingWorkArea).all():
# load_ex
ac
tor_dict[value.Id] = value.Exactorld
# load_ex
cava
tor_dict[value.Id] = value.Exactorld
# for value in session_postgre.query(WalkTime).all():
# if value.load_area_id in load_ex
ac
tor_dict:
# cls.load_excavator_distance[value.load_area_id] = [load_ex
ac
tor_dict[value.load_area_id],
# if value.load_area_id in load_ex
cava
tor_dict:
# cls.load_excavator_distance[value.load_area_id] = [load_ex
cava
tor_dict[value.load_area_id],
# value.to_load_distance]
# cls.unload_excavator_distance[value.unload_area_id] = [load_ex
ac
tor_dict[value.load_area_id],
# cls.unload_excavator_distance[value.unload_area_id] = [load_ex
cava
tor_dict[value.load_area_id],
# value.to_unload_distance]
# except Exception as es:
# logger.error("路网数据更新异常")
...
...
tables.py
View file @
93958978
...
...
@@ -257,7 +257,7 @@ class EquipmentPair(Base):
id
=
Column
(
VARCHAR
(
36
),
primary_key
=
True
)
truck_id
=
Column
(
VARCHAR
(
36
))
ex
ac
tor_id
=
Column
(
VARCHAR
(
36
))
ex
cava
tor_id
=
Column
(
VARCHAR
(
36
))
dump_id
=
Column
(
VARCHAR
(
36
))
load_area_id
=
Column
(
VARCHAR
(
36
))
unload_area_id
=
Column
(
VARCHAR
(
36
))
...
...
@@ -265,11 +265,11 @@ class EquipmentPair(Base):
isdeleted
=
Column
(
BOOLEAN
)
createtime
=
Column
(
DateTime
)
def
__init__
(
self
,
id
,
truck_id
,
ex
ac
tor_id
,
dump_id
,
load_area_id
,
unload_area_id
,
dispatch_id
,
isdeleted
,
def
__init__
(
self
,
id
,
truck_id
,
ex
cava
tor_id
,
dump_id
,
load_area_id
,
unload_area_id
,
dispatch_id
,
isdeleted
,
createtime
):
self
.
id
=
id
self
.
truck_id
=
truck_id
self
.
ex
actor_id
=
exac
tor_id
self
.
ex
cavator_id
=
excava
tor_id
self
.
dump_id
=
dump_id
self
.
load_area_id
=
load_area_id
self
.
unload_area_id
=
unload_area_id
...
...
@@ -307,7 +307,7 @@ class Dispatch(Base):
id
=
Column
(
VARCHAR
(
36
),
primary_key
=
True
)
load_area_id
=
Column
(
VARCHAR
(
36
))
ex
ac
tor_id
=
Column
(
VARCHAR
(
36
))
ex
cava
tor_id
=
Column
(
VARCHAR
(
36
))
unload_area_id
=
Column
(
VARCHAR
(
36
))
dump_id
=
Column
(
VARCHAR
(
36
))
isauto
=
Column
(
BOOLEAN
)
...
...
@@ -323,12 +323,12 @@ class Dispatch(Base):
deletor
=
Column
(
VARCHAR
(
36
))
deletetime
=
Column
(
DateTime
)
def
__init__
(
self
,
id
,
load_area_id
,
ex
ac
tor_id
,
unload_area_id
,
dump_id
,
isauto
,
truck_id
,
group_id
,
remark
,
def
__init__
(
self
,
id
,
load_area_id
,
ex
cava
tor_id
,
unload_area_id
,
dump_id
,
isauto
,
truck_id
,
group_id
,
remark
,
proportion_id
,
isdeleted
,
creator
,
createtime
,
updator
,
updatetime
,
deletor
,
deletetime
):
self
.
id
=
id
self
.
load_area_id
=
load_area_id
self
.
excavator_id
=
ex
ac
tor_id
self
.
excavator_id
=
ex
cava
tor_id
self
.
unload_area_id
=
unload_area_id
self
.
dump_id
=
dump_id
self
.
isauto
=
isauto
...
...
@@ -559,16 +559,16 @@ class DispatchMatch(Base):
match_code
=
Column
(
VARCHAR
(
36
))
team_id
=
Column
(
VARCHAR
(
36
))
unload_area_id
=
Column
(
VARCHAR
(
36
))
ex
ac
tor_id
=
Column
(
VARCHAR
(
36
))
ex
cava
tor_id
=
Column
(
VARCHAR
(
36
))
def
__init__
(
self
,
id
,
group_type
,
group_code
,
match_code
,
team_id
,
unload_area_id
,
ex
ac
tor_id
):
def
__init__
(
self
,
id
,
group_type
,
group_code
,
match_code
,
team_id
,
unload_area_id
,
ex
cava
tor_id
):
self
.
id
=
id
self
.
group_type
=
group_type
self
.
group_code
=
group_code
self
.
match_code
=
match_code
self
.
team_id
=
team_id
self
.
unload_area_id
=
unload_area_id
self
.
ex
actor_id
=
exac
tor_id
self
.
ex
cavator_id
=
excava
tor_id
class
DispatchEquipment
(
Base
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment