agroplan-ai-cli 1.0.32 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cli_version": "1.0.
|
|
3
|
-
"backend_template_version": "1.0.
|
|
2
|
+
"cli_version": "1.0.33",
|
|
3
|
+
"backend_template_version": "1.0.33",
|
|
4
4
|
"zarc_index_version": "2025-2026-fast-index-v2",
|
|
5
5
|
"price_index_version": "2025-05-reference-v1",
|
|
6
6
|
"features": [
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"smart_crop_calendar_engine",
|
|
22
22
|
"manual_field_registration",
|
|
23
23
|
"crop_calendar_from_manual_field",
|
|
24
|
-
"expanded_crop_calendar_10_cultures"
|
|
24
|
+
"expanded_crop_calendar_10_cultures",
|
|
25
|
+
"calendar_date_safety"
|
|
25
26
|
],
|
|
26
|
-
"generated_at": "2026-05-
|
|
27
|
+
"generated_at": "2026-05-10T20:00:00Z"
|
|
27
28
|
}
|
|
@@ -875,6 +875,48 @@ def gerar_calendario_cultura(
|
|
|
875
875
|
# Ordenar tarefas por data
|
|
876
876
|
tasks.sort(key=lambda t: t.date)
|
|
877
877
|
|
|
878
|
+
# Detectar e ajustar tarefas no passado
|
|
879
|
+
today = date.today()
|
|
880
|
+
adjusted_tasks_count = 0
|
|
881
|
+
calendar_warnings = []
|
|
882
|
+
|
|
883
|
+
for task in tasks:
|
|
884
|
+
if task.date < today:
|
|
885
|
+
# Marcar tarefa como ajustada
|
|
886
|
+
task.original_date = task.date
|
|
887
|
+
task.date = today
|
|
888
|
+
task.adjusted = True
|
|
889
|
+
|
|
890
|
+
# Aumentar prioridade se não for crítica
|
|
891
|
+
if task.priority != TaskPriority.CRITICAL:
|
|
892
|
+
task.priority = TaskPriority.HIGH
|
|
893
|
+
|
|
894
|
+
# Adicionar observação à descrição
|
|
895
|
+
task.description += f" [AJUSTADA: Data original era {task.original_date.isoformat()}, mas já passou. Tarefa reagendada para hoje.]"
|
|
896
|
+
|
|
897
|
+
adjusted_tasks_count += 1
|
|
898
|
+
|
|
899
|
+
# Adicionar avisos se houver tarefas ajustadas
|
|
900
|
+
if adjusted_tasks_count > 0:
|
|
901
|
+
calendar_warnings.append(
|
|
902
|
+
f"{adjusted_tasks_count} tarefa(s) foram ajustadas porque a data original já havia passado. "
|
|
903
|
+
"Considere escolher uma data de plantio mais distante no futuro."
|
|
904
|
+
)
|
|
905
|
+
|
|
906
|
+
# Verificar se data de plantio está muito próxima
|
|
907
|
+
days_until_planting = (planting_date - today).days
|
|
908
|
+
if days_until_planting <= 7 and days_until_planting >= 0:
|
|
909
|
+
calendar_warnings.append(
|
|
910
|
+
f"Sua data de plantio está em {days_until_planting} dia(s). "
|
|
911
|
+
"Tarefas preparatórias podem ter sido ajustadas. "
|
|
912
|
+
"Recomendamos planejar com pelo menos 2 semanas de antecedência."
|
|
913
|
+
)
|
|
914
|
+
elif days_until_planting < 0:
|
|
915
|
+
calendar_warnings.append(
|
|
916
|
+
"A data de plantio escolhida já passou. "
|
|
917
|
+
"O calendário foi ajustado, mas recomendamos escolher uma data futura."
|
|
918
|
+
)
|
|
919
|
+
|
|
878
920
|
# Montar resposta
|
|
879
921
|
return {
|
|
880
922
|
"cultura": cultura,
|
|
@@ -906,6 +948,9 @@ def gerar_calendario_cultura(
|
|
|
906
948
|
"total_tasks": len(tasks),
|
|
907
949
|
"weather_sensitive_tasks": sum(1 for task in tasks if task.weather_sensitive),
|
|
908
950
|
"critical_tasks": sum(1 for task in tasks if task.priority == TaskPriority.CRITICAL),
|
|
951
|
+
"has_adjusted_tasks": adjusted_tasks_count > 0,
|
|
952
|
+
"adjusted_tasks_count": adjusted_tasks_count,
|
|
953
|
+
"calendar_warnings": calendar_warnings,
|
|
909
954
|
"cautela": "Este calendário é uma base inicial de planejamento. As datas e tarefas devem ser ajustadas conforme clima, solo, cultivar, manejo e orientação técnica."
|
|
910
955
|
}
|
|
911
956
|
|
|
@@ -259,9 +259,11 @@ class CalendarTask:
|
|
|
259
259
|
status: TaskStatus = TaskStatus.PENDING
|
|
260
260
|
weather_sensitive: bool = False
|
|
261
261
|
completed_at: Optional[datetime] = None
|
|
262
|
+
adjusted: bool = False # Se a tarefa foi ajustada por estar no passado
|
|
263
|
+
original_date: Optional[date] = None # Data original antes do ajuste
|
|
262
264
|
|
|
263
265
|
def to_dict(self) -> Dict:
|
|
264
|
-
|
|
266
|
+
result = {
|
|
265
267
|
"id": self.id,
|
|
266
268
|
"crop_plan_id": self.crop_plan_id,
|
|
267
269
|
"date": self.date.isoformat(),
|
|
@@ -272,8 +274,14 @@ class CalendarTask:
|
|
|
272
274
|
"source": self.source,
|
|
273
275
|
"status": self.status.value,
|
|
274
276
|
"weather_sensitive": self.weather_sensitive,
|
|
275
|
-
"completed_at": self.completed_at.isoformat() if self.completed_at else None
|
|
277
|
+
"completed_at": self.completed_at.isoformat() if self.completed_at else None,
|
|
278
|
+
"adjusted": self.adjusted
|
|
276
279
|
}
|
|
280
|
+
|
|
281
|
+
if self.original_date:
|
|
282
|
+
result["original_date"] = self.original_date.isoformat()
|
|
283
|
+
|
|
284
|
+
return result
|
|
277
285
|
|
|
278
286
|
|
|
279
287
|
@dataclass
|