diff --git a/assets/sass/forms.scss b/assets/sass/forms.scss index a579d1f2..c367bca3 100644 --- a/assets/sass/forms.scss +++ b/assets/sass/forms.scss @@ -35,4 +35,8 @@ display: inline-block; margin-right: 10px; border-radius: var(--tblr-border-radius); +} + +fieldset:empty { + display: none; } \ No newline at end of file diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml index cc26e4a9..8cb6f741 100644 --- a/config/packages/kimai.yaml +++ b/config/packages/kimai.yaml @@ -107,7 +107,7 @@ kimai: REPORTING: ['view_reporting','view_other_reporting','project_reporting','customer_reporting'] # permissions which are deactivated, as these features are hidden for now # brave users can try to activate them and be surprised what happens - REGISTER_BETA: ['contract_other_profile'] + REGISTER_BETA: [] # mapping a "role name" to an array of "set names" maps: ROLE_USER: ['TIMESHEET','PROFILE'] @@ -118,10 +118,8 @@ kimai: roles: ROLE_USER: ['view_team_member','time_team_project','create_tag','view_reporting'] ROLE_TEAMLEAD: ['view_rate_own_timesheet','view_rate_other_timesheet','hourly-rate_own_profile','view_team_member'] - # TODO contract_other_profile - ROLE_ADMIN: ['hourly-rate_own_profile','edit_exported_timesheet','teams_own_profile','view_team_member','view_all_data'] - # TODO contract_other_profile - ROLE_SUPER_ADMIN: ['hourly-rate_own_profile','hourly-rate_other_profile','roles_own_profile','system_information','system_configuration','plugins','edit_exported_timesheet','teams_own_profile','view_team_member','upload_invoice_template','view_all_data'] + ROLE_ADMIN: ['hourly-rate_own_profile','edit_exported_timesheet','teams_own_profile','view_team_member','view_all_data','contract_other_profile'] + ROLE_SUPER_ADMIN: ['hourly-rate_own_profile','hourly-rate_other_profile','roles_own_profile','system_information','system_configuration','plugins','edit_exported_timesheet','teams_own_profile','view_team_member','upload_invoice_template','view_all_data','contract_other_profile'] # -------------------------------------------------------------------------------- diff --git a/phpstan.neon b/phpstan.neon index 2d05fb82..521a239b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4002,12 +4002,12 @@ parameters: path: src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php - - message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedDateTime\\(\\) expects DateTime, DateTime\\|null given\\.$#" + message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedDateTime\\(\\) expects DateTimeInterface, DateTime\\|null given\\.$#" count: 3 path: src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php - - message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedTime\\(\\) expects DateTime, DateTime\\|null given\\.$#" + message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedTime\\(\\) expects DateTimeInterface, DateTime\\|null given\\.$#" count: 2 path: src/Invoice/Hydrator/InvoiceItemDefaultHydrator.php @@ -4046,11 +4046,6 @@ parameters: count: 1 path: src/Invoice/Hydrator/InvoiceModelCustomerHydrator.php - - - message: "#^Cannot call method format\\(\\) on DateTime\\|null\\.$#" - count: 3 - path: src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php - - message: "#^Cannot call method getAddress\\(\\) on App\\\\Entity\\\\InvoiceTemplate\\|null\\.$#" count: 1 @@ -4137,13 +4132,8 @@ parameters: path: src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php - - message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedDateTime\\(\\) expects DateTime, DateTime\\|null given\\.$#" - count: 4 - path: src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php - - - - message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedMonthName\\(\\) expects DateTime, DateTime\\|null given\\.$#" - count: 1 + message: "#^Parameter \\#1 \\$date of method App\\\\Invoice\\\\InvoiceFormatter\\:\\:getFormattedDateTime\\(\\) expects DateTimeInterface, DateTime\\|null given\\.$#" + count: 2 path: src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php - diff --git a/public/build/app.f82609fb.css b/public/build/app.eb575c90.css similarity index 68% rename from public/build/app.f82609fb.css rename to public/build/app.eb575c90.css index 7f3bb1e9..7b292b80 100644 --- a/public/build/app.f82609fb.css +++ b/public/build/app.eb575c90.css @@ -1 +1 @@ -.inline-search{max-width:200px}.inline-search #searchTerm{border-right:0}@media (min-width:360px){.inline-search{max-width:235px}}@media (min-width:768px){.inline-search{max-width:325px}.search-dropdown{width:500px}}h1.navbar-brand a span{display:inline-block;padding-top:.5rem}h1.navbar-brand a:hover{text-decoration:none}#export-buttons .dropdown-menu,.inline-search .dropdown-menu,.page-actions .dropdown-menu{z-index:1021}.navbar{--tblr-navbar-brand-font-size:1rem}.error-page{margin-bottom:50px}@media print{.control-sidebar,.sf-toolbar{display:none!important}.col-print-12{width:100%}.content-wrapper{margin:0!important}section.content{margin:0;padding:0}span i.dot{display:none;margin-right:0!important}}.page-center{justify-content:center}.hidden-no-space{margin:0;padding:0}.pre-scrollable{max-height:340px;overflow-y:scroll}td.timesheet-description ul{padding-left:15px}td.timesheet-description p{margin:0}td.badges{line-height:22px}.open-edit{cursor:pointer}td.w-min,th.w-min{white-space:nowrap;width:1%}table.dataTable thead>tr>th.hw-min{white-space:normal;width:1%}.w-avatar{width:40px}.w-avatar img.avatar{max-width:40px}.list-group-item.danger{border-left:.2rem solid #d63939!important;padding-left:1.3rem}.list-group-item.success{border-left:.2rem solid #2fb344!important;padding-left:1.3rem}.box-body-scrollable{max-height:340px;overflow:auto}#activity_details_box th,#customer_details_box th,#project_details_box th{width:30%}.overlay{background:hsla(0,0%,100%,.7);height:100%;left:0;position:fixed;top:0;width:100%;z-index:1021}.overlay>.fas{color:#000;font-size:30px;left:50vw;margin-left:-15px;margin-top:-15px;position:absolute;top:50vh}table.dataTable{clear:both;margin-bottom:0!important;max-width:none!important}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;position:relative}table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{font-weight:700}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after{font-family:Font Awesome\ 5 Free;font-size:12px;opacity:.5;padding-left:5px}table.dataTable thead .sorting:after{content:"\f0dc";opacity:.2}table.dataTable thead .sorting_asc:after{content:"\f077"}table.dataTable thead .sorting_desc:after{content:"\f078"}table.dataTable thead>tr>th{vertical-align:top;white-space:nowrap}table.dataTable th:active{outline:none}table.table-bordered thead td,table.table-bordered thead th{border-left-width:0;border-top-width:0}table.table-bordered tbody td,table.table-bordered tbody th,table.table-bordered tfoot td,table.table-bordered tfoot th{border-bottom-width:0;border-left-width:0}table.table-bordered td:last-child,table.table-bordered th:last-child{border-right-width:0}@media (min-width:1200px){table.dataTable.table>tbody>tr>td{vertical-align:middle}}table.dataTable .actions{width:40px}table.dataTable tr.summary td{background-color:var(--tblr-bg-surface-secondary);border:0;font-weight:700}table.dataTable tr th.multiCheckbox{width:15px}table.dataTable tr.overlapping{border-top:2px solid rgba(214,57,57,.1)}table.dataTable tr.exported{opacity:.7}table.dataTable td .btn-group{display:flex}table.dataTable td .label{font-size:85%;line-height:24px;padding:.3em .6em}table.dataTable td span.label-invisible{opacity:.6}table.dataTable td.weekend,table.dataTable th.weekend{background-color:var(--tblr-bg-surface-secondary)}table.dataTable th.today{background-color:var(--tblr-highlight-bg)}table.dataTable td.total,table.dataTable th.total{font-weight:700}.form-dataTable table.dataTable .form-group{margin-bottom:0}table.table-hover tr.exported:hover{opacity:1}.calendar-entry ul{list-style-type:none;padding:0}.calendar-entry div{white-space:pre-line}.draggable{cursor:grab}#timesheet_calendar{--bs-gray-400:var(--tblr-border-color);--bs-gray-200:var(--tblr-gray-200)}.fc-day-sat,.fc-day-sun{background-color:var(--tblr-bg-surface-secondary)}@keyframes ticktac-blink{0%{opacity:1}5%{opacity:.95}10%{opacity:.9}15%{opacity:.85}20%{opacity:.8}25%{opacity:.75}30%{opacity:.7}35%{opacity:.65}40%{opacity:.6}45%{opacity:.65}50%{opacity:.7}55%{opacity:.75}60%{opacity:.8}65%{opacity:.85}70%{opacity:.9}75%{opacity:.95}to{opacity:1}}.ticktac-start i,.ticktac-stop i{animation:ticktac-blink 2s step-end infinite;font-size:140%}@media (max-width:991.98px){aside.navbar .btn-outline-white,header.navbar .btn-outline-white{border-color:hsla(0,0%,100%,.2)}}.ts-dropdown{z-index:1021}.ts-control>input{min-width:unset}.ts-dropdown .optgroup [data-selectable].option{padding-left:20px}.checkbox-menu.show{z-index:1021}.duration-widget .input-group{min-width:110px}.duration-widget input.duration-input{min-width:55px}#report-form div.btn-list{width:100%}#report-form div.btn-list div.selectpicker{max-width:400px;min-width:200px}#report-form div.btn-list li.dropdown-item .form-check{margin-bottom:0}.color-choice-item{border-radius:var(--tblr-border-radius);display:inline-block;height:20px;margin-right:10px;width:20px}.modal-content{box-shadow:0 10px 80px rgba(0,0,0,.6)}.progress-group .progress-title{white-space:nowrap;width:100%}.progress-group .progress-title .progress-text{display:inline-block;width:1%}.progress-group .progress-title .progress-number{display:inline-block;float:none;width:98%}.initials{font-size:13px;font-weight:700}.avatar-xs{height:23px;width:23px}.avatar-xs .initials{font-size:10px}.avatar-sm{height:38px;width:38px}.avatar-sm .initials{font-size:17px}.avatar-md{height:45px;width:45px}.avatar-md .initials{font-size:21px}.avatar-lg{height:60px;width:60px}.avatar-lg .initials{font-size:28px}.widget-user-image{border:3px solid #fff;border-radius:50%}.widget-user-image .avatar{height:83px;width:83px}.widget-user-image .avatar .initials{font-size:40px}table.dataTable.table>tbody>tr>td.avatars .avatar{margin:1px}.avatar-list-stacked .avatar{margin-right:calc(var(--tblr-avatar-size)*-.2)!important}[data-bs-theme=dark] table.dataTable th.today{color:var(--tblr-muted)}[data-bs-theme=dark] .overlay{background:rgba(0,0,0,.5)}[data-bs-theme=dark] .overlay>.fas{color:var(--tblr-white)}section.quick-entry-page #quick_entry_form{display:none}section.quick-entry-page .ts-wrapper{display:table;table-layout:fixed}section.quick-entry-page #quick_entry_box .duration-widget .input-group{min-width:85px}section.quick-entry-page #quick_entry_box .duration-widget .btn-duration-preset{padding:7px 8px 7px 5px}section.quick-entry-page #quick_entry_box .duration-widget input{padding:7px 3px 7px 7px}fieldset legend.col-form-label{padding-top:0}fieldset.form-fieldset legend{font-size:1rem;font-weight:700}.ts-dropdown .optgroup:before{--tblr-spacer:.5rem}.dropdown-divider{--tblr-dropdown-divider-margin-y:.5rem}.float-help{background-color:var(--tblr-body-color);border-radius:50px;bottom:20px;height:50px;position:fixed;right:20px;text-align:center;width:50px;z-index:1021}.float-help i{color:var(--tblr-body-bg);font-size:30px;margin-top:11px}@media (max-width:767.98px){.float-help{border-radius:36px;height:36px;width:36px}.float-help i{font-size:20px;margin-top:8px}}html[dir=rtl] .fa-chevron-left:before{content:"\f054"}html[dir=rtl] .fa-chevron-right:before{content:"\f053"} \ No newline at end of file +.inline-search{max-width:200px}.inline-search #searchTerm{border-right:0}@media (min-width:360px){.inline-search{max-width:235px}}@media (min-width:768px){.inline-search{max-width:325px}.search-dropdown{width:500px}}h1.navbar-brand a span{display:inline-block;padding-top:.5rem}h1.navbar-brand a:hover{text-decoration:none}#export-buttons .dropdown-menu,.inline-search .dropdown-menu,.page-actions .dropdown-menu{z-index:1021}.navbar{--tblr-navbar-brand-font-size:1rem}.error-page{margin-bottom:50px}@media print{.control-sidebar,.sf-toolbar{display:none!important}.col-print-12{width:100%}.content-wrapper{margin:0!important}section.content{margin:0;padding:0}span i.dot{display:none;margin-right:0!important}}.page-center{justify-content:center}.hidden-no-space{margin:0;padding:0}.pre-scrollable{max-height:340px;overflow-y:scroll}td.timesheet-description ul{padding-left:15px}td.timesheet-description p{margin:0}td.badges{line-height:22px}.open-edit{cursor:pointer}td.w-min,th.w-min{white-space:nowrap;width:1%}table.dataTable thead>tr>th.hw-min{white-space:normal;width:1%}.w-avatar{width:40px}.w-avatar img.avatar{max-width:40px}.list-group-item.danger{border-left:.2rem solid #d63939!important;padding-left:1.3rem}.list-group-item.success{border-left:.2rem solid #2fb344!important;padding-left:1.3rem}.box-body-scrollable{max-height:340px;overflow:auto}#activity_details_box th,#customer_details_box th,#project_details_box th{width:30%}.overlay{background:hsla(0,0%,100%,.7);height:100%;left:0;position:fixed;top:0;width:100%;z-index:1021}.overlay>.fas{color:#000;font-size:30px;left:50vw;margin-left:-15px;margin-top:-15px;position:absolute;top:50vh}table.dataTable{clear:both;margin-bottom:0!important;max-width:none!important}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;position:relative}table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{font-weight:700}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after{font-family:Font Awesome\ 5 Free;font-size:12px;opacity:.5;padding-left:5px}table.dataTable thead .sorting:after{content:"\f0dc";opacity:.2}table.dataTable thead .sorting_asc:after{content:"\f077"}table.dataTable thead .sorting_desc:after{content:"\f078"}table.dataTable thead>tr>th{vertical-align:top;white-space:nowrap}table.dataTable th:active{outline:none}table.table-bordered thead td,table.table-bordered thead th{border-left-width:0;border-top-width:0}table.table-bordered tbody td,table.table-bordered tbody th,table.table-bordered tfoot td,table.table-bordered tfoot th{border-bottom-width:0;border-left-width:0}table.table-bordered td:last-child,table.table-bordered th:last-child{border-right-width:0}@media (min-width:1200px){table.dataTable.table>tbody>tr>td{vertical-align:middle}}table.dataTable .actions{width:40px}table.dataTable tr.summary td{background-color:var(--tblr-bg-surface-secondary);border:0;font-weight:700}table.dataTable tr th.multiCheckbox{width:15px}table.dataTable tr.overlapping{border-top:2px solid rgba(214,57,57,.1)}table.dataTable tr.exported{opacity:.7}table.dataTable td .btn-group{display:flex}table.dataTable td .label{font-size:85%;line-height:24px;padding:.3em .6em}table.dataTable td span.label-invisible{opacity:.6}table.dataTable td.weekend,table.dataTable th.weekend{background-color:var(--tblr-bg-surface-secondary)}table.dataTable th.today{background-color:var(--tblr-highlight-bg)}table.dataTable td.total,table.dataTable th.total{font-weight:700}.form-dataTable table.dataTable .form-group{margin-bottom:0}table.table-hover tr.exported:hover{opacity:1}.calendar-entry ul{list-style-type:none;padding:0}.calendar-entry div{white-space:pre-line}.draggable{cursor:grab}#timesheet_calendar{--bs-gray-400:var(--tblr-border-color);--bs-gray-200:var(--tblr-gray-200)}.fc-day-sat,.fc-day-sun{background-color:var(--tblr-bg-surface-secondary)}@keyframes ticktac-blink{0%{opacity:1}5%{opacity:.95}10%{opacity:.9}15%{opacity:.85}20%{opacity:.8}25%{opacity:.75}30%{opacity:.7}35%{opacity:.65}40%{opacity:.6}45%{opacity:.65}50%{opacity:.7}55%{opacity:.75}60%{opacity:.8}65%{opacity:.85}70%{opacity:.9}75%{opacity:.95}to{opacity:1}}.ticktac-start i,.ticktac-stop i{animation:ticktac-blink 2s step-end infinite;font-size:140%}@media (max-width:991.98px){aside.navbar .btn-outline-white,header.navbar .btn-outline-white{border-color:hsla(0,0%,100%,.2)}}.ts-dropdown{z-index:1021}.ts-control>input{min-width:unset}.ts-dropdown .optgroup [data-selectable].option{padding-left:20px}.checkbox-menu.show{z-index:1021}.duration-widget .input-group{min-width:110px}.duration-widget input.duration-input{min-width:55px}#report-form div.btn-list{width:100%}#report-form div.btn-list div.selectpicker{max-width:400px;min-width:200px}#report-form div.btn-list li.dropdown-item .form-check{margin-bottom:0}.color-choice-item{border-radius:var(--tblr-border-radius);display:inline-block;height:20px;margin-right:10px;width:20px}fieldset:empty{display:none}.modal-content{box-shadow:0 10px 80px rgba(0,0,0,.6)}.progress-group .progress-title{white-space:nowrap;width:100%}.progress-group .progress-title .progress-text{display:inline-block;width:1%}.progress-group .progress-title .progress-number{display:inline-block;float:none;width:98%}.initials{font-size:13px;font-weight:700}.avatar-xs{height:23px;width:23px}.avatar-xs .initials{font-size:10px}.avatar-sm{height:38px;width:38px}.avatar-sm .initials{font-size:17px}.avatar-md{height:45px;width:45px}.avatar-md .initials{font-size:21px}.avatar-lg{height:60px;width:60px}.avatar-lg .initials{font-size:28px}.widget-user-image{border:3px solid #fff;border-radius:50%}.widget-user-image .avatar{height:83px;width:83px}.widget-user-image .avatar .initials{font-size:40px}table.dataTable.table>tbody>tr>td.avatars .avatar{margin:1px}.avatar-list-stacked .avatar{margin-right:calc(var(--tblr-avatar-size)*-.2)!important}[data-bs-theme=dark] table.dataTable th.today{color:var(--tblr-muted)}[data-bs-theme=dark] .overlay{background:rgba(0,0,0,.5)}[data-bs-theme=dark] .overlay>.fas{color:var(--tblr-white)}section.quick-entry-page #quick_entry_form{display:none}section.quick-entry-page .ts-wrapper{display:table;table-layout:fixed}section.quick-entry-page #quick_entry_box .duration-widget .input-group{min-width:85px}section.quick-entry-page #quick_entry_box .duration-widget .btn-duration-preset{padding:7px 8px 7px 5px}section.quick-entry-page #quick_entry_box .duration-widget input{padding:7px 3px 7px 7px}fieldset legend.col-form-label{padding-top:0}fieldset.form-fieldset legend{font-size:1rem;font-weight:700}.ts-dropdown .optgroup:before{--tblr-spacer:.5rem}.dropdown-divider{--tblr-dropdown-divider-margin-y:.5rem}.float-help{background-color:var(--tblr-body-color);border-radius:50px;bottom:20px;height:50px;position:fixed;right:20px;text-align:center;width:50px;z-index:1021}.float-help i{color:var(--tblr-body-bg);font-size:30px;margin-top:11px}@media (max-width:767.98px){.float-help{border-radius:36px;height:36px;width:36px}.float-help i{font-size:20px;margin-top:8px}}html[dir=rtl] .fa-chevron-left:before{content:"\f054"}html[dir=rtl] .fa-chevron-right:before{content:"\f053"} \ No newline at end of file diff --git a/public/build/entrypoints.json b/public/build/entrypoints.json index 44d0e8f7..2f841aa9 100644 --- a/public/build/entrypoints.json +++ b/public/build/entrypoints.json @@ -6,7 +6,7 @@ "/build/app.99c7b6b4.js" ], "css": [ - "/build/app.f82609fb.css" + "/build/app.eb575c90.css" ] }, "export-pdf": { @@ -64,7 +64,7 @@ "integrity": { "/build/runtime.f0079159.js": "sha384-H22sAW1aTvyIPqvHOvGXWSWTxf0y6mptp+MsVmyXCfjx/WJjBbhX9gbUZ+qIuihV", "/build/app.99c7b6b4.js": "sha384-bPAdOMl3I6Ia3clnHgDiwoNKKe/bKnAdHUJdl7BXbsFNMg2wHsUDrGH+uNCQowqM", - "/build/app.f82609fb.css": "sha384-X848pib0qXUB72LdaVSupYXnYPE/lNXHXNkJdlh4FRj534BVHyupi+ly3cfCkDRS", + "/build/app.eb575c90.css": "sha384-CT92SMS+AjbulH+hT+pOq4jicscpVYpl/acq388EdqruZe26icGl9sNq9xaYXH8l", "/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u", "/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg", "/build/invoice.2604495e.js": "sha384-D6JvhGSqlx7z72b/qD3nF3QDXPy+XsCSRGtWfs1icjDKOcd2UzuXwuSa/E1Fg2TJ", diff --git a/public/build/manifest.json b/public/build/manifest.json index 4a7bd38c..149bedb5 100644 --- a/public/build/manifest.json +++ b/public/build/manifest.json @@ -1,5 +1,5 @@ { - "build/app.css": "/build/app.f82609fb.css", + "build/app.css": "/build/app.eb575c90.css", "build/app.js": "/build/app.99c7b6b4.js", "build/export-pdf.css": "/build/export-pdf.d8a6c23b.css", "build/export-pdf.js": "/build/export-pdf.d367a32e.js", diff --git a/src/Constants.php b/src/Constants.php index 502bf8ac..e5f4617f 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -17,11 +17,11 @@ class Constants /** * The current release version */ - public const VERSION = '2.0.28'; + public const VERSION = '2.0.29'; /** * The current release: major * 10000 + minor * 100 + patch */ - public const VERSION_ID = 20028; + public const VERSION_ID = 20029; /** * The software name */ diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 4655b32c..2c28423c 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -305,7 +305,7 @@ final class Configuration implements ConfigurationInterface ->defaultValue(0) ->end() ->integerNode('long_running_duration') - ->defaultValue(600) + ->defaultValue(0) ->end() ->booleanNode('require_activity') ->defaultTrue() diff --git a/src/Entity/Invoice.php b/src/Entity/Invoice.php index 8a7b4080..2bc15fca 100644 --- a/src/Entity/Invoice.php +++ b/src/Entity/Invoice.php @@ -208,7 +208,7 @@ class Invoice implements EntityWithMetaFields $this->currency = $model->getCurrency(); $createdAt = $model->getInvoiceDate(); - $this->createdAt = $createdAt; + $this->createdAt = \DateTime::createFromInterface($createdAt); $this->timezone = $createdAt->getTimezone()->getName(); $this->dueDays = $template->getDueDays(); diff --git a/src/Event/PageActionsEvent.php b/src/Event/PageActionsEvent.php index 67971e79..75edf051 100644 --- a/src/Event/PageActionsEvent.php +++ b/src/Event/PageActionsEvent.php @@ -175,9 +175,9 @@ class PageActionsEvent extends ThemeEvent public function addDelete(string $url, bool $remoteConfirm = true): void { if ($remoteConfirm) { - $this->addAction('trash', ['url' => $url, 'class' => 'modal-ajax-form text-red', 'translation_domain' => 'actions']); + $this->addAction('trash', ['url' => $url, 'class' => 'modal-ajax-form text-red', 'translation_domain' => 'actions', 'title' => 'trash']); } else { - $this->addAction('trash', ['url' => $url, 'class' => 'confirmation-link text-red', 'attr' => ['data-question' => 'confirm.delete'], 'translation_domain' => 'actions']); + $this->addAction('trash', ['url' => $url, 'class' => 'confirmation-link text-red', 'attr' => ['data-question' => 'confirm.delete'], 'translation_domain' => 'actions', 'title' => 'trash']); } } diff --git a/src/Form/Type/DateRangeType.php b/src/Form/Type/DateRangeType.php index 4c857686..22393872 100644 --- a/src/Form/Type/DateRangeType.php +++ b/src/Form/Type/DateRangeType.php @@ -49,6 +49,7 @@ final class DateRangeType extends AbstractType 'format' => $formFormat, 'separator' => self::DATE_SPACER, 'allow_empty' => true, + 'with_presets' => true, 'attr' => [ 'pattern' => $pattern . self::DATE_SPACER . $pattern ], @@ -61,26 +62,28 @@ final class DateRangeType extends AbstractType $user = $options['user']; $factory = DateTimeFactory::createByUser($user); - $ranges = [ - 'daterangepicker.allTime' => [null, null], - 'daterangepicker.today' => [$factory->createDateTime('00:00:00'), $factory->createDateTime('23:59:59')], - 'daterangepicker.yesterday' => [$factory->createDateTime('-1 day 00:00:00'), $factory->createDateTime('-1 day 23:59:59')], - 'daterangepicker.thisWeek' => [$factory->getStartOfWeek(), $factory->getEndOfWeek()], - 'daterangepicker.lastWeek' => [$factory->getStartOfWeek('-1 week'), $factory->getEndOfWeek('-1 week')], - 'daterangepicker.thisMonth' => [$factory->getStartOfMonth(), $factory->getEndOfMonth()], - 'daterangepicker.lastMonth' => [$factory->getStartOfLastMonth(), $factory->getEndOfLastMonth()], - 'daterangepicker.thisYearUntilNow' => [$factory->createStartOfYear(), $factory->createDateTime('23:59:59')], - ]; + if ($options['with_presets']) { + $ranges = [ + 'daterangepicker.allTime' => [null, null], + 'daterangepicker.today' => [$factory->createDateTime('00:00:00'), $factory->createDateTime('23:59:59')], + 'daterangepicker.yesterday' => [$factory->createDateTime('-1 day 00:00:00'), $factory->createDateTime('-1 day 23:59:59')], + 'daterangepicker.thisWeek' => [$factory->getStartOfWeek(), $factory->getEndOfWeek()], + 'daterangepicker.lastWeek' => [$factory->getStartOfWeek('-1 week'), $factory->getEndOfWeek('-1 week')], + 'daterangepicker.thisMonth' => [$factory->getStartOfMonth(), $factory->getEndOfMonth()], + 'daterangepicker.lastMonth' => [$factory->getStartOfLastMonth(), $factory->getEndOfLastMonth()], + 'daterangepicker.thisYearUntilNow' => [$factory->createStartOfYear(), $factory->createDateTime('23:59:59')], + ]; - $thisYear = (int) $factory->createStartOfYear()->format('Y'); - for ($i = 0; $i < 3; $i++) { - $year = $thisYear - $i; - $ranges[$year] = [$year . '-01-01', $year . '-12-31']; + $thisYear = (int) $factory->createStartOfYear()->format('Y'); + for ($i = 0; $i < 3; $i++) { + $year = $thisYear - $i; + $ranges[$year] = [$year . '-01-01', $year . '-12-31']; + } + + $view->vars['ranges'] = $ranges; + $view->vars['rangeFormat'] = $options['format']; } - $view->vars['ranges'] = $ranges; - $view->vars['rangeFormat'] = $options['format']; - $view->vars['attr'] = array_merge($view->vars['attr'], [ 'data-separator' => $options['separator'], ]); diff --git a/src/Invoice/DefaultInvoiceFormatter.php b/src/Invoice/DefaultInvoiceFormatter.php index 30666713..98912814 100644 --- a/src/Invoice/DefaultInvoiceFormatter.php +++ b/src/Invoice/DefaultInvoiceFormatter.php @@ -32,17 +32,17 @@ final class DefaultInvoiceFormatter implements InvoiceFormatter return $this->formatter; } - public function getFormattedDateTime(\DateTime $date): string + public function getFormattedDateTime(\DateTimeInterface $date): string { return (string) $this->getFormatter()->dateShort($date); } - public function getFormattedTime(\DateTime $date): string + public function getFormattedTime(\DateTimeInterface $date): string { return (string) $this->getFormatter()->time($date); } - public function getFormattedMonthName(\DateTime $date): string + public function getFormattedMonthName(\DateTimeInterface $date): string { return $this->getFormatter()->monthName($date); } diff --git a/src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php b/src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php index e8b56762..426e3fa3 100644 --- a/src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php +++ b/src/Invoice/Hydrator/InvoiceModelDefaultHydrator.php @@ -71,8 +71,6 @@ final class InvoiceModelDefaultHydrator implements InvoiceModelHydrator $query = $model->getQuery(); if ($query !== null) { $begin = $query->getBegin(); - $end = $query->getEnd(); - if ($begin !== null) { $values = array_merge($values, [ 'query.day' => $begin->format('d'), @@ -88,6 +86,12 @@ final class InvoiceModelDefaultHydrator implements InvoiceModelHydrator 'query.begin_month' => $formatter->getFormattedMonthName($begin), 'query.begin_month_number' => $begin->format('m'), 'query.begin_year' => $begin->format('Y'), + ]); + } + + $end = $query->getEnd(); + if ($end !== null) { + $values = array_merge($values, [ 'query.end' => $formatter->getFormattedDateTime($end), // since 1.9 'query.end_day' => $end->format('d'), @@ -97,7 +101,6 @@ final class InvoiceModelDefaultHydrator implements InvoiceModelHydrator 'query.end_month_number' => $end->format('m'), // since 1.9 'query.end_year' => $end->format('Y'), - // since 1.9 ]); } diff --git a/src/Invoice/InvoiceFormatter.php b/src/Invoice/InvoiceFormatter.php index 6e06f8c8..c4bf3c6f 100644 --- a/src/Invoice/InvoiceFormatter.php +++ b/src/Invoice/InvoiceFormatter.php @@ -9,7 +9,7 @@ namespace App\Invoice; -use DateTime; +use DateTimeInterface; /** * @internal this is subject to change @@ -20,15 +20,15 @@ interface InvoiceFormatter public function setLocale(string $locale): void; - public function getFormattedDateTime(DateTime $date): string; + public function getFormattedDateTime(DateTimeInterface $date): string; - public function getFormattedTime(DateTime $date): string; + public function getFormattedTime(DateTimeInterface $date): string; public function getFormattedAmount(float $amount): string; public function getFormattedMoney(float $amount, ?string $currency, bool $withCurrency = true): string; - public function getFormattedMonthName(DateTime $date): string; + public function getFormattedMonthName(DateTimeInterface $date): string; public function getFormattedDuration(int $seconds): string; diff --git a/src/Invoice/InvoiceModel.php b/src/Invoice/InvoiceModel.php index 01f46a58..630c8280 100644 --- a/src/Invoice/InvoiceModel.php +++ b/src/Invoice/InvoiceModel.php @@ -39,7 +39,7 @@ final class InvoiceModel private ?InvoiceTemplate $template = null; private ?CalculatorInterface $calculator = null; private ?NumberGeneratorInterface $generator = null; - private \DateTime $invoiceDate; + private \DateTimeInterface $invoiceDate; private ?User $user = null; private InvoiceFormatter $formatter; /** @@ -58,7 +58,7 @@ final class InvoiceModel */ public function __construct(InvoiceFormatter $formatter, CustomerStatisticService $customerStatistic, ProjectStatisticService $projectStatistic, ActivityStatisticService $activityStatistic) { - $this->invoiceDate = new \DateTime(); + $this->invoiceDate = new \DateTimeImmutable(); $this->formatter = $formatter; $this->addModelHydrator(new InvoiceModelDefaultHydrator()); $this->addModelHydrator(new InvoiceModelCustomerHydrator($customerStatistic)); @@ -73,11 +73,9 @@ final class InvoiceModel return $this->query; } - public function setQuery(InvoiceQuery $query): InvoiceModel + public function setQuery(InvoiceQuery $query): void { $this->query = $query; - - return $this; } /** @@ -124,11 +122,9 @@ final class InvoiceModel return $this->template; } - public function setTemplate(InvoiceTemplate $template): InvoiceModel + public function setTemplate(InvoiceTemplate $template): void { $this->template = $template; - - return $this; } public function getCustomer(): ?Customer @@ -136,32 +132,34 @@ final class InvoiceModel return $this->customer; } - public function setCustomer(?Customer $customer): InvoiceModel + public function setCustomer(Customer $customer): void { $this->customer = $customer; - - return $this; } - public function getDueDate(): ?\DateTime + /** + * Requires the template and invoice date to be set + */ + public function getDueDate(): \DateTimeInterface { - if (null === $this->getTemplate()) { - return null; + $date = \DateTimeImmutable::createFromInterface($this->getInvoiceDate()); + + $dueDays = 14; + if ($this->getTemplate() !== null) { + $dueDays = $this->getTemplate()->getDueDays(); } - return new \DateTime('+' . $this->getTemplate()->getDueDays() . ' days'); + return $date->add(new \DateInterval('P' . $dueDays . 'D')); } - public function getInvoiceDate(): \DateTime + public function getInvoiceDate(): \DateTimeInterface { return $this->invoiceDate; } - public function setInvoiceDate(\DateTime $date): InvoiceModel + public function setInvoiceDate(\DateTimeInterface $date): void { $this->invoiceDate = $date; - - return $this; } public function getInvoiceNumber(): string diff --git a/src/Invoice/InvoiceModelFactory.php b/src/Invoice/InvoiceModelFactory.php index c3217db9..1c264c9c 100644 --- a/src/Invoice/InvoiceModelFactory.php +++ b/src/Invoice/InvoiceModelFactory.php @@ -11,7 +11,10 @@ namespace App\Invoice; use App\Activity\ActivityStatisticService; use App\Customer\CustomerStatisticService; +use App\Entity\Customer; +use App\Entity\InvoiceTemplate; use App\Project\ProjectStatisticService; +use App\Repository\Query\InvoiceQuery; final class InvoiceModelFactory { @@ -22,8 +25,14 @@ final class InvoiceModelFactory ) { } - public function createModel(InvoiceFormatter $formatter): InvoiceModel + public function createModel(InvoiceFormatter $formatter, Customer $customer, InvoiceTemplate $template, InvoiceQuery $query): InvoiceModel { - return new InvoiceModel($formatter, $this->customerStatisticService, $this->projectStatisticService, $this->activityStatisticService); + $model = new InvoiceModel($formatter, $this->customerStatisticService, $this->projectStatisticService, $this->activityStatisticService); + + $model->setCustomer($customer); + $model->setTemplate($template); + $model->setQuery($query); + + return $model; } } diff --git a/src/Invoice/ServiceInvoice.php b/src/Invoice/ServiceInvoice.php index bef25577..7ff3518f 100644 --- a/src/Invoice/ServiceInvoice.php +++ b/src/Invoice/ServiceInvoice.php @@ -410,12 +410,12 @@ final class ServiceInvoice $formatter = new DefaultInvoiceFormatter($this->formatter, $template->getLanguage()); - $model = $this->invoiceModelFactory->createModel($formatter); - $model - ->setCustomer($customer) - ->setTemplate($template) - ->setQuery($query) - ; + $model = $this->invoiceModelFactory->createModel( + $formatter, + $customer, + $template, + $query + ); if ($query->getInvoiceDate() !== null) { $model->setInvoiceDate($query->getInvoiceDate()); diff --git a/src/Pdf/MPdfConverter.php b/src/Pdf/MPdfConverter.php index b0f621cd..d940a2f4 100644 --- a/src/Pdf/MPdfConverter.php +++ b/src/Pdf/MPdfConverter.php @@ -128,8 +128,14 @@ final class MPdfConverter implements HtmlToPdfConverter $defaultFontConfig = (new FontVariables())->getDefaults(); $fontData = $defaultFontConfig['fontdata']; + // lowercase all font names, otherwise they cannot be loaded + // see https://github.com/kimai/www.kimai.org/issues/280 if (\array_key_exists('fonts', $options)) { - $fontData = array_merge($fontData, $options['fonts']); + $fonts = []; + foreach ($options['fonts'] as $name => $values) { + $fonts[strtolower($name)] = $values; + } + $fontData = array_merge($fontData, $fonts); } return $fontData; diff --git a/src/Repository/InvoiceRepository.php b/src/Repository/InvoiceRepository.php index a193e218..03037357 100644 --- a/src/Repository/InvoiceRepository.php +++ b/src/Repository/InvoiceRepository.php @@ -91,24 +91,27 @@ class InvoiceRepository extends EntityRepository return $result['counter']; } - public function getCounterForDay(\DateTime $date, ?Customer $customer = null, ?User $user = null): int + public function getCounterForDay(\DateTimeInterface $date, ?Customer $customer = null, ?User $user = null): int { + $date = \DateTime::createFromInterface($date); $start = (clone $date)->setTime(0, 0, 0); $end = (clone $date)->setTime(23, 59, 59); return $this->getCounterFor($start, $end, $customer, $user); } - public function getCounterForMonth(\DateTime $date, ?Customer $customer = null, ?User $user = null): int + public function getCounterForMonth(\DateTimeInterface $date, ?Customer $customer = null, ?User $user = null): int { + $date = \DateTime::createFromInterface($date); $start = (clone $date)->setDate((int) $date->format('Y'), (int) $date->format('n'), 1)->setTime(0, 0, 0); $end = (clone $date)->setDate((int) $date->format('Y'), (int) $date->format('n'), (int) $date->format('t'))->setTime(23, 59, 59); return $this->getCounterFor($start, $end, $customer, $user); } - public function getCounterForYear(\DateTime $date, ?Customer $customer = null, ?User $user = null): int + public function getCounterForYear(\DateTimeInterface $date, ?Customer $customer = null, ?User $user = null): int { + $date = \DateTime::createFromInterface($date); $start = (clone $date)->setDate((int) $date->format('Y'), 1, 1)->setTime(0, 0, 0); $end = (clone $date)->setDate((int) $date->format('Y'), 12, 31)->setTime(23, 59, 59); diff --git a/templates/user/contract.html.twig b/templates/user/contract.html.twig index b2f614fb..ac2692cc 100644 --- a/templates/user/contract.html.twig +++ b/templates/user/contract.html.twig @@ -4,6 +4,8 @@ {% form_theme form 'form/horizontal.html.twig' %} + {{ form_row(form._token) }} +
{% endblock %} diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index 6dd020e6..86193052 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -288,7 +288,7 @@ class ConfigurationTest extends TestCase 'allow_overbooking_budget' => true, 'lockdown_period_timezone' => null, 'break_warning_duration' => 0, - 'long_running_duration' => 600, + 'long_running_duration' => 0, 'require_activity' => true, ], 'duration_increment' => 15, diff --git a/tests/Entity/InvoiceTest.php b/tests/Entity/InvoiceTest.php index ab2a81fd..012790af 100644 --- a/tests/Entity/InvoiceTest.php +++ b/tests/Entity/InvoiceTest.php @@ -190,11 +190,8 @@ class InvoiceTest extends TestCase $query->setBegin(new \DateTime()); $query->setEnd(new \DateTime()); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $model->setUser($user); $model->setInvoiceDate($created); diff --git a/tests/Event/InvoiceCreatedEventTest.php b/tests/Event/InvoiceCreatedEventTest.php index efb92b45..6b19ad06 100644 --- a/tests/Event/InvoiceCreatedEventTest.php +++ b/tests/Event/InvoiceCreatedEventTest.php @@ -9,8 +9,11 @@ namespace App\Tests\Event; +use App\Entity\Customer; use App\Entity\Invoice; +use App\Entity\InvoiceTemplate; use App\Event\InvoiceCreatedEvent; +use App\Repository\Query\InvoiceQuery; use App\Tests\Invoice\DebugFormatter; use App\Tests\Mocks\InvoiceModelFactoryFactory; use PHPUnit\Framework\TestCase; @@ -23,7 +26,7 @@ class InvoiceCreatedEventTest extends TestCase public function testDefaultValues() { $invoice = new Invoice(); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery()); $sut = new InvoiceCreatedEvent($invoice, $model); diff --git a/tests/Event/InvoicePostRenderEventTest.php b/tests/Event/InvoicePostRenderEventTest.php index d5e8eecb..e4c7f838 100644 --- a/tests/Event/InvoicePostRenderEventTest.php +++ b/tests/Event/InvoicePostRenderEventTest.php @@ -9,8 +9,11 @@ namespace App\Tests\Event; +use App\Entity\Customer; +use App\Entity\InvoiceTemplate; use App\Event\InvoicePostRenderEvent; use App\Model\InvoiceDocument; +use App\Repository\Query\InvoiceQuery; use App\Tests\Invoice\DebugFormatter; use App\Tests\Invoice\Renderer\DebugRenderer; use App\Tests\Mocks\InvoiceModelFactoryFactory; @@ -24,7 +27,7 @@ class InvoicePostRenderEventTest extends TestCase { public function testDefaultValues() { - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery()); $document = new InvoiceDocument(new \SplFileInfo(__FILE__)); $renderer = new DebugRenderer(); $response = new Response(); diff --git a/tests/Event/InvoicePreRenderEventTest.php b/tests/Event/InvoicePreRenderEventTest.php index 116db23d..82907226 100644 --- a/tests/Event/InvoicePreRenderEventTest.php +++ b/tests/Event/InvoicePreRenderEventTest.php @@ -9,8 +9,11 @@ namespace App\Tests\Event; +use App\Entity\Customer; +use App\Entity\InvoiceTemplate; use App\Event\InvoicePreRenderEvent; use App\Model\InvoiceDocument; +use App\Repository\Query\InvoiceQuery; use App\Tests\Invoice\DebugFormatter; use App\Tests\Invoice\Renderer\DebugRenderer; use App\Tests\Mocks\InvoiceModelFactoryFactory; @@ -23,7 +26,7 @@ class InvoicePreRenderEventTest extends TestCase { public function testDefaultValues() { - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery()); $document = new InvoiceDocument(new \SplFileInfo(__FILE__)); $renderer = new DebugRenderer(); diff --git a/tests/Event/PageActionsEventTest.php b/tests/Event/PageActionsEventTest.php index b15a31d8..7d041897 100644 --- a/tests/Event/PageActionsEventTest.php +++ b/tests/Event/PageActionsEventTest.php @@ -104,7 +104,7 @@ class PageActionsEventTest extends TestCase 'create' => ['url' => 'foo5', 'class' => 'modal-ajax-form', 'title' => 'create', 'accesskey' => 'a'], 'download' => ['url' => 'foo7', 'class' => 'toolbar-action', 'title' => 'export'], 'edit' => ['url' => 'trölölö', 'class' => 'modal-ajax-form', 'translation_domain' => 'actions', 'title' => 'edit'], - 'trash' => ['url' => 'foo3', 'class' => 'modal-ajax-form text-red', 'translation_domain' => 'actions'], + 'trash' => ['url' => 'foo3', 'class' => 'modal-ajax-form text-red', 'translation_domain' => 'actions', 'title' => 'trash'], ]; $this->assertEquals(\count($expected), $sut->countActions()); diff --git a/tests/Invoice/Calculator/AbstractCalculatorTest.php b/tests/Invoice/Calculator/AbstractCalculatorTest.php index a4b0cc88..0ff99bf1 100644 --- a/tests/Invoice/Calculator/AbstractCalculatorTest.php +++ b/tests/Invoice/Calculator/AbstractCalculatorTest.php @@ -56,12 +56,7 @@ abstract class AbstractCalculatorTest extends TestCase $template = new InvoiceTemplate(); $query = new InvoiceQuery(); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); - $model->setQuery($query); - - return $model; + return (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); } protected function assertDescription(CalculatorInterface $sut, $addProject = false, $addActivity = false): void @@ -100,11 +95,8 @@ abstract class AbstractCalculatorTest extends TestCase ->setActivity($activity) ->setProject($project); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries([$timesheet]); - $model->setQuery($query); $sut->setModel($model); $this->assertEquals(1, \count($sut->getEntries())); diff --git a/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php b/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php index 683f3a6e..5c28cbdc 100644 --- a/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/ActivityInvoiceCalculatorTest.php @@ -135,11 +135,8 @@ class ActivityInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->addActivity($activity1); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/ActivityUserInvoiceCalculatorTest.php b/tests/Invoice/Calculator/ActivityUserInvoiceCalculatorTest.php index 4de0a168..928eb164 100644 --- a/tests/Invoice/Calculator/ActivityUserInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/ActivityUserInvoiceCalculatorTest.php @@ -148,11 +148,8 @@ class ActivityUserInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->addActivity($activity1); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/DateInvoiceCalculatorTest.php b/tests/Invoice/Calculator/DateInvoiceCalculatorTest.php index 5e48f362..0c5f94a2 100644 --- a/tests/Invoice/Calculator/DateInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/DateInvoiceCalculatorTest.php @@ -108,11 +108,8 @@ class DateInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->setProjects([$project1]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/DateUserInvoiceCalculatorTest.php b/tests/Invoice/Calculator/DateUserInvoiceCalculatorTest.php index 885a82d4..3c19e8d5 100644 --- a/tests/Invoice/Calculator/DateUserInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/DateUserInvoiceCalculatorTest.php @@ -111,11 +111,8 @@ class DateUserInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->setProjects([$project1]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/DefaultCalculatorTest.php b/tests/Invoice/Calculator/DefaultCalculatorTest.php index 55e51cf0..a2285c60 100644 --- a/tests/Invoice/Calculator/DefaultCalculatorTest.php +++ b/tests/Invoice/Calculator/DefaultCalculatorTest.php @@ -64,11 +64,8 @@ class DefaultCalculatorTest extends AbstractCalculatorTest $entries = [$timesheet, $timesheet2, $timesheet3]; - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, new InvoiceQuery()); $model->addEntries($entries); - $model->setQuery(new InvoiceQuery()); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/PriceInvoiceCalculatorTest.php b/tests/Invoice/Calculator/PriceInvoiceCalculatorTest.php index 555ce4ac..7d19c3d6 100644 --- a/tests/Invoice/Calculator/PriceInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/PriceInvoiceCalculatorTest.php @@ -112,11 +112,8 @@ class PriceInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->setProjects([$project1]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/ProjectInvoiceCalculatorTest.php b/tests/Invoice/Calculator/ProjectInvoiceCalculatorTest.php index 80c915d8..5f2222b1 100644 --- a/tests/Invoice/Calculator/ProjectInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/ProjectInvoiceCalculatorTest.php @@ -108,11 +108,8 @@ class ProjectInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->setProjects([$project1]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/ProjectUserInvoiceCalculatorTest.php b/tests/Invoice/Calculator/ProjectUserInvoiceCalculatorTest.php index d5db51af..6f7e1b6c 100644 --- a/tests/Invoice/Calculator/ProjectUserInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/ProjectUserInvoiceCalculatorTest.php @@ -111,11 +111,8 @@ class ProjectUserInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->setProjects([$project1]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/ShortInvoiceCalculatorTest.php b/tests/Invoice/Calculator/ShortInvoiceCalculatorTest.php index 506933c4..1e43688a 100644 --- a/tests/Invoice/Calculator/ShortInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/ShortInvoiceCalculatorTest.php @@ -92,11 +92,8 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->addActivity($activity); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); @@ -174,11 +171,8 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->addActivity($activity); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); @@ -253,11 +247,8 @@ class ShortInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->addActivity($activity); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/UserInvoiceCalculatorTest.php b/tests/Invoice/Calculator/UserInvoiceCalculatorTest.php index 699eb460..7ffd6e07 100644 --- a/tests/Invoice/Calculator/UserInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/UserInvoiceCalculatorTest.php @@ -106,11 +106,8 @@ class UserInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->addActivity($activity); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/Calculator/WeeklyInvoiceCalculatorTest.php b/tests/Invoice/Calculator/WeeklyInvoiceCalculatorTest.php index ac34b914..d974d117 100644 --- a/tests/Invoice/Calculator/WeeklyInvoiceCalculatorTest.php +++ b/tests/Invoice/Calculator/WeeklyInvoiceCalculatorTest.php @@ -111,11 +111,8 @@ class WeeklyInvoiceCalculatorTest extends AbstractCalculatorTest $query = new InvoiceQuery(); $query->setProjects([$project1]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $sut = $this->getCalculator(); $sut->setModel($model); diff --git a/tests/Invoice/DebugFormatter.php b/tests/Invoice/DebugFormatter.php index df7c8fed..38ba1a96 100644 --- a/tests/Invoice/DebugFormatter.php +++ b/tests/Invoice/DebugFormatter.php @@ -13,12 +13,12 @@ use App\Invoice\InvoiceFormatter; class DebugFormatter implements InvoiceFormatter { - public function getFormattedDateTime(\DateTime $date): string + public function getFormattedDateTime(\DateTimeInterface $date): string { return $date->format('d.m.Y'); } - public function getFormattedTime(\DateTime $date): string + public function getFormattedTime(\DateTimeInterface $date): string { return $date->format('H:i'); } @@ -36,7 +36,7 @@ class DebugFormatter implements InvoiceFormatter return (string) $amount; } - public function getFormattedMonthName(\DateTime $date): string + public function getFormattedMonthName(\DateTimeInterface $date): string { return $date->format('m'); } diff --git a/tests/Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php b/tests/Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php index cd2100ac..8dcb2d3a 100644 --- a/tests/Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php +++ b/tests/Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php @@ -21,7 +21,7 @@ class InvoiceModelCustomerHydratorTest extends TestCase { use RendererTestTrait; - public function testHydrate() + public function testHydrate(): void { $model = $this->getInvoiceModel(); @@ -30,12 +30,36 @@ class InvoiceModelCustomerHydratorTest extends TestCase $result = $sut->hydrate($model); $this->assertModelStructure($result); - $model->setCustomer(null); $result = $sut->hydrate($model); - self::assertEmpty($result); + + $this->assertModelStructure($result); + + self::assertEquals([ + 'customer.id' => null, + 'customer.address' => "Foo\nStreet\n1111 City", + 'customer.name' => 'customer,with/special#name', + 'customer.contact' => '', + 'customer.company' => '', + 'customer.vat' => '', + 'customer.vat_id' => '', + 'customer.number' => '', + 'customer.country' => null, + 'customer.homepage' => '', + 'customer.comment' => '', + 'customer.email' => '', + 'customer.fax' => '', + 'customer.phone' => '', + 'customer.mobile' => '', + 'customer.invoice_text' => '', + 'customer.budget_open' => '€0.00', + 'customer.budget_open_plain' => 0.0, + 'customer.time_budget_open' => '0.00', + 'customer.time_budget_open_plain' => 0, + 'customer.meta.foo-customer' => 'bar-customer', + ], $result); } - protected function assertModelStructure(array $model) + protected function assertModelStructure(array $model): void { $keys = [ 'customer.id', diff --git a/tests/Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php b/tests/Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php index 8950018a..72484f66 100644 --- a/tests/Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php +++ b/tests/Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php @@ -20,7 +20,7 @@ class InvoiceModelDefaultHydratorTest extends TestCase { use RendererTestTrait; - public function testHydrate() + public function testHydrate(): void { $model = $this->getInvoiceModel(); @@ -30,7 +30,7 @@ class InvoiceModelDefaultHydratorTest extends TestCase $this->assertModelStructure($result); } - protected function assertModelStructure(array $model, $hasProject = true) + protected function assertModelStructure(array $model, bool $hasProject = true): void { $keys = [ 'invoice.due_date', diff --git a/tests/Invoice/InvoiceFilenameTest.php b/tests/Invoice/InvoiceFilenameTest.php index 0c554ae9..1a278bed 100644 --- a/tests/Invoice/InvoiceFilenameTest.php +++ b/tests/Invoice/InvoiceFilenameTest.php @@ -29,39 +29,35 @@ class InvoiceFilenameTest extends TestCase { $customer = new Customer('foo'); $template = new InvoiceTemplate(); + $query = new InvoiceQuery(); + $project = new Project(); + $project->setName('Demo ProjecT1'); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $query->addProject($project); + + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); $model->setNumberGenerator($this->getNumberGeneratorSut()); - $model->setTemplate($template); - $model->setCustomer($customer); $datePrefix = date('ymd'); $sut = new InvoiceFilename($model); - self::assertEquals($datePrefix . '-foo', $sut->getFilename()); - self::assertEquals($datePrefix . '-foo', (string) $sut); + self::assertEquals($datePrefix . '-foo-Demo_ProjecT1', $sut->getFilename()); + self::assertEquals($datePrefix . '-foo-Demo_ProjecT1', (string) $sut); $customer->setCompany('barß / laölala # ldksjf 123 MyAwesome GmbH'); $sut = new InvoiceFilename($model); - self::assertEquals($datePrefix . '-barss_laolala_ldksjf_123_MyAwesome_GmbH', $sut->getFilename()); - self::assertEquals($datePrefix . '-barss_laolala_ldksjf_123_MyAwesome_GmbH', (string) $sut); + self::assertEquals($datePrefix . '-barss_laolala_ldksjf_123_MyAwesome_GmbH-Demo_ProjecT1', $sut->getFilename()); + self::assertEquals($datePrefix . '-barss_laolala_ldksjf_123_MyAwesome_GmbH-Demo_ProjecT1', (string) $sut); $customer->setCompany('까깨꺄꺠꺼께껴꼐꼬꽈sssss'); $sut = new InvoiceFilename($model); - self::assertEquals($datePrefix . '-kkakkaekkyakkyaekkeokkekkyeokkyekkokkwasssss', $sut->getFilename()); + self::assertEquals($datePrefix . '-kkakkaekkyakkyaekkeokkekkyeokkyekkokkwasssss-Demo_ProjecT1', $sut->getFilename()); $customer->setCompany('\"#+ß.!$%&/()=?\\n=/*-+´_<>@' . "\n"); $sut = new InvoiceFilename($model); - self::assertEquals($datePrefix . '-ss_n_-', $sut->getFilename()); - - $project = new Project(); - $project->setName('Demo ProjecT1'); - - $query = new InvoiceQuery(); - $query->addProject($project); - $model->setQuery($query); + self::assertEquals($datePrefix . '-ss_n_--Demo_ProjecT1', $sut->getFilename()); $customer->setCompany('\"#+ß.!$%&/()=?\\n=/*-+´_<>@' . "\n"); $sut = new InvoiceFilename($model); diff --git a/tests/Invoice/InvoiceModelTest.php b/tests/Invoice/InvoiceModelTest.php index 18ae073c..9083ed7d 100644 --- a/tests/Invoice/InvoiceModelTest.php +++ b/tests/Invoice/InvoiceModelTest.php @@ -23,21 +23,19 @@ use PHPUnit\Framework\TestCase; */ class InvoiceModelTest extends TestCase { - public function testEmptyObject() + public function testEmptyObject(): void { $formatter = new DebugFormatter(); - $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel($formatter); + $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel($formatter, new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery()); + + self::assertNotNull($sut->getQuery()); + self::assertNotNull($sut->getCustomer()); + self::assertNotNull($sut->getTemplate()); - self::assertNull($sut->getQuery()); - self::assertNull($sut->getCustomer()); - self::assertNull($sut->getDueDate()); self::assertNull($sut->getCalculator()); - self::assertEmpty($sut->getEntries()); self::assertIsArray($sut->getEntries()); - - self::assertNull($sut->getTemplate()); - self::assertInstanceOf(\DateTime::class, $sut->getInvoiceDate()); + self::assertInstanceOf(\DateTimeInterface::class, $sut->getInvoiceDate()); self::assertSame($formatter, $sut->getFormatter()); @@ -47,27 +45,24 @@ class InvoiceModelTest extends TestCase self::assertSame($newFormatter, $sut->getFormatter()); } - public function testEmptyObjectThrowsExceptionOnNumberGenerator() + public function testEmptyObjectThrowsExceptionOnNumberGenerator(): void { $formatter = new DebugFormatter(); - $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel($formatter); + $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel($formatter, new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery()); $this->expectException(\Exception::class); $this->expectExceptionMessage('InvoiceModel::getInvoiceNumber() cannot be called before calling setNumberGenerator()'); $sut->getInvoiceNumber(); } - public function testSetter() + public function testSetter(): void { - $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); - - $query = new InvoiceQuery(); - self::assertInstanceOf(InvoiceModel::class, $sut->setQuery($query)); - self::assertSame($query, $sut->getQuery()); - $customer = new Customer('foo'); - self::assertInstanceOf(InvoiceModel::class, $sut->setCustomer($customer)); - self::assertSame($customer, $sut->getCustomer()); + $query = new InvoiceQuery(); + $template = new InvoiceTemplate(); + $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); + + self::assertSame($query, $sut->getQuery()); $calculator = new DefaultCalculator(); self::assertInstanceOf(InvoiceModel::class, $sut->setCalculator($calculator)); @@ -78,11 +73,28 @@ class InvoiceModelTest extends TestCase $number = $sut->getInvoiceNumber(); self::assertEquals($number, $sut->getInvoiceNumber()); - $template = new InvoiceTemplate(); - self::assertNull($sut->getDueDate()); - self::assertInstanceOf(InvoiceModel::class, $sut->setTemplate($template)); self::assertSame($template, $sut->getTemplate()); - /* @phpstan-ignore-next-line */ - self::assertInstanceOf(\DateTime::class, $sut->getDueDate()); + self::assertInstanceOf(\DateTimeInterface::class, $sut->getDueDate()); + } + + public function testDueDate(): void + { + $customer = new Customer('foo'); + $query = new InvoiceQuery(); + $template = new InvoiceTemplate(); + $sut = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, $template, $query); + + $dueDate = $sut->getDueDate(); + $dueDays = $template->getDueDays(); + self::assertNotNull($dueDays); + $expected = new \DateTimeImmutable('+' . $dueDays . ' days'); + + self::assertEquals($expected->format('Y-m-d'), $dueDate->format('Y-m-d')); + + $sut->setInvoiceDate(new \DateTimeImmutable('2022-05-23')); + $template->setDueDays(14); + $dueDate = $sut->getDueDate(); + $expected = new \DateTimeImmutable('2022-06-06'); + self::assertEquals($expected->format('Y-m-d'), $dueDate->format('Y-m-d')); } } diff --git a/tests/Invoice/NumberGenerator/ConfigurableNumberGeneratorTest.php b/tests/Invoice/NumberGenerator/ConfigurableNumberGeneratorTest.php index 16da7e37..2ab24dd3 100644 --- a/tests/Invoice/NumberGenerator/ConfigurableNumberGeneratorTest.php +++ b/tests/Invoice/NumberGenerator/ConfigurableNumberGeneratorTest.php @@ -10,9 +10,11 @@ namespace App\Tests\Invoice\NumberGenerator; use App\Entity\Customer; +use App\Entity\InvoiceTemplate; use App\Entity\User; use App\Invoice\NumberGenerator\ConfigurableNumberGenerator; use App\Repository\InvoiceRepository; +use App\Repository\Query\InvoiceQuery; use App\Tests\Invoice\DebugFormatter; use App\Tests\Mocks\InvoiceModelFactoryFactory; use App\Tests\Mocks\SystemConfigurationFactory; @@ -156,9 +158,8 @@ class ConfigurableNumberGeneratorTest extends TestCase $user->method('getAccountNumber')->willReturn('0815'); $sut = $this->getSut($format, $counter); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, new InvoiceTemplate(), new InvoiceQuery()); $model->setInvoiceDate($invoiceDate); - $model->setCustomer($customer); $model->setUser($user); $sut->setModel($model); @@ -200,9 +201,8 @@ class ConfigurableNumberGeneratorTest extends TestCase $this->expectExceptionMessage(sprintf('Unknown %s found', $brokenPart)); $sut = $this->getSut($format); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery()); $model->setInvoiceDate($invoiceDate); - $model->setCustomer(new Customer('foo')); $sut->setModel($model); $sut->getInvoiceNumber(); @@ -235,9 +235,8 @@ class ConfigurableNumberGeneratorTest extends TestCase $customer->setName(null); $sut = $this->getSut($format); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter()); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), $customer, new InvoiceTemplate(), new InvoiceQuery()); $model->setInvoiceDate(new \DateTime()); - $model->setCustomer($customer); $model->setUser($user); $sut->setModel($model); diff --git a/tests/Invoice/NumberGenerator/DateNumberGeneratorTest.php b/tests/Invoice/NumberGenerator/DateNumberGeneratorTest.php index fba420ff..98045d4a 100644 --- a/tests/Invoice/NumberGenerator/DateNumberGeneratorTest.php +++ b/tests/Invoice/NumberGenerator/DateNumberGeneratorTest.php @@ -9,8 +9,11 @@ namespace App\Tests\Invoice\NumberGenerator; +use App\Entity\Customer; +use App\Entity\InvoiceTemplate; use App\Invoice\NumberGenerator\DateNumberGenerator; use App\Repository\InvoiceRepository; +use App\Repository\Query\InvoiceQuery; use App\Tests\Invoice\DebugFormatter; use App\Tests\Mocks\InvoiceModelFactoryFactory; use PHPUnit\Framework\TestCase; @@ -40,7 +43,7 @@ class DateNumberGeneratorTest extends TestCase public function testGetInvoiceNumber() { $sut = $this->getSut(false, false); - $sut->setModel((new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter())); + $sut->setModel((new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery())); $this->assertEquals(date('ymd'), $sut->getInvoiceNumber()); $this->assertEquals('date', $sut->getId()); @@ -49,7 +52,7 @@ class DateNumberGeneratorTest extends TestCase public function testGetInvoiceNumberWithExisting() { $sut = $this->getSut(true, false); - $sut->setModel((new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter())); + $sut->setModel((new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery())); $this->assertEquals(date('ymd-01'), $sut->getInvoiceNumber()); $this->assertEquals('date', $sut->getId()); @@ -58,7 +61,7 @@ class DateNumberGeneratorTest extends TestCase public function testGetInvoiceNumberWithManyExisting() { $sut = $this->getSut(true, true); - $sut->setModel((new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter())); + $sut->setModel((new InvoiceModelFactoryFactory($this))->create()->createModel(new DebugFormatter(), new Customer('foo'), new InvoiceTemplate(), new InvoiceQuery())); $this->assertEquals(date('ymd-99'), $sut->getInvoiceNumber()); $this->assertEquals('date', $sut->getId()); diff --git a/tests/Invoice/Renderer/RendererTestTrait.php b/tests/Invoice/Renderer/RendererTestTrait.php index 54e3204d..20e578ef 100644 --- a/tests/Invoice/Renderer/RendererTestTrait.php +++ b/tests/Invoice/Renderer/RendererTestTrait.php @@ -238,11 +238,8 @@ trait RendererTestTrait $query->setEnd(new \DateTime()); $query->setProjects([$project, $project2]); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel($this->getFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel($this->getFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $model->setUser($user); $calculator = new DefaultCalculator(); @@ -326,11 +323,8 @@ trait RendererTestTrait $query->setBegin(new \DateTime()); $query->setEnd(new \DateTime()); - $model = (new InvoiceModelFactoryFactory($this))->create()->createModel($this->getFormatter()); - $model->setCustomer($customer); - $model->setTemplate($template); + $model = (new InvoiceModelFactoryFactory($this))->create()->createModel($this->getFormatter(), $customer, $template, $query); $model->addEntries($entries); - $model->setQuery($query); $model->setUser($user); $calculator = new DefaultCalculator(); diff --git a/tests/phpstan.neon b/tests/phpstan.neon index 1db6450a..8235a13c 100644 --- a/tests/phpstan.neon +++ b/tests/phpstan.neon @@ -6612,11 +6612,6 @@ parameters: count: 1 path: Invoice/Hydrator/InvoiceModelActivityHydratorTest.php - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelCustomerHydratorTest\\:\\:assertModelStructure\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelCustomerHydratorTest\\:\\:assertModelStructure\\(\\) has parameter \\$model with no value type specified in iterable type array\\.$#" count: 1 @@ -6632,21 +6627,6 @@ parameters: count: 1 path: Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelCustomerHydratorTest\\:\\:testHydrate\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/Hydrator/InvoiceModelCustomerHydratorTest.php - - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelDefaultHydratorTest\\:\\:assertModelStructure\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php - - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelDefaultHydratorTest\\:\\:assertModelStructure\\(\\) has parameter \\$hasProject with no type specified\\.$#" - count: 1 - path: Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelDefaultHydratorTest\\:\\:assertModelStructure\\(\\) has parameter \\$model with no value type specified in iterable type array\\.$#" count: 1 @@ -6662,11 +6642,6 @@ parameters: count: 1 path: Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelDefaultHydratorTest\\:\\:testHydrate\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/Hydrator/InvoiceModelDefaultHydratorTest.php - - message: "#^Method App\\\\Tests\\\\Invoice\\\\Hydrator\\\\InvoiceModelProjectHydratorTest\\:\\:assertModelStructure\\(\\) has no return type specified\\.$#" count: 1 @@ -6722,21 +6697,6 @@ parameters: count: 1 path: Invoice/InvoiceItemTest.php - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\InvoiceModelTest\\:\\:testEmptyObject\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/InvoiceModelTest.php - - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\InvoiceModelTest\\:\\:testEmptyObjectThrowsExceptionOnNumberGenerator\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/InvoiceModelTest.php - - - - message: "#^Method App\\\\Tests\\\\Invoice\\\\InvoiceModelTest\\:\\:testSetter\\(\\) has no return type specified\\.$#" - count: 1 - path: Invoice/InvoiceModelTest.php - - message: "#^Method App\\\\Tests\\\\Invoice\\\\NumberGenerator\\\\DateNumberGeneratorTest\\:\\:getSut\\(\\) has no return type specified\\.$#" count: 1