InvoicePresenter
extends BasePresenter
in package
uses
InvoiceFormTrait, InvoiceCreditNoteFormTrait, InvoicerSelectDataTrait, SellerPickerTrait, CustomerPickerTrait, PaymentPickerTrait, InvoiceTemplatePickerTrait, PickerHostTrait, AdminFormHelpersTrait, AdminEditFormComponentsTrait
Invoice administration (`/admin/invoicer/invoice`).
A large form (the skeleton of InvoiceTemplatePresenter) with number, dates, payment and e-mail.
The grid links to the PDF and sends an e-mail with the PDF attached (action sendEmail). "Create
an invoice from a template" (add?itId) prefills the form from InvoiceTemplate. E-mail sending
goes through the ApiBridge to the Api (EmailManager with SendEmailTrait); the admin has no
sending of its own.
Table of Contents
Constants
- LOGIN_BACKLINK : string = 'backlink'
- Login page parameter with the key of the stored request to return to ({@see loginReturnArgs()}).
- DEFAULT_ITEMS_PER_PAGE : mixed = 20
- Items per page of admin lists when the DB setting is missing.
- FORM_BACK_SUBSECTION : mixed = 'formBack'
- Session subsection mapping a key to the previous page URL of edit forms.
- SESSION_NAMESPACE : mixed = 'admin'
- BLOCKED_EXTENSIONS : mixed = ['php', 'php3', 'php4', 'php5', 'php7', 'php8',...
- Extensions that must not be uploaded into the web-served folder; otherwise an editor upload would mean running foreign code on the server. It is no content whitelist (the editor uploads what is needed), only a safeguard against executable files.
- CREDIT_NOTE_COLLECTIONS : array<string|int, mixed> = ['items', 'shippers', 'paymentMethods']
- Row collections that carry a quantity (same as `CreditNoteLedger`).
- EDITOR_PAGE_LIMIT : mixed = 500
- Listing cap; the dialog is a suggester, not a paged list.
- EDITOR_PAGE_TARGETS : mixed = ['front:system:page:show']
- Routes the editor may link to: text pages only.
- EDITOR_UPLOAD_FOLDER : mixed = 'editorUploads'
- Editor root (relative to the `uploads/` root). Changing it to `''` would open the whole `uploads/` tree to the manager; the editor user could then reach (and delete) files of other modules such as products and avatars.
- IMAGE_EXTENSIONS : mixed = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'avif', '...
- Extensions the file manager shows as a preview instead of a document icon.
- LOCALE_MAP : mixed = ['cs' => 'cs_CZ', 'en' => 'en_US', 'sk' => 'sk_...
- Maps the short language code to the full locale of the registered NEON sources.
- PRICE_PATTERN : string = '\s*-?\d{1,7}([.,]\d{1,3})?\s*'
- Price mask for `decimal(10,3)`: up to 7 integer digits, 0-3 decimals.
- QUANTITY_PATTERN : string = '\s*-?\d{1,6}([.,]\d{1,2})?\s*'
- Quantity mask for `decimal(8,2)`: up to 6 integer digits, 0-2 decimals, comma or dot, surrounding spaces tolerated.
Properties
- $accessTokenValidator : AccessTokenValidator
- Signature and expiry alone are not enough: a revoked token (`jti` on the deny-list) that has not expired yet would keep the session logged in although the Api guard rejects the same token. Same contract as {@see \App\Core\Traits\Api\Presenters\JwtAuthTrait::checkJwtAuth()}, one implementation.
- $adminFormActionsFactory : FormActionsFactory
- $adminLangNavFactory : LangNavFactory
- $adminLanguageManager : LanguageManager
- $adminPageManager : AdminPageManager
- $authManager : AuthManager
- $authStorageManager : AuthStorageManager
- $authUserManager : UserManager
- Admin `UserManager` for {@see UserManager::login()}. A module must not read through another module, so admin has its own `login()` that calls the same Api endpoint (`api/system/auth/login`).
- $columnSchema : ColumnSchema
- Limits of the real database columns for {@see guardColumns()}.
- $container : Container
- $customerManager : CustomerManager
- $deviceDetector : DeviceDetector
- $editorAutosaveScope : EditorAutosaveScope
- Scope of the editor autosave drafts, see {@see \App\Core\Security\EditorAutosaveScope}.
- $editorLinkPageManager : PageManager
- NOTE: own property name. `$pageManager` already exists on presenters (`PagePickerTrait`), and two `#[Inject]` properties of the same name would collide in the trait composition.
- $editorUploadManager : FileSystemManager
- NOTE: own property name, not `$fileSystemManager`.
- $eventDispatcher : EventDispatcher
- $formSubmissionGuard : FormSubmissionGuard
- One-time submission tokens of "add" forms, see {@see guardFormSubmitOnce()}.
- $jwtManager : JwtManager
- $languageContext : LanguageContext
- $languageManager : LanguageManager
- $localizationContext : LocalizationContext
- $localizationManager : LocalizationManager
- $loginDeviceCookie : LoginDeviceCookie
- Cookie of a known device for the password login throttle ({@see self::rememberLoginDevice()}).
- $modalWindowFactory : ModalWindowFactory
- Injected through Nette presenter inject (after construction), not the constructor.
- $paymentManager : PaymentManager
- $picker : string
- Picker mode of a list; when not empty, the presenter renders its `show` grid as a selection modal (no add/edit/delete/checkboxes, each row has a select button) in the minimal `@picker.latte` layout.
- $pickerExclude : int
- Id of the record that cannot be selected in picker mode (its select button is hidden).
- $pickerExcludeSubtreeLft : int
- `lft`/`rgt` bounds of a whole subtree whose nodes cannot be selected in picker mode.
- $pickerExcludeSubtreeRgt : int
- $presenterContext : PresenterContext
- $privilegeManager : PrivilegeManager
- $queryCacheContext : QueryCacheContext
- Query cache policy for the whole admin request; `startup()` disables it.
- $routerDispatcher : RouterDispatcher
- $sellerManager : SellerManager
- $settingContext : SettingContext
- $settingManager : SettingManager
- $themeContext : ThemeContext
- $themeManager : ThemeManager
- $themeResolver : DefaultThemeResolver
- $translator : ITranslator
- $translatorSessionResolver : Session
- $userManager : UserManager
- $adminPageEntity : AdminPage|null
- $billingLines : array<int, object>
- $currencies : array<int, object>
- $debugMode : bool
- $invoicerDefaultUnit : string
- $invoicerDuePeriod : int
- $invoiceTypes : array<int, object>
- $languages : array<int, object>
- $localizations : array<int, object>
- $paymentMethods : array<int, object>
- $paymentRegions : array<int, object>
- $pdfVariantOptionsData : array<int, NotTranslate>
- $productionMode : bool
- $productTypes : array<int, object>
- $savedEntityId : int|null
- Id of the record just saved; set by the `$processData` callback in `createForm()` after a successful save.
- $translatorDomain : string
- $userTypes : array<int, object>
- $apiBridge : ApiBridge
- $billingLineManager : BillingLineManager
- $countryManager : CountryManager
- $creditNoteError : string|null
- `errorCode` from the Api preview (`orderOwned`, `sourceNotIssued`, ...).
- $creditNotePreview : array<string, mixed>|null
- Basis of the manual credit note form from the Api (`credit-note-preview`); `null` means no credit note can be issued for the invoice (reason in {@see $creditNoteError}).
- $currencyManager : CurrencyManager
- $dataGridFactory : DataGridFactory
- $editedInvoice : Invoice|null
- $emailDefaultBody : string
- $emailDefaultSubject : string
- $emailManager : EmailManager
- $invoiceManager : InvoiceManager
- $invoiceSupplyKindDefaultId : int|null
- Default supply kind of a new line; `null` when the code list offers none.
- $invoiceSupplyKindOptions : array<int, string>|null
- Options of the supply kind select on a line (loaded once per request).
- $invoiceTaxManager : InvoiceTaxManager
- $invoiceTemplateManager : InvoiceTemplateManager
- $invoiceTypeManager : InvoiceTypeManager
- $isLoggingIn : bool
- $paymentMethodManager : PaymentMethodManager
- $paymentRegionManager : PaymentRegionManager
- $pdfTemplateManager : PdfTemplateManager
- $pickerFactory : PickerFactory
- $prefillFromTemplate : bool
- Prefill from the template picker (signal `useTemplate`); allows applying defaults outside a plain GET.
- $productTypeManager : ProductTypeManager
- $sendEmailInvoice : Invoice|null
- $theme : Theme|null
- $userPrivileges : array<int, string>
- $userTypeManager : UserTypeManager
Methods
- __construct() : mixed
- actionAdd() : void
- actionCreditNote() : void
- Shows the form of a manual credit note for an issued invoice.
- actionDownloadPdf() : void
- Streams the invoice PDF through a PHP proxy; the real disk path is never published (and the PDF directory need not be under the document root).
- actionEdit() : void
- actionSendEmail() : void
- beforeRender() : void
- createComponent() : IComponent|null
- flashFormOwnErrors() : void
- Flashes form-level errors (`$form->getOwnErrors()`) as `danger` messages.
- flashRejectedUploads() : void
- Flashes one `warning` listing the files the Api rejected (type, dimensions, unreadable) after a successful save of a form with a dropzone ({@see UploadRejection}).
- formatLayoutTemplateFiles() : array<string|int, mixed>
- Admin version of {@see \App\Core\Traits\Front\Presenters\ThemeInitTrait::formatLayoutTemplateFiles()}.
- getAdminPageEntity() : AdminPage|null
- getContainer() : Container
- getFormBackUrl() : string
- Returns the stored previous page URL for the key, used by the `cancel` link in the template.
-
getInvoiceSupplyKindProto()
: array{options: array
, defaultId: int|null} - Returns the options and the default kind for the client prototype of a new line (`lineProto`).
- getModalWindow() : ModalWindow
- getRouterDispatcher() : RouterDispatcher
- getTranslator() : ITranslator
- guardFormSubmitOnce() : void
- Protects a form against a double submit: one rendered form saves at most once.
- handleChangeLocale() : void
- handleEditorCreateFolder() : void
- Creates a subfolder in `folder` (path relative to the editor root).
- handleEditorDelete() : void
- Deletes a file or (recursively) a folder. An empty path would point to the editor root, which cannot be deleted.
- handleEditorFiles() : void
- Sends the folder listing for the editor file manager. The `folder` parameter is a path relative to the editor root (empty means the root).
- handleEditorPages() : void
- Sends the page list for the link dialog as JSON `{"pages": [{id, label, url}, ...]}` sorted by label.
- handleEditorRename() : void
- Renames a file or folder (`path` relative to the editor root).
- handleEditorUpload() : void
- Accepts a file from the editor (field `file`, multipart POST; optional `folder` = subfolder of the editor root) and sends JSON `{"location": "/www/uploads/editorUploads/..."}`, the format TinyMCE expects from `images_upload_handler`.
- handleLock() : void
- Explicitly locks the invoice (irreversible).
- handleLogout() : void
- handleSignOut() : void
- handleUseTemplate() : void
- Rebuilds the add form from the chosen template and redraws it (template picker signal).
- hasServiceByType() : bool
- Returns whether the container has a service of the given type.
- initializeTranslator() : void
- isAddAction() : bool
- Tells whether the current action creates a record: `add` and the `add<Something>` actions (`addMenu`, `addKey`). Derived from the server context only, like {@see formSubmitPrivilege()}.
- isAllowed() : bool
- Returns whether the logged-in user has the given privilege.
- isSubmitOnceForm() : bool
- Tells whether the form was protected by {@see guardFormSubmitOnce()}.
- loginWithCredentials() : void
- Logs in with username and password; called only by the login form (after validation and CSRF).
- publishFieldErrors() : void
- Publishes element errors of a failed submit to the client.
- redirectToFormBack() : void
- Redirects to the stored previous page and discards the key.
- renderAdd() : void
- renderCreditNote() : void
- renderEdit() : void
- renderSendEmail() : void
- renderShow() : void
- resolveFormBackKey() : string
- Returns the previous-page key: from the URL if present (survives the update redirect), otherwise on a plain GET render of the edit page stores `Referer` in the session under a new random key.
- runSubmitOnce() : bool|null
- Runs a saving step of a form under its one-time token (a form without the token just runs it).
- setConfigParameters() : void
- setTranslator() : $this
- startup() : void
- typedComponent() : T
- Returns a subcomponent with a verified type.
- authorize() : void
- Authorization hook; by default requires the `:Admin` privilege.
- authorizeFormSubmit() : void
- Gate for writing presenter forms built by `createForm()`.
- authorizeListing() : void
- Gate for reading lists.
- checkAdminAccess() : void
- Entry gate to the admin: a guest is sent to login; a logged-in user without `:Admin` is sent to login with an error.
- checkAuthentication() : void
- checkCurrentPrivilege() : void
- Builds the key from the current request (`:Admin:<Module>:<Presenter>:<action>`) and checks it. `getName()` already contains the `Admin:...` prefix, so only one leading colon is added.
- checkPrivilege() : void
- Checks a specific privilege; throws 403 when denied.
- createComponentAdminFormActions() : FormActions
- createComponentAdminLangNav() : LangNav
- createComponentCreditNoteForm() : Form
- createComponentEditForm() : Form
- createComponentGrid() : DataGrid
- createComponentModalWindow() : ModalWindow
- createComponentPicker() : Multiplier<string|int, Picker>
- createComponentSendEmailForm() : Form
- createForm() : Form
- Creates an edit form with the standard actions and a return to the previous page.
- currentLangId() : int|null
- Returns the current language id (for picker labels etc.), null when unknown.
- customerDeliveryPicker() : PickerConfig
- customerPicker() : PickerConfig
- domainTranslator() : PrefixedTranslator|null
- Returns a translator prefixed with the presenter domain, or `null` (empty domain or a translator other than Contributte).
- formSubmitPrivilege() : string
- Builds the e-mail sending form, which belongs to its own action `sendEmail` with the same-named key ({@see actionSendEmail()}, {@see processSendEmail()}), not to `edit`, which {@see BasePresenter::formSubmitPrivilege()} would derive otherwise. The exception applies to this form only; `editForm` still goes through add/edit.
- getAdminItemsPerPage() : int
- Returns the default items per page of admin lists from the DB setting `admin.itemsPerPage` (module System = 1), falling back to {@see DEFAULT_ITEMS_PER_PAGE}.
- getAdminLayout() : string
- Returns the layout name; in picker mode ({@see $picker}) the `show` grid uses the minimal `@picker.latte` (no sidebar/header) so the opener fetch returns only the table.
- getFormBackFallback() : string
- Returns the return URL when the previous page is unknown; override in a presenter without a `show` action.
- getFormLanguages() : array<int, Language>
- Returns the languages for multilingual form fields (admin `LanguageManager`).
- getSessionKey() : string
- Returns a session key string, e.g. 'front.auth.step1'.
- getSessionSection() : SessionSection
- Returns a Nette\SessionSection instance using a dynamically built session key.
- guardColumns() : void
- Gates every text and number field of the form by the real column it writes to ({@see \App\Core\Forms\ColumnGate::guard()}): an oversized value is an error at the field, never a database error that closes the entity manager (admin walkthrough A1, A14).
- initializePresenterContext() : void
- intOrNull() : int|null
- Converts mixed to int or null (an empty or zero value becomes null).
- invoiceTemplatePicker() : PickerConfig
- isSameSiteRequest() : bool
- Tells whether the request comes from the own site (Nette SameSite cookie); protects GET actions with a side effect.
- loadInvoicerSelectData() : void
- loadUserPrivileges() : void
- Loads all privileges of the logged-in user with one database query. Call it right after `checkAdminAccess()` in `startup()` (the user is guaranteed to be logged in by then).
- logout() : void
- parseDateTime() : DateTime|null
- Converts a `datetime-local` input or text value to `DateTime`, or null when empty or unparsable.
- paymentPicker() : PickerConfig
- pickers() : array<string, PickerConfig>
- sellerPicker() : PickerConfig
- setTranslatorDomain() : void
- setupTemplateTranslator() : void
- Sets a translator prefixed with the presenter domain into the template (as Front components do, see {@see \App\Core\Base\BaseComponent::setup()}).
- str() : string
- Safely converts a mixed form value to string.
- strOrNull() : string|null
- Converts mixed to string or null (an empty string is stored as null).
- templateItemDescriptions() : array<string, array<int, string|null>>
- Returns item descriptions of the template for a new invoice from a template: the form does not render a description, so {@see InvoiceFormTrait::buildItems()} looks them up here on save.
- templateItemKey() : string
- Key of a template item to form row pair: code + name.
- addCustomerBlock() : void
- addDeliveryBlock() : void
- addEmailBlock() : void
- addGiftsMultiplier() : void
- Same gate as {@see addItemsMultiplier()}, limit for gifts.
- addInvoiceHeaderFields() : void
- addInvoiceTaxFields() : void
- Panel "VAT": manual override of the tax treatment.
- addItemsMultiplier() : void
- The row count limit is read from the raw HTTP data (`onAnchor`, see {@see MultiplierLimits::guard()}), with `$maxCopies` as the second line of defense against materialization.
- addLineControls() : void
- addNullableSelect() : SelectBox
- addPaymentMethodBlock() : void
- addSellerBlock() : void
- addShipperBlock() : void
- addVouchersMultiplier() : void
- Same gate as {@see addItemsMultiplier()}, limit for vouchers.
- applyInvoiceTax() : bool
- Applies the invoice VAT from the engine plus the manual override.
- applyLine() : void
- applyNewInvoiceDefaults() : void
- New invoice (no template): dates today and today + `duePeriod`, `IN_INVOICE` e-mail defaults.
- billingLineOptions() : array<int, NotTranslate>
- buildGifts() : ArrayCollection<int, InvoiceGift>
- buildInvoiceFromTemplate() : Invoice|null
- buildInvoiceTaxPanel() : array<string, mixed>|null
- Returns data of the VAT panel as ready-made strings for the template (no calculation in Latte).
- buildItems() : ArrayCollection<int, InvoiceItem>
- buildPaymentMethods() : ArrayCollection<int, InvoicePaymentMethod>
- buildShippers() : ArrayCollection<int, InvoiceShipper>
- buildVouchers() : ArrayCollection<int, InvoiceVoucher>
- canOfferCreditNote() : bool
- Mirrors the Api conditions of a manual credit note source ( {@see \App\UI\Api\Invoicer\Models\Generators\InvoiceGenerator::manualCreditNoteSource()}): a numbered, non-credit invoice without an order. UX only; the Api is authoritative.
- copyLine() : void
- countryOptions() : array<string, string>
- Returns ISO country options for the customer select: active countries, CZ and SK first.
- createIdentity() : SimpleIdentity|null
- createMultiplierComponent() : Multiplier<string|int, IComponent>
- Creates a multiplier for the component.
- createNewComponentInstance() : IComponent|null
- Creates a new component instance without adding it to the presenter; used by the multiplier.
- createStandardComponent() : IComponent|null
- Creates a standard component (not a multiplier).
- creditNoteTypeIds() : array<int, int>
- creditNoteTypeOptions() : array<int, string>
- Returns the credit types from the preview (id => key) translated to invoice type names.
- currencyOptions() : array<int, NotTranslate>
- customerDeliveryFieldMap() : array<string, string>
- customerFieldMap() : array<string, string>
- Returns the mapping data key (from {@see customerPrefillData()}) to billing field. Shared by the picker (client `fieldMap`) and the server-side prefill (snippet redraw after a pick).
- customerLabel() : string
- customerPrefillData() : array<string, string>
- dateOrNull() : DateTime|null
- `<input type=date>`: strict parser (see `StrictDateInput`), not `new DateTime()`.
- dateOrToday() : DateTime
- Parses a date or falls back to today for a truly empty field.
- defaultCreditNoteTypeId() : int|null
- Returns the default type: `DOBROPIS` (the corrective tax document), otherwise the first one offered.
- defaultCurrencyShortcut() : string
- defaultUnit() : string
- editorBreadcrumb() : array<int, array{label: string, path: string}>
- Builds the breadcrumb navigation: cumulative segment paths.
- editorLinkLangId() : int
- Returns the language used to pick labels and URLs (default 1, Czech).
- editorPageLabel() : string
- Returns the page label: title, otherwise name, otherwise `#id`.
- editorPageRoute() : Route|null
- Returns the first page route the editor may link to. A page may have several (many-to-many); the whitelisted one is taken, not the first in order, so a page with both `Page:show` and `Page:form` ends up on the right one.
- editorPageUrl() : string|null
- Returns the front end address of a page. The router builds it from the page route, so `/o-nas` and any prefix come out on their own.
- editorParentFolder() : string|null
- Returns the parent folder (null in the editor root).
- editorPath() : string|null
- Converts a client path (relative to the editor root) to an Api path (relative to the `uploads/` root).
- editorUploadName() : string|null
- Builds a safe and unique file name. Sanitization copies the Api layer rules (webalize of the base and of the extension), so the name returned in the URL is exactly the name the file is stored under. The random suffix prevents collisions: `writeFile()` overwrites the same name without asking, so two different `obrazek.jpg` files would overwrite each other.
- editorUploadUrl() : string
- Returns the public URL of a file. `$path` is relative to the `uploads/` root (so it includes `editorUploads/`), the same shape as other uploads in the system.
- ensureEditorRoot() : void
- Creates the editor root folder; when it already exists the Api returns false and nothing happens.
- expireIdleLogin() : bool
- Returns whether the login expired from inactivity. If so, revokes the tokens (like a logout), clears the `auth` section, logs out the Nette identity and returns true; otherwise moves the activity stamp forward.
- findInvoice() : Invoice|null
- firstItemVat() : string|null
- Returns the rate of the first line of the invoice, used to prefill the manual override field.
- firstLineDefaults() : array<string, mixed>
- flashInvoiceEmailAfterSave() : void
- Outcome of the e-mail sent by the Api right after the save (`saveInfo.invoiceEmail`); nothing when no e-mail was due (not checked, already sent).
- getClientIp() : string
- giftDefaults() : array<int, array<string, mixed>>
- initializeMetaTags() : void
- Fills the template with the title, meta tags and HTML text of the page from the translation (`PageText`) of the current language, for the layout (like the Front {@see \App\Core\Traits\Front\Presenters\PageInitTrait}).
- initializePage() : void
- invoiceTemplateLabel() : string
- invoiceTypeNameOptions() : array<int, string>
- Returns a map of invoice types `id => name` for the grid column/filter.
- invoiceTypeOptions() : array<int, NotTranslate>
- isDevelopment() : bool
- isInvoiceEdit() : bool
- Whether a saved invoice (has id) is edited; add and template prefill (transient copy) return false.
- isInvoiceLocked() : bool
- Whether the invoice is locked: its own state `lockedDatetime`, set only by the Api (e-mail dispatch, credit note or cancellation of the invoice, explicit lock).
- languageOptions() : array<int, NotTranslate>
- lineDefaults() : array<int, array<string, mixed>>
- lineRow() : array<string, mixed>
- loadCustomer() : Customer|null
- Loads the customer including contacts for the server-side prefill of the invoice snapshot.
- loadEmailDefaults() : void
- Prefills the subject/body of the e-mail sent from the administration ({@see InvoiceEmailTemplate::Admin}, falls back to the automatic template) by language. Admin `EmailManager` is plain CRUD and reads the translation.
- loadFormData() : void
- loadInvoiceSupplyKinds() : void
- Loads the line supply kind options and the default kind (mirror of {@see InvoiceTemplateFormTrait::loadInvoiceTemplateSupplyKinds()}).
- loadLocalization() : Localization|null
- loadPdfVariantOptions() : array<int, NotTranslate>
- loadSeller() : Seller|null
- Loads the seller with contacts, accounts and tax status history for the server-side prefill of the invoice snapshot.
- localizationCurrencyKey() : string|null
- Admin ignores the localization currency (it takes the language only).
- localizationOptions() : array<int, NotTranslate>
- Returns localization options: the amount format on the invoice.
- loginReturnArgs() : array<string, string>
- Remembers the request of a logged-out user so the login can return to it ({@see storeRequest()}, `backlink` of the login page, restored by `AuthStorageTrait::redirectAfterLoginAction()`).
- logoutNetteUser() : void
-
parsePickerName()
: array{0: string, 1: list
} - Splits a picker instance name into the config key plus row indexes (multiplier and nested multiplier). `parentId` -> `['parentId', []]`; `address_2` -> `['address', ['2']]`; `parameter_1_0` -> `['parameter', ['1','0']]` (nested).
- paymentLabel() : string
- paymentMethodOptions() : array<int, NotTranslate>
- paymentRegionOptions() : array<int, NotTranslate>
- pdfVariantMatrixJson() : string
- Returns the JSON matrix of the PDF variant choice for the dependent select: `{invoiceTypeId: {"pt_pr_bvt_suv": variantId}}` (axes: productType, paymentRegion, buyerVatType, sellerUseVat).
- pdfVariantOptions() : array<int, NotTranslate>
- pdfVariantTreatmentMatrixJson() : string
- Returns the JSON matrix of PDF variants by VAT treatment code: `{invoiceTypeId: {"<code>" | "*": variantId}}`, only rows with a selected variant.
- processCreditNote() : bool
- Issues the credit note through the Api; redirects on success, returns false (with a flash) otherwise.
- processFailedLogin() : void
- processInvalidToken() : void
- processLogin() : void
- processLoginException() : void
- processMissingToken() : void
- processSendEmail() : bool
- processSuccessfulLogin() : void
- processValidToken() : void
- productTypeOptions() : array<int, NotTranslate>
- readLoginDeviceToken() : string|null
- Returns the raw known-device cookie for the Api login (the Api verifies its signature).
- redirectAfterLoginAction() : void
- After a login attempt: a successful login returns to the request remembered before the login (`backlink`, {@see PrivilegeCheckTrait::loginReturnArgs()}), otherwise to the dashboard; a failed one stays on the login page and keeps the way back.
- refreshNetteIdentity() : bool
- Refreshes the token of the same logged-in user: identity data (token, name, email) are overwritten in the stored object without `login()`, so neither the session id nor the form CSRF tokens change. The identity is stored in the session section as an object; the change is written at the end of the request.
- rememberLoginDevice() : void
- After a successful login (password or OAuth) issues or renews the known-device cookie ({@see LoginDeviceCookie}): a signed proof that this browser has already logged in to the account. The next login sends it to the Api ({@see self::processLogin()}), and above the account limit the password from this browser is still verified, so foreign attempts do not lock out the owner. HttpOnly, SameSite=Lax, Secure on HTTPS; lifetime from `ratelimit.loginDevice.cookieLifetime`.
- resolveCustomerLabel() : string|null
- resolveInvoicerSetting() : string
- resolveInvoiceTemplateLabel() : string|null
- resolveLoginErrorMessage() : string
- Resolves the flash message of a failed login.
- resolvePaymentLabel() : string|null
- resolveSellerLabel() : string|null
- revokeTokensOnLogout() : void
- Calls the Api logout (revokes the refresh family and deny-lists the access `jti`) for the tokens of the current session. Fail-open on purpose: any failure is only logged, because the local logout must not stay unfinished.
- rows() : iterable<string|int, array<string, mixed>|ArrayHash<string|int, mixed>>
- saveInvoiceForm() : bool
- saveLockedInvoice() : bool
- Saves a locked invoice: only the allowed fields are written by a direct update (no recalculation, no new PDF). Other form values are dropped and the admin gets an explanation.
- sellerLabel() : string
- sellerPrefillData() : array<string, string>
- setInvoiceFormDefaults() : void
- setNetteUser() : void
- snapshotLineIdentity() : InvoicePaymentMethod}
- Snapshot of the lines before the full replace, indexed by id, so `build*()` can pull in columns the form does not render (line identity).
- statusOptions() : array<string, string>
- storeEditorUpload() : bool
- Stores a file; the target folder may not exist (first upload into the root), so after a failure the root is created once and the write is retried. Deeper subfolders are created by the editor user through `editorCreateFolder`.
-
suggestCustomers()
: array<int, array{id: int, label: string, data: array
}> - suggestInvoiceTemplates() : array<int, array{id: int, label: string}>
-
suggestPayments()
: array<int, array{id: int, label: string, data: array
}> -
suggestSellers()
: array<int, array{id: int, label: string, data: array
}> - taxTreatmentOptions() : array<string, NotTranslate>
- Returns treatment code options for the manual override: translated names from the form domain (`form.fields.taxOverrideCode.codes.<CODE>`), ordered as the enum.
- trInvoice() : string
- Translates a key in the form domain to a final string (for fields with `setTranslator(null)`).
- tryRefresh() : bool
- Tries an auto-refresh for an expired access token. If the session holds a refresh token and the Api accepts it, stores the new pair in the session and returns true; otherwise returns false and the caller cancels the session.
- userTypeOptions() : array<int, NotTranslate>
- voucherDefaults() : array<int, array<string, mixed>>
Constants
LOGIN_BACKLINK
Login page parameter with the key of the stored request to return to ({@see loginReturnArgs()}).
public
string
LOGIN_BACKLINK
= 'backlink'
DEFAULT_ITEMS_PER_PAGE
Items per page of admin lists when the DB setting is missing.
protected
mixed
DEFAULT_ITEMS_PER_PAGE
= 20
FORM_BACK_SUBSECTION
Session subsection mapping a key to the previous page URL of edit forms.
protected
mixed
FORM_BACK_SUBSECTION
= 'formBack'
SESSION_NAMESPACE
protected
mixed
SESSION_NAMESPACE
= 'admin'
BLOCKED_EXTENSIONS
Extensions that must not be uploaded into the web-served folder; otherwise an editor upload would mean running foreign code on the server. It is no content whitelist (the editor uploads what is needed), only a safeguard against executable files.
private
mixed
BLOCKED_EXTENSIONS
= ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phps', 'phtml', 'phar', 'cgi', 'pl', 'py', 'sh', 'bash', 'htaccess', 'htpasswd']
CREDIT_NOTE_COLLECTIONS
Row collections that carry a quantity (same as `CreditNoteLedger`).
private
array<string|int, mixed>
CREDIT_NOTE_COLLECTIONS
= ['items', 'shippers', 'paymentMethods']
EDITOR_PAGE_LIMIT
Listing cap; the dialog is a suggester, not a paged list.
private
mixed
EDITOR_PAGE_LIMIT
= 500
EDITOR_PAGE_TARGETS
Routes the editor may link to: text pages only.
private
mixed
EDITOR_PAGE_TARGETS
= ['front:system:page:show']
Other page routes need parameters the editor cannot know (Front:System:User:profile
wants id and username, Front:System:Registration:registration wants email and
activationKey, advert details want id/name). A link to them could not be built or
would lead to a broken address, so they stay out of the offer.
Another target (e.g. Front:System:Page:homepage or Front:System:Page:form) is one
more line here, provided its route needs only slug.
EDITOR_UPLOAD_FOLDER
Editor root (relative to the `uploads/` root). Changing it to `''` would open the whole `uploads/` tree to the manager; the editor user could then reach (and delete) files of other modules such as products and avatars.
private
mixed
EDITOR_UPLOAD_FOLDER
= 'editorUploads'
IMAGE_EXTENSIONS
Extensions the file manager shows as a preview instead of a document icon.
private
mixed
IMAGE_EXTENSIONS
= ['jpg', 'jpeg', 'png', 'gif', 'webp', 'avif', 'svg', 'bmp']
LOCALE_MAP
Maps the short language code to the full locale of the registered NEON sources.
private
mixed
LOCALE_MAP
= ['cs' => 'cs_CZ', 'en' => 'en_US', 'sk' => 'sk_SK']
The short code (cs, en, sk) comes from LanguageContext, derived from the URL parameter
loc/lang; the full locales are cs_CZ, en_US, sk_SK. translator.neon configures one
shared fallback chain [cs_CZ, cs, en_US, en, sk_SK, sk] for all languages, so a short code
would always map to cs_CZ first, whatever language is active. A direct match on the full
locale bypasses that.
The Contributte LocaleResolvers\Router (the only configured resolver) looks for the route
parameter locale, but this application routes under loc, so it always returns null and the
translator falls back to default: cs. An explicit setLocale() from here bypasses the
resolver, which Translator::getLocale() asks only while no locale has been set explicitly.
PRICE_PATTERN
Price mask for `decimal(10,3)`: up to 7 integer digits, 0-3 decimals.
private
string
PRICE_PATTERN
= '\s*-?\d{1,7}([.,]\d{1,3})?\s*'
Without a rule "1 000" was silently stored as 0. The minus is part of the mask because credit note lines carry a negative price and the admin must be able to save them.
QUANTITY_PATTERN
Quantity mask for `decimal(8,2)`: up to 6 integer digits, 0-2 decimals, comma or dot, surrounding spaces tolerated.
private
string
QUANTITY_PATTERN
= '\s*-?\d{1,6}([.,]\d{1,2})?\s*'
A thousands space inside the number is an error on purpose: without a rule "1 000" passes
Decimal::fromInput() as null and is silently stored as quantity 1, and a loud message is
the only thing that tells the user.
IMPORTANT: the mask accepts a leading minus, like PRICE_PATTERN. The column is signed and
negative quantities arrive from legacy documents, imports and the Api; without the minus the
admin could not save such an invoice again, even unchanged. Credit notes do not create
negative quantities (they mirror the positive quantity and negate the price in
OrderInvoiceGenerator::mirrorLine()).
Properties
$accessTokenValidator
Signature and expiry alone are not enough: a revoked token (`jti` on the deny-list) that has not expired yet would keep the session logged in although the Api guard rejects the same token. Same contract as {@see \App\Core\Traits\Api\Presenters\JwtAuthTrait::checkJwtAuth()}, one implementation.
public
AccessTokenValidator
$accessTokenValidator
Attributes
- #[Inject]
$adminFormActionsFactory
public
FormActionsFactory
$adminFormActionsFactory
Attributes
- #[Inject]
$adminLangNavFactory
public
LangNavFactory
$adminLangNavFactory
Attributes
- #[Inject]
$adminLanguageManager
public
LanguageManager
$adminLanguageManager
Attributes
- #[Inject]
$adminPageManager
public
AdminPageManager
$adminPageManager
Attributes
- #[Inject]
$authManager
public
AuthManager
$authManager
Attributes
- #[Inject]
$authStorageManager
public
AuthStorageManager
$authStorageManager
Attributes
- #[Inject]
$authUserManager
Admin `UserManager` for {@see UserManager::login()}. A module must not read through another module, so admin has its own `login()` that calls the same Api endpoint (`api/system/auth/login`).
public
UserManager
$authUserManager
The own property name avoids a collision with the generic $userManager from UserTrait
(typed to the admin CRUD manager).
Attributes
- #[Inject]
$columnSchema
Limits of the real database columns for {@see guardColumns()}.
public
ColumnSchema
$columnSchema
Attributes
- #[Inject]
$container
public
Container
$container
Attributes
- #[Inject]
$customerManager
public
CustomerManager
$customerManager
Attributes
- #[Inject]
$deviceDetector
public
DeviceDetector
$deviceDetector
Attributes
- #[Inject]
$editorAutosaveScope
Scope of the editor autosave drafts, see {@see \App\Core\Security\EditorAutosaveScope}.
public
EditorAutosaveScope
$editorAutosaveScope
Attributes
- #[Inject]
$editorLinkPageManager
NOTE: own property name. `$pageManager` already exists on presenters (`PagePickerTrait`), and two `#[Inject]` properties of the same name would collide in the trait composition.
public
PageManager
$editorLinkPageManager
Attributes
- #[Inject]
$editorUploadManager
NOTE: own property name, not `$fileSystemManager`.
public
FileSystemManager
$editorUploadManager
FileSystemPresenter takes the same manager as
private readonly in its constructor, and PHP cannot redeclare a property of the same
name between public and private.
Attributes
- #[Inject]
$eventDispatcher
public
EventDispatcher
$eventDispatcher
Attributes
- #[Inject]
$formSubmissionGuard
One-time submission tokens of "add" forms, see {@see guardFormSubmitOnce()}.
public
FormSubmissionGuard
$formSubmissionGuard
Attributes
- #[Inject]
$jwtManager
public
JwtManager
$jwtManager
Attributes
- #[Inject]
$languageContext
public
LanguageContext
$languageContext
Attributes
- #[Inject]
$languageManager
public
LanguageManager
$languageManager
Attributes
- #[Inject]
$localizationContext
public
LocalizationContext
$localizationContext
Attributes
- #[Inject]
$localizationManager
public
LocalizationManager
$localizationManager
Attributes
- #[Inject]
$loginDeviceCookie
Cookie of a known device for the password login throttle ({@see self::rememberLoginDevice()}).
public
LoginDeviceCookie
$loginDeviceCookie
Attributes
- #[Inject]
$modalWindowFactory
Injected through Nette presenter inject (after construction), not the constructor.
public
ModalWindowFactory
$modalWindowFactory
Attributes
- #[Inject]
$paymentManager
public
PaymentManager
$paymentManager
Attributes
- #[Inject]
$picker
Picker mode of a list; when not empty, the presenter renders its `show` grid as a selection modal (no add/edit/delete/checkboxes, each row has a select button) in the minimal `@picker.latte` layout.
public
string
$picker
= ''
Opened by Picker; the value is the
name of the opener's target field that receives the selection. Persistent, so it stays in
grid links (filter/sort/paging) inside the modal. The presenter activates it in
createComponent…Grid(): if ($this->picker !== '') { $grid->setPickerMode($this->picker); }.
Attributes
- #[Persistent]
$pickerExclude
Id of the record that cannot be selected in picker mode (its select button is hidden).
public
int
$pickerExclude
= 0
Serves self-referencing pickers (a parent page cannot be itself). Passed by
Picker in the modal link via
PickerConfig::targetParams; 0 means no exclusion.
Attributes
- #[Persistent]
$pickerExcludeSubtreeLft
`lft`/`rgt` bounds of a whole subtree whose nodes cannot be selected in picker mode.
public
int
$pickerExcludeSubtreeLft
= 0
Excludes the root and all descendants, so a node cannot be moved under its own descendant. 0 means no subtree exclusion.
Attributes
- #[Persistent]
$pickerExcludeSubtreeRgt
public
int
$pickerExcludeSubtreeRgt
= 0
Attributes
- #[Persistent]
$presenterContext
public
PresenterContext
$presenterContext
Attributes
- #[Inject]
$privilegeManager
public
PrivilegeManager
$privilegeManager
Attributes
- #[Inject]
$queryCacheContext
Query cache policy for the whole admin request; `startup()` disables it.
public
QueryCacheContext
$queryCacheContext
Injected as a public property like the other admin base services; it cannot live in a
trait because startup() touches it first.
Attributes
- #[Inject]
$routerDispatcher
public
RouterDispatcher
$routerDispatcher
Tags
$sellerManager
public
SellerManager
$sellerManager
Attributes
- #[Inject]
$settingContext
public
SettingContext
$settingContext
Attributes
- #[Inject]
$settingManager
public
SettingManager
$settingManager
Attributes
- #[Inject]
$themeContext
public
ThemeContext
$themeContext
Attributes
- #[Inject]
$themeManager
public
ThemeManager
$themeManager
Attributes
- #[Inject]
$themeResolver
public
DefaultThemeResolver
$themeResolver
Attributes
- #[Inject]
$translator
public
ITranslator
$translator
Tags
$translatorSessionResolver
public
Session
$translatorSessionResolver
Tags
$userManager
public
UserManager
$userManager
Attributes
- #[Inject]
$adminPageEntity
protected
AdminPage|null
$adminPageEntity
= null
$billingLines
protected
array<int, object>
$billingLines
= []
$currencies
protected
array<int, object>
$currencies
= []
$debugMode
protected
bool
$debugMode
= false
$invoicerDefaultUnit
protected
string
$invoicerDefaultUnit
= 'ks'
$invoicerDuePeriod
protected
int
$invoicerDuePeriod
= 14
$invoiceTypes
protected
array<int, object>
$invoiceTypes
= []
$languages
protected
array<int, object>
$languages
= []
$localizations
protected
array<int, object>
$localizations
= []
$paymentMethods
protected
array<int, object>
$paymentMethods
= []
$paymentRegions
protected
array<int, object>
$paymentRegions
= []
$pdfVariantOptionsData
protected
array<int, NotTranslate>
$pdfVariantOptionsData
= []
$productionMode
protected
bool
$productionMode
= false
$productTypes
protected
array<int, object>
$productTypes
= []
$savedEntityId
Id of the record just saved; set by the `$processData` callback in `createForm()` after a successful save.
protected
int|null
$savedEntityId
= null
The apply button (update) uses it: on the add action (new record, no id in the URL)
it redirects to editing the new record (edit?id=...). Redirecting to this would lead
back to an empty add form and the next apply would create a duplicate. When the callback
leaves it null (e.g. a settings form without an edit action), the redirect goes to this.
$translatorDomain
protected
string
$translatorDomain
= 'admin.invoicer.presenters.invoice'
$userTypes
protected
array<int, object>
$userTypes
= []
$apiBridge read-only
private
ApiBridge
$apiBridge
$billingLineManager read-only
private
BillingLineManager
$billingLineManager
$countryManager read-only
private
CountryManager
$countryManager
$creditNoteError
`errorCode` from the Api preview (`orderOwned`, `sourceNotIssued`, ...).
private
string|null
$creditNoteError
= null
$creditNotePreview
Basis of the manual credit note form from the Api (`credit-note-preview`); `null` means no credit note can be issued for the invoice (reason in {@see $creditNoteError}).
private
array<string, mixed>|null
$creditNotePreview
= null
$currencyManager read-only
private
CurrencyManager
$currencyManager
$dataGridFactory read-only
private
DataGridFactory
$dataGridFactory
$editedInvoice
private
Invoice|null
$editedInvoice
= null
$emailDefaultBody
private
string
$emailDefaultBody
= ''
$emailDefaultSubject
private
string
$emailDefaultSubject
= ''
$emailManager read-only
private
EmailManager
$emailManager
$invoiceManager read-only
private
InvoiceManager
$invoiceManager
$invoiceSupplyKindDefaultId
Default supply kind of a new line; `null` when the code list offers none.
private
int|null
$invoiceSupplyKindDefaultId
= null
$invoiceSupplyKindOptions
Options of the supply kind select on a line (loaded once per request).
private
array<int, string>|null
$invoiceSupplyKindOptions
= null
$invoiceTaxManager read-only
private
InvoiceTaxManager
$invoiceTaxManager
$invoiceTemplateManager read-only
private
InvoiceTemplateManager
$invoiceTemplateManager
$invoiceTypeManager read-only
private
InvoiceTypeManager
$invoiceTypeManager
$isLoggingIn
private
bool
$isLoggingIn
= false
$paymentMethodManager read-only
private
PaymentMethodManager
$paymentMethodManager
$paymentRegionManager read-only
private
PaymentRegionManager
$paymentRegionManager
$pdfTemplateManager read-only
private
PdfTemplateManager
$pdfTemplateManager
$pickerFactory read-only
private
PickerFactory
$pickerFactory
$prefillFromTemplate
Prefill from the template picker (signal `useTemplate`); allows applying defaults outside a plain GET.
private
bool
$prefillFromTemplate
= false
$productTypeManager read-only
private
ProductTypeManager
$productTypeManager
$sendEmailInvoice
private
Invoice|null
$sendEmailInvoice
= null
$theme
private
Theme|null
$theme
= null
$userPrivileges
private
array<int, string>
$userPrivileges
= []
privileges of the current user loaded in startup()
$userTypeManager read-only
private
UserTypeManager
$userTypeManager
Methods
__construct()
public
__construct(DataGridFactory $dataGridFactory, InvoiceManager $invoiceManager, InvoiceTemplateManager $invoiceTemplateManager, BillingLineManager $billingLineManager, ProductTypeManager $productTypeManager, InvoiceTypeManager $invoiceTypeManager, PaymentMethodManager $paymentMethodManager, CurrencyManager $currencyManager, PaymentRegionManager $paymentRegionManager, UserTypeManager $userTypeManager, PdfTemplateManager $pdfTemplateManager, EmailManager $emailManager, ApiBridge $apiBridge, PickerFactory $pickerFactory, InvoiceTaxManager $invoiceTaxManager, CountryManager $countryManager) : mixed
Parameters
- $dataGridFactory : DataGridFactory
- $invoiceManager : InvoiceManager
- $invoiceTemplateManager : InvoiceTemplateManager
- $billingLineManager : BillingLineManager
- $productTypeManager : ProductTypeManager
- $invoiceTypeManager : InvoiceTypeManager
- $paymentMethodManager : PaymentMethodManager
- $currencyManager : CurrencyManager
- $paymentRegionManager : PaymentRegionManager
- $userTypeManager : UserTypeManager
- $pdfTemplateManager : PdfTemplateManager
- $emailManager : EmailManager
- $apiBridge : ApiBridge
- $pickerFactory : PickerFactory
- $invoiceTaxManager : InvoiceTaxManager
- $countryManager : CountryManager
actionAdd()
public
actionAdd([int|null $itId = null ]) : void
Parameters
- $itId : int|null = null
actionCreditNote()
Shows the form of a manual credit note for an issued invoice.
public
actionCreditNote(int $id) : void
The basis (rows with a balance, credit types) and the issuing go only through the Api
(credit-note-preview / credit-note); the server enforces the ceiling and the invoice
lock.
Parameters
- $id : int
actionDownloadPdf()
Streams the invoice PDF through a PHP proxy; the real disk path is never published (and the PDF directory need not be under the document root).
public
actionDownloadPdf(int $id) : void
Parameters
- $id : int
actionEdit()
public
actionEdit(int $id) : void
Parameters
- $id : int
actionSendEmail()
public
actionSendEmail(int $id) : void
Parameters
- $id : int
beforeRender()
public
beforeRender() : void
createComponent()
public
createComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullflashFormOwnErrors()
Flashes form-level errors (`$form->getOwnErrors()`) as `danger` messages.
public
flashFormOwnErrors(Form $form) : void
Called from onError of createForm(); public for component forms
(AdminComponentFormTrait). Element errors are not
flashed; {inputError} renders them at the field.
Parameters
- $form : Form
flashRejectedUploads()
Flashes one `warning` listing the files the Api rejected (type, dimensions, unreadable) after a successful save of a form with a dropzone ({@see UploadRejection}).
public
flashRejectedUploads(Result $result) : void
The save itself passed and accepted files are stored. The message is already translated
(a list of names), so translate = false (see flashFormOwnErrors()). Call it
before the redirect, because a flash sent through redirectUrl is lost; public for
component forms.
Parameters
- $result : Result
formatLayoutTemplateFiles()
Admin version of {@see \App\Core\Traits\Front\Presenters\ThemeInitTrait::formatLayoutTemplateFiles()}.
public
formatLayoutTemplateFiles() : array<string|int, mixed>
It starts from AdminPage ($adminPageEntity,
column layout), not from the Front $pageEntity, which an admin presenter does not have;
admin also has no loggedLayout. The database value wins; getAdminLayout() is the
fallback that LoginPresenter overrides with @login.latte.
Return values
array<string|int, mixed>getAdminPageEntity()
public
getAdminPageEntity() : AdminPage|null
Return values
AdminPage|nullgetContainer()
public
getContainer() : Container
Return values
ContainergetFormBackUrl()
Returns the stored previous page URL for the key, used by the `cancel` link in the template.
public
getFormBackUrl(string|null $key) : string
Parameters
- $key : string|null
Return values
stringgetInvoiceSupplyKindProto()
Returns the options and the default kind for the client prototype of a new line (`lineProto`).
public
getInvoiceSupplyKindProto() : array{options: array, defaultId: int|null}
IMPORTANT: do not pass them through $this->template->... from the form factory; the form is
created lazily at {form editForm}, so the template value would not exist yet.
Return values
array{options: arraygetModalWindow()
public
getModalWindow() : ModalWindow
Return values
ModalWindowgetRouterDispatcher()
public
getRouterDispatcher() : RouterDispatcher
Return values
RouterDispatchergetTranslator()
public
getTranslator() : ITranslator
Return values
ITranslatorguardFormSubmitOnce()
Protects a form against a double submit: one rendered form saves at most once.
public
guardFormSubmitOnce(Form $form) : void
createForm() applies it to every form of an "add" action (isAddAction()), the component skeleton AdminComponentFormTrait likewise, and forms built outside both call it themselves (product import upload, credit notes, stocktake). A repeated submit of an edit form only saves the same values again, so edits are not guarded.
Adds the hidden token (FormSubmissionGuard::FIELD), issued on every GET render (on POST it
comes back from the browser), and data-submit-once for submit-once.js, which blocks a second
click in the browser. The server side (runSubmitOnce()) is the authority, because a request
can come from outside the browser or the client script may not run. Idempotent.
Parameters
- $form : Form
handleChangeLocale()
public
handleChangeLocale(string $locale) : void
Parameters
- $locale : string
handleEditorCreateFolder()
Creates a subfolder in `folder` (path relative to the editor root).
public
handleEditorCreateFolder([string $folder = '' ][, string $name = '' ]) : void
Parameters
- $folder : string = ''
- $name : string = ''
Attributes
- #[Requires]
- $methods: 'POST'
handleEditorDelete()
Deletes a file or (recursively) a folder. An empty path would point to the editor root, which cannot be deleted.
public
handleEditorDelete([string $path = '' ]) : void
Parameters
- $path : string = ''
Attributes
- #[Requires]
- $methods: 'POST'
handleEditorFiles()
Sends the folder listing for the editor file manager. The `folder` parameter is a path relative to the editor root (empty means the root).
public
handleEditorFiles([string $folder = '' ]) : void
Sends JSON {folder, parent, breadcrumb[], folders[], files[]}; paths in the response are
again relative to the editor root, and a public URL is given for files only. The server
path never leaves the server.
A non-existent folder gives an empty listing, not an error (until something is uploaded the root does not exist physically and the manager just shows the empty state).
Parameters
- $folder : string = ''
handleEditorPages()
Sends the page list for the link dialog as JSON `{"pages": [{id, label, url}, ...]}` sorted by label.
public
handleEditorPages() : void
Only text pages (EDITOR_PAGE_TARGETS); pages without a filled URL (href) are
skipped too, because no link can be built for them.
handleEditorRename()
Renames a file or folder (`path` relative to the editor root).
public
handleEditorRename([string $path = '' ][, string $name = '' ]) : void
Parameters
- $path : string = ''
- $name : string = ''
Attributes
- #[Requires]
- $methods: 'POST'
handleEditorUpload()
Accepts a file from the editor (field `file`, multipart POST; optional `folder` = subfolder of the editor root) and sends JSON `{"location": "/www/uploads/editorUploads/..."}`, the format TinyMCE expects from `images_upload_handler`.
public
handleEditorUpload() : void
Attributes
- #[Requires]
- $methods: 'POST'
handleLock()
Explicitly locks the invoice (irreversible).
public
handleLock(int $id) : void
A presenter signal, because the grid on show has no entity loaded (see
ProductPresenter::handleDuplicateProduct()).
Parameters
- $id : int
Attributes
- #[Requires]
- $methods: 'POST'
handleLogout()
public
handleLogout() : void
Attributes
- #[Requires]
- $methods: 'POST'
handleSignOut()
public
handleSignOut() : void
Attributes
- #[Requires]
- $methods: 'POST'
handleUseTemplate()
Rebuilds the add form from the chosen template and redraws it (template picker signal).
public
handleUseTemplate(int $id) : void
The picker uses a GET signal, not a form submit: only then do the item, gift and coupon
multipliers take their values from the defaults (a submit fills them from httpData only).
actionAdd() ran before the signal (select options are loaded), so only the edited transient
invoice is rebuilt here, with buildInvoiceFromTemplate.
Parameters
- $id : int
hasServiceByType()
Returns whether the container has a service of the given type.
public
hasServiceByType(string $className) : bool
The name is composed dynamically (module plus component), so class_exists() runs first, and
a true result guarantees a valid type.
Parameters
- $className : string
Tags
Return values
boolinitializeTranslator()
public
initializeTranslator(string|null $alias) : void
Parameters
- $alias : string|null
isAddAction()
Tells whether the current action creates a record: `add` and the `add<Something>` actions (`addMenu`, `addKey`). Derived from the server context only, like {@see formSubmitPrivilege()}.
public
isAddAction() : bool
Return values
boolisAllowed()
Returns whether the logged-in user has the given privilege.
public
isAllowed(string $key) : bool
Reads the array loaded in startup(), with no database query.
Fail-closed: returns false when loadUserPrivileges() was not called or failed.
Public so templates can call it ($presenter->isAllowed(...)) for conditional display
of actions outside DataGrid (e.g. static menu management links).
Parameters
- $key : string
Return values
boolisSubmitOnceForm()
Tells whether the form was protected by {@see guardFormSubmitOnce()}.
public
isSubmitOnceForm(Form $form) : bool
Parameters
- $form : Form
Return values
boolloginWithCredentials()
Logs in with username and password; called only by the login form (after validation and CSRF).
public
loginWithCredentials(string $username, string $password[, bool $remember = false ]) : void
IMPORTANT: this must not be named handleLogin(). A handle* method is a public signal of
every presenter (?do=login&username=...&password=...): the password could end up in the URL
and the server log, and the form token would be bypassed. Nette finds signals by the
handle prefix only.
Parameters
- $username : string
- $password : string
- $remember : bool = false
publishFieldErrors()
Publishes element errors of a failed submit to the client.
public
publishFieldErrors(Form $form) : void
IMPORTANT: field errors were visible only where the template has {inputError}; server
rules on fields without it stopped the form but showed the user no message.
An AJAX submit sends payload.fieldErrors; a full render sets data-server-field-errors
on <body> (see @layout.latte), which the script reads on load. The script avoids
duplicating {inputError}.
Parameters
- $form : Form
redirectToFormBack()
Redirects to the stored previous page and discards the key.
public
redirectToFormBack(string|null $key) : void
Public for component forms (AdminComponentFormTrait),
whose save submit calls it through $this->getPresenter().
Parameters
- $key : string|null
renderAdd()
public
renderAdd() : void
renderCreditNote()
public
renderCreditNote() : void
renderEdit()
public
renderEdit() : void
renderSendEmail()
public
renderSendEmail() : void
renderShow()
public
renderShow() : void
resolveFormBackKey()
Returns the previous-page key: from the URL if present (survives the update redirect), otherwise on a plain GET render of the edit page stores `Referer` in the session under a new random key.
public
resolveFormBackKey() : string
Public for component forms (AdminComponentFormTrait);
a component reaches it through $this->getPresenter().
Return values
stringrunSubmitOnce()
Runs a saving step of a form under its one-time token (a form without the token just runs it).
public
runSubmitOnce(Form $form, string $backKey, callable(): bool $save) : bool|null
- the first submit claims the token and saves; a failed save (
falseor an exception) releases it, so the corrected form can be sent again; a successful one keeps it with $savedEntityId. A redirect thrown from inside the step counts as a successful save, so the step should set$savedEntityIdbefore redirecting; - a submit of an already used token does not run the step, flashes a notice, sets
$savedEntityIdto the record of the first submit and returnsnull; the caller leads where the first submit led; - a submit arriving while the first one still saves waits for it a few seconds, then behaves as above, or ends on the previous page with a warning (redirect);
- a missing or malformed token does not run the step; the form gets a fresh token and a message
and
falseis returned (the browser case is a form opened before the protection was deployed).
Public for component forms and form traits outside createForm().
Parameters
- $form : Form
- $backKey : string
- $save : callable(): bool
Return values
bool|null —true = saved now, false = not saved, null = saved by an earlier submit of the same form
setConfigParameters()
public
setConfigParameters([bool $debugMode = false ][, bool $productionMode = false ]) : void
Parameters
- $debugMode : bool = false
- $productionMode : bool = false
setTranslator()
public
setTranslator(ITranslator $translator) : $this
Parameters
- $translator : ITranslator
Return values
$thisstartup()
public
startup() : void
typedComponent()
Returns a subcomponent with a verified type.
public
typedComponent(string $name, T> $type) : T
Use it instead of an inline @var above $this['x'] (which does not narrow the type) and
instead of the generic IComponent that $this['x'] returns. See
Form::typedComponent().
Parameters
- $name : string
- $type : T>
Tags
Return values
Tauthorize()
Authorization hook; by default requires the `:Admin` privilege.
protected
authorize() : void
LoginPresenter overrides it so the login page stays reachable for a guest.
authorizeFormSubmit()
Gate for writing presenter forms built by `createForm()`.
protected
authorizeFormSubmit(Form $form) : void
IMPORTANT: a form submit is a signal (?do=editForm-submit) that Nette handles on any
action, after action*(). A gate in actionAdd()/actionEdit() therefore covers only
submits sent to add/edit; a submit sent to a list (show) passes authorizeListing()
only, and a save callback without its own gate would write with view-only rights.
Called by createForm() before $processData (only for the update/save buttons)
and by custom saving submits outside that gate.
Parameters
- $form : Form
authorizeListing()
Gate for reading lists.
protected
authorizeListing() : void
IMPORTANT: without this gate anyone inside the admin could open any list without the
privilege. The gate lives here once, not in every presenter. The key is derived as in PrivilegeCheckTrait::checkCurrentPrivilege():
:Admin:<Module>:<Presenter>:show.
IMPORTANT: guards only the show action. Other actions have their own gates
(add/edit/signals), and a blanket key would not fit them: dashboard, login,
downloadPdf, statistics and similar have no ...:<action> key, so the fail-closed
check would lock out even the administrator.
NOTE: every show screen needs its key in the privilege table and enabled for the
admin role.
checkAdminAccess()
Entry gate to the admin: a guest is sent to login; a logged-in user without `:Admin` is sent to login with an error.
protected
checkAdminAccess() : void
checkAuthentication()
protected
checkAuthentication() : void
checkCurrentPrivilege()
Builds the key from the current request (`:Admin:<Module>:<Presenter>:<action>`) and checks it. `getName()` already contains the `Admin:...` prefix, so only one leading colon is added.
protected
checkCurrentPrivilege() : void
Use it where the key matches the action; use explicit checkPrivilege() where it differs (another presenter, add versus edit).
checkPrivilege()
Checks a specific privilege; throws 403 when denied.
protected
checkPrivilege(string $key) : void
IMPORTANT: a hidden button is no protection. A hand-built ?...&do=<signal> URL runs the
action, so every non-standard action and every mutating signal needs the gate as its
first statement; otherwise anyone who types the URL can run it.
IMPORTANT: form actions need two gates, one in the signal and one in process*() (the
submit), because a submit arrives as its own request. With only the signal gate the
submit stays open. See the WorkList traits.
Parameters
- $key : string
createComponentAdminFormActions()
protected
createComponentAdminFormActions() : FormActions
Return values
FormActionscreateComponentAdminLangNav()
protected
createComponentAdminLangNav() : LangNav
Return values
LangNavcreateComponentCreditNoteForm()
protected
createComponentCreditNoteForm() : Form
Return values
FormcreateComponentEditForm()
protected
createComponentEditForm() : Form
Return values
FormcreateComponentGrid()
protected
createComponentGrid() : DataGrid
Return values
DataGridcreateComponentModalWindow()
protected
createComponentModalWindow() : ModalWindow
Return values
ModalWindowcreateComponentPicker()
protected
createComponentPicker() : Multiplier<string|int, Picker>
Return values
Multiplier<string|int, Picker>createComponentSendEmailForm()
protected
createComponentSendEmailForm() : Form
Return values
FormcreateForm()
Creates an edit form with the standard actions and a return to the previous page.
protected
createForm(callable(ArrayHash<string|int, mixed>, Form): bool $processData) : Form
Buttons (the template renders them on the right as cancel, update, save):
savesaves and returns to the previous page,updatesaves and stays on the edit page (redirect tothis),cancelis only a link back, rendered by the template via getFormBackUrl().
On the first load of the edit page (plain GET render, not POST/signal) the previous page
is taken from Referer, stored in the session under a random key, and the key goes into
the hidden backKey field. It is per form so concurrent tabs do not overwrite each
other, and it travels through the update redirect as a URL parameter.
The concrete presenter adds fields and defaults; this method provides the skeleton, buttons and redirects.
Parameters
- $processData : callable(ArrayHash<string|int, mixed>, Form): bool
-
Saves the data; returns success (handles its own flash).
Return values
FormcurrentLangId()
Returns the current language id (for picker labels etc.), null when unknown.
protected
currentLangId() : int|null
Return values
int|nullcustomerDeliveryPicker()
protected
customerDeliveryPicker(string $formName, string $targetField[, string|null $submitButton = null ]) : PickerConfig
Parameters
- $formName : string
- $targetField : string
- $submitButton : string|null = null
Return values
PickerConfigcustomerPicker()
protected
customerPicker(string $formName, string $targetField[, string|null $submitButton = null ]) : PickerConfig
Parameters
- $formName : string
- $targetField : string
- $submitButton : string|null = null
Return values
PickerConfigdomainTranslator()
Returns a translator prefixed with the presenter domain, or `null` (empty domain or a translator other than Contributte).
protected
domainTranslator() : PrefixedTranslator|null
beforeRender() sets it only on $this->template. Templates created separately through
createTemplate() (e.g. modal content built in the handle phase) do not have it, and
their relative {_'...'} keys would print raw. Such places obtain it here.
Return values
PrefixedTranslator|nullformSubmitPrivilege()
Builds the e-mail sending form, which belongs to its own action `sendEmail` with the same-named key ({@see actionSendEmail()}, {@see processSendEmail()}), not to `edit`, which {@see BasePresenter::formSubmitPrivilege()} would derive otherwise. The exception applies to this form only; `editForm` still goes through add/edit.
protected
formSubmitPrivilege(Form $form) : string
Parameters
- $form : Form
Return values
stringgetAdminItemsPerPage()
Returns the default items per page of admin lists from the DB setting `admin.itemsPerPage` (module System = 1), falling back to {@see DEFAULT_ITEMS_PER_PAGE}.
protected
getAdminItemsPerPage() : int
Return values
intgetAdminLayout()
Returns the layout name; in picker mode ({@see $picker}) the `show` grid uses the minimal `@picker.latte` (no sidebar/header) so the opener fetch returns only the table.
protected
getAdminLayout() : string
LoginPresenter overrides it with @login.latte.
Return values
stringgetFormBackFallback()
Returns the return URL when the previous page is unknown; override in a presenter without a `show` action.
protected
getFormBackFallback() : string
Return values
stringgetFormLanguages()
Returns the languages for multilingual form fields (admin `LanguageManager`).
protected
getFormLanguages() : array<int, Language>
Return values
array<int, Language>getSessionKey()
Returns a session key string, e.g. 'front.auth.step1'.
protected
getSessionKey([string|null $namespace = null ][, string|null $subsection = null ], string ...$extra) : string
Parameters
- $namespace : string|null = null
-
Base namespace (module prefix). Uses SESSION_NAMESPACE if null.
- $subsection : string|null = null
-
Subsection under the namespace. Uses SESSION_SUBSECTION constant if null.
- $extra : string
-
Additional parts to append (e.g. 'step1', 'wizard', etc.).
Return values
stringgetSessionSection()
Returns a Nette\SessionSection instance using a dynamically built session key.
protected
getSessionSection([string|null $namespace = null ][, string|null $subsection = null ], string ...$extra) : SessionSection
Parameters
- $namespace : string|null = null
- $subsection : string|null = null
- $extra : string
Tags
Return values
SessionSectionguardColumns()
Gates every text and number field of the form by the real column it writes to ({@see \App\Core\Forms\ColumnGate::guard()}): an oversized value is an error at the field, never a database error that closes the entity manager (admin walkthrough A1, A14).
protected
guardColumns(Form $form, array<string, array<int, class-string>> $containers[, array<int, string> $except = [] ]) : void
Parameters
- $form : Form
- $containers : array<string, array<int, class-string>>
-
container path ('' = the form, a multiplier name = its rows) => entities
- $except : array<int, string> = []
-
control names never gated (a value transformed before storage)
initializePresenterContext()
protected
initializePresenterContext() : void
intOrNull()
Converts mixed to int or null (an empty or zero value becomes null).
protected
intOrNull(mixed $value) : int|null
Parameters
- $value : mixed
Return values
int|nullinvoiceTemplatePicker()
protected
invoiceTemplatePicker(string $formName, string $targetField[, string|null $submitButton = null ]) : PickerConfig
Parameters
- $formName : string
-
name of the form with the hidden field
- $targetField : string
-
name of the hidden control (invoiceTemplateId)
- $submitButton : string|null = null
-
name of the refresh submit the picker clicks after a pick
Return values
PickerConfigisSameSiteRequest()
Tells whether the request comes from the own site (Nette SameSite cookie); protects GET actions with a side effect.
protected
isSameSiteRequest() : bool
getHttpRequest() returns the IRequest interface, while isSameSite() exists only on
Nette\Http\Request.
Return values
boolloadInvoicerSelectData()
protected
loadInvoicerSelectData() : void
loadUserPrivileges()
Loads all privileges of the logged-in user with one database query. Call it right after `checkAdminAccess()` in `startup()` (the user is guaranteed to be logged in by then).
protected
loadUserPrivileges() : void
logout()
protected
logout() : void
parseDateTime()
Converts a `datetime-local` input or text value to `DateTime`, or null when empty or unparsable.
protected
parseDateTime(mixed $value) : DateTime|null
Parameters
- $value : mixed
Return values
DateTime|nullpaymentPicker()
protected
paymentPicker(string $formName, string $targetField) : PickerConfig
Parameters
- $formName : string
- $targetField : string
Return values
PickerConfigpickers()
protected
pickers() : array<string, PickerConfig>
Return values
array<string, PickerConfig>sellerPicker()
protected
sellerPicker(string $formName, string $targetField[, string|null $submitButton = null ]) : PickerConfig
Parameters
- $formName : string
-
name of the form with the hidden field
- $targetField : string
-
name of the hidden control (sellerId)
- $submitButton : string|null = null
Return values
PickerConfigsetTranslatorDomain()
protected
setTranslatorDomain() : void
setupTemplateTranslator()
Sets a translator prefixed with the presenter domain into the template (as Front components do, see {@see \App\Core\Base\BaseComponent::setup()}).
protected
setupTemplateTranslator() : void
Templates then use short keys {_'key'} resolved as <translatorDomain>.key without
{translator}. Shared keys in the layout are written absolutely with the // prefix,
which bypasses the domain. The domain comes from the $translatorDomain property of the
concrete presenter (admin.system.presenters.<presenter>).
str()
Safely converts a mixed form value to string.
protected
str(mixed $value) : string
Parameters
- $value : mixed
Return values
stringstrOrNull()
Converts mixed to string or null (an empty string is stored as null).
protected
strOrNull(mixed $value) : string|null
Parameters
- $value : mixed
Return values
string|nulltemplateItemDescriptions()
Returns item descriptions of the template for a new invoice from a template: the form does not render a description, so {@see InvoiceFormTrait::buildItems()} looks them up here on save.
protected
templateItemDescriptions(int $templateId) : array<string, array<int, string|null>>
Parameters
- $templateId : int
Return values
array<string, array<int, string|null>>templateItemKey()
Key of a template item to form row pair: code + name.
protected
templateItemKey(mixed $code, mixed $name) : string
Parameters
- $code : mixed
- $name : mixed
Return values
stringaddCustomerBlock()
private
addCustomerBlock(Form $form) : void
Parameters
- $form : Form
addDeliveryBlock()
private
addDeliveryBlock(Form $form) : void
Parameters
- $form : Form
addEmailBlock()
private
addEmailBlock(Form $form) : void
Parameters
- $form : Form
addGiftsMultiplier()
Same gate as {@see addItemsMultiplier()}, limit for gifts.
private
addGiftsMultiplier(Form $form) : void
Parameters
- $form : Form
addInvoiceHeaderFields()
private
addInvoiceHeaderFields(Form $form) : void
Parameters
- $form : Form
addInvoiceTaxFields()
Panel "VAT": manual override of the tax treatment.
private
addInvoiceTaxFields(Form $form) : void
The treatment code, rate and clause are decided by InvoiceTaxManager from the supply kinds of the lines
and the customer data; the admin enters only through this override, and only with a reason.
Without a reason the invoice is not saved: the rule hangs on the taxOverrideReason field
(addConditionOn), not on the form, because form-level errors are not rendered anywhere in
the admin and the admin would see only a silent rejection.
DOMESTIC_REVERSE_CHARGE is offered on purpose: the engine never returns it itself, it
arises only here.
Parameters
- $form : Form
addItemsMultiplier()
The row count limit is read from the raw HTTP data (`onAnchor`, see {@see MultiplierLimits::guard()}), with `$maxCopies` as the second line of defense against materialization.
private
addItemsMultiplier(Form $form) : void
Parameters
- $form : Form
addLineControls()
private
addLineControls(Container $c[, bool $decimalQuantity = false ]) : void
Parameters
- $c : Container
- $decimalQuantity : bool = false
addNullableSelect()
private
addNullableSelect(Form $form, string $name, array<int, NotTranslate> $options, string $promptKey) : SelectBox
Parameters
- $form : Form
- $name : string
- $options : array<int, NotTranslate>
- $promptKey : string
Return values
SelectBoxaddPaymentMethodBlock()
private
addPaymentMethodBlock(Form $form) : void
Parameters
- $form : Form
addSellerBlock()
private
addSellerBlock(Form $form) : void
Parameters
- $form : Form
addShipperBlock()
private
addShipperBlock(Form $form) : void
Parameters
- $form : Form
addVouchersMultiplier()
Same gate as {@see addItemsMultiplier()}, limit for vouchers.
private
addVouchersMultiplier(Form $form) : void
Parameters
- $form : Form
applyInvoiceTax()
Applies the invoice VAT from the engine plus the manual override.
private
applyInvoiceTax(Invoice $invoice, ArrayHash<string|int, mixed> $values) : bool
Returns false for an incomplete manual override (missing code, rate or reason). Validation
catches it earlier (field rules), but an invoice with a half override would pass as "no
override" and the admin would never learn it, hence this second, loud gate.
Parameters
- $invoice : Invoice
- $values : ArrayHash<string|int, mixed>
Return values
boolapplyLine()
private
applyLine(InvoiceItem|InvoiceShipper|InvoicePaymentMethod $line, array<string, mixed>|ArrayHash<string|int, mixed> $row) : void
Parameters
- $line : InvoiceItem|InvoiceShipper|InvoicePaymentMethod
- $row : array<string, mixed>|ArrayHash<string|int, mixed>
applyNewInvoiceDefaults()
New invoice (no template): dates today and today + `duePeriod`, `IN_INVOICE` e-mail defaults.
private
applyNewInvoiceDefaults(Form $form) : void
Parameters
- $form : Form
billingLineOptions()
private
billingLineOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>buildGifts()
private
buildGifts(ArrayHash<string|int, mixed> $values, Invoice $invoice, InvoicePaymentMethod} $originalLines) : ArrayCollection<int, InvoiceGift>
Parameters
- $values : ArrayHash<string|int, mixed>
- $invoice : Invoice
- $originalLines : InvoicePaymentMethod}
Return values
ArrayCollection<int, InvoiceGift>buildInvoiceFromTemplate()
private
buildInvoiceFromTemplate(int $templateId) : Invoice|null
Parameters
- $templateId : int
Return values
Invoice|nullbuildInvoiceTaxPanel()
Returns data of the VAT panel as ready-made strings for the template (no calculation in Latte).
private
buildInvoiceTaxPanel(Invoice $invoice) : array<string, mixed>|null
null means the invoice predates the engine (tax_treatment is null) and the panel shows an
empty state.
Parameters
- $invoice : Invoice
Return values
array<string, mixed>|nullbuildItems()
private
buildItems(ArrayHash<string|int, mixed> $values, Invoice $invoice, InvoicePaymentMethod} $originalLines) : ArrayCollection<int, InvoiceItem>
Parameters
- $values : ArrayHash<string|int, mixed>
- $invoice : Invoice
- $originalLines : InvoicePaymentMethod}
Return values
ArrayCollection<int, InvoiceItem>buildPaymentMethods()
private
buildPaymentMethods(ArrayHash<string|int, mixed> $values, Invoice $invoice, InvoicePaymentMethod} $originalLines) : ArrayCollection<int, InvoicePaymentMethod>
Parameters
- $values : ArrayHash<string|int, mixed>
- $invoice : Invoice
- $originalLines : InvoicePaymentMethod}
Return values
ArrayCollection<int, InvoicePaymentMethod>buildShippers()
private
buildShippers(ArrayHash<string|int, mixed> $values, Invoice $invoice, InvoicePaymentMethod} $originalLines) : ArrayCollection<int, InvoiceShipper>
Parameters
- $values : ArrayHash<string|int, mixed>
- $invoice : Invoice
- $originalLines : InvoicePaymentMethod}
Return values
ArrayCollection<int, InvoiceShipper>buildVouchers()
private
buildVouchers(ArrayHash<string|int, mixed> $values, Invoice $invoice, InvoicePaymentMethod} $originalLines) : ArrayCollection<int, InvoiceVoucher>
Parameters
- $values : ArrayHash<string|int, mixed>
- $invoice : Invoice
- $originalLines : InvoicePaymentMethod}
Return values
ArrayCollection<int, InvoiceVoucher>canOfferCreditNote()
Mirrors the Api conditions of a manual credit note source ( {@see \App\UI\Api\Invoicer\Models\Generators\InvoiceGenerator::manualCreditNoteSource()}): a numbered, non-credit invoice without an order. UX only; the Api is authoritative.
private
canOfferCreditNote(Invoice $invoice[, array<int, int>|null $creditTypeIds = null ]) : bool
Parameters
- $invoice : Invoice
- $creditTypeIds : array<int, int>|null = null
-
credit type ids (the grid passes them once for all rows)
Return values
boolcopyLine()
private
copyLine(InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod $from, InvoiceItem|InvoiceShipper|InvoicePaymentMethod $to) : void
Parameters
countryOptions()
Returns ISO country options for the customer select: active countries, CZ and SK first.
private
countryOptions() : array<string, string>
A stored (meanwhile deactivated) country stays selectable; otherwise saving would drop it.
Return values
array<string, string>createIdentity()
private
createIdentity(array<string, mixed> $payload, string $token) : SimpleIdentity|null
Parameters
- $payload : array<string, mixed>
- $token : string
Return values
SimpleIdentity|nullcreateMultiplierComponent()
Creates a multiplier for the component.
private
createMultiplierComponent(string $name) : Multiplier<string|int, IComponent>
Parameters
- $name : string
Return values
Multiplier<string|int, IComponent>createNewComponentInstance()
Creates a new component instance without adding it to the presenter; used by the multiplier.
private
createNewComponentInstance(string $baseName[, int|string|null $uniqueKey = null ]) : IComponent|null
Parameters
- $baseName : string
- $uniqueKey : int|string|null = null
Return values
IComponent|nullcreateStandardComponent()
Creates a standard component (not a multiplier).
private
createStandardComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullcreditNoteTypeIds()
private
creditNoteTypeIds() : array<int, int>
Return values
array<int, int> —ids of invoice types that are credit notes or cancellations
creditNoteTypeOptions()
Returns the credit types from the preview (id => key) translated to invoice type names.
private
creditNoteTypeOptions(array<string, mixed> $preview) : array<int, string>
Parameters
- $preview : array<string, mixed>
Return values
array<int, string>currencyOptions()
private
currencyOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>customerDeliveryFieldMap()
private
customerDeliveryFieldMap() : array<string, string>
Return values
array<string, string> —mapping to the delivery fields (customerDlv*)
customerFieldMap()
Returns the mapping data key (from {@see customerPrefillData()}) to billing field. Shared by the picker (client `fieldMap`) and the server-side prefill (snippet redraw after a pick).
private
customerFieldMap() : array<string, string>
Return values
array<string, string>customerLabel()
private
customerLabel(Customer $customer) : string
Parameters
- $customer : Customer
Return values
stringcustomerPrefillData()
private
customerPrefillData(Customer $customer) : array<string, string>
Parameters
- $customer : Customer
Return values
array<string, string>dateOrNull()
`<input type=date>`: strict parser (see `StrictDateInput`), not `new DateTime()`.
private
dateOrNull(mixed $value) : DateTime|null
Parameters
- $value : mixed
Return values
DateTime|nulldateOrToday()
Parses a date or falls back to today for a truly empty field.
private
dateOrToday(mixed $value) : DateTime
dateRules() (see addInvoiceHeaderFields()) rejects an invalid non-empty value before
onSuccess, so only a valid Y-m-d or empty gets here. The fallback is not for an
unparsable value (the form already rejected it); creationDate is never empty in the UI
because the GET default fills it with today (see applyNewInvoiceDefaults()).
Parameters
- $value : mixed
Return values
DateTimedefaultCreditNoteTypeId()
Returns the default type: `DOBROPIS` (the corrective tax document), otherwise the first one offered.
private
defaultCreditNoteTypeId(array<string, mixed> $preview) : int|null
Parameters
- $preview : array<string, mixed>
Return values
int|nulldefaultCurrencyShortcut()
private
defaultCurrencyShortcut() : string
Return values
stringdefaultUnit()
private
defaultUnit() : string
Return values
stringeditorBreadcrumb()
Builds the breadcrumb navigation: cumulative segment paths.
private
editorBreadcrumb(string $relative) : array<int, array{label: string, path: string}>
Parameters
- $relative : string
Return values
array<int, array{label: string, path: string}>editorLinkLangId()
Returns the language used to pick labels and URLs (default 1, Czech).
private
editorLinkLangId() : int
Return values
inteditorPageLabel()
Returns the page label: title, otherwise name, otherwise `#id`.
private
editorPageLabel(Page $page, int $langId) : string
Parameters
- $page : Page
- $langId : int
Return values
stringeditorPageRoute()
Returns the first page route the editor may link to. A page may have several (many-to-many); the whitelisted one is taken, not the first in order, so a page with both `Page:show` and `Page:form` ends up on the right one.
private
editorPageRoute(Page $page) : Route|null
Parameters
- $page : Page
Return values
Route|nulleditorPageUrl()
Returns the front end address of a page. The router builds it from the page route, so `/o-nas` and any prefix come out on their own.
private
editorPageUrl(Page $page, int $langId) : string|null
Parameters
- $page : Page
- $langId : int
Return values
string|null —null when the page is not a text page (see EDITOR_PAGE_TARGETS), has no filled URL, or its route cannot build a link
editorParentFolder()
Returns the parent folder (null in the editor root).
private
editorParentFolder(string $relative) : string|null
Parameters
- $relative : string
Return values
string|nulleditorPath()
Converts a client path (relative to the editor root) to an Api path (relative to the `uploads/` root).
private
editorPath(string $relative) : string|null
This is the only place where the prefix is added, so the segment check lives here too. The
Api rejects .. as well, but without this check a ../ from the request would not escape
uploads/ yet would escape editorUploads/ into neighboring folders of other modules.
Parameters
- $relative : string
Return values
string|null —null when the path contains a forbidden segment
editorUploadName()
Builds a safe and unique file name. Sanitization copies the Api layer rules (webalize of the base and of the extension), so the name returned in the URL is exactly the name the file is stored under. The random suffix prevents collisions: `writeFile()` overwrites the same name without asking, so two different `obrazek.jpg` files would overwrite each other.
private
editorUploadName(string $untrustedName) : string|null
Parameters
- $untrustedName : string
Return values
string|null —null for a forbidden extension or an unusable name
editorUploadUrl()
Returns the public URL of a file. `$path` is relative to the `uploads/` root (so it includes `editorUploads/`), the same shape as other uploads in the system.
private
editorUploadUrl(string $path) : string
Parameters
- $path : string
Return values
stringensureEditorRoot()
Creates the editor root folder; when it already exists the Api returns false and nothing happens.
private
ensureEditorRoot() : void
expireIdleLogin()
Returns whether the login expired from inactivity. If so, revokes the tokens (like a logout), clears the `auth` section, logs out the Nette identity and returns true; otherwise moves the activity stamp forward.
private
expireIdleLogin(AuthSessionStorage $authStorage) : bool
Admin keeps 30 min, or 8 h with its own "remember me", regardless of the front end
"remember me" (the auth section is shared, its 31 days do not count here). An expiry in
admin logs out of the front end too (one session).
Parameters
- $authStorage : AuthSessionStorage
Return values
boolfindInvoice()
private
findInvoice(int $id) : Invoice|null
Parameters
- $id : int
Return values
Invoice|nullfirstItemVat()
Returns the rate of the first line of the invoice, used to prefill the manual override field.
private
firstItemVat(Invoice $invoice) : string|null
Parameters
- $invoice : Invoice
Return values
string|nullfirstLineDefaults()
private
firstLineDefaults(iterable<string|int, InvoiceItem|InvoiceShipper|InvoicePaymentMethod> $lines) : array<string, mixed>
Parameters
- $lines : iterable<string|int, InvoiceItem|InvoiceShipper|InvoicePaymentMethod>
Return values
array<string, mixed>flashInvoiceEmailAfterSave()
Outcome of the e-mail sent by the Api right after the save (`saveInfo.invoiceEmail`); nothing when no e-mail was due (not checked, already sent).
private
flashInvoiceEmailAfterSave(mixed $data) : void
Parameters
- $data : mixed
getClientIp()
private
getClientIp() : string
Return values
stringgiftDefaults()
private
giftDefaults(Invoice $invoice) : array<int, array<string, mixed>>
Parameters
- $invoice : Invoice
Return values
array<int, array<string, mixed>>initializeMetaTags()
Fills the template with the title, meta tags and HTML text of the page from the translation (`PageText`) of the current language, for the layout (like the Front {@see \App\Core\Traits\Front\Presenters\PageInitTrait}).
private
initializeMetaTags(AdminPage|null $adminPageEntity) : void
When the page or translation is missing, the values are empty strings and the layout uses its fallbacks.
Parameters
- $adminPageEntity : AdminPage|null
initializePage()
private
initializePage() : void
invoiceTemplateLabel()
private
invoiceTemplateLabel(InvoiceTemplate $template) : string
Parameters
- $template : InvoiceTemplate
Return values
stringinvoiceTypeNameOptions()
Returns a map of invoice types `id => name` for the grid column/filter.
private
invoiceTypeNameOptions() : array<int, string>
A light load of the types only: loadInvoicerSelectData() would pull whole form code lists,
which is too heavy for the grid.
Return values
array<int, string>invoiceTypeOptions()
private
invoiceTypeOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>isDevelopment()
private
isDevelopment() : bool
Return values
boolisInvoiceEdit()
Whether a saved invoice (has id) is edited; add and template prefill (transient copy) return false.
private
isInvoiceEdit() : bool
Return values
boolisInvoiceLocked()
Whether the invoice is locked: its own state `lockedDatetime`, set only by the Api (e-mail dispatch, credit note or cancellation of the invoice, explicit lock).
private
isInvoiceLocked(Invoice $invoice) : bool
Only UX: saving a locked invoice through the full form is rejected by the Api
(InvoiceManager::beforeSave(), ResultCode::INVOICE_LOCKED).
Parameters
- $invoice : Invoice
Return values
boollanguageOptions()
private
languageOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>lineDefaults()
private
lineDefaults(iterable<string|int, InvoiceItem|InvoiceShipper|InvoicePaymentMethod> $lines, bool $withId) : array<int, array<string, mixed>>
Parameters
- $lines : iterable<string|int, InvoiceItem|InvoiceShipper|InvoicePaymentMethod>
- $withId : bool
Return values
array<int, array<string, mixed>>lineRow()
private
lineRow(InvoiceItem|InvoiceShipper|InvoicePaymentMethod $line, bool $withId) : array<string, mixed>
Parameters
- $line : InvoiceItem|InvoiceShipper|InvoicePaymentMethod
- $withId : bool
Return values
array<string, mixed>loadCustomer()
Loads the customer including contacts for the server-side prefill of the invoice snapshot.
private
loadCustomer(int $id) : Customer|null
Parameters
- $id : int
Return values
Customer|nullloadEmailDefaults()
Prefills the subject/body of the e-mail sent from the administration ({@see InvoiceEmailTemplate::Admin}, falls back to the automatic template) by language. Admin `EmailManager` is plain CRUD and reads the translation.
private
loadEmailDefaults(int|null $languageId) : void
Parameters
- $languageId : int|null
loadFormData()
private
loadFormData() : void
loadInvoiceSupplyKinds()
Loads the line supply kind options and the default kind (mirror of {@see InvoiceTemplateFormTrait::loadInvoiceTemplateSupplyKinds()}).
private
loadInvoiceSupplyKinds() : void
A kind already carried by an invoice line stays offered even if the admin deactivated it meanwhile; otherwise saving would silently drop it.
loadLocalization()
private
loadLocalization() : Localization|null
Return values
Localization|nullloadPdfVariantOptions()
private
loadPdfVariantOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>loadSeller()
Loads the seller with contacts, accounts and tax status history for the server-side prefill of the invoice snapshot.
private
loadSeller(int $id) : Seller|null
Parameters
- $id : int
Return values
Seller|nulllocalizationCurrencyKey()
Admin ignores the localization currency (it takes the language only).
private
localizationCurrencyKey(object $localization) : string|null
Parameters
- $localization : object
Return values
string|nulllocalizationOptions()
Returns localization options: the amount format on the invoice.
private
localizationOptions() : array<int, NotTranslate>
No translations: name is an operational row label (for example the country name), not text
for the customer. Wrapped in NotTranslate (see the trait header), otherwise the form domain
translator would look the name up as a key.
Return values
array<int, NotTranslate>loginReturnArgs()
Remembers the request of a logged-out user so the login can return to it ({@see storeRequest()}, `backlink` of the login page, restored by `AuthStorageTrait::redirectAfterLoginAction()`).
private
loginReturnArgs() : array<string, string>
Without it a save sent after a logout in another tab (or after the idle timeout) ended on the
login page with no explanation, the login led to the dashboard and the filled-in form was lost.
A restored POST renders the form again with the submitted values, but Nette does not process it
(Request::RESTORED, no blind replay): the admin checks the values and saves once more. An AJAX
request is not stored (naja would replay it as a page). The user id stored with the request is
the previous identity, so a different account logging in is not sent there.
Return values
array<string, string>logoutNetteUser()
private
logoutNetteUser() : void
parsePickerName()
Splits a picker instance name into the config key plus row indexes (multiplier and nested multiplier). `parentId` -> `['parentId', []]`; `address_2` -> `['address', ['2']]`; `parameter_1_0` -> `['parameter', ['1','0']]` (nested).
private
parsePickerName(string $name) : array{0: string, 1: list}
The separator is an underscore, not a dash: - is the component path separator in Nette
({control picker-address_0} = Multiplier picker -> child address_0).
A config key must not end with _<number> (keys: parentId, address, parameter).
Parameters
- $name : string
Return values
array{0: string, 1: listpaymentLabel()
private
paymentLabel(Payment $payment) : string
Parameters
- $payment : Payment
Return values
stringpaymentMethodOptions()
private
paymentMethodOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>paymentRegionOptions()
private
paymentRegionOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>pdfVariantMatrixJson()
Returns the JSON matrix of the PDF variant choice for the dependent select: `{invoiceTypeId: {"pt_pr_bvt_suv": variantId}}` (axes: productType, paymentRegion, buyerVatType, sellerUseVat).
private
pdfVariantMatrixJson() : string
Source: the owned collection InvoiceType::getPdfTemplateVariantRels() across all invoice types (the same matrix the invoice type edits); only cells with a selected variant.
The matrix is dense: both seller-mode halves (1 = VAT payer, 0 = non-payer) go in and the
last key part is the mode. The client fills it from the useVat checkbox of the form (VAT
payer status of the invoice), so switching the mode picks the variant from the matching half.
Return values
stringpdfVariantOptions()
private
pdfVariantOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>pdfVariantTreatmentMatrixJson()
Returns the JSON matrix of PDF variants by VAT treatment code: `{invoiceTypeId: {"<code>" | "*": variantId}}`, only rows with a selected variant.
private
pdfVariantTreatmentMatrixJson() : string
The client prefills the variant of an invoice that carries tax_treatment from it (exact
match, then *; mirror of InvoiceTypePdfVariantTreatmentRelCollectionTrait::resolvePdfVariantIdForTreatment()).
Return values
stringprocessCreditNote()
Issues the credit note through the Api; redirects on success, returns false (with a flash) otherwise.
private
processCreditNote(ArrayHash<string|int, mixed> $values) : bool
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
boolprocessFailedLogin()
private
processFailedLogin(AuthSessionStorage $authStorage, Result $result, string $username) : void
Parameters
- $authStorage : AuthSessionStorage
- $result : Result
- $username : string
processInvalidToken()
private
processInvalidToken(AuthStorageInterface $authStorage) : void
Parameters
- $authStorage : AuthStorageInterface
processLogin()
private
processLogin(string $username, string $password[, bool $remember = false ]) : void
Parameters
- $username : string
- $password : string
- $remember : bool = false
processLoginException()
private
processLoginException(Exception $e) : void
Parameters
- $e : Exception
processMissingToken()
private
processMissingToken() : void
processSendEmail()
private
processSendEmail(ArrayHash<string|int, mixed> $values) : bool
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
boolprocessSuccessfulLogin()
private
processSuccessfulLogin(AuthSessionStorage $authStorage, Result $result, string $username[, bool $remember = false ]) : void
Parameters
- $authStorage : AuthSessionStorage
- $result : Result
- $username : string
- $remember : bool = false
processValidToken()
private
processValidToken(AuthSessionStorage $authStorage, string $token) : void
Parameters
- $authStorage : AuthSessionStorage
- $token : string
productTypeOptions()
private
productTypeOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>readLoginDeviceToken()
Returns the raw known-device cookie for the Api login (the Api verifies its signature).
private
readLoginDeviceToken() : string|null
Return values
string|nullredirectAfterLoginAction()
After a login attempt: a successful login returns to the request remembered before the login (`backlink`, {@see PrivilegeCheckTrait::loginReturnArgs()}), otherwise to the dashboard; a failed one stays on the login page and keeps the way back.
private
redirectAfterLoginAction() : void
refreshNetteIdentity()
Refreshes the token of the same logged-in user: identity data (token, name, email) are overwritten in the stored object without `login()`, so neither the session id nor the form CSRF tokens change. The identity is stored in the session section as an object; the change is written at the end of the request.
private
refreshNetteIdentity(array<string, mixed> $payload, string $token) : bool
Parameters
- $payload : array<string, mixed>
- $token : string
Return values
bool —false when impossible (nobody logged in or another user); the caller uses login
rememberLoginDevice()
After a successful login (password or OAuth) issues or renews the known-device cookie ({@see LoginDeviceCookie}): a signed proof that this browser has already logged in to the account. The next login sends it to the Api ({@see self::processLogin()}), and above the account limit the password from this browser is still verified, so foreign attempts do not lock out the owner. HttpOnly, SameSite=Lax, Secure on HTTPS; lifetime from `ratelimit.loginDevice.cookieLifetime`.
private
rememberLoginDevice(mixed $payload) : void
Parameters
- $payload : mixed
resolveCustomerLabel()
private
resolveCustomerLabel(int $id) : string|null
Parameters
- $id : int
Return values
string|nullresolveInvoicerSetting()
private
resolveInvoicerSetting(string $key, string $default) : string
Parameters
- $key : string
- $default : string
Return values
stringresolveInvoiceTemplateLabel()
private
resolveInvoiceTemplateLabel(int $id) : string|null
Parameters
- $id : int
Return values
string|nullresolveLoginErrorMessage()
Resolves the flash message of a failed login.
private
resolveLoginErrorMessage(Result $result) : string
IMPORTANT: a brute-force throttle must not be shown as "wrong password"; the limit would then look like an inexplicably failing form.
results.rateLimitExceeded (the generic text of ResultCode) carries no seconds and
does not belong to login. The login flow therefore has its own key in the same family as
admin.general.login.error.message: login.rateLimit.message, with the seconds passed as
%count% (Contributte: numeric 2nd argument).
The Api sends retryAfter in data (AuthPresenter::rateLimitedResult());
the internal bridge call does not see the Retry-After header.
Parameters
- $result : Result
Return values
stringresolvePaymentLabel()
private
resolvePaymentLabel(int $id) : string|null
Parameters
- $id : int
Return values
string|nullresolveSellerLabel()
private
resolveSellerLabel(int $id) : string|null
Parameters
- $id : int
Return values
string|nullrevokeTokensOnLogout()
Calls the Api logout (revokes the refresh family and deny-lists the access `jti`) for the tokens of the current session. Fail-open on purpose: any failure is only logged, because the local logout must not stay unfinished.
private
revokeTokensOnLogout(AuthSessionStorage $authStorage, mixed $userId) : void
Parameters
- $authStorage : AuthSessionStorage
- $userId : mixed
rows()
private
rows(mixed $rows) : iterable<string|int, array<string, mixed>|ArrayHash<string|int, mixed>>
Parameters
- $rows : mixed
Return values
iterable<string|int, array<string, mixed>|ArrayHash<string|int, mixed>>saveInvoiceForm()
private
saveInvoiceForm(ArrayHash<string|int, mixed> $values) : bool
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
boolsaveLockedInvoice()
Saves a locked invoice: only the allowed fields are written by a direct update (no recalculation, no new PDF). Other form values are dropped and the admin gets an explanation.
private
saveLockedInvoice(Invoice $invoice, ArrayHash<string|int, mixed> $values) : bool
Parameters
- $invoice : Invoice
- $values : ArrayHash<string|int, mixed>
Return values
boolsellerLabel()
private
sellerLabel(Seller $seller) : string
Parameters
- $seller : Seller
Return values
stringsellerPrefillData()
private
sellerPrefillData(Seller $seller) : array<string, string>
Parameters
- $seller : Seller
Return values
array<string, string>setInvoiceFormDefaults()
private
setInvoiceFormDefaults(Form $form) : void
Parameters
- $form : Form
setNetteUser()
private
setNetteUser(array<string, mixed>|null $payload, string $token) : void
Parameters
- $payload : array<string, mixed>|null
- $token : string
snapshotLineIdentity()
Snapshot of the lines before the full replace, indexed by id, so `build*()` can pull in columns the form does not render (line identity).
private
snapshotLineIdentity(Invoice $invoice) : InvoicePaymentMethod}
The form renders one container without id for shipping and payment method, so the first original row is kept; without it the save would delete the row and insert a new one (new id means a lost link to the source invoice).
Parameters
- $invoice : Invoice
Return values
InvoicePaymentMethod}statusOptions()
private
statusOptions() : array<string, string>
Return values
array<string, string>storeEditorUpload()
Stores a file; the target folder may not exist (first upload into the root), so after a failure the root is created once and the write is retried. Deeper subfolders are created by the editor user through `editorCreateFolder`.
private
storeEditorUpload(string $folder, string $name, string $base64) : bool
Parameters
- $folder : string
- $name : string
- $base64 : string
Return values
boolsuggestCustomers()
private
suggestCustomers(string $query) : array<int, array{id: int, label: string, data: array}>
Parameters
- $query : string
Return values
array<int, array{id: int, label: string, data: arraysuggestInvoiceTemplates()
private
suggestInvoiceTemplates(string $query) : array<int, array{id: int, label: string}>
Parameters
- $query : string
Return values
array<int, array{id: int, label: string}>suggestPayments()
private
suggestPayments(string $query) : array<int, array{id: int, label: string, data: array}>
Parameters
- $query : string
Return values
array<int, array{id: int, label: string, data: arraysuggestSellers()
private
suggestSellers(string $query) : array<int, array{id: int, label: string, data: array}>
Parameters
- $query : string
Return values
array<int, array{id: int, label: string, data: arraytaxTreatmentOptions()
Returns treatment code options for the manual override: translated names from the form domain (`form.fields.taxOverrideCode.codes.<CODE>`), ordered as the enum.
private
taxTreatmentOptions() : array<string, NotTranslate>
Return values
array<string, NotTranslate>trInvoice()
Translates a key in the form domain to a final string (for fields with `setTranslator(null)`).
private
trInvoice(string $key) : string
Parameters
- $key : string
Return values
stringtryRefresh()
Tries an auto-refresh for an expired access token. If the session holds a refresh token and the Api accepts it, stores the new pair in the session and returns true; otherwise returns false and the caller cancels the session.
private
tryRefresh(AuthSessionStorage $authStorage) : bool
Parameters
- $authStorage : AuthSessionStorage
Return values
booluserTypeOptions()
private
userTypeOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>voucherDefaults()
private
voucherDefaults(Invoice $invoice) : array<int, array<string, mixed>>
Parameters
- $invoice : Invoice