记得上下班打卡 | git大法好,push需谨慎
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liquidnet-bus-v1
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
董敬伟
liquidnet-bus-v1
Commits
4a79e8c1
Commit
4a79e8c1
authored
Jul 13, 2021
by
胡佳晨
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
提交 order
parent
3577c0d1
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
52 additions
and
95 deletions
+52
-95
DragonOrderRefundsServiceImpl.java
...ce/dragon/service/impl/DragonOrderRefundsServiceImpl.java
+27
-91
PayWepayUtils.java
...ava/com/liquidnet/service/dragon/utils/PayWepayUtils.java
+23
-3
KylinOrderTicketsServiceImpl.java
...vice/order/service/impl/KylinOrderTicketsServiceImpl.java
+2
-1
No files found.
liquidnet-bus-service/liquidnet-service-dragon/liquidnet-service-dragon-impl/src/main/java/com/liquidnet/service/dragon/service/impl/DragonOrderRefundsServiceImpl.java
View file @
4a79e8c1
...
@@ -63,33 +63,33 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -63,33 +63,33 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
//创建退款单
//创建退款单
boolean
insertResult
=
sendMySqlRedis
(
boolean
insertResult
=
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund.insert"
),
SqlMapping
.
get
(
"dragon_order_refund.insert"
),
new
Object
[]{
orderRefundC
ode
,
refundCode
,
orderRefundCode
,
price
,
reason
,
notifyUrl
,
paymentType
,
nowTime
,
nowTime
}
new
Object
[]{
c
ode
,
refundCode
,
orderRefundCode
,
price
,
reason
,
notifyUrl
,
paymentType
,
nowTime
,
nowTime
}
);
);
redisUtil
.
set
(
DragonConstant
.
REFUND_REDIS_KET
+
orderRefundC
ode
,
notifyUrl
);
redisUtil
.
set
(
DragonConstant
.
REFUND_REDIS_KET
+
c
ode
,
notifyUrl
);
DragonRefundChannelDto
dto
=
null
;
DragonRefundChannelDto
dto
=
null
;
String
localWePayCallBackUrl
=
url
+
"/refund/callBack/wepay"
;
String
localWePayCallBackUrl
=
url
+
"/refund/callBack/wepay"
;
if
(
insertResult
)
{
if
(
insertResult
)
{
switch
(
paymentType
)
{
switch
(
paymentType
)
{
case
DragonConstant
.
REFUND_TYPE_APP_ALIPAY
:
case
DragonConstant
.
REFUND_TYPE_APP_ALIPAY
:
dto
=
aliPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
paymentId
,
paymentType
,
nowTime
);
dto
=
aliPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
paymentId
,
paymentType
,
nowTime
);
break
;
break
;
case
DragonConstant
.
REFUND_TYPE_WAP_ALIPAY
:
case
DragonConstant
.
REFUND_TYPE_WAP_ALIPAY
:
dto
=
aliPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
paymentId
,
paymentType
,
nowTime
);
dto
=
aliPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
paymentId
,
paymentType
,
nowTime
);
break
;
break
;
case
DragonConstant
.
REFUND_TYPE_WEB_ALIPAY
:
case
DragonConstant
.
REFUND_TYPE_WEB_ALIPAY
:
dto
=
aliPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
paymentId
,
paymentType
,
nowTime
);
dto
=
aliPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
paymentId
,
paymentType
,
nowTime
);
break
;
break
;
case
DragonConstant
.
REFUND_TYPE_APP_WEPAY
:
case
DragonConstant
.
REFUND_TYPE_APP_WEPAY
:
dto
=
weyPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
dto
=
weyPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
break
;
break
;
case
DragonConstant
.
REFUND_TYPE_WAP_WEPAY
:
case
DragonConstant
.
REFUND_TYPE_WAP_WEPAY
:
dto
=
weyPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
dto
=
weyPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
break
;
break
;
case
DragonConstant
.
REFUND_TYPE_WEB_WEPAY
:
case
DragonConstant
.
REFUND_TYPE_WEB_WEPAY
:
dto
=
weyPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
dto
=
weyPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
break
;
break
;
case
DragonConstant
.
REFUND_TYPE_JS_WEPAY
:
case
DragonConstant
.
REFUND_TYPE_JS_WEPAY
:
dto
=
weyPayRefund
(
orderRefundC
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
dto
=
weyPayRefund
(
c
ode
,
orderRefundCode
,
code
,
reason
,
price
,
priceTotal
,
paymentId
,
paymentType
,
localWePayCallBackUrl
,
nowTime
);
break
;
break
;
}
}
...
@@ -131,12 +131,22 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -131,12 +131,22 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
String
nonceStr
=
PayWepayUtils
.
getInstance
().
getNonceStr
();
String
nonceStr
=
PayWepayUtils
.
getInstance
().
getNonceStr
();
SortedMap
<
Object
,
Object
>
parameters
=
new
TreeMap
<>();
SortedMap
<
Object
,
Object
>
parameters
=
new
TreeMap
<>();
parameters
.
put
(
"mch_id"
,
PayWepayUtils
.
getInstance
().
getMerchantId
());
parameters
.
put
(
"mch_id"
,
PayWepayUtils
.
getInstance
().
getMerchantId
());
parameters
.
put
(
"appid"
,
PayWepayUtils
.
getInstance
().
getAppId
());
if
(
paymentType
.
equalsIgnoreCase
(
DragonConstant
.
PayTypeEnum
.
PAYMENT_TYPE_JS_WEPAY
.
getCode
()))
{
parameters
.
put
(
"appid"
,
PayWepayUtils
.
getInstance
().
getJS_APP_ID
());
}
else
if
(
paymentType
.
equalsIgnoreCase
(
DragonConstant
.
PayTypeEnum
.
PAYMENT_TYPE_WEB_WEPAY
.
getCode
()))
{
parameters
.
put
(
"appid"
,
PayWepayUtils
.
getInstance
().
getWEB_APP_ID
());
}
else
if
(
paymentType
.
equalsIgnoreCase
(
DragonConstant
.
PayTypeEnum
.
PAYMENT_TYPE_APP_WEPAY
.
getCode
()))
{
parameters
.
put
(
"appid"
,
PayWepayUtils
.
getInstance
().
getAPP_ID
());
}
else
if
(
paymentType
.
equalsIgnoreCase
(
DragonConstant
.
PayTypeEnum
.
PAYMENT_TYPE_APPLET_WEPAY
.
getCode
()))
{
parameters
.
put
(
"appid"
,
PayWepayUtils
.
getInstance
().
getAPPLET_APP_ID
());
}
else
if
(
paymentType
.
equalsIgnoreCase
(
DragonConstant
.
PayTypeEnum
.
PAYMENT_TYPE_WAP_WEPAY
.
getCode
()))
{
parameters
.
put
(
"appid"
,
PayWepayUtils
.
getInstance
().
getWAP_APP_ID
());
}
parameters
.
put
(
"nonce_str"
,
nonceStr
);
parameters
.
put
(
"nonce_str"
,
nonceStr
);
parameters
.
put
(
"out_refund_no"
,
refundCode
);
parameters
.
put
(
"out_refund_no"
,
refundCode
);
parameters
.
put
(
"out_trade_no"
,
code
);
parameters
.
put
(
"out_trade_no"
,
code
);
parameters
.
put
(
"refund_fee"
,
(
int
)
(
price
.
doubleValue
()
*
100
)+
""
);
parameters
.
put
(
"refund_fee"
,
(
int
)
(
price
.
doubleValue
()
*
100
)
+
""
);
parameters
.
put
(
"total_fee"
,
(
int
)
(
priceTotal
.
doubleValue
()
*
100
)+
""
);
parameters
.
put
(
"total_fee"
,
(
int
)
(
priceTotal
.
doubleValue
()
*
100
)
+
""
);
parameters
.
put
(
"notify_url"
,
notifyUrl
);
parameters
.
put
(
"notify_url"
,
notifyUrl
);
parameters
.
put
(
"refund_desc"
,
reason
);
parameters
.
put
(
"refund_desc"
,
reason
);
parameters
.
put
(
"refund_account"
,
"REFUND_SOURCE_RECHARGE_FUNDS"
);
parameters
.
put
(
"refund_account"
,
"REFUND_SOURCE_RECHARGE_FUNDS"
);
...
@@ -167,7 +177,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -167,7 +177,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
// 修改退款订单
// 修改退款订单
sendMySqlRedis
(
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_error.update"
),
SqlMapping
.
get
(
"dragon_order_refund_error.update"
),
new
Object
[]{
nowTime
,
refundError
,
refundStatus
,
refundC
ode
}
new
Object
[]{
nowTime
,
refundError
,
refundStatus
,
c
ode
}
);
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
...
@@ -199,7 +209,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -199,7 +209,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
}
}
sendMySqlRedis
(
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_success.update"
),
SqlMapping
.
get
(
"dragon_order_refund_success.update"
),
new
Object
[]{
nowTime
,
null
,
refundStatus
,
refundC
ode
}
new
Object
[]{
nowTime
,
null
,
refundStatus
,
c
ode
}
);
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
...
@@ -257,7 +267,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -257,7 +267,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
// 修改退款订单
// 修改退款订单
sendMySqlRedis
(
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_error.update"
),
SqlMapping
.
get
(
"dragon_order_refund_error.update"
),
new
Object
[]{
nowTime
,
refundError
,
refundStatus
,
refundC
ode
}
new
Object
[]{
nowTime
,
refundError
,
refundStatus
,
c
ode
}
);
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
...
@@ -293,7 +303,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -293,7 +303,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
}
}
sendMySqlRedis
(
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_success.update"
),
SqlMapping
.
get
(
"dragon_order_refund_success.update"
),
new
Object
[]{
nowTime
,
refundAt
,
refundStatus
,
refundC
ode
}
new
Object
[]{
nowTime
,
refundAt
,
refundStatus
,
c
ode
}
);
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
...
@@ -394,80 +404,6 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -394,80 +404,6 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
}
}
}
}
public
String
aliPayRefundCallBack
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
InputStream
inStream
;
ByteArrayOutputStream
outSteam
;
LocalDateTime
nowTime
=
LocalDateTime
.
now
();
try
{
inStream
=
request
.
getInputStream
();
outSteam
=
new
ByteArrayOutputStream
();
byte
[]
buffer
=
new
byte
[
1024
];
int
len
=
0
;
while
((
len
=
inStream
.
read
(
buffer
))
!=
-
1
)
{
outSteam
.
write
(
buffer
,
0
,
len
);
}
// 获取微信调用我们notify_url的返回信息
String
jsonStr
=
new
String
(
outSteam
.
toByteArray
(),
"utf-8"
);
outSteam
.
close
();
inStream
.
close
();
log
.
debug
(
"JSON = "
+
jsonStr
);
WePayRefundReturnCallBackDto
callBackDto
=
XmlUtil
.
toBean
(
jsonStr
,
WePayRefundReturnCallBackDto
.
class
);
log
.
debug
(
"DATA = "
+
callBackDto
);
if
(
callBackDto
.
getReturnCode
().
equalsIgnoreCase
(
"SUCCESS"
))
{
String
reqInfo
=
PayWepayUtils
.
getInstance
().
unCodeReqInfo
(
callBackDto
.
getReqInfo
());
log
.
debug
(
"REQINFO = "
+
reqInfo
);
WePayRefundReturnCallBackInfoDto
info
=
XmlUtil
.
toBean
(
reqInfo
,
WePayRefundReturnCallBackInfoDto
.
class
);
String
outRefundNo
=
info
.
getOutRefundNo
();
String
refundAt
=
info
.
getSuccessTime
();
try
{
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_log.insert"
),
new
Object
[]{
outRefundNo
,
info
.
getRefundRequestSource
(),
JSON
.
toJSONString
(
info
),
nowTime
,
nowTime
}
);
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_success.update"
),
new
Object
[]{
nowTime
,
refundAt
,
DragonConstant
.
RefundStatusEnum
.
STATUS_REFUNDED
.
getCode
(),
outRefundNo
}
);
NotifyUrlDto
dto
=
new
NotifyUrlDto
();
if
(
info
.
getRefundStatus
().
equalsIgnoreCase
(
"SUCCESS"
))
{
dto
.
setStatus
(
1
);
}
else
{
dto
.
setStatus
(
0
);
}
// dto.setOrderCode();
// dto.setCode();
// dto.setType();
// dto.setPrice();
// dto.setPaymentType();
// dto.setPaymentId();
// dto.setPaymentAt();
dto
.
setOrderRefundCode
(
info
.
getOutRefundNo
());
dto
.
setRefundCode
(
info
.
getOutTradeNo
());
dto
.
setRefundPrice
(
info
.
getRefundFee
());
// dto.setRefundReason();
dto
.
setRefundId
(
info
.
getRefundId
());
// dto.setRefundType(info.getrefund);
dto
.
setRefundAt
(
refundAt
);
dto
.
setRefundError
(
callBackDto
.
getReturnMsg
());
sendNotifyUrl
(
dto
);
return
"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
log
.
error
(
""
);
return
"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>"
;
}
}
else
{
return
"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>"
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
log
.
error
(
""
);
return
"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>"
;
}
}
/**
/**
* 给 REDIS 队列发送消息 数据库相关
* 给 REDIS 队列发送消息 数据库相关
*
*
...
@@ -506,7 +442,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
...
@@ -506,7 +442,7 @@ public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService
params
.
add
(
"refundPrice"
,
notifyUrlDto
.
getRefundPrice
());
params
.
add
(
"refundPrice"
,
notifyUrlDto
.
getRefundPrice
());
params
.
add
(
"status"
,
notifyUrlDto
.
getStatus
().
toString
());
params
.
add
(
"status"
,
notifyUrlDto
.
getStatus
().
toString
());
String
response
=
HttpUtil
.
post
((
String
)
redisUtil
.
get
(
DragonConstant
.
REFUND_REDIS_KET
+
notifyUrlDto
.
getOrderRefundCode
()),
params
);
String
response
=
HttpUtil
.
post
((
String
)
redisUtil
.
get
(
DragonConstant
.
REFUND_REDIS_KET
+
notifyUrlDto
.
getOrderRefundCode
()),
params
);
log
.
debug
(
"RETURN RESPONSE="
+
response
);
log
.
debug
(
"RETURN RESPONSE="
+
response
);
if
(
response
.
equals
(
"success"
))
{
if
(
response
.
equals
(
"success"
))
{
sendMySqlRedis
(
sendMySqlRedis
(
SqlMapping
.
get
(
"dragon_order_refund_call_back.update"
),
SqlMapping
.
get
(
"dragon_order_refund_call_back.update"
),
...
...
liquidnet-bus-service/liquidnet-service-dragon/liquidnet-service-dragon-impl/src/main/java/com/liquidnet/service/dragon/utils/PayWepayUtils.java
View file @
4a79e8c1
...
@@ -24,9 +24,13 @@ public class PayWepayUtils {
...
@@ -24,9 +24,13 @@ public class PayWepayUtils {
private
static
PayWepayUtils
instance
=
new
PayWepayUtils
();
private
static
PayWepayUtils
instance
=
new
PayWepayUtils
();
private
final
String
merchantId
=
"1551961491"
;
private
final
String
merchantId
=
"1551961491"
;
private
final
String
appId
=
"wx3498304dda39c5a1"
;
private
final
String
parentKey
=
"itIuO65O9yKmemOu3S8g1S4orqvCGwXK"
;
private
final
String
parentKey
=
"itIuO65O9yKmemOu3S8g1S4orqvCGwXK"
;
private
final
String
APP_ID
=
"wx86f9777acf2cb585"
;
private
final
String
WEB_APP_ID
=
"wx3498304dda39c5a1"
;
private
final
String
JS_APP_ID
=
"wx3498304dda39c5a1"
;
private
final
String
WAP_APP_ID
=
"wx3498304dda39c5a1"
;
private
final
String
APPLET_APP_ID
=
"wx4732efeaa2b08086"
;
public
PayWepayUtils
()
{
public
PayWepayUtils
()
{
}
}
...
@@ -36,8 +40,24 @@ public class PayWepayUtils {
...
@@ -36,8 +40,24 @@ public class PayWepayUtils {
}
}
public
String
getAppId
()
{
public
String
getAPP_ID
()
{
return
appId
;
return
APP_ID
;
}
public
String
getAPPLET_APP_ID
()
{
return
APPLET_APP_ID
;
}
public
String
getJS_APP_ID
()
{
return
JS_APP_ID
;
}
public
String
getWEB_APP_ID
()
{
return
WEB_APP_ID
;
}
public
String
getWAP_APP_ID
()
{
return
WAP_APP_ID
;
}
}
public
String
getMerchantId
()
{
public
String
getMerchantId
()
{
...
...
liquidnet-bus-service/liquidnet-service-order/liquidnet-service-order-impl/src/main/java/com/liquidnet/service/order/service/impl/KylinOrderTicketsServiceImpl.java
View file @
4a79e8c1
package
com
.
liquidnet
.
service
.
order
.
service
.
impl
;
package
com
.
liquidnet
.
service
.
order
.
service
.
impl
;
import
com.alibaba.fastjson.JSON
;
import
com.liquidnet.common.cache.redis.util.RedisUtil
;
import
com.liquidnet.common.cache.redis.util.RedisUtil
;
import
com.liquidnet.common.cache.redisson.util.RedisLockUtil
;
import
com.liquidnet.common.cache.redisson.util.RedisLockUtil
;
import
com.liquidnet.common.mq.constant.MQConst
;
import
com.liquidnet.common.mq.constant.MQConst
;
...
@@ -554,7 +555,7 @@ public class KylinOrderTicketsServiceImpl implements IKylinOrderTicketsOrderServ
...
@@ -554,7 +555,7 @@ public class KylinOrderTicketsServiceImpl implements IKylinOrderTicketsOrderServ
currentTime
=
System
.
currentTimeMillis
();
currentTime
=
System
.
currentTimeMillis
();
String
returnData
=
HttpUtil
.
post
(
payUrl
,
httpData
);
String
returnData
=
HttpUtil
.
post
(
payUrl
,
httpData
);
log
.
debug
(
"
NOTIFY_URL = "
+
synUrl
);
log
.
debug
(
"
httpData = "
+
JSON
.
toJSONString
(
httpData
)
);
currentTime
=
System
.
currentTimeMillis
()
-
currentTime
;
currentTime
=
System
.
currentTimeMillis
()
-
currentTime
;
log
.
debug
(
"调用 PHP 支付 -> time:"
+
(
currentTime
)
+
"毫秒"
);
log
.
debug
(
"调用 PHP 支付 -> time:"
+
(
currentTime
)
+
"毫秒"
);
PayResultVo
payResultVo
=
JsonUtils
.
fromJson
(
returnData
,
PayResultVo
.
class
);
PayResultVo
payResultVo
=
JsonUtils
.
fromJson
(
returnData
,
PayResultVo
.
class
);
...
...
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