diff --git a/accountant/api/models/scheduled_operations.py b/accountant/api/models/scheduled_operations.py index 4819864..a1db35e 100644 --- a/accountant/api/models/scheduled_operations.py +++ b/accountant/api/models/scheduled_operations.py @@ -81,31 +81,42 @@ class ScheduledOperation(db.Model): ).delete() # 2) schedule remaining operations. + # Find the first date to have all dates in the range with the right day. start_date = arrow.get(self.start_date) + day = min(self.day, monthrange(start_date.year, start_date.month)[1]) + + # First date is in the next month is below the start date day. + if day < start_date.day: + start_date = start_date.replace(months=+1) + start_date = start_date.replace(day=day) + + # Stop date remains the same. stop_date = arrow.get(self.stop_date) - for r in arrow.Arrow.range( + # Iterate over the range. + for c_date in arrow.Arrow.range( "month", start_date, stop_date )[::self.frequency]: - current_monthrange = monthrange(r.year, r.month) + # If a date day is below the first date day, next dates will not + # have the right day. + day = min(self.day, monthrange( + c_date.year, c_date.month)[1]) - day = max(self.day, current_monthrange[0]) - day = min(self.day, current_monthrange[1]) - - r.replace(day=day) + c_date = c_date.replace(day=day) # Search if a close operation exists. + if not session.query( Operation ).filter( Operation.account_id == self.account_id, Operation.scheduled_operation_id == self.id, - Operation.operation_date >= r.clone().replace(weeks=-2).date(), - Operation.operation_date <= r.clone().replace(weeks=+2).date() + Operation.operation_date >= c_date.replace(weeks=-2).date(), + Operation.operation_date <= c_date.replace(weeks=+2).date() ).count(): # Create not confirmed operation if not found. operation = Operation( - operation_date=r.date(), + operation_date=c_date.date(), label=self.label, value=self.value, category=self.category,