diff --git a/rowers/courseutils.py b/rowers/courseutils.py
index 75130af5..2ce31fb3 100644
--- a/rowers/courseutils.py
+++ b/rowers/courseutils.py
@@ -95,5 +95,5 @@ def coursetime_paths(data,paths,finalmaxmin='min'):
entrytime = data['time'].max()
entrydistance = data['cum_dist'].max()
coursecompleted = False
-
+
return entrytime, entrydistance, coursecompleted
diff --git a/rowers/models.py b/rowers/models.py
index 38151ee3..cbc298ef 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -840,6 +840,7 @@ def checkworkoutuser(user,workout):
except Rower.DoesNotExist:
return False
+
# Check if user is coach or rower
def checkaccessuser(user,rower):
try:
@@ -979,11 +980,60 @@ class TrainingTargetForm(ModelForm):
class TrainingPlan(models.Model):
rower = models.ForeignKey(Rower)
name = models.CharField(max_length=150,blank=True)
- target = models.ForeignKey(TrainingTarget,blank=True)
+ target = models.ForeignKey(TrainingTarget,blank=True,null=True)
startdate = models.DateField(default=timezone.now)
enddate = models.DateField(
default=half_year_from_now)
+ def __unicode__(self):
+ name = self.name
+ startdate = self.startdate
+ enddate = self.enddate
+ firstname = self.rower.user.first_name
+ lastname = self.rower.user.last_name
+
+ stri = u'Training Plan for {firstname} {lastname} {s} - {e}: {name}'.format(
+ s = startdate.strftime('%Y-%m-%d'),
+ e = enddate.strftime('%Y-%m-%d'),
+ firstname = firstname,
+ lastname = lastname,
+ name=name
+ )
+
+ return stri
+
+ def save(self, *args, **kwargs):
+ if self.enddate < self.startdate:
+ startdate = self.startdate
+ enddate = self.enddate
+ self.startdate = enddate
+ self.enddate = startdate
+
+ otherplans = TrainingPlan.objects.filter(rower=self.rower).exclude(pk=self.pk).order_by("-startdate")
+
+ for otherplan in otherplans:
+ if otherplan.startdate <= self.enddate and otherplan.startdate >= self.startdate:
+ self.enddate = otherplan.startdate-datetime.timedelta(days=1)
+ if otherplan.enddate >= self.startdate and otherplan.enddate <= self.enddate:
+ self.startdate = otherplan.enddate+datetime.timedelta(days=1)
+
+ if not self.enddate <= self.startdate:
+ super(TrainingPlan,self).save(*args, **kwargs)
+
+ macrocycles = TrainingMacroCycle.objects.filter(plan = self)
+ if not macrocycles:
+ m = TrainingMacroCycle(
+ plan = self,
+ name = 'Filler',
+ startdate = self.startdate,
+ enddate = self.enddate,
+ )
+
+ m.save()
+
+ else:
+ createmacrofillers(self)
+
class TrainingPlanForm(ModelForm):
class Meta:
model = TrainingPlan
@@ -1009,6 +1059,253 @@ cycletypechoices = (
('userdefined','User Defined')
)
+def createmacrofillers(plan):
+ fillers = TrainingMacroCycle.objects.filter(
+ plan = plan, type = 'filler'
+ )
+
+ for f in fillers:
+ f.delete()
+
+ cycles = TrainingMacroCycle.objects.filter(
+ plan = plan
+ ).order_by("-startdate")
+
+ if not cycles:
+ macr = TrainingMacroCycle(
+ plan=plan,
+ startdate = plan.startdate,
+ enddate = plan.enddate,
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+
+ thedate = plan.enddate
+ while cycles:
+ if cycles[0].enddate < thedate:
+ macr = TrainingMacroCycle(
+ plan=plan,
+ startdate = cycles[0].enddate+datetime.timedelta(days=1),
+ enddate = thedate,
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+ thedate = cycles[0].startdate-datetime.timedelta(days=1)
+ cycles = cycles[1:]
+
+ cycles = TrainingMacroCycle.objects.filter(
+ plan = plan
+ ).order_by("startdate")
+
+ if cycles[0].startdate > plan.startdate:
+ macr = TrainingMacroCycle(
+ plan=plan,
+ startdate = plan.startdate,
+ enddate = cycles[0].startdate-datetime.timedelta(days=1),
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+
+def createmesofillers(plan):
+ fillers = TrainingMesoCycle.objects.filter(
+ plan = plan, type = 'filler'
+ )
+
+ for f in fillers:
+ f.delete()
+
+ cycles = TrainingMesoCycle.objects.filter(
+ plan = plan
+ ).order_by("-startdate")
+
+ if not cycles:
+ macr = TrainingMesoCycle(
+ plan = plan,
+ startdate = plan.startdate,
+ enddate = plan.enddate,
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+
+ thedate = plan.enddate
+ while cycles:
+ if cycles[0].enddate < thedate:
+ macr = TrainingMesoCycle(
+ plan=plan,
+ startdate = cycles[0].enddate+datetime.timedelta(days=1),
+ enddate = thedate,
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+ thedate = cycles[0].startdate-datetime.timedelta(days=1)
+ cycles = cycles[1:]
+
+ cycles = TrainingMesoCycle.objects.filter(
+ plan = plan
+ ).order_by("startdate")
+
+ if cycles[0].startdate > plan.startdate:
+ macr = TrainingMesoCycle(
+ plan=plan,
+ startdate = plan.startdate,
+ enddate = cycles[0].startdate-datetime.timedelta(days=1),
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+
+
+def createmicrofillers(plan):
+ fillers = TrainingMicroCycle.objects.filter(
+ plan = plan, type = 'filler'
+ )
+
+ for f in fillers:
+ f.delete()
+
+ cycles = TrainingMicroCycle.objects.filter(
+ plan = plan
+ ).order_by("-startdate")
+
+ if not cycles:
+ macr = TrainingMicroCycle(
+ plan=plan,
+ startdate = plan.startdate,
+ enddate = plan.enddate,
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+
+ thedate = plan.enddate
+ while cycles:
+ if cycles[0].enddate < thedate:
+ macr = TrainingMicroCycle(
+ plan=plan,
+ startdate = cycles[0].enddate+datetime.timedelta(days=1),
+ enddate = thedate,
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+ thedate = cycles[0].startdate-datetime.timedelta(days=1)
+ cycles = cycles[1:]
+
+ cycles = TrainingMicroCycle.objects.filter(
+ plan = plan
+ ).order_by("startdate")
+
+ if cycles[0].startdate > plan.startdate:
+ macr = TrainingMicroCycle(
+ plan=plan,
+ startdate = plan.startdate,
+ enddate = cycles[0].startdate-datetime.timedelta(days=1),
+ type='filler',
+ name='Filler'
+ )
+ macr.save()
+
+def microcyclecheckdates(plan):
+ cycles = TrainingMicroCycle.objects.filter(
+ plan=plan
+ ).order_by("-startdate")
+
+ thedate = plan.enddate
+ while cycles:
+ if cycles[0].enddate < plan.startdate:
+ cycles[0].delete()
+ if cycles[0].startdate > plan.enddate:
+ cycles[0].delete()
+ if cycles[0].enddate > thedate:
+ cycles[0].enddate = thedate
+ cycles[0].save()
+ thedate = cycles[0].startdate-datetime.timedelta(days=1)
+ cycles = cycles[1:]
+
+ cycles = TrainingMicroCycle.objects.filter(
+ plan=plan
+ ).order_by("startdate")
+
+ thedate = plan.startdate
+ while cycles:
+ if cycles[0].startdate < thedate:
+ cycles[0].startdate = thedate
+ cycles[0].save()
+ try:
+ thedate = cycles[1].startdate-datetime.timedelta(days=1)
+ except IndexError:
+ pass
+ cycles = cycles[1:]
+
+def mesocyclecheckdates(plan):
+ cycles = TrainingMesoCycle.objects.filter(
+ plan=plan
+ ).order_by("-startdate")
+
+ thedate = plan.enddate
+ while cycles:
+ if cycles[0].enddate < plan.startdate:
+ cycles[0].delete()
+ if cycles[0].startdate > plan.enddate:
+ cycles[0].delete()
+ if cycles[0].enddate > thedate:
+ cycles[0].enddate = thedate
+ cycles[0].save()
+ thedate = cycles[0].startdate-datetime.timedelta(days=1)
+ cycles = cycles[1:]
+
+ cycles = TrainingMesoCycle.objects.filter(
+ plan=plan
+ ).order_by("startdate")
+
+ thedate = plan.startdate
+ while cycles:
+ if cycles[0].startdate < thedate:
+ cycles[0].startdate = thedate
+ cycles[0].save()
+ try:
+ thedate = cycles[1].startdate-datetime.timedelta(days=1)
+ except IndexError:
+ pass
+ cycles = cycles[1:]
+
+def macrocyclecheckdates(plan):
+ cycles = TrainingMacroCycle.objects.filter(
+ plan=plan
+ ).order_by("-startdate")
+
+ thedate = plan.enddate
+ while cycles:
+ if cycles[0].enddate < plan.startdate:
+ cycles[0].delete()
+ if cycles[0].startdate > plan.enddate:
+ cycles[0].delete()
+ if cycles[0].enddate > thedate:
+ cycles[0].enddate = thedate
+ cycles[0].save()
+ thedate = cycles[0].startdate-datetime.timedelta(days=1)
+ cycles = cycles[1:]
+
+ cycles = TrainingMacroCycle.objects.filter(
+ plan=plan
+ ).order_by("startdate")
+
+ thedate = plan.startdate
+ while cycles:
+ if cycles[0].startdate < thedate:
+ cycles[0].startdate = thedate
+ cycles[0].save()
+ try:
+ thedate = cycles[1].startdate-datetime.timedelta(days=1)
+ except IndexError:
+ pass
+ cycles = cycles[1:]
+
class TrainingMacroCycle(models.Model):
plan = models.ForeignKey(TrainingPlan)
name = models.CharField(max_length=150,blank=True)
@@ -1016,10 +1313,85 @@ class TrainingMacroCycle(models.Model):
enddate = models.DateField(
default=half_year_from_now)
notes = models.TextField(max_length=300,blank=True)
+
type = models.CharField(default='filler',
choices=cycletypechoices,
max_length=150)
+ plantime = models.IntegerField(default=0,verbose_name='Planned Duration')
+ plandistance = models.IntegerField(default=0,verbose_name='Planned Distance')
+ planrscore = models.IntegerField(default=0,verbose_name='Planned rScore')
+ plantrimp = models.IntegerField(default=0,verbose_name='Planned TRIMP')
+
+ actualtime = models.IntegerField(default=0,verbose_name='Actual Duration')
+ actualdistance = models.IntegerField(default=0,verbose_name='Actual Distance')
+ actualrscore = models.IntegerField(default=0,verbose_name='Actual rScore')
+ actualtrimp = models.IntegerField(default=0,verbose_name='Actual TRIMP')
+
+ def __unicode__(self):
+ stri = 'Macro Cycle - {n} ({sd} - {ed})'.format(
+ n = self.name,
+ sd = self.startdate,
+ ed = self.enddate,
+ )
+
+ return stri
+
+ def save(self, *args, **kwargs):
+ if self.enddate < self.startdate:
+ startdate = self.startdate
+ enddate = self.enddate
+ self.startdate = enddate
+ self.enddate = startdate
+
+ fillers = TrainingMacroCycle.objects.filter(
+ plan=self.plan,type='filler')
+ for f in fillers:
+ f.delete()
+
+ if self.enddate > self.plan.enddate:
+ self.enddate = self.plan.enddate
+
+ if self.startdate < self.plan.startdate:
+ self.startdate = self.plan.startdate
+
+ othercycles = TrainingMacroCycle.objects.filter(
+ plan=self.plan).exclude(pk=self.pk).order_by("-startdate")
+
+ for othercycle in othercycles:
+ if othercycle.startdate <= self.enddate and othercycle.startdate >= self.startdate:
+ self.enddate = othercycle.startdate-datetime.timedelta(days=1)
+
+ if othercycle.enddate >= self.startdate and othercycle.enddate <= self.enddate:
+ self.startdate = othercycle.enddate+datetime.timedelta(days=1)
+
+ if not self.enddate <= self.startdate:
+ super(TrainingMacroCycle,self).save(*args, **kwargs)
+
+
+ mesocycles = TrainingMesoCycle.objects.filter(plan = self)
+ if not mesocycles:
+ meso = TrainingMesoCycle(
+ plan = self,
+ name = 'Filler',
+ startdate = self.startdate,
+ enddate = self.enddate,
+ )
+
+ meso.save()
+ else:
+ createmesofillers(self)
+
+class TrainingMacroCycleForm(ModelForm):
+ class Meta:
+ model = TrainingMacroCycle
+ fields = ['name','startdate','enddate','notes']
+
+ widgets = {
+ 'startdate': AdminDateWidget(),
+ 'enddate': AdminDateWidget()
+ }
+
class TrainingMesoCycle(models.Model):
plan = models.ForeignKey(TrainingMacroCycle)
name = models.CharField(max_length=150,blank=True)
@@ -1031,6 +1403,69 @@ class TrainingMesoCycle(models.Model):
choices=cycletypechoices,
max_length=150)
+ plantime = models.IntegerField(default=0,verbose_name='Planned Duration')
+ plandistance = models.IntegerField(default=0,verbose_name='Planned Distance')
+ planrscore = models.IntegerField(default=0,verbose_name='Planned rScore')
+ plantrimp = models.IntegerField(default=0,verbose_name='Planned TRIMP')
+
+ actualtime = models.IntegerField(default=0,verbose_name='Actual Duration')
+ actualdistance = models.IntegerField(default=0,verbose_name='Actual Distance')
+ actualrscore = models.IntegerField(default=0,verbose_name='Actual rScore')
+ actualtrimp = models.IntegerField(default=0,verbose_name='Actual TRIMP')
+
+
+ def __unicode__(self):
+ stri = 'Meso Cycle - {n} ({sd} - {ed})'.format(
+ n = self.name,
+ sd = self.startdate,
+ ed = self.enddate,
+ )
+
+ return stri
+
+ def save(self, *args, **kwargs):
+ if self.enddate < self.startdate:
+ startdate = self.startdate
+ enddate = self.enddate
+ self.startdate = enddate
+ self.enddate = startdate
+
+ fillers = TrainingMesoCycle.objects.filter(
+ plan=self.plan,type='filler')
+ for f in fillers:
+ f.delete()
+
+ if self.enddate > self.plan.enddate:
+ self.enddate = self.plan.enddate
+
+ if self.startdate < self.plan.startdate:
+ self.startdate = self.plan.startdate
+
+ othercycles = TrainingMesoCycle.objects.filter(
+ plan=self.plan).exclude(pk=self.pk).order_by("-startdate")
+
+ for othercycle in othercycles:
+ if othercycle.startdate <= self.enddate and othercycle.startdate >= self.startdate:
+ self.enddate = othercycle.startdate-datetime.timedelta(days=1)
+
+ if othercycle.enddate >= self.startdate and othercycle.enddate <= self.enddate:
+ self.startdate = othercycle.enddate+datetime.timedelta(days=1)
+
+ if not self.enddate <= self.startdate:
+ super(TrainingMesoCycle,self).save(*args, **kwargs)
+
+ microcycles = TrainingMicroCycle.objects.filter(plan = self)
+ if not microcycles:
+ micro = TrainingMicroCycle(
+ plan = self,
+ name = 'Filler',
+ startdate = self.startdate,
+ enddate = self.enddate,
+ )
+
+ micro.save()
+ else:
+ createmicrofillers(self)
class TrainingMicroCycle(models.Model):
plan = models.ForeignKey(TrainingMesoCycle)
@@ -1043,15 +1478,81 @@ class TrainingMicroCycle(models.Model):
choices=cycletypechoices,
max_length=150)
+ plantime = models.IntegerField(default=0,verbose_name='Planned Duration')
+ plandistance = models.IntegerField(default=0,verbose_name='Planned Distance')
+ planrscore = models.IntegerField(default=0,verbose_name='Planned rScore')
+ plantrimp = models.IntegerField(default=0,verbose_name='Planned TRIMP')
-# Needs some error checking
-# - Microcycles should not overlap with other microcycles, same for MesoCycles, MacroCycles
-# - When a TrainingPlan is created, it should create 1 "collector" Macro, Meso & MicroCycle - this is invisible for users who choose to not use cycles
-# - When a new Microcycle is inserted, the "collector" cycle is automatically adjusted to "go out of the way" of the new MicroCycle - and similar for Macro & Meso
-# - If the entire MesoCycle is filled with user defined MicroCycles - there are no "filler" MicroCycles
-# - Sessions are automatically linked to the correct Cycles based on their start/end date - no need for a hard link
+ actualtime = models.IntegerField(default=0,verbose_name='Actual Duration')
+ actualdistance = models.IntegerField(default=0,verbose_name='Actual Distance')
+ actualrscore = models.IntegerField(default=0,verbose_name='Actual rScore')
+ actualtrimp = models.IntegerField(default=0,verbose_name='Actual TRIMP')
+
+
+
+
+ def __unicode__(self):
+ stri = 'Micro Cycle - {n} ({sd} - {ed})'.format(
+ n = self.name,
+ sd = self.startdate,
+ ed = self.enddate,
+ )
+
+ return stri
+
+ def save(self, *args, **kwargs):
+ if self.enddate < self.startdate:
+ startdate = self.startdate
+ enddate = self.enddate
+ self.startdate = enddate
+ self.enddate = startdate
+
+ fillers = TrainingMicroCycle.objects.filter(
+ plan=self.plan,type='filler')
+ for f in fillers:
+ f.delete()
+
+ if self.enddate > self.plan.enddate:
+ self.enddate = self.plan.enddate
+
+ if self.startdate < self.plan.startdate:
+ self.startdate = self.plan.startdate
+
+ othercycles = TrainingMicroCycle.objects.filter(
+ plan=self.plan).exclude(pk=self.pk).order_by("-startdate")
+
+ for othercycle in othercycles:
+ if othercycle.startdate <= self.enddate and othercycle.startdate >= self.startdate:
+ self.enddate = othercycle.startdate-datetime.timedelta(days=1)
+
+ if othercycle.enddate >= self.startdate and othercycle.enddate <= self.enddate:
+ self.startdate = othercycle.enddate+datetime.timedelta(days=1)
+
+
+
+ if not self.enddate <= self.startdate:
+ super(TrainingMicroCycle,self).save(*args, **kwargs)
+
+class TrainingMesoCycleForm(ModelForm):
+ class Meta:
+ model = TrainingMesoCycle
+ fields = ['name','startdate','enddate','notes']
+
+ widgets = {
+ 'startdate': AdminDateWidget(),
+ 'enddate': AdminDateWidget()
+ }
+
+class TrainingMicroCycleForm(ModelForm):
+ class Meta:
+ model = TrainingMicroCycle
+ fields = ['name','startdate','enddate','notes']
+
+ widgets = {
+ 'startdate': AdminDateWidget(),
+ 'enddate': AdminDateWidget()
+ }
-# Cycle error checking goes in forms
# model for Planned Session (Workout, Challenge, Test)
class PlannedSession(models.Model):
diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index 4134ed87..46b7f326 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -10,7 +10,7 @@ import uuid
from django.conf import settings
import pytz
from utils import myqueue,calculate_age,totaltime_sec_to_string
-
+import re
import django_rq
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
@@ -296,52 +296,28 @@ def is_session_complete_ws(ws,ps):
if record.coursecompleted:
ratio = record.distance/ps.sessionvalue
return ratio,'completed',completiondate
-
- if ps.course:
- (
- coursetime,
- coursemeters,
- coursecompleted
- ) = get_time_course(ws,ps.course)
- if coursecompleted:
- return 1.0,'completed',completiondate
- else:
- return ratio,'partial',completiondate
- else:
- if ps.criterium == 'exact':
- if ratio == 1.0:
- return ratio,'completed',completiondate
- else:
- if not completiondate:
- completiondate = ws.reverse()[0].date
- return ratio,'partial',completiondate
- elif ps.criterium == 'minimum':
- if ratio >= 1.0:
- return ratio,'completed',completiondate
- else:
- if not completiondate:
- completiondate = ws.reverse()[0].date
-
- return ratio,'partial',completiondate
- else:
- if ratio>cratiomin and ratio
+ {% if user|is_planmember %} + Power Progress + {% else %} + Power Progress + {% endif %} +
++ Monitoring power duration evidence from all your workouts. Feel free to explore. +
+{% if user|is_planmember %} The Labs diff --git a/rowers/templates/laboratory.html b/rowers/templates/laboratory.html index 9b5b2964..1485f78a 100644 --- a/rowers/templates/laboratory.html +++ b/rowers/templates/laboratory.html @@ -24,13 +24,13 @@
{% if user|is_planmember %} - Power Progress + Training Target {% else %} - Power Progress + Training Target {% endif %}
- Monitoring power duration evidence from all your workouts. Feel free to explore. + Experiments with a training target and plan builder
- {% if timeperiod and rower %} - Plan Overview - {% elif timeperiod %} - Plan Overview - {% else %} - Plan Overview - {% endif %} -
+diff --git a/rowers/templates/trainingplan.html b/rowers/templates/trainingplan.html new file mode 100644 index 00000000..e3d67466 --- /dev/null +++ b/rowers/templates/trainingplan.html @@ -0,0 +1,221 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% load rowerfilters %} + +{% block title %}Rowsandall Training Plans{% endblock %} + +{% block scripts %} + +{% endblock %} + +{% block content %} + + +
This plan starts on {{ plan.startdate }} and ends on {{ plan.enddate }}. The training plan target is: {{ plan.target.name }} on {{ plan.target.date }}.
+ +| + {{ macrocycle.0.name }} ({{ macrocycle.0.startdate }} - {{ macrocycle.0.enddate }}) + | +||||
|---|---|---|---|---|
| + | dist (m) | +t (min) | +rScore | +TRIMP | +
| plan | +{{ macrocycle.0.plandistance }} | +{{ macrocycle.0.plantime }} | +{{ maccrocycle.0.planrscore }} | +{{ macrocycle.0.plantrimp }} | +
| actual | +{{ macrocycle.0.actualdistance }} | +{{ macrocycle.0.actualtime }} | +{{ macrocycle.0.actualrscore }} | +{{ macrocycle.0.actualtrimp }} | +
| + | ||||
| + edit + / + delete + / + sessions + | +||||
| + {{ mesocycle.0.name }} ({{ mesocycle.0.startdate }} - {{ mesocycle.0.enddate }}) + | +||||
|---|---|---|---|---|
| + | dist (m) | +t (min) | +rScore | +TRIMP | +
| plan | +{{ mesocycle.0.plandistance }} | +{{ mesocycle.0.plantime }} | +{{ mesocycle.0.planrscore }} | +{{ mesocycle.0.plantrimp }} | +
| actual | +{{ mesocycle.0.actualdistance }} | +{{ mesocycle.0.actualtime }} | +{{ mesocycle.0.actualrscore }} | +{{ mesocycle.0.actualtrimp }} | +
| + | ||||
| + edit + / + delete + / + sessions + | +||||
| + {{ microcycle.name }} ({{ microcycle.startdate }} - {{ microcycle.enddate }}) + | +||||
|---|---|---|---|---|
| + | dist (m) | +t (min) | +rScore | +TRIMP | +
| plan | +{{ microcycle.plandistance }} | +{{ microcycle.plantime }} | +{{ microcycle.planrscore }} | +{{ microcycle.plantrimp }} | +
| actual | +{{ microcycle.actualdistance }} | +{{ microcycle.actualtime }} | +{{ microcycle.actualrscore }} | +{{ microcycle.actualtrimp }} | +
| + | ||||
| + edit + / + delete + / + sessions + | +||||
Click on the plan cycles to edit their names, start and end dates. The gray "filler" + cycles are generated, adjusted and deleted automatically to ensure the entire plan + duration is covered with non-overlapping cycles. + Once you edit a filler cycle, it become a user-defined cycle, which cannot be deleted + by the system.
+Filler cycles which have a filler cycle as a parent cannot be edited + or deleted. You have to edit the parent cycle first. The reason is + that children of filler cycles are not safe. They are deleted when + their parent is deleted by the system.
+Click on "Sessions" in the cycle of your interest to see details + of the individual training sessions planned for this period.
+A good way to organize the plan is to think of micro cycles as training weeks. Macro cycles + are typically used to address specific phases of preparation and to indicate the racing + season and may span several months. + Meso cycles can be used to group sequences of three to five light, medium and + hard weeks. It is recommended to work from left to right, starting with the macro cycles.
+