Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-backend
Overview
Overview
Details
Activity
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
AutogeneralShanghai
yd-backend
Commits
93004b28
Commit
93004b28
authored
Sep 15, 2020
by
jianan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
查询PEP得分接口
parent
736e5a94
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
307 additions
and
11 deletions
+307
-11
yd-api/src/main/java/com/yd/api/practitioner/PractitionerController.java
+15
-4
yd-api/src/main/java/com/yd/api/practitioner/service/ScheduleTrackService.java
+3
-4
yd-api/src/main/java/com/yd/api/practitioner/service/impl/ScheduleTrackServiceImpl.java
+124
-2
yd-api/src/main/java/com/yd/api/practitioner/vo/sechedule/QueryPEPScoreResponseVO.java
+14
-0
yd-api/src/main/java/com/yd/dal/entity/practitioner/PersonalSchedule.java
+13
-0
yd-api/src/main/java/com/yd/dal/mapper/marketing/ScheduleTrackMapper.java
+14
-1
yd-api/src/main/java/com/yd/util/CommonUtil.java
+38
-0
yd-api/src/main/resources/mapper/marketing/ScheduleTrackMapper.xml
+86
-0
No files found.
yd-api/src/main/java/com/yd/api/practitioner/PractitionerController.java
View file @
93004b28
...
...
@@ -22,10 +22,7 @@ import com.yd.api.practitioner.vo.rank.PractitionerRankRequestVO;
import
com.yd.api.practitioner.vo.rank.PractitionerRankResponseVO
;
import
com.yd.api.practitioner.vo.recruit.*
;
import
com.yd.api.practitioner.vo.salestarget.*
;
import
com.yd.api.practitioner.vo.sechedule.AddScheduleTrackRequestVO
;
import
com.yd.api.practitioner.vo.sechedule.AddScheduleTrackResponseVO
;
import
com.yd.api.practitioner.vo.sechedule.QueryScheduleTrackListRequestVO
;
import
com.yd.api.practitioner.vo.sechedule.QueryScheduleTrackListResponseVO
;
import
com.yd.api.practitioner.vo.sechedule.*
;
import
com.yd.api.practitioner.vo.setting.*
;
import
com.yd.api.practitioner.vo.subordinate.SubordinateSystemMemberQueryRequestVO
;
import
com.yd.api.practitioner.vo.subordinate.SubordinateSystemMemberQueryResponseVO
;
...
...
@@ -540,4 +537,18 @@ public class PractitionerController {
return
result
;
}
/**
* 查询战队PEP得分
* @param practitionerId
* @return
*/
@RequestMapping
(
"/queryPEPScore"
)
public
Object
queryPEPScore
(
String
practitionerId
){
JsonResult
result
=
new
JsonResult
();
QueryPEPScoreResponseVO
responseVO
=
scheduleTrackService
.
queryPEPScore
(
Long
.
parseLong
(
practitionerId
));
result
.
addResult
(
responseVO
);
result
.
setData
(
responseVO
);
return
result
;
}
}
yd-api/src/main/java/com/yd/api/practitioner/service/ScheduleTrackService.java
View file @
93004b28
package
com
.
yd
.
api
.
practitioner
.
service
;
import
com.yd.api.practitioner.vo.sechedule.AddScheduleTrackRequestVO
;
import
com.yd.api.practitioner.vo.sechedule.AddScheduleTrackResponseVO
;
import
com.yd.api.practitioner.vo.sechedule.QueryScheduleTrackListRequestVO
;
import
com.yd.api.practitioner.vo.sechedule.QueryScheduleTrackListResponseVO
;
import
com.yd.api.practitioner.vo.sechedule.*
;
public
interface
ScheduleTrackService
{
AddScheduleTrackResponseVO
insert
(
AddScheduleTrackRequestVO
requestVO
);
QueryScheduleTrackListResponseVO
queryScheduleTrackList
(
QueryScheduleTrackListRequestVO
requestVO
);
QueryPEPScoreResponseVO
queryPEPScore
(
Long
practitionerId
);
}
yd-api/src/main/java/com/yd/api/practitioner/service/impl/ScheduleTrackServiceImpl.java
View file @
93004b28
package
com
.
yd
.
api
.
practitioner
.
service
.
impl
;
import
com.yd.api.practitioner.service.ScheduleTrackService
;
import
com.yd.api.practitioner.vo.opportunity.OwnOpportunityRecordSaveResponseVO
;
import
com.yd.api.practitioner.vo.sechedule.*
;
import
com.yd.api.result.CommonResult
;
import
com.yd.api.result.JsonResult
;
import
com.yd.dal.entity.customer.AclPractitionerPotentialAssignedTrack
;
import
com.yd.dal.entity.marketing.MktLeadsAssignedTrack
;
import
com.yd.dal.entity.meta.MdDropOptions
;
import
com.yd.dal.entity.practitioner.PersonalSchedule
;
import
com.yd.dal.entity.practitioner.ScheduleTrack
;
import
com.yd.dal.mapper.marketing.ScheduleTrackMapper
;
import
com.yd.dal.service.customer.AclPractitionerPotentialAssignedTrackDALService
;
...
...
@@ -20,6 +19,9 @@ import org.springframework.beans.BeanUtils;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.math.BigDecimal
;
import
java.text.DecimalFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
@Service
...
...
@@ -220,5 +222,125 @@ public class ScheduleTrackServiceImpl implements ScheduleTrackService {
}
}
@Override
public
QueryPEPScoreResponseVO
queryPEPScore
(
Long
practitionerId
)
{
QueryPEPScoreResponseVO
resp
=
new
QueryPEPScoreResponseVO
();
// 获取本月第一天
Calendar
cal
=
Calendar
.
getInstance
();
cal
.
add
(
Calendar
.
MONTH
,
0
);
// 获取到本月起始日
int
actualMinimum
=
cal
.
getActualMinimum
(
Calendar
.
DAY_OF_MONTH
);
cal
.
set
(
cal
.
get
(
Calendar
.
YEAR
),
cal
.
get
(
Calendar
.
MONDAY
),
actualMinimum
,
00
,
00
,
00
);
// 获取本月起始日的年月日时分秒格式
Date
monthOne
=
cal
.
getTime
();
// 获取本月当前日的年月日时分秒格式
Date
today
=
new
Date
();
// 获取本周第一天(周一为始)
cal
.
set
(
Calendar
.
DAY_OF_WEEK
,
Calendar
.
MONDAY
);
cal
.
set
(
Calendar
.
HOUR_OF_DAY
,
0
);
cal
.
set
(
Calendar
.
MINUTE
,
0
);
cal
.
set
(
Calendar
.
SECOND
,
0
);
Date
weekOne
=
cal
.
getTime
();
// 根据团队长经纪人id查询团队每个成员本日,本周,本月得分以及本月FYC
List
<
Map
<
String
,
Object
>>
saleAndRecuit
=
scheduleTrackMapper
.
querySaleRecuitScoreFYC
(
practitionerId
,
monthOne
,
today
);
// 其他活动有长期固定,通过计算时间段内展示次数,算得总分
// 先获得每个人所有的其他活动
List
<
Long
>
practitionerIdList
=
scheduleTrackMapper
.
queryTeamAllPractitionerId
(
practitionerId
);
List
<
PersonalSchedule
>
personalScheduleList
=
scheduleTrackMapper
.
queryPersonalScheduleList
(
practitionerIdList
);
// 根据活动算本日,本周,本月的分数
this
.
computeOtherScore
(
personalScheduleList
,
today
,
weekOne
,
monthOne
);
// 最后合并营销增员和其他活动的分数
this
.
mergeScore
(
personalScheduleList
,
saleAndRecuit
);
resp
.
setPersonalList
(
saleAndRecuit
);
System
.
out
.
println
(
"看看结果集"
);
System
.
out
.
println
(
saleAndRecuit
);
return
resp
;
}
private
void
mergeScore
(
List
<
PersonalSchedule
>
personalScheduleList
,
List
<
Map
<
String
,
Object
>>
saleAndRecuit
)
{
DecimalFormat
df
=
new
DecimalFormat
(
"#.##%"
);
for
(
Map
<
String
,
Object
>
scoreMap:
saleAndRecuit
)
{
for
(
PersonalSchedule
perSchedule:
personalScheduleList
)
{
Long
curPractitionerId
=
perSchedule
.
getPractitionerId
();
if
(
curPractitionerId
.
equals
(
scoreMap
.
get
(
"practitionerId"
)))
{
Map
<
String
,
Long
>
otherMap
=
perSchedule
.
getOther
();
Long
dayScore
=
Long
.
parseLong
(
scoreMap
.
get
(
"dayScore"
).
toString
())
+
otherMap
.
get
(
"dayScore"
);
Long
weekScore
=
Long
.
parseLong
(
scoreMap
.
get
(
"weekScore"
).
toString
())
+
otherMap
.
get
(
"weekScore"
);
Long
monthScore
=
Long
.
parseLong
(
scoreMap
.
get
(
"monthScore"
).
toString
())
+
otherMap
.
get
(
"monthScore"
);
scoreMap
.
put
(
"dayScore"
,
dayScore
);
scoreMap
.
put
(
"weekScore"
,
weekScore
);
scoreMap
.
put
(
"monthScore"
,
monthScore
);
}
}
// 单人分效 scoreMap.get("monthScore").toString()
Double
rate
=
BigDecimal
.
valueOf
(
Double
.
parseDouble
(
scoreMap
.
get
(
"FYC"
).
toString
()))
.
divide
(
BigDecimal
.
valueOf
(
Long
.
parseLong
(
scoreMap
.
get
(
"monthScore"
).
toString
())
),
2
,
BigDecimal
.
ROUND_HALF_UP
)
.
doubleValue
();
scoreMap
.
put
(
"rate"
,
df
.
format
(
rate
));
}
}
private
void
computeOtherScore
(
List
<
PersonalSchedule
>
personalScheduleList
,
Date
today
,
Date
weekOne
,
Date
monthOne
)
{
Integer
trackScore
=
null
;
long
dayOther
=
0L
;
long
weekOther
=
0L
;
long
monthOther
=
0L
;
for
(
PersonalSchedule
perSchedule:
personalScheduleList
)
{
List
<
ScheduleTrack
>
scheduleList
=
perSchedule
.
getScheduleList
();
// 计算所有其他活动的本日,本周,本月得分
for
(
ScheduleTrack
s:
scheduleList
)
{
trackScore
=
s
.
getTrackScore
();
dayOther
+=
this
.
calculateScheduleDisplayCount
(
s
,
today
,
today
)
*
trackScore
;
weekOther
+=
this
.
calculateScheduleDisplayCount
(
s
,
weekOne
,
today
)
*
trackScore
;
monthOther
+=
this
.
calculateScheduleDisplayCount
(
s
,
monthOne
,
today
)
*
trackScore
;
Map
<
String
,
Long
>
map
=
new
HashMap
<>();
map
.
put
(
"dayScore"
,
dayOther
);
map
.
put
(
"weekScore"
,
weekOther
);
map
.
put
(
"monthScore"
,
monthOther
);
perSchedule
.
setOther
(
map
);
}
}
}
private
long
calculateScheduleDisplayCount
(
ScheduleTrack
s
,
Date
firstDay
,
Date
lastDay
)
{
long
count
=
0L
;
if
(
1
==
s
.
getTaskRoutineAtweek1
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
1
);
}
if
(
1
==
s
.
getTaskRoutineAtweek2
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
2
);
}
if
(
1
==
s
.
getTaskRoutineAtweek3
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
3
);
}
if
(
1
==
s
.
getTaskRoutineAtweek4
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
4
);
}
if
(
1
==
s
.
getTaskRoutineAtweek5
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
5
);
}
if
(
1
==
s
.
getTaskRoutineAtweek6
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
6
);
}
if
(
1
==
s
.
getTaskRoutineAtweek7
())
{
count
+=
CommonUtil
.
weekDayCount
(
firstDay
,
lastDay
,
7
);
}
return
count
;
}
}
yd-api/src/main/java/com/yd/api/practitioner/vo/sechedule/QueryPEPScoreResponseVO.java
0 → 100644
View file @
93004b28
package
com
.
yd
.
api
.
practitioner
.
vo
.
sechedule
;
import
com.yd.api.result.CommonResult
;
import
lombok.Data
;
import
java.util.List
;
import
java.util.Map
;
@Data
public
class
QueryPEPScoreResponseVO
{
private
Map
<
String
,
String
>
average
;
private
List
<
Map
<
String
,
Object
>>
personalList
;
private
CommonResult
commonResult
;
}
yd-api/src/main/java/com/yd/dal/entity/practitioner/PersonalSchedule.java
0 → 100644
View file @
93004b28
package
com
.
yd
.
dal
.
entity
.
practitioner
;
import
lombok.Data
;
import
java.util.List
;
import
java.util.Map
;
@Data
public
class
PersonalSchedule
{
private
Long
practitionerId
;
private
List
<
ScheduleTrack
>
scheduleList
;
private
Map
<
String
,
Long
>
other
;
}
yd-api/src/main/java/com/yd/dal/mapper/marketing/ScheduleTrackMapper.java
View file @
93004b28
package
com
.
yd
.
dal
.
mapper
.
marketing
;
import
com.yd.dal.entity.practitioner.PersonalSchedule
;
import
com.yd.dal.entity.practitioner.ScheduleTrack
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
public
interface
ScheduleTrackMapper
{
void
insert
(
ScheduleTrack
schedule
);
List
<
ScheduleTrack
>
queryScheduleTrackList
(
@Param
(
"practitionerId"
)
Long
practitionerId
);
List
<
ScheduleTrack
>
queryScheduleTrackList
(
@Param
(
"practitionerId"
)
Long
practitionerId
);
int
checkTimePeriodConflict
(
@Param
(
"taskTimeFrom"
)
String
taskTimeFrom
,
@Param
(
"taskTimeEnd"
)
String
taskTimeEnd
,
@Param
(
"practitionerId"
)
Long
practitionerId
);
List
<
Map
<
String
,
Object
>>
querySaleRecuitScoreFYC
(
@Param
(
"practitionerId"
)
Long
practitionerId
,
@Param
(
"firstDay"
)
Date
firstDay
,
@Param
(
"lastDay"
)
Date
lastDay
);
List
<
Map
<
String
,
Object
>>
queryOtherScore
(
@Param
(
"practitionerId"
)
Long
practitionerId
);
List
<
Long
>
queryTeamAllPractitionerId
(
@Param
(
"practitionerId"
)
Long
practitionerId
);
List
<
PersonalSchedule
>
queryPersonalScheduleList
(
List
<
Long
>
practitionerIdList
);
}
yd-api/src/main/java/com/yd/util/CommonUtil.java
View file @
93004b28
...
...
@@ -16,6 +16,7 @@ import java.lang.reflect.Method;
import
java.math.BigDecimal
;
import
java.math.BigInteger
;
import
java.net.*
;
import
java.text.DateFormat
;
import
java.text.DecimalFormat
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
...
...
@@ -1465,4 +1466,41 @@ public class CommonUtil {
return
weekDaysCode
[
intWeek
];
}
/**
* 给定时间段和星期几,计算该时间段内共有多少个给定的星期几
* @param start 开始时间
* @param end 结束时间
* @param a 星期几,从星期一到星期天,分别用数字1-7表示
* @return 星期几统计数
*/
public
static
long
weekDayCount
(
Date
start
,
Date
end
,
int
a
){
long
sumDay
=
0
;
//计数
try
{
Calendar
startDate
=
Calendar
.
getInstance
();
//开始时间
startDate
.
setTime
(
start
);
Calendar
endDate
=
Calendar
.
getInstance
();
//结束时间
endDate
.
setTime
(
end
);
int
SW
=
startDate
.
get
(
Calendar
.
DAY_OF_WEEK
)-
1
;
//开始日期是星期几
int
EW
=
endDate
.
get
(
Calendar
.
DAY_OF_WEEK
)-
1
;
//结束日期是星期几
long
diff
=
endDate
.
getTimeInMillis
()-
startDate
.
getTimeInMillis
();
long
days
=
diff
/
(
1000
*
60
*
60
*
24
);
//给定时间段内一共有多少天
long
w
=
Math
.
round
(
Math
.
ceil
(((
days
+
SW
+(
7
-
EW
))/
7.0
)));
//给定时间内,共有多少个星期
sumDay
=
w
;
//总的星期几统计数
if
(
a
<
SW
)
{
//给定的星期几小于起始日期的星期几,需要减少一天
sumDay
--;
}
if
(
a
>
EW
)
{
//给定的星期几大于结束日期的星期几,需要减少一天
sumDay
--;
}
}
catch
(
Exception
se
){
se
.
printStackTrace
();
}
return
sumDay
;
}
}
yd-api/src/main/resources/mapper/marketing/ScheduleTrackMapper.xml
View file @
93004b28
...
...
@@ -87,5 +87,90 @@
</select>
<select
id=
"querySaleRecuitScoreFYC"
resultType=
"hashmap"
>
SELECT practitioner_id, dayScore, weekScore, monthScore, COALESCE(fyc,0) FYC
FROM
(select practitioner_id,
sum(case when to_days(created_at) = to_days(now()) then COALESCE(track_score,0) else 0 end) dayScore,
sum(case when YEARWEEK(date_format(created_at,'%Y-%m-%d'),1) = YEARWEEK(now(),1) then COALESCE(track_score,0) else 0 end) weekScore,
sum(case when date_format(created_at,'%Y-%m')=date_format(now(),'%Y-%m') then COALESCE(track_score,0) else 0 end) monthScore
from ag_mkt_schedule_task_tracking
where is_active = 1
and practitioner_id in (SELECT id from ag_acl_practitioner
where subordinate_system_id =
(select subordinate_system_id from ag_acl_practitioner where id = #{practitionerId,jdbcType=BIGINT})
)
and md_drop_option_id not in (223,224,225,226,227)
and created_at between #{firstDay,jdbcType=TIMESTAMP}
and #{lastDay,jdbcType=TIMESTAMP}
group by practitioner_id
) s
LEFT JOIN
(select t.customer_id, sum(t.fyc_amount) fyc
from ag_acl_customer_fortune t left join ag_po_order o on t.order_id = o.id
where o.`status` =3
and o.payment_status =3
and o.fyc_amount>0
and t.drop_option_code ='S01'
and o.created_at between #{firstDay,jdbcType=TIMESTAMP}
and #{lastDay,jdbcType=TIMESTAMP}
group by t.customer_id
) fyc
ON s.practitioner_id = fyc.customer_id
</select>
<select
id=
"queryTeamAllPractitionerId"
resultType=
"Long"
>
SELECT id from ag_acl_practitioner
where subordinate_system_id =
(select subordinate_system_id from ag_acl_practitioner where id = #{practitionerId,jdbcType=BIGINT})
</select>
<resultMap
id=
"PersonalSchedule"
type=
"com.yd.dal.entity.practitioner.PersonalSchedule"
>
<result
column=
"practitioner_id"
jdbcType=
"BIGINT"
property=
"practitionerId"
/>
<collection
property=
"scheduleList"
ofType=
"com.yd.dal.entity.practitioner.ScheduleTrack"
>
<id
column=
"id"
jdbcType=
"BIGINT"
property=
"id"
/>
<result
column=
"notice"
jdbcType=
"VARCHAR"
property=
"notice"
/>
<result
column=
"task_type"
jdbcType=
"INTEGER"
property=
"taskType"
/>
<result
column=
"refer_leads_id"
jdbcType=
"BIGINT"
property=
"referLeadsId"
/>
<result
column=
"refer_potential_id"
jdbcType=
"BIGINT"
property=
"referPotentialId"
/>
<result
column=
"task_important_tag"
jdbcType=
"INTEGER"
property=
"taskImportantTag"
/>
<result
column=
"task_routine_at_week7"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek7"
/>
<result
column=
"task_routine_at_week6"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek6"
/>
<result
column=
"task_routine_at_week5"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek5"
/>
<result
column=
"task_routine_at_week4"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek4"
/>
<result
column=
"task_routine_at_week3"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek3"
/>
<result
column=
"task_routine_at_week2"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek2"
/>
<result
column=
"task_routine_at_week1"
jdbcType=
"INTEGER"
property=
"taskRoutineAtweek1"
/>
<result
column=
"task_time_from"
jdbcType=
"VARCHAR"
property=
"taskTimeFrom"
/>
<result
column=
"task_time_end"
jdbcType=
"VARCHAR"
property=
"taskTimeEnd"
/>
<result
column=
"is_active"
jdbcType=
"INTEGER"
property=
"isActive"
/>
<result
column=
"practitioner_id"
jdbcType=
"BIGINT"
property=
"practitionerId"
/>
<result
column=
"customer_id"
jdbcType=
"BIGINT"
property=
"customerId"
/>
<result
column=
"md_drop_option_id"
jdbcType=
"BIGINT"
property=
"mdDropOptionId"
/>
<result
column=
"track_score"
jdbcType=
"INTEGER"
property=
"trackScore"
/>
<result
column=
"track_time"
jdbcType=
"TIMESTAMP"
property=
"trackTime"
/>
<result
column=
"created_at"
jdbcType=
"TIMESTAMP"
property=
"createdAt"
/>
<result
column=
"created_by"
jdbcType=
"BIGINT"
property=
"createdBy"
/>
<result
column=
"updated_at"
jdbcType=
"TIMESTAMP"
property=
"updatedAt"
/>
<result
column=
"updated_by"
jdbcType=
"BIGINT"
property=
"updatedBy"
/>
<result
column=
"updator_type"
jdbcType=
"INTEGER"
property=
"updatorType"
/>
<result
column=
"creator_type"
jdbcType=
"INTEGER"
property=
"creatorType"
/>
</collection>
</resultMap>
<select
id=
"queryPersonalScheduleList"
resultMap=
"PersonalSchedule"
>
SELECT id, notice, task_type, refer_leads_id, refer_potential_id,
task_important_tag, task_routine_at_week7,task_routine_at_week6, task_routine_at_week5,
task_routine_at_week4, task_routine_at_week3, task_routine_at_week2, task_routine_at_week1,
task_time_from, task_time_end, is_active, practitioner_id, customer_id, md_drop_option_id, track_score, track_time,
created_at, created_by, updated_at, updated_by, updator_type, creator_type
FROM
ag_mkt_schedule_task_tracking t
WHERE 1=1
AND md_drop_option_id in (223,224,225,226,227)
AND practitioner_id in
<foreach
collection=
"list"
item=
"practitionerId"
index=
"index"
open=
"("
close=
")"
separator=
","
>
#{practitionerId,jdbcType=BIGINT}
</foreach>
</select>
</mapper>
\ No newline at end of file
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