diff --git a/locale/de.po b/locale/de.po
index e62fd0f..711e118 100644
--- a/locale/de.po
+++ b/locale/de.po
@@ -106,6 +106,10 @@ msgctxt "view:cashbook.planner:"
msgid "Booking text"
msgstr "Buchungstext"
+msgctxt "view:cashbook.planner:"
+msgid "Available placeholders: ${date} ${month} ${year} ${amount} ${quantity}"
+msgstr "verfügbare Platzhalter: ${date} ${month} ${year} ${amount} ${quantity}"
+
msgctxt "field:cashbook.planner,company:"
msgid "Company"
msgstr "Unternehmen"
diff --git a/locale/en.po b/locale/en.po
index 77d1b8b..3bb5c0a 100644
--- a/locale/en.po
+++ b/locale/en.po
@@ -82,6 +82,10 @@ msgctxt "view:cashbook.planner:"
msgid "Booking text"
msgstr "Booking text"
+msgctxt "view:cashbook.planner:"
+msgid "Available placeholders: ${date} ${month} ${year} ${amount} ${quantity}"
+msgstr "Available placeholders: ${date} ${month} ${year} ${amount} ${quantity}"
+
msgctxt "field:cashbook.planner,company:"
msgid "Company"
msgstr "Company"
diff --git a/planner.py b/planner.py
index d6fbef7..441b93d 100644
--- a/planner.py
+++ b/planner.py
@@ -5,6 +5,7 @@
from decimal import Decimal
from datetime import date, timedelta
+from string import Template
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
@@ -430,6 +431,60 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView):
IrDate = Pool().get('ir.date')
return IrDate.today()
+ @classmethod
+ def fill_placeholder(cls, linedata):
+ """ replace placeholder in description
+
+ Args:
+ description (str): booking text of planned booking
+ allowed substitution strings:
+ ${date}, ${month}, ${year}, ${amount}, ${quantity}
+
+ Returns:
+ str: booking text
+ """
+ pool = Pool()
+ IrDate = pool.get('ir.date')
+ Cashbook = pool.get('cashbook.book')
+
+ line_date = linedata.get('date', IrDate.today())
+ amount = linedata.get('amount', None)
+ from_book = linedata.get('cashbook', None)
+ if from_book:
+ from_book = Cashbook(from_book)
+ to_book = linedata.get('booktransf', None)
+ if to_book:
+ to_book = Cashbook(to_book)
+
+ quantity_txt = '-'
+ quantity = linedata.get('quantity', None)
+ if quantity is not None:
+ uom = (
+ to_book.quantity_uom if to_book and to_book.quantity_uom
+ else from_book.quantity_uom
+ if from_book and from_book.quantity_uom else None)
+ uom_digits = (
+ to_book.quantity_digits
+ if to_book and to_book.quantity_digits is not None
+ else from_book.quantity_digits
+ if from_book and from_book.quantity_digits is not None
+ else 2)
+ if uom:
+ quantity_txt = Report.format_number_symbol(
+ quantity, lang=None, symbol=uom, digits=uom_digits)
+ else:
+ quantity_txt = Report.format_number(
+ quantity, lang=None, digits=uom_digits)
+
+ return Template(linedata.get('description')).safe_substitute({
+ 'date': Report.format_date(line_date, lang=None),
+ 'month': line_date.month,
+ 'year': line_date.year,
+ 'amount': Report.format_currency(
+ amount, lang=None, currency=from_book.currency)
+ if (amount is not None) and from_book else '-',
+ 'quantity': quantity_txt})
+
@classmethod
def update_next_occurence(cls, records, query_date=None):
""" compute date of next execution, create/update nextrun-record,
@@ -573,6 +628,7 @@ class ScheduledBooking(DeactivableMixin, ModelSQL, ModelView):
if record.booktransf.feature == 'asset':
line.update(add_asset_values(
line, record.cashbook, record.booktransf))
+ line['description'] = cls.fill_placeholder(line)
if record.wfcheck:
to_create_check.append(line)
diff --git a/tests/planner.py b/tests/planner.py
index 1566e18..d507fdb 100644
--- a/tests/planner.py
+++ b/tests/planner.py
@@ -353,6 +353,23 @@ class PlannerTestCase(object):
IrDate.today = MagicMock(return_value=date.today())
+ @with_transaction()
+ def test_planner_check_description_template(self):
+ """ check replacement of template strings in description
+ """
+ pool = Pool()
+ Planner = pool.get('cashbook.planner')
+
+ asset_book = self.prep_planner_asset_book()
+ self.assertEqual(Planner.fill_placeholder({
+ 'date': date(2022, 5, 2),
+ 'amount': Decimal('12.4567'),
+ 'quantity': Decimal('32.4423'),
+ 'cashbook': asset_book.id,
+ 'description': '- ${amount} - ${date} - ${month} - ' +
+ '${year} - ${quantity}'}),
+ '- usd12.46 - 05/02/2022 - 5 - 2022 - 32.4423\xa0u')
+
@with_transaction()
def test_planner_cronjobs_booking_with_category(self):
""" create job, configure booking with category, run job
@@ -397,8 +414,7 @@ class PlannerTestCase(object):
self.assertEqual(len(job.cashbook.lines), 1)
self.assertEqual(
job.cashbook.lines[0].rec_name,
- "06/01/2022|Exp|-10.00 usd|booking " +
- "${month}/${year}, ${date} [Cat1]")
+ "06/01/2022|Exp|-10.00 usd|booking 6/2022, 06/01/2022 [Cat1]")
self.assertEqual(job.cashbook.lines[0].state, 'check')
with Transaction().set_context({'date': date(2022, 6, 1)}):
@@ -464,8 +480,8 @@ class PlannerTestCase(object):
self.assertEqual(len(cashbook.lines), 1)
self.assertEqual(
cashbook.lines[0].rec_name,
- "06/01/2022|to|-10.00 usd|booking ${month}/${year}, " +
- "${date} [Book 2 | 10.00 usd | Open]")
+ "06/01/2022|to|-10.00 usd|booking 6/2022, 06/01/2022 " +
+ "[Book 2 | 10.00 usd | Open]")
self.assertEqual(cashbook.lines[0].state, 'check')
target_book, = Cashbook.browse([job.booktransf])
@@ -473,8 +489,8 @@ class PlannerTestCase(object):
self.assertEqual(len(target_book.lines), 1)
self.assertEqual(
target_book.lines[0].rec_name,
- "06/01/2022|from|10.00 usd|booking ${month}/${year}, " +
- "${date} [Book 1 | -10.00 usd | Open]")
+ "06/01/2022|from|10.00 usd|booking 6/2022, 06/01/2022 " +
+ "[Book 1 | -10.00 usd | Open]")
self.assertEqual(target_book.lines[0].state, 'check')
self.assertEqual(target_book.lines[0].state, 'check')
@@ -775,12 +791,4 @@ class PlannerTestCase(object):
IrDate.today = MagicMock(return_value=date.today())
- @with_transaction()
- def test_planner_cronjobs_booking_transfer_asset_eur_usd2(self):
- """ create job, configure transfer-booking to asset-cashbook,
- from euro to usd,
- asset-unit = u, cashbook-unit = 10x u
- """
- raise ValueError('stop')
-
# end PlannerTestCase
diff --git a/view/planner_form.xml b/view/planner_form.xml
index cc1ebbc..455520c 100644
--- a/view/planner_form.xml
+++ b/view/planner_form.xml
@@ -58,6 +58,8 @@ full copyright notices and license terms. -->
+