|
|
|
|
@ -19,6 +19,7 @@ from django.db.models import Avg, Sum, Count
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PointService:
|
|
|
|
|
|
|
|
|
|
def update_fact(self, postamat_id: str, fact: int):
|
|
|
|
|
qs = self.get_point_by_postamat_id(postamat_id)
|
|
|
|
|
qs.update(**{'fact': fact})
|
|
|
|
|
@ -28,7 +29,7 @@ class PointService:
|
|
|
|
|
qs.update(**{'postamat_id': postamat_id})
|
|
|
|
|
|
|
|
|
|
def start_mathing(self, obj_id: int, task_name=STATUS_TASK_NAME_IMPORT):
|
|
|
|
|
change_status('Шаг 1. Начинается мэтчинг точек', task_name)
|
|
|
|
|
change_status('Шаг 1 из 3 (Мэтчинг точек).', task_name)
|
|
|
|
|
file = models.TempFiles.objects.get(id=obj_id)
|
|
|
|
|
excel_file = base64.b64decode(file.data)
|
|
|
|
|
df = pd.read_excel(excel_file)
|
|
|
|
|
@ -129,7 +130,7 @@ class PointService:
|
|
|
|
|
matching_status=MatchingStatus.New.name,
|
|
|
|
|
status=PointStatus.Pending.name, area=rayon,
|
|
|
|
|
district=rayon.AO)
|
|
|
|
|
change_status(f'Шаг 1. Обработано {matched + problem} из {total}', task_name)
|
|
|
|
|
change_status(f'Шаг 1 из 3 (Мэчинг точек). Обработано {matched + problem} из {total}', task_name)
|
|
|
|
|
|
|
|
|
|
ts = models.TaskStatus.objects.get(task_name=task_name)
|
|
|
|
|
ts.data = {'total': total, 'matched': matched, 'error': problem, 'unmatched': total - matched - problem}
|
|
|
|
|
@ -137,11 +138,10 @@ class PointService:
|
|
|
|
|
# return total, matched, problem
|
|
|
|
|
|
|
|
|
|
def make_enrichment(self, task_name=STATUS_TASK_NAME_IMPORT):
|
|
|
|
|
change_status('Шаг 2. Начинается обогащение точек', task_name)
|
|
|
|
|
change_status('Шаг 2 из 3 (Обогащение точек).', task_name)
|
|
|
|
|
points = models.PrePlacementPoint.objects.filter(matching_status=MatchingStatus.New.name).all()
|
|
|
|
|
groups = models.Post_and_pvzGroup.objects.all()
|
|
|
|
|
|
|
|
|
|
for point in points:
|
|
|
|
|
for _i, point in enumerate(points):
|
|
|
|
|
origin = point.geometry
|
|
|
|
|
qs = models.PlacementPoint.objects.filter(status=PointStatus.Working.name).annotate(
|
|
|
|
|
dist=Dist('geometry', origin)).order_by('dist')
|
|
|
|
|
@ -157,35 +157,44 @@ class PointService:
|
|
|
|
|
point.rival_pvz_cnt = models.Post_and_pvz.objects.filter(
|
|
|
|
|
category__name="ПВЗ", include_in_ml=True,
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).count()
|
|
|
|
|
point.metro_dist = models.OtherObjects.objects.filter(group__name='metro_stations').annotate(
|
|
|
|
|
dist=Dist('wkt', origin)).order_by('dist')[0].dist.m
|
|
|
|
|
point.property_price_bargains = models.OtherObjects.objects.filter(
|
|
|
|
|
metro = models.OtherObjects.objects.filter(group__name='metro_stations').annotate(
|
|
|
|
|
dist=Dist('wkt', origin)).order_by('dist')
|
|
|
|
|
if metro:
|
|
|
|
|
point.metro_dist = metro[0].dist.m
|
|
|
|
|
bargains = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="bargains",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(Avg('param1'))[
|
|
|
|
|
'param1__avg']
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(Avg('param1'))
|
|
|
|
|
if bargains:
|
|
|
|
|
point.property_price_bargains = bargains['param1__avg']
|
|
|
|
|
offers_estate = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="offers_estate",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(
|
|
|
|
|
param1__avg=Avg('param1'), param3__avg=Avg('param3'))
|
|
|
|
|
if offers_estate:
|
|
|
|
|
point.property_price_offers = offers_estate['param1__avg']
|
|
|
|
|
point.property_mean_floor = offers_estate['param3__avg']
|
|
|
|
|
point.property_era = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="offers_estate").values('param2').annotate(cnt=Count('param2')).order_by('-cnt').first()[
|
|
|
|
|
'param2']
|
|
|
|
|
point.flats_cnt = models.OtherObjects.objects.filter(
|
|
|
|
|
offers_estate = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="offers_estate").values('param2').annotate(cnt=Count('param2')).order_by('-cnt').first()
|
|
|
|
|
if offers_estate:
|
|
|
|
|
point.property_era = offers_estate['param2']
|
|
|
|
|
flats_cnt = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="flats_cnt",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(
|
|
|
|
|
param1__sum=Sum('param1'))['param1__sum']
|
|
|
|
|
param1__sum=Sum('param1'))
|
|
|
|
|
if flats_cnt:
|
|
|
|
|
point.flats_cnt = flats_cnt['param1__sum']
|
|
|
|
|
popul_home_job = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="popul_home_job",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(
|
|
|
|
|
param1__sum=Sum('param1'), param3__sum=Sum('param3'))
|
|
|
|
|
if popul_home_job:
|
|
|
|
|
point.popul_home = popul_home_job['param1__sum']
|
|
|
|
|
point.popul_job = popul_home_job['param3__sum']
|
|
|
|
|
yndx_food_cnt_amt = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="yndx_food_cnt_amt",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(
|
|
|
|
|
param1__sum=Sum('param1'), param3__sum=Sum('param3'))
|
|
|
|
|
if yndx_food_cnt_amt:
|
|
|
|
|
point.yndxfood_sum = yndx_food_cnt_amt['param1__sum']
|
|
|
|
|
point.yndxfood_cnt = yndx_food_cnt_amt['param3__sum']
|
|
|
|
|
point.school_cnt = models.OtherObjects.objects.filter(
|
|
|
|
|
@ -236,10 +245,12 @@ class PointService:
|
|
|
|
|
point.tc_cnt = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="TC",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).count()
|
|
|
|
|
point.business_activity = models.OtherObjects.objects.filter(
|
|
|
|
|
business_activity = models.OtherObjects.objects.filter(
|
|
|
|
|
group__name="business_activity",
|
|
|
|
|
wkt__distance_lt=(origin, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).aggregate(
|
|
|
|
|
param1__sum=Sum('param1'))['param1__sum']
|
|
|
|
|
param1__sum=Sum('param1'))
|
|
|
|
|
if business_activity:
|
|
|
|
|
point.business_activity = business_activity['param1__sum']
|
|
|
|
|
point.age_day = AGE_DAY_LIMIT
|
|
|
|
|
placement_point = models.PlacementPoint.objects.annotate(
|
|
|
|
|
dist=Dist('geometry', origin)).order_by('dist')
|
|
|
|
|
@ -250,20 +261,19 @@ class PointService:
|
|
|
|
|
for group in groups:
|
|
|
|
|
self.calculate_dist_for_group(point, group, instance_type=models.PrePlacementPointPVZDistance)
|
|
|
|
|
change_status(
|
|
|
|
|
f'Шаг 2. Обогащено {points.filter(matching_status=MatchingStatus.Matched.name).count()} из {points.count()}',
|
|
|
|
|
f'Шаг 2 из 3 (Обогащение точек). Обработано {_i} из {points.count()}',
|
|
|
|
|
task_name)
|
|
|
|
|
|
|
|
|
|
run_psql_command()
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def calculate_dist_for_group(point, group, instance_type=models.PlacementPointPVZDistance):
|
|
|
|
|
post_object = models.Post_and_pvz.objects.filter(group__name=group.name).annotate(
|
|
|
|
|
post_object = models.Post_and_pvz.objects.filter(group__id=group.id).annotate(
|
|
|
|
|
distance=Dist("wkt", point.geometry)).order_by('distance').first()
|
|
|
|
|
d = instance_type.objects.filter(placement_point=point,
|
|
|
|
|
pvz_postamates_group=group).first()
|
|
|
|
|
if post_object:
|
|
|
|
|
if d:
|
|
|
|
|
if d.dist > post_object.distance.m:
|
|
|
|
|
d.dist = post_object.distance.m
|
|
|
|
|
d.save()
|
|
|
|
|
else:
|
|
|
|
|
|