diff --git a/__init__.py b/__init__.py index 62501a1..a3c966b 100644 --- a/__init__.py +++ b/__init__.py @@ -8,10 +8,11 @@ from .book import Book from .types import Type from .line import Line, LineContext from .wizard_openline import OpenCashBook, OpenCashBookStart +from .wizard_runreport import RunCbReport, RunCbReportStart from .configuration import Configuration, UserConfiguration from .category import Category from .reconciliation import Reconciliation -from .cbreport import CashbookReport +from .cbreport import ReconciliationReport def register(): Pool.register( @@ -24,10 +25,12 @@ def register(): Line, Reconciliation, OpenCashBookStart, + RunCbReportStart, module='cashbook', type_='model') Pool.register( - CashbookReport, + ReconciliationReport, module='cashbook', type_='report') Pool.register( OpenCashBook, + RunCbReport, module='cashbook', type_='wizard') diff --git a/book.xml b/book.xml index 61fba5e..5ee9fc1 100644 --- a/book.xml +++ b/book.xml @@ -44,21 +44,21 @@ full copyright notices and license terms. --> - - + + - + - + - + @@ -78,15 +78,37 @@ full copyright notices and license terms. --> - + - + - - + + - Owners, observers and reviewers: Cashbook read + Owners: Cashbook read/write + + + + + + + + + + + + + + + + + + + + Observers and Reviewers: Cashbook read @@ -94,16 +116,15 @@ full copyright notices and license terms. --> - + - + - - + + @@ -127,9 +148,9 @@ full copyright notices and license terms. --> + id="book_wfopen_button-group_cashbook_admin"> - + @@ -139,9 +160,9 @@ full copyright notices and license terms. --> + id="book_wfclosed_button-group_cashbook_admin"> - + @@ -151,9 +172,9 @@ full copyright notices and license terms. --> + id="book_wfarchive_button-group_cashbook_admin"> - + @@ -161,9 +182,273 @@ full copyright notices and license terms. --> Cashbook Line + id="sequence_type_cashbook_line-group_cashbook_admin"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/category.xml b/category.xml index 6df3c33..a5dcc66 100644 --- a/category.xml +++ b/category.xml @@ -68,10 +68,10 @@ full copyright notices and license terms. --> - - + + - + diff --git a/cbreport.py b/cbreport.py index c56302e..bde7523 100644 --- a/cbreport.py +++ b/cbreport.py @@ -5,11 +5,24 @@ from trytond.report import Report from trytond.i18n import gettext +from trytond.pool import Pool +from trytond.transaction import Transaction from slugify import slugify -class CashbookReport(Report): - __name__ = 'cashbook.repbook' +class ReconciliationReport(Report): + __name__ = 'cashbook.reprecon' + + @classmethod + def get_context(cls, records, header, data): + """ update context + """ + Company = Pool().get('company.company') + context2 = Transaction().context + + context = super(ReconciliationReport, cls).get_context(records, header, data) + context['company'] = Company(context2['company']) + return context @classmethod def execute(cls, ids, data): @@ -17,9 +30,25 @@ class CashbookReport(Report): """ pool = Pool() IrDate = pool.get('ir.date') - ExpObj = pool.get(data['model'])(data['id']) - (ext1, cont1, dirprint, title) = super(CashbookReport, cls).execute(ids, data) + if data['model'] == 'cashbook.book': + ExpObj = pool.get(data['model'])(data['id']) + rep_name = ExpObj.rec_name[:50] + elif data['model'] == 'cashbook.line': + line_obj = pool.get(data['model'])(data['id']) + rep_name = line_obj.cashbook.rec_name[:50] + elif data['model'] == 'cashbook.recon': + recon_obj = pool.get(data['model'])(data['id']) + rep_name = gettext( + 'cashbook.msg_rep_reconciliation_fname', + recname = recon_obj.cashbook.rec_name[:50], + date_from = recon_obj.date_from.isoformat(), + date_to = recon_obj.date_to.isoformat(), + ) + else : + raise ValueError('invalid model') + + (ext1, cont1, dirprint, title) = super(ReconciliationReport, cls).execute(ids, data) return ( ext1, @@ -28,9 +57,11 @@ class CashbookReport(Report): slugify('%(date)s-%(book)s-%(descr)s' % { 'date': IrDate.today().isoformat().replace('-', ''), 'book': gettext('cashbook.msg_name_cashbook'), - 'descr': ExpObj.name[:15], + 'descr': rep_name, }, - max_length=75, word_boundary=True, save_order=True), + max_length=100, word_boundary=True, save_order=True), ) -# end CashbookReport +# end ReconciliationReport + + diff --git a/cbreport.xml b/cbreport.xml index 75d382c..f7b79f5 100644 --- a/cbreport.xml +++ b/cbreport.xml @@ -5,23 +5,14 @@ full copyright notices and license terms. --> - - Cashbook - cashbook.line - cashbook.repbook - cashbook/report/cashbook.fods + + Cashbook Reconciliation + cashbook.recon + cashbook.reprecon + cashbook/report/reconciliation.fods + ods - - form_print - cashbook.line,-1 - - - - form_print - cashbook.book,-1 - - diff --git a/configuration.xml b/configuration.xml index ad86c6d..ec4255e 100644 --- a/configuration.xml +++ b/configuration.xml @@ -29,15 +29,16 @@ full copyright notices and license terms. --> - - + + - + + @@ -55,10 +56,10 @@ full copyright notices and license terms. --> - - + + - + diff --git a/group.xml b/group.xml index 78ca2d3..dfefc85 100644 --- a/group.xml +++ b/group.xml @@ -14,6 +14,14 @@ full copyright notices and license terms. --> Cashbook - WF - Done + + Cashbook - Administrator + + + + + + diff --git a/line.xml b/line.xml index 036f7b0..284f259 100644 --- a/line.xml +++ b/line.xml @@ -85,10 +85,10 @@ full copyright notices and license terms. --> - - + + - + @@ -119,9 +119,9 @@ full copyright notices and license terms. --> - + - + @@ -190,9 +190,9 @@ full copyright notices and license terms. --> + id="line_wfedit_button-group_cashbook_admin"> - + @@ -212,9 +212,9 @@ full copyright notices and license terms. --> + id="line_wfcheck_button-group_cashbook_admin"> - + @@ -234,9 +234,9 @@ full copyright notices and license terms. --> + id="line_wfdone_button-group_cashbook_admin"> - + diff --git a/locale/de.po b/locale/de.po index 9f01e07..9bdb54f 100644 --- a/locale/de.po +++ b/locale/de.po @@ -14,6 +14,10 @@ msgctxt "model:ir.message,text:msg_name_cashbook" msgid "Cashbook" msgstr "Kassenbuch" +msgctxt "model:ir.message,text:msg_name_reconciliation" +msgid "Reconciliation" +msgstr "Abstimmung" + msgctxt "model:ir.message,text:msg_line_wrong_state_value" msgid "Invalid value of the field 'Status', allowed: edit, check, done." msgstr "Ungültiger Wert des Feldes 'Status', erlaubt: edit, check, done." @@ -122,6 +126,10 @@ msgctxt "model:ir.message,text:msg_line_denywf_by_reference" msgid "The current line is managed by the cashbook line '%(recname)s', cashbook: '%(cbook)s'." msgstr "Die aktuelle Zeile wird durch die Kassenbuchzeile '%(recname)s' verwaltet, Kassenbuch: '%(cbook)s'." +msgctxt "model:ir.message,text:msg_rep_reconciliation_fname" +msgid "%(recname)s Reconciliation from %(date_from)s to %(date_to)s" +msgstr "%(recname)s Abstimmung von %(date_from)s bis %(date_to)s" + ############# # res.group # @@ -138,13 +146,21 @@ msgctxt "model:res.group,name:group_cashbook_doneline" msgid "Cashbook - WF - Done" msgstr "Kassenbuch - WF - Fertig" +msgctxt "model:res.group,name:group_cashbook_admin" +msgid "Cashbook - Administrator" +msgstr "Kassenbuch - Administrator" + ################# # ir.rule.group # ################# -msgctxt "model:ir.rule.group,name:rg_book_read" -msgid "Owners, observers and reviewers: Cashbook read" -msgstr "Eigentümer, Beobachter und Bearbeiter: Kassenbuch lesen" +msgctxt "model:ir.rule.group,name:rg_book_rw_owner" +msgid "Owners: Cashbook read/write" +msgstr "Eigentümer: Kassenbuch schreiben" + +msgctxt "model:ir.rule.group,name:rg_book_read_nonowner" +msgid "Observers and Reviewers: Cashbook read" +msgstr "Beobachter und Bearbeiter: Kassenbuch lesen" msgctxt "model:ir.rule.group,name:rg_book_write_adm" msgid "Administrators: Cashbook read/write" @@ -218,6 +234,10 @@ msgctxt "model:ir.ui.menu,name:menu_category_list" msgid "Category" msgstr "Kategorie" +msgctxt "model:ir.ui.menu,name:act_category_view" +msgid "Category" +msgstr "Kategorie" + ############# # ir.action # @@ -238,9 +258,13 @@ msgctxt "model:ir.action,name:act_open_lines" msgid "Open Cashbook" msgstr "Kassenbuch öffnen" -msgctxt "model:ir.ui.menu,name:act_category_view" -msgid "Category" -msgstr "Kategorie" +msgctxt "model:ir.action,name:report_cashbook" +msgid "Cashbook" +msgstr "Kassenbuch" + +msgctxt "model:ir.action,name:act_wizard_report" +msgid "Cashbook Report" +msgstr "Kassenbuch Bericht" ############################### @@ -917,3 +941,91 @@ msgstr "Endbetrag" msgctxt "field:cashbook.recon,predecessor:" msgid "Predecessor" msgstr "Vorgänger" + + +############################# +# cashbook.runrepbook.start # +############################# +msgctxt "model:cashbook.runrepbook.start,name:" +msgid "Cashbook Report" +msgstr "Kassenbuch Bericht" + +msgctxt "field:cashbook.runrepbook.start,cashbook:" +msgid "Cashbook" +msgstr "Kassenbuch" + +msgctxt "field:cashbook.runrepbook.start,cashbooks:" +msgid "Cashbooks" +msgstr "Kassenbücher" + +msgctxt "field:cashbook.runrepbook.start,reconciliation:" +msgid "Reconciliation" +msgstr "Abstimmung" + +msgctxt "field:cashbook.runrepbook.start,reconciliations:" +msgid "Reconciliations" +msgstr "Abstimmungen" + + +##################### +# cashbook.reprecon # +##################### +msgctxt "report:cashbook.reprecon:" +msgid "Cashbook:" +msgstr "Kassenbuch:" + +msgctxt "report:cashbook.reprecon:" +msgid "Period:" +msgstr "Zeitraum:" + +msgctxt "report:cashbook.reprecon:" +msgid "to" +msgstr "bis" + +msgctxt "report:cashbook.reprecon:" +msgid "Bookings:" +msgstr "Buchungen:" + +msgctxt "report:cashbook.reprecon:" +msgid "Initial Amount" +msgstr "Anfangsbetrag" + +msgctxt "report:cashbook.reprecon:" +msgid "End Amount" +msgstr "Endbetrag" + +msgctxt "report:cashbook.reprecon:" +msgid "Date" +msgstr "Datum" + +msgctxt "report:cashbook.reprecon:" +msgid "No." +msgstr "Nr" + +msgctxt "report:cashbook.reprecon:" +msgid "Description" +msgstr "Beschreibung" + +msgctxt "report:cashbook.reprecon:" +msgid "Revenue" +msgstr "Einnahme" + +msgctxt "report:cashbook.reprecon:" +msgid "Expense" +msgstr "Ausgabe" + +msgctxt "report:cashbook.reprecon:" +msgid "Sum" +msgstr "Summe" + +msgctxt "report:cashbook.reprecon:" +msgid "- Expenses" +msgstr "- Ausgaben" + +msgctxt "report:cashbook.reprecon:" +msgid "Total" +msgstr "Gesamt" + +msgctxt "report:cashbook.reprecon:" +msgid "Payee" +msgstr "Empfänger" diff --git a/locale/en.po b/locale/en.po index a73b4e2..54ab2dc 100644 --- a/locale/en.po +++ b/locale/en.po @@ -10,6 +10,10 @@ msgctxt "model:ir.message,text:msg_name_cashbook" msgid "Cashbook" msgstr "Cashbook" +msgctxt "model:ir.message,text:msg_name_reconciliation" +msgid "Reconciliation" +msgstr "Reconciliation" + msgctxt "model:ir.message,text:msg_line_wrong_state_value" msgid "Invalid value of the field 'Status', allowed: edit, check, done." msgstr "Invalid value of the field 'Status', allowed: edit, check, done." @@ -118,6 +122,10 @@ msgctxt "model:ir.message,text:msg_line_denywf_by_reference" msgid "The current line is managed by the cashbook line '%(recname)s', cashbook: '%(cbook)s'." msgstr "The current line is managed by the cashbook line '%(recname)s', cashbook: '%(cbook)s'." +msgctxt "model:ir.message,text:msg_rep_reconciliation_fname" +msgid "%(recname)s Reconciliation from %(date_from)s to %(date_to)s" +msgstr "%(recname)s Reconciliation from %(date_from)s to %(date_to)s" + msgctxt "model:res.group,name:group_cashbook" msgid "Cashbook" msgstr "Cashbook" @@ -202,6 +210,10 @@ msgctxt "model:ir.ui.menu,name:menu_category_list" msgid "Category" msgstr "Category" +msgctxt "model:ir.ui.menu,name:act_category_view" +msgid "Category" +msgstr "Category" + msgctxt "model:ir.action,name:act_book_view" msgid "Cashbook" msgstr "Cashbook" @@ -218,9 +230,13 @@ msgctxt "model:ir.action,name:act_open_lines" msgid "Open Cashbook" msgstr "Open Cashbook" -msgctxt "model:ir.ui.menu,name:act_category_view" -msgid "Category" -msgstr "Category" +msgctxt "model:ir.action,name:report_cashbook" +msgid "Cashbook" +msgstr "Cashbook" + +msgctxt "model:ir.action,name:act_wizard_report" +msgid "Cashbook Report" +msgstr "Cashbook Report" msgctxt "model:ir.action.act_window.domain,name:act_line_domain_current" msgid "Current Month" @@ -270,6 +286,10 @@ msgctxt "model:ir.model.button,string:recon_wfdone_button" msgid "Done" msgstr "Done" +msgctxt "model:ir.sequence.type,name:sequence_type_cashbook_line" +msgid "Cashbook Line" +msgstr "Cashbook Line" + msgctxt "model:cashbook.book,name:" msgid "Cashbook" msgstr "Cashbook" @@ -350,6 +370,22 @@ msgctxt "field:cashbook.book,lines:" msgid "Lines" msgstr "Lines" +msgctxt "field:cashbook.book,number_sequ:" +msgid "Line numbering" +msgstr "Line numbering" + +msgctxt "help:cashbook.book,number_sequ:" +msgid "Number sequence for numbering of the cash book lines." +msgstr "Number sequence for numbering of the cash book lines." + +msgctxt "field:cashbook.book,number_atcheck:" +msgid "number when 'Checking'" +msgstr "number when 'Checking'" + +msgctxt "help:cashbook.book,number_atcheck:" +msgid "The numbering of the lines is done in the step Check. If the check mark is inactive, this happens with Done." +msgstr "The numbering of the lines is done in the step Check. If the check mark is inactive, this happens with Done." + msgctxt "model:cashbook.line,name:" msgid "Cashbook Line" msgstr "Cashbook Line" @@ -514,6 +550,10 @@ msgctxt "selection:cashbook.line,payee:" msgid "Party" msgstr "Party" +msgctxt "field:cashbook.line,number:" +msgid "Number" +msgstr "Number" + msgctxt "model:cashbook.type,name:" msgid "Cashbook Type" msgstr "Cashbook Type" @@ -818,3 +858,23 @@ msgctxt "field:cashbook.recon,end_amount:" msgid "End Amount" msgstr "End Amount" +msgctxt "field:cashbook.recon,predecessor:" +msgid "Predecessor" +msgstr "Predecessor" + +msgctxt "model:cashbook.runrepbook.start,name:" +msgid "Cashbook Report" +msgstr "Cashbook Report" + +msgctxt "field:cashbook.runrepbook.start,cashbook:" +msgid "Cashbook" +msgstr "Cashbook" + +msgctxt "field:cashbook.runrepbook.start,cashbooks:" +msgid "Cashbooks" +msgstr "Cashbooks" + +msgctxt "field:cashbook.runrepbook.start,reconciliation:" +msgid "Reconciliation" +msgstr "Reconciliation" + diff --git a/menu.xml b/menu.xml index 30094cd..c37eb13 100644 --- a/menu.xml +++ b/menu.xml @@ -8,79 +8,79 @@ full copyright notices and license terms. --> - - - - + + + + - - - - + + + + - + - + - + - + - + - + - - - - + + + + - - - - + + + + diff --git a/message.xml b/message.xml index 5eef64b..da666f8 100644 --- a/message.xml +++ b/message.xml @@ -11,6 +11,9 @@ full copyright notices and license terms. --> Cashbook + + Reconciliation + Invalid value of the field 'Status', allowed: edit, check, done. @@ -92,6 +95,9 @@ full copyright notices and license terms. --> The current line is managed by the cashbook line '%(recname)s', cashbook: '%(cbook)s'. + + %(recname)s Reconciliation from %(date_from)s to %(date_to)s + diff --git a/reconciliation.py b/reconciliation.py index f74cf2f..37bc15f 100644 --- a/reconciliation.py +++ b/reconciliation.py @@ -5,7 +5,7 @@ from trytond.model import Workflow, ModelView, ModelSQL, fields from trytond.transaction import Transaction -from trytond.pyson import Eval, If, Or +from trytond.pyson import Eval, If, Or, Bool from trytond.pool import Pool from trytond.report import Report from trytond.exceptions import UserError diff --git a/reconciliation.xml b/reconciliation.xml index 2ee17fb..6e6576d 100644 --- a/reconciliation.xml +++ b/reconciliation.xml @@ -44,10 +44,10 @@ full copyright notices and license terms. --> - - + + - + @@ -78,9 +78,9 @@ full copyright notices and license terms. --> - + - + @@ -148,9 +148,14 @@ full copyright notices and license terms. --> + id="recon_wfedit_button-group_cashbook_admin"> - + + + + + @@ -165,9 +170,14 @@ full copyright notices and license terms. --> + id="recon_wfcheck_button-group_cashbook_admin"> - + + + + + @@ -182,9 +192,9 @@ full copyright notices and license terms. --> + id="recon_wfdone_button-group_cashbook_admin"> - + diff --git a/report/reconciliation.fods b/report/reconciliation.fods new file mode 100644 index 0000000..7f0bcf6 --- /dev/null +++ b/report/reconciliation.fods @@ -0,0 +1,551 @@ + + + + 2022-08-16T16:46:07.4074891592022-08-17T15:50:10.077622122PT1H48M44S47LibreOffice/6.0.7.3$Linux_X86_64 LibreOffice_project/00m0$Build-3 + + + 0 + 0 + 18199 + 7676 + + + view1 + + + 3 + 7 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 100 + 60 + true + false + + + Tabelle1 + 1193 + 0 + 100 + 60 + false + true + true + true + 12632256 + true + true + true + true + false + false + false + 1000 + 1000 + 1 + 1 + true + false + + + + + 7 + true + false + false + 0 + true + vgH+/0hQX0xhc2VySmV0X01GUF9NNDI2ZmRuX0IyNUM3Ml8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ1VQUzpIUF9MYXNlckpldF9NRlBfTTQyNmZkbl9CMgAWAAMA3wAAAAAAAAAEAAhSAAAEdAAASm9iRGF0YSAxCnByaW50ZXI9SFBfTGFzZXJKZXRfTUZQX000MjZmZG5fQjI1QzcyXwpvcmllbnRhdGlvbj1Qb3J0cmFpdApjb3BpZXM9MQpjb2xsYXRlPWZhbHNlCm1hcmdpbmRhanVzdG1lbnQ9MCwwLDAsMApjb2xvcmRlcHRoPTI0CnBzbGV2ZWw9MApwZGZkZXZpY2U9MQpjb2xvcmRldmljZT0wClBQRENvbnRleERhdGEKUGFnZVNpemU6QTQASW5wdXRTbG90OkF1dG8ARHVwbGV4Ok5vbmUAABIAQ09NUEFUX0RVUExFWF9NT0RFDwBEdXBsZXhNb2RlOjpPZmY= + HP_LaserJet_MFP_M426fdn_B25C72_ + true + 3 + true + false + true + true + 12632256 + true + true + true + false + true + false + true + 1 + false + 1000 + 1000 + false + 1 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ??? + + + Seite 1/99 + 00.00.0000 + + + + + + + + ???(???) + + + 00.00.0000, 00:00:00 + + + + + Seite 1/ 99 + + + + + + + + + + + + + + + for each="record in records" + + + + + + Cashbook: + + record.cashbook.name+' (' + record.cashbook.state_string +')' + + + + + + Period: + + format_date(record.date_from) to format_date(record.date_to) + + + + + + + Bookings: + + len(record.lines) + + + + + + + + + Date + + + No. + + + Description + + + Payee + + + Revenue + + + Expense + + + + format_date(record.date_from) + + + + Initial Amount + + + format_currency(record.start_amount, None, record.cashbook.currency) if record.start_amount >= 0 else '' + + relatorio://format_currency(record.start_amount, None, record.cashbook.currency) if record.start_amount < 0 else '' + + + + for each="line in record.lines" + + + + + + + format_date(line.date) + + line.number + + line.description + + getattr(line.payee, 'rec_name', '') + + format_currency(line.credit, None, line.reconciliation.cashbook.currency) if line.credit!= 0 else '' + + format_currency(line.debit, None, line.reconciliation.cashbook.currency) if line.debit!= 0 else '' + + + + /for + + + + + + + + + + + + + + + + + + + + + Sum + + format_currency(sum([x.credit for x in record.lines]) + (record.start_amount if record.start_amount > 0 else 0), None, record.cashbook.currency) + + format_currency(sum([x.debit for x in record.lines]) - (record.start_amount if record.start_amount < 0 else 0), None, record.cashbook.currency) + + + + + + - Expenses + + format_currency(sum([x.debit for x in record.lines]) - (record.start_amount if record.start_amount < 0 else 0), None, record.cashbook.currency) + + + + + + + Total + + format_currency(record.end_amount, None, record.cashbook.currency) + + + + + /for + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tryton.cfg b/tryton.cfg index 4d9b25a..92dec51 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -17,4 +17,5 @@ xml: book.xml line.xml wizard_openline.xml + wizard_runreport.xml menu.xml diff --git a/types.xml b/types.xml index d3a628a..7df9bb0 100644 --- a/types.xml +++ b/types.xml @@ -44,10 +44,10 @@ full copyright notices and license terms. --> - - + + - + diff --git a/view/wizard_runrepbook_form.xml b/view/wizard_runrepbook_form.xml new file mode 100644 index 0000000..b45e5fc --- /dev/null +++ b/view/wizard_runrepbook_form.xml @@ -0,0 +1,15 @@ + + +
+