From 9f3e33d225c5c532873d83f3e86bcdbdb15315c1 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Tue, 27 Feb 2024 22:40:59 +0100 Subject: [PATCH] add cronjob --- __init__.py | 4 + cron.py | 18 +++ cron.xml | 15 ++ locale/de.po | 28 ++++ locale/en.po | 340 +++++++++++++++++++++--------------------- nextrun.py | 30 ++++ planner.py | 51 +++++++ tests/planner.py | 15 ++ tryton.cfg | 1 + view/planner_form.xml | 4 + view/planner_list.xml | 1 + 11 files changed, 339 insertions(+), 168 deletions(-) create mode 100644 cron.py create mode 100644 cron.xml create mode 100644 nextrun.py diff --git a/__init__.py b/__init__.py index 53c377a..965ecf3 100644 --- a/__init__.py +++ b/__init__.py @@ -7,11 +7,15 @@ from trytond.pool import Pool from .ir import Rule from .planner import ScheduledBooking from .cashbook import Cashbook +from .cron import Cron +from .nextrun import NextRun def register(): Pool.register( Rule, ScheduledBooking, + NextRun, Cashbook, + Cron, module='cashbook_planner', type_='model') diff --git a/cron.py b/cron.py new file mode 100644 index 0000000..5c411dc --- /dev/null +++ b/cron.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# This file is part of the cashbook-planner from m-ds for Tryton. +# The COPYRIGHT file at the top level of this repository contains the +# full copyright notices and license terms. + +from trytond.pool import PoolMeta + + +class Cron(metaclass=PoolMeta): + __name__ = 'ir.cron' + + @classmethod + def __setup__(cls): + super(Cron, cls).__setup__() + cls.method.selection.append( + ('cashbook.planner|cronjob', "Execute scheduled bookings")) + +# end Cron diff --git a/cron.xml b/cron.xml new file mode 100644 index 0000000..ba9450d --- /dev/null +++ b/cron.xml @@ -0,0 +1,15 @@ + + + + + + + cashbook.planner|cronjob + + days + + + + diff --git a/locale/de.po b/locale/de.po index 480d2ae..a08bed0 100644 --- a/locale/de.po +++ b/locale/de.po @@ -3,6 +3,14 @@ msgid "" msgstr "Content-Type: text/plain; charset=utf-8\n" +########### +# ir.cron # +########### +msgctxt "selection:ir.cron,method:" +msgid "Execute scheduled bookings" +msgstr "geplante Buchungen ausführen" + + ############# # res.group # ############# @@ -182,6 +190,26 @@ msgctxt "help:cashbook.planner,setpos:" msgid "For example, if you want to run the rule on the second Wednesday of the month, enter 2 here." msgstr "Wenn Sie die Regel z.B. am zweiten Mittwoch im Monat ausführen möchten, tragen Sie hier 2 ein." +msgctxt "field:cashbook.planner,nextrun:" +msgid "Next Execution Date" +msgstr "Nächster Ausführungstermin" + + +############################ +# cashbook.planner.nextrun # +############################ +msgctxt "model:cashbook.planner.nextrun,name:" +msgid "Next Execution Date" +msgstr "Nächster Ausführungstermin" + +msgctxt "field:cashbook.planner.nextrun,planner:" +msgid "Planner" +msgstr "geplante Buchung" + +msgctxt "field:cashbook.planner.nextrun,date:" +msgid "Date" +msgstr "Datum" + ################# # cashbook.book # diff --git a/locale/en.po b/locale/en.po index 10a9846..ba49c61 100644 --- a/locale/en.po +++ b/locale/en.po @@ -1,168 +1,172 @@ -# -msgid "" -msgstr "Content-Type: text/plain; charset=utf-8\n" - -msgctxt "model:res.group,name:group_planner" -msgid "Cashbook - Scheduled Bookings" -msgstr "Cashbook - Scheduled Bookings" - -msgctxt "model:ir.ui.menu,name:menu_planner" -msgid "Scheduled Bookings" -msgstr "Scheduled Bookings" - -msgctxt "model:ir.action,name:act_planner_view" -msgid "Scheduled Bookings" -msgstr "Scheduled Bookings" - -msgctxt "model:ir.rule.group,name:rg_planner_write_admin" -msgid "Administrators: scheduled bookings read/write" -msgstr "Administrators: scheduled bookings read/write" - -msgctxt "model:ir.rule.group,name:rg_planner_owner" -msgid "Owners: scheduled bookings" -msgstr "Owners: scheduled bookings" - -msgctxt "model:ir.rule.group,name:rg_planner_read_nonowner" -msgid "Observers: scheduled bookings read" -msgstr "Observers: scheduled bookings read" - -msgctxt "model:ir.rule.group,name:rg_planner_write_nonowner" -msgid "Reviewer: scheduled bookings write" -msgstr "Reviewer: scheduled bookings write" - -msgctxt "model:ir.rule.group,name:rg_planner_companies" -msgid "User in companies" -msgstr "User in companies" - -msgctxt "model:cashbook.planner,name:" -msgid "Scheduled Booking" -msgstr "Scheduled Booking" - -msgctxt "view:cashbook.planner:" -msgid "Recurrence Rule" -msgstr "Recurrence Rule" - -msgctxt "view:cashbook.planner:" -msgid "Result of the recurrence rule" -msgstr "Result of the recurrence rule" - -msgctxt "field:cashbook.planner,company:" -msgid "Company" -msgstr "Company" - -msgctxt "field:cashbook.planner,cashbook:" -msgid "Cashbook" -msgstr "Cashbook" - -msgctxt "help:cashbook.planner,cashbook:" -msgid "Cash book for which the planned posting is to be executed." -msgstr "Cash book for which the planned posting is to be executed." - -msgctxt "field:cashbook.planner,name:" -msgid "Name" -msgstr "Name" - -msgctxt "field:cashbook.planner,description:" -msgid "Description" -msgstr "Description" - -msgctxt "field:cashbook.planner,start_date:" -msgid "Start Date" -msgstr "Start Date" - -msgctxt "field:cashbook.planner,end_date:" -msgid "End Date" -msgstr "End Date" - -msgctxt "field:cashbook.planner,frequ:" -msgid "Frequency" -msgstr "Frequency" - -msgctxt "selection:cashbook.planner,frequ:" -msgid "Yearly" -msgstr "Yearly" - -msgctxt "selection:cashbook.planner,frequ:" -msgid "Monthly" -msgstr "Monthly" - -msgctxt "selection:cashbook.planner,frequ:" -msgid "Weekly" -msgstr "Weekly" - -msgctxt "selection:cashbook.planner,frequ:" -msgid "Daily" -msgstr "Daily" - -msgctxt "field:cashbook.planner,weekday:" -msgid "Weekday" -msgstr "Weekday" - -msgctxt "help:cashbook.planner,weekday:" -msgid "Select a day of the week if you want the rule to run on that day." -msgstr "Select a day of the week if you want the rule to run on that day." - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Monday" -msgstr "Monday" - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Tuesday" -msgstr "Tuesday" - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Wednesday" -msgstr "Wednesday" - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Thursday" -msgstr "Thursday" - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Friday" -msgstr "Friday" - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Saturday" -msgstr "Saturday" - -msgctxt "selection:cashbook.planner,weekday:" -msgid "Sunday" -msgstr "Sunday" - -msgctxt "field:cashbook.planner,monthday:" -msgid "Day of month" -msgstr "Day of month" - -msgctxt "help:cashbook.planner,monthday:" -msgid "If you want the rule to run on a specific day of the month, select the day here." -msgstr "If you want the rule to run on a specific day of the month, select the day here." - -msgctxt "field:cashbook.planner,interval:" -msgid "Interval" -msgstr "Interval" - -msgctxt "help:cashbook.planner,interval:" -msgid "Select an interval to run the rule on every n-th date." -msgstr "Select an interval to run the rule on every n-th date." - -msgctxt "field:cashbook.planner,nextdates:" -msgid "Next Dates" -msgstr "Next Dates" - -msgctxt "help:cashbook.planner,nextdates:" -msgid "the next 5 appointments based on the configured rule" -msgstr "the next 5 appointments based on the configured rule" - -msgctxt "field:cashbook.planner,setpos:" -msgid "Occurrence" -msgstr "Occurrence" - -msgctxt "help:cashbook.planner,setpos:" -msgid "For example, if you want to run the rule on the second Wednesday of the month, enter 2 here." -msgstr "For example, if you want to run the rule on the second Wednesday of the month, enter 2 here." - -msgctxt "view:cashbook.book:" -msgid "Scheduled Bookings" -msgstr "Scheduled Bookings" - +# +msgid "" +msgstr "Content-Type: text/plain; charset=utf-8\n" + +msgctxt "selection:ir.cron,method:" +msgid "Execute scheduled bookings" +msgstr "Execute scheduled bookings" + +msgctxt "model:res.group,name:group_planner" +msgid "Cashbook - Scheduled Bookings" +msgstr "Cashbook - Scheduled Bookings" + +msgctxt "model:ir.ui.menu,name:menu_planner" +msgid "Scheduled Bookings" +msgstr "Scheduled Bookings" + +msgctxt "model:ir.action,name:act_planner_view" +msgid "Scheduled Bookings" +msgstr "Scheduled Bookings" + +msgctxt "model:ir.rule.group,name:rg_planner_write_admin" +msgid "Administrators: scheduled bookings read/write" +msgstr "Administrators: scheduled bookings read/write" + +msgctxt "model:ir.rule.group,name:rg_planner_owner" +msgid "Owners: scheduled bookings" +msgstr "Owners: scheduled bookings" + +msgctxt "model:ir.rule.group,name:rg_planner_read_nonowner" +msgid "Observers: scheduled bookings read" +msgstr "Observers: scheduled bookings read" + +msgctxt "model:ir.rule.group,name:rg_planner_write_nonowner" +msgid "Reviewer: scheduled bookings write" +msgstr "Reviewer: scheduled bookings write" + +msgctxt "model:ir.rule.group,name:rg_planner_companies" +msgid "User in companies" +msgstr "User in companies" + +msgctxt "model:cashbook.planner,name:" +msgid "Scheduled Booking" +msgstr "Scheduled Booking" + +msgctxt "view:cashbook.planner:" +msgid "Recurrence Rule" +msgstr "Recurrence Rule" + +msgctxt "view:cashbook.planner:" +msgid "Result of the recurrence rule" +msgstr "Result of the recurrence rule" + +msgctxt "field:cashbook.planner,company:" +msgid "Company" +msgstr "Company" + +msgctxt "field:cashbook.planner,cashbook:" +msgid "Cashbook" +msgstr "Cashbook" + +msgctxt "help:cashbook.planner,cashbook:" +msgid "Cash book for which the planned posting is to be executed." +msgstr "Cash book for which the planned posting is to be executed." + +msgctxt "field:cashbook.planner,name:" +msgid "Name" +msgstr "Name" + +msgctxt "field:cashbook.planner,description:" +msgid "Description" +msgstr "Description" + +msgctxt "field:cashbook.planner,start_date:" +msgid "Start Date" +msgstr "Start Date" + +msgctxt "field:cashbook.planner,end_date:" +msgid "End Date" +msgstr "End Date" + +msgctxt "field:cashbook.planner,frequ:" +msgid "Frequency" +msgstr "Frequency" + +msgctxt "selection:cashbook.planner,frequ:" +msgid "Yearly" +msgstr "Yearly" + +msgctxt "selection:cashbook.planner,frequ:" +msgid "Monthly" +msgstr "Monthly" + +msgctxt "selection:cashbook.planner,frequ:" +msgid "Weekly" +msgstr "Weekly" + +msgctxt "selection:cashbook.planner,frequ:" +msgid "Daily" +msgstr "Daily" + +msgctxt "field:cashbook.planner,weekday:" +msgid "Weekday" +msgstr "Weekday" + +msgctxt "help:cashbook.planner,weekday:" +msgid "Select a day of the week if you want the rule to run on that day." +msgstr "Select a day of the week if you want the rule to run on that day." + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Monday" +msgstr "Monday" + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Tuesday" +msgstr "Tuesday" + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Wednesday" +msgstr "Wednesday" + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Thursday" +msgstr "Thursday" + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Friday" +msgstr "Friday" + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Saturday" +msgstr "Saturday" + +msgctxt "selection:cashbook.planner,weekday:" +msgid "Sunday" +msgstr "Sunday" + +msgctxt "field:cashbook.planner,monthday:" +msgid "Day of month" +msgstr "Day of month" + +msgctxt "help:cashbook.planner,monthday:" +msgid "If you want the rule to run on a specific day of the month, select the day here." +msgstr "If you want the rule to run on a specific day of the month, select the day here." + +msgctxt "field:cashbook.planner,interval:" +msgid "Interval" +msgstr "Interval" + +msgctxt "help:cashbook.planner,interval:" +msgid "Select an interval to run the rule on every n-th date." +msgstr "Select an interval to run the rule on every n-th date." + +msgctxt "field:cashbook.planner,nextdates:" +msgid "Next Dates" +msgstr "Next Dates" + +msgctxt "help:cashbook.planner,nextdates:" +msgid "the next 5 appointments based on the configured rule" +msgstr "the next 5 appointments based on the configured rule" + +msgctxt "field:cashbook.planner,setpos:" +msgid "Occurrence" +msgstr "Occurrence" + +msgctxt "help:cashbook.planner,setpos:" +msgid "For example, if you want to run the rule on the second Wednesday of the month, enter 2 here." +msgstr "For example, if you want to run the rule on the second Wednesday of the month, enter 2 here." + +msgctxt "view:cashbook.book:" +msgid "Scheduled Bookings" +msgstr "Scheduled Bookings" + diff --git a/nextrun.py b/nextrun.py new file mode 100644 index 0000000..22e5cda --- /dev/null +++ b/nextrun.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# This file is part of the cashbook-planner from m-ds for Tryton. +# The COPYRIGHT file at the top level of this repository contains the +# full copyright notices and license terms. + +from trytond.model import ModelSQL, ModelView, fields +from trytond.report import Report + + +class NextRun(ModelSQL, ModelView): + 'Next Execution Date' + __name__ = 'cashbook.planner.nextrun' + + planner = fields.Many2One( + string='Planner', required=True, ondelete='CASCADE', + model_name='cashbook.planner') + date = fields.Date(string='Date', required=True) + + def get_rec_name(self, name): + """ get date for record name + + Args: + name (string): name of field + + Returns: + string: formatted date + """ + return Report.format_date(self.date) if self.date is not None else '-' + +# end NextRun diff --git a/planner.py b/planner.py index d1dfd6a..5b33c9e 100644 --- a/planner.py +++ b/planner.py @@ -84,6 +84,9 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView): string='Next Dates', readonly=True, help='the next 5 appointments based on the configured rule'), 'on_change_with_nextdates') + nextrun = fields.One2Many( + string='Next Execution Date', size=1, field='planner', + model_name='cashbook.planner.nextrun') @classmethod def __setup__(cls): @@ -277,4 +280,52 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView): IrDate = Pool().get('ir.date') return IrDate.today() + @classmethod + def update_next_occurence(cls, records): + """ compute date of next execution, create/update nextrun-record, + delete nextrun-record if scheduled booking is disabled + + Args: + records (list): scheduled-booking records + """ + pool = Pool() + IrDate = pool.get('ir.date') + NextRun = pool.get('cashbook.planner.nextrun') + + to_create = [] + to_write = [] + to_delete = [] + for record in records: + if not record.active: + # delete nextrun-record if disabled + if record.nextrun: + to_delete.extend(record.nextrun) + elif record.active: + # get next-run date + next_date = record._compute_dates_by_rrule( + start_date=IrDate.today(), count=1) + if next_date: + next_date = next_date[0] + else: + continue + + if not record.nextrun: + # add record if not exist + to_create.append({'planner': record.id, 'date': next_date}) + else: + # update existing records + for nxrun in record.nextrun: + if nxrun.date != next_date: + to_write.extend([[nxrun], {'date': next_date}]) + if to_create: + NextRun.create(to_create) + if to_delete: + NextRun.delete(to_delete) + if to_write: + NextRun.write(*to_write) + + @classmethod + def cronjob(cls): + pass + # ens ScheduledBooking diff --git a/tests/planner.py b/tests/planner.py index d23fa40..a731280 100644 --- a/tests/planner.py +++ b/tests/planner.py @@ -207,4 +207,19 @@ class PlannerTestCase(object): 'setpos': 5, 'monthday': None, 'weekday': '2', 'end_date': None}]) + @with_transaction() + def test_planner_create_update_nextrun(self): + """ create job, check nextrun-record + """ + Planner = Pool().get('cashbook.planner') + + job = self.prep_create_job() + self.assertEqual( + job._compute_dates_by_rrule( + count=1, start_date=date(2022, 5, 1)), [ + date(2022, 5, 1)]) + + job.update_next_occurence([job]) + self.assertEqual(len(job.nextrun), 1) + # end PlannerTestCase diff --git a/tryton.cfg b/tryton.cfg index 5c94af5..41b8434 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -8,4 +8,5 @@ xml: group.xml planner.xml cashbook.xml + cron.xml menu.xml diff --git a/view/planner_form.xml b/view/planner_form.xml index e9d4245..beab02b 100644 --- a/view/planner_form.xml +++ b/view/planner_form.xml @@ -35,6 +35,10 @@ full copyright notices and license terms. --> +