diff --git a/planner.py b/planner.py index 6dbe3ed..15f0131 100644 --- a/planner.py +++ b/planner.py @@ -3,7 +3,7 @@ # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. -from datetime import date +from datetime import date, timedelta from dateutil.rrule import ( rrule, YEARLY, MONTHLY, WEEKLY, DAILY, MO, TU, WE, TH, FR, SA, SU) from trytond.model import ModelSQL, ModelView, fields, Index, DeactivableMixin @@ -281,18 +281,25 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView): return IrDate.today() @classmethod - def update_next_occurence(cls, records): + def update_next_occurence(cls, records, query_date=None): """ compute date of next execution, create/update nextrun-record, delete nextrun-record if scheduled booking is disabled Args: records (list): scheduled-booking records + query_date (date): set date to compute next run, + defaults to 'today+1' """ pool = Pool() IrDate = pool.get('ir.date') NextRun = pool.get('cashbook.planner.nextrun') context = Transaction().context + if not query_date: + query_date = context.get( + 'nextrun_querydate', + IrDate.today() + timedelta(days=1)) + to_create = [] to_write = [] to_delete = [] @@ -304,9 +311,7 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView): elif record.active: # get next-run date next_date = record._compute_dates_by_rrule( - query_date=context.get( - 'nextrun_querydate', IrDate.today()), - count=1) + query_date=query_date, count=1) if next_date: next_date = next_date[0] else: @@ -354,8 +359,28 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView): super(ScheduledBooking, cls).write(*args) cls.update_next_occurence(records) + def run_booking(self): + """ do prepared booking + """ + print('-- booking:', self.rec_name) + @classmethod def cronjob(cls): - pass + """ run planned booking for due jobs, re-schedule for next runs + """ + IrDate = Pool().get('ir.date') + context = Transaction().context + + query_date = context.get('nextrun_crondate', IrDate.today()) + records = cls.search([ + ('active', '=', True), + ('nextrun.date', '<=', query_date)]) + + for record in records: + record.run_booking() + + cls.update_next_occurence( + records, + query_date=query_date + timedelta(days=1)) # ens ScheduledBooking diff --git a/tests/planner.py b/tests/planner.py index 887cf6d..611ce7a 100644 --- a/tests/planner.py +++ b/tests/planner.py @@ -219,35 +219,54 @@ class PlannerTestCase(object): count=1, query_date=date(2022, 5, 1)), [ date(2022, 5, 1)]) - with Transaction().set_context({ - 'nextrun_querydate': date(2022, 5, 25)}): - Planner.update_next_occurence([job]) - self.assertEqual(len(job.nextrun), 1) - self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) + Planner.update_next_occurence([job], query_date=date(2022, 5, 25)) + self.assertEqual(len(job.nextrun), 1) + self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) - with Transaction().set_context({ - 'nextrun_querydate': date(2022, 5, 30)}): - Planner.update_next_occurence([job]) - self.assertEqual(len(job.nextrun), 1) - self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) + Planner.update_next_occurence([job], query_date=date(2022, 5, 30)) + self.assertEqual(len(job.nextrun), 1) + self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) - with Transaction().set_context({ - 'nextrun_querydate': date(2022, 6, 1)}): - Planner.update_next_occurence([job]) - self.assertEqual(len(job.nextrun), 1) - self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) + Planner.update_next_occurence([job], query_date=date(2022, 6, 1)) + self.assertEqual(len(job.nextrun), 1) + self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) + + # cron will use 'today+1' as query_date + Planner.update_next_occurence([job], query_date=date(2022, 6, 2)) + self.assertEqual(len(job.nextrun), 1) + self.assertEqual(job.nextrun[0].date, date(2022, 7, 1)) with Transaction().set_context({ 'nextrun_querydate': date(2022, 6, 2)}): - Planner.update_next_occurence([job]) - self.assertEqual(len(job.nextrun), 1) - self.assertEqual(job.nextrun[0].date, date(2022, 7, 1)) - - with Transaction().set_context({ - 'nextrun_querydate': date(2022, 6, 2)}): - # set end-date to check delete of futore runs + # set end-date to check delete of future runs Planner.write(*[[job], {'end_date': date(2022, 6, 20)}]) # write to planner-record updates nextrun-records too self.assertEqual(len(job.nextrun), 0) + @with_transaction() + def test_planner_run_cronjobs(self): + """ create job, check cron + """ + Planner = Pool().get('cashbook.planner') + + job = self.prep_create_job() + self.assertEqual( + job._compute_dates_by_rrule( + count=1, query_date=date(2022, 5, 1)), [ + date(2022, 5, 1)]) + + with Transaction().set_context({ + 'nextrun_crondate': date(2022, 5, 24)}): + job, = Planner.search([]) + self.assertEqual(job.nextrun[0].date, date(2022, 5, 1)) + Planner.cronjob() + self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) + + with Transaction().set_context({ + 'nextrun_crondate': date(2022, 6, 1)}): + job, = Planner.search([]) + self.assertEqual(job.nextrun[0].date, date(2022, 6, 1)) + Planner.cronjob() + self.assertEqual(job.nextrun[0].date, date(2022, 7, 1)) + # end PlannerTestCase