InvoiceTemplateFormTrait uses trait:short, trait:short, trait:short
Edit/add form of an invoice template; the structure mirrors the `Invoice` form.
Blocks: header (name, variable symbol, currency, code list selects), seller (picker + editable snapshot + bank + refresh button, InvoicerPickerRefreshTrait), customer (picker + snapshot
- refresh), lines (items/gifts/vouchers as client-side multipliers with
client-multiplier.jsandinvoice-calc.js), shipping and payment (fixed one-row blocks), delivery address (toggle + picker + refresh), notes.
Seller and customer snapshots are denormalized editable copies (the picker prefills them, see
SellerPickerTrait). Line amounts are
computed client-side by invoice-calc.js (UX) and overwritten authoritatively by InvoiceCalculator in the Api beforeSave().
Table of Contents
Constants
- PRICE_PATTERN : string = '\s*-?\d{1,7}([.,]\d{1,3})?\s*'
- Price mask for `decimal(10,3)`; mirrors {@see InvoiceFormTrait::PRICE_PATTERN}.
- QUANTITY_PATTERN : string = '\s*-?\d{1,6}([.,]\d{1,2})?\s*'
- Quantity mask for `decimal(8,2)`; mirrors {@see InvoiceFormTrait::QUANTITY_PATTERN}.
- SUPPLY_KIND_SETTING_MODULE_INVOICER : mixed = 7
- Module "invoicer" in the settings table (`cms_system_settings.module`); holds the portal `sellerId`.
Properties
- $supplyKindFieldsManager : SupplyKindManager
- $supplyKindFieldsSellerManager : SellerManager
- $supplyKindFieldsVatRateManager : VatRateManager
- $invoiceTemplateSupplyKindDefaultId : int|null
- $invoiceTemplateSupplyKindOptions : array<int, string>
- Options of the "supply kind" select of items (active kinds plus kinds the template items already carry) and the preselected kind of a new item (`is_default`). Filled by {@see loadInvoiceTemplateSupplyKinds()}.
Methods
-
getInvoiceTemplateSupplyKindProto()
: array{options: array
, defaultId: int|null} - Returns the options and the default kind for `lineProto` in the template.
- addSupplyKindSelect() : SelectBox
- Adds the supply kind select. The options are database names, so the select translator is off and the prompt is translated here. IMPORTANT: the label must stay a translation key (`BaseControl::getLabel()` takes the translator from the form); a translated label would be translated twice.
- buildSupplyKindRegionVatMaps() : array<int, array<int, string>>
- Returns the rate map for the helper field "price with VAT": `regionId => supplyKindId => percent` (valid today).
-
buildSupplyKindVatMapAttributes()
: array<int, array{json: string, map: array
}> - Returns the same as {@see buildSupplyKindRegionVatMaps()} plus JSON for the `data-price-vat-map` attribute of the region matrix (keys as strings, because JS reads `map[select.value]`).
- createComponentEditForm() : Form
- getSupplyKindOptions() : array<int, string>
- Returns active supply kinds as `id => name` in the admin language.
- resolveSupplyKindDefaultId() : int|null
- supplyKindIdValue() : int|null
- Converts the supply kind select value to an id, or null for the empty prompt.
- addCustomerBlock() : void
- addDeliveryBlock() : void
- addGiftsMultiplier() : void
- Same gate as {@see addItemsMultiplier()}, limit for gifts.
- addHeaderFields() : void
- addItemsMultiplier() : void
- Items: client-side multiplier.
- addLineControls() : void
- addNullableSelect() : void
- addPaymentMethodBlock() : void
- addPickerRefreshButtons() : void
- Hidden `*Refresh` submit buttons: after a pick, `picker.js` clicks them (naja), the server fills the seller/customer snapshot from the picked entity (nested contacts/accounts too) and redraws the block snippet.
- addSellerBlock() : void
- addShipperBlock() : void
- Shipping: fixed one-row block (a collection, but one container in the UI).
- addVouchersMultiplier() : void
- Same gate as {@see addItemsMultiplier()}, limit for vouchers.
- applyLine() : void
- Maps the shared line fields from the form to the entity (computed fields are overwritten by the Api calculator).
- applyLineId() : void
- buildGifts() : ArrayCollection<int, InvoiceTemplateGift>
- buildItems() : ArrayCollection<int, InvoiceTemplateItem>
- buildPaymentMethods() : ArrayCollection<int, InvoiceTemplatePaymentMethod>
- buildShippers() : ArrayCollection<int, InvoiceTemplateShipper>
- buildVouchers() : ArrayCollection<int, InvoiceTemplateVoucher>
- defaultUnit() : string
- fillMappedFields() : void
- Force-sets form fields from prefill data through a fieldMap (data key to field name; an empty map means the key is the field name, as for the seller). Only existing fields; a checkbox becomes bool.
- firstLineDefaults() : array<string, mixed>
- giftDefaults() : array<int, array<string, mixed>>
- lineDefaults() : array<int, array<string, mixed>>
- lineRow() : array<string, mixed>
- loadInvoiceTemplateSupplyKinds() : void
- Supply kind options of items plus the default kind (the form and the client prototype of a new item, {@see getInvoiceTemplateSupplyKindProto()}).
- ownedLineId() : int|null
- Returns the form row id only if it belongs to this template; a foreign or made-up id is dropped (the row is saved as new, a foreign row is never adopted or overwritten).
- pickedId() : int
- Reads the picked id safely from the hidden picker field (after submit).
- pickerRefreshButton() : void
- resolveSupplyKindSellerCountryCode() : string|null
- Returns the portal seller country (`7/invoice.default.sellerId`) as a fallback for a region without a country; null when the seller is not found.
- rows() : iterable<string|int, array<string, mixed>|ArrayHash<string|int, mixed>>
- saveInvoiceTemplateForm() : bool
- setInvoiceTemplateFormDefaults() : void
- snapshotTemplateLineIdentity() : InvoiceTemplatePaymentMethod}
- Returns what belongs to the template before the collections are overwritten: ids of items/gifts/vouchers and the first shipping and payment (the form renders just one container without id).
- voucherDefaults() : array<int, array<string, mixed>>
Constants
PRICE_PATTERN
Price mask for `decimal(10,3)`; mirrors {@see InvoiceFormTrait::PRICE_PATTERN}.
private
string
PRICE_PATTERN
= '\s*-?\d{1,7}([.,]\d{1,3})?\s*'
QUANTITY_PATTERN
Quantity mask for `decimal(8,2)`; mirrors {@see InvoiceFormTrait::QUANTITY_PATTERN}.
private
string
QUANTITY_PATTERN
= '\s*-?\d{1,6}([.,]\d{1,2})?\s*'
The template is the source of invoice lines, so it must accept exactly what the invoice accepts, including the optional minus; the rationale is at the mirrored constant.
SUPPLY_KIND_SETTING_MODULE_INVOICER
Module "invoicer" in the settings table (`cms_system_settings.module`); holds the portal `sellerId`.
private
mixed
SUPPLY_KIND_SETTING_MODULE_INVOICER
= 7
Properties
$supplyKindFieldsManager
public
SupplyKindManager
$supplyKindFieldsManager
Attributes
- #[Inject]
$supplyKindFieldsSellerManager
public
SellerManager
$supplyKindFieldsSellerManager
Attributes
- #[Inject]
$supplyKindFieldsVatRateManager
public
VatRateManager
$supplyKindFieldsVatRateManager
Attributes
- #[Inject]
$invoiceTemplateSupplyKindDefaultId
private
int|null
$invoiceTemplateSupplyKindDefaultId
= null
$invoiceTemplateSupplyKindOptions
Options of the "supply kind" select of items (active kinds plus kinds the template items already carry) and the preselected kind of a new item (`is_default`). Filled by {@see loadInvoiceTemplateSupplyKinds()}.
private
array<int, string>
$invoiceTemplateSupplyKindOptions
= []
Methods
getInvoiceTemplateSupplyKindProto()
Returns the options and the default kind for `lineProto` in the template.
public
getInvoiceTemplateSupplyKindProto() : array{options: array, defaultId: int|null}
IMPORTANT: do not use $this->template->... from the form factory; the form is created
lazily at {form editForm}, when the template has its parameters already copied.
Return values
array{options: arrayaddSupplyKindSelect()
Adds the supply kind select. The options are database names, so the select translator is off and the prompt is translated here. IMPORTANT: the label must stay a translation key (`BaseControl::getLabel()` takes the translator from the form); a translated label would be translated twice.
protected
addSupplyKindSelect(Form $form, string $name, string $labelKey, string|null $promptKey[, string|null $descriptionKey = null ][, int|null $currentId = null ]) : SelectBox
Parameters
- $form : Form
- $name : string
- $labelKey : string
- $promptKey : string|null
-
null = no prompt (the field is required, the first or current kind is preselected)
- $descriptionKey : string|null = null
- $currentId : int|null = null
Return values
SelectBoxbuildSupplyKindRegionVatMaps()
Returns the rate map for the helper field "price with VAT": `regionId => supplyKindId => percent` (valid today).
protected
buildSupplyKindRegionVatMaps(iterable<string|int, PaymentRegion> $regions) : array<int, array<int, string>>
Parameters
- $regions : iterable<string|int, PaymentRegion>
Return values
array<int, array<int, string>>buildSupplyKindVatMapAttributes()
Returns the same as {@see buildSupplyKindRegionVatMaps()} plus JSON for the `data-price-vat-map` attribute of the region matrix (keys as strings, because JS reads `map[select.value]`).
protected
buildSupplyKindVatMapAttributes(iterable<string|int, PaymentRegion> $regions) : array<int, array{json: string, map: array}>
For the template: regionId => {json, map}.
Parameters
- $regions : iterable<string|int, PaymentRegion>
Return values
array<int, array{json: string, map: arraycreateComponentEditForm()
protected
createComponentEditForm() : Form
Return values
FormgetSupplyKindOptions()
Returns active supply kinds as `id => name` in the admin language.
protected
getSupplyKindOptions([int|null $keepId = null ]) : array<int, string>
Parameters
- $keepId : int|null = null
Return values
array<int, string>resolveSupplyKindDefaultId()
protected
resolveSupplyKindDefaultId(SupplyKindManager $manager, array<int, mixed> $options[, string|null $preferredKey = null ]) : int|null
Parameters
- $manager : SupplyKindManager
- $options : array<int, mixed>
-
select options (
SupplyKindManager::findSelectOptions()) - $preferredKey : string|null = null
Return values
int|nullsupplyKindIdValue()
Converts the supply kind select value to an id, or null for the empty prompt.
protected
supplyKindIdValue(mixed $value) : int|null
Parameters
- $value : mixed
Return values
int|nulladdCustomerBlock()
private
addCustomerBlock(Form $form) : void
Parameters
- $form : Form
addDeliveryBlock()
private
addDeliveryBlock(Form $form) : void
Parameters
- $form : Form
addGiftsMultiplier()
Same gate as {@see addItemsMultiplier()}, limit for gifts.
private
addGiftsMultiplier(Form $form) : void
Parameters
- $form : Form
addHeaderFields()
private
addHeaderFields(Form $form) : void
Parameters
- $form : Form
addItemsMultiplier()
Items: client-side multiplier.
private
addItemsMultiplier(Form $form) : void
The row count limit is read from the raw HTTP data (onAnchor, see MultiplierLimits::guard()), with $maxCopies as the second line of defense against
materialization.
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, string|Stringable> $options, string $promptKey) : void
Parameters
- $form : Form
- $name : string
- $options : array<int, string|Stringable>
-
labels, typically
NotTranslate(values from the DB) - $promptKey : string
addPaymentMethodBlock()
private
addPaymentMethodBlock(Form $form) : void
Parameters
- $form : Form
addPickerRefreshButtons()
Hidden `*Refresh` submit buttons: after a pick, `picker.js` clicks them (naja), the server fills the seller/customer snapshot from the picked entity (nested contacts/accounts too) and redraws the block snippet.
private
addPickerRefreshButtons(Form $form) : void
validationScope([]) skips validation (a required line does not block it); the createForm
gate lets only update/save save, so this does not save. useVat is handled by the client
(fieldMap + change, invoice-calc recalculates VAT at once); the server fills only the text
fields of the block.
Parameters
- $form : Form
addSellerBlock()
private
addSellerBlock(Form $form) : void
Parameters
- $form : Form
addShipperBlock()
Shipping: fixed one-row block (a collection, but one container in the UI).
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
applyLine()
Maps the shared line fields from the form to the entity (computed fields are overwritten by the Api calculator).
private
applyLine(InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod $line, array<string, mixed>|ArrayHash<string|int, mixed> $row) : void
Parameters
- $line : InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod
- $row : array<string, mixed>|ArrayHash<string|int, mixed>
applyLineId()
private
applyLineId(InvoiceTemplateItem $line, mixed $idValue, array<int, mixed> $ownedIds) : void
Parameters
- $line : InvoiceTemplateItem
- $idValue : mixed
- $ownedIds : array<int, mixed>
-
ids (keys) of the rows that really belong to the template
buildGifts()
private
buildGifts(ArrayHash<string|int, mixed> $values, InvoiceTemplate $template, InvoiceTemplatePaymentMethod} $own) : ArrayCollection<int, InvoiceTemplateGift>
Parameters
- $values : ArrayHash<string|int, mixed>
- $template : InvoiceTemplate
- $own : InvoiceTemplatePaymentMethod}
Return values
ArrayCollection<int, InvoiceTemplateGift>buildItems()
private
buildItems(ArrayHash<string|int, mixed> $values, InvoiceTemplate $template, InvoiceTemplatePaymentMethod} $own) : ArrayCollection<int, InvoiceTemplateItem>
Parameters
- $values : ArrayHash<string|int, mixed>
- $template : InvoiceTemplate
- $own : InvoiceTemplatePaymentMethod}
Return values
ArrayCollection<int, InvoiceTemplateItem>buildPaymentMethods()
private
buildPaymentMethods(ArrayHash<string|int, mixed> $values, InvoiceTemplate $template, InvoiceTemplatePaymentMethod} $own) : ArrayCollection<int, InvoiceTemplatePaymentMethod>
Parameters
- $values : ArrayHash<string|int, mixed>
- $template : InvoiceTemplate
- $own : InvoiceTemplatePaymentMethod}
Return values
ArrayCollection<int, InvoiceTemplatePaymentMethod>buildShippers()
private
buildShippers(ArrayHash<string|int, mixed> $values, InvoiceTemplate $template, InvoiceTemplatePaymentMethod} $own) : ArrayCollection<int, InvoiceTemplateShipper>
Parameters
- $values : ArrayHash<string|int, mixed>
- $template : InvoiceTemplate
- $own : InvoiceTemplatePaymentMethod}
Return values
ArrayCollection<int, InvoiceTemplateShipper>buildVouchers()
private
buildVouchers(ArrayHash<string|int, mixed> $values, InvoiceTemplate $template, InvoiceTemplatePaymentMethod} $own) : ArrayCollection<int, InvoiceTemplateVoucher>
Parameters
- $values : ArrayHash<string|int, mixed>
- $template : InvoiceTemplate
- $own : InvoiceTemplatePaymentMethod}
Return values
ArrayCollection<int, InvoiceTemplateVoucher>defaultUnit()
private
defaultUnit() : string
Return values
stringfillMappedFields()
Force-sets form fields from prefill data through a fieldMap (data key to field name; an empty map means the key is the field name, as for the seller). Only existing fields; a checkbox becomes bool.
private
fillMappedFields(Form $form, array<string, string> $data, array<string, string> $fieldMap) : void
Parameters
- $form : Form
- $data : array<string, string>
- $fieldMap : array<string, string>
firstLineDefaults()
private
firstLineDefaults(iterable<string|int, InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod> $lines) : array<string, mixed>
Parameters
- $lines : iterable<string|int, InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod>
Return values
array<string, mixed>giftDefaults()
private
giftDefaults(InvoiceTemplate $template) : array<int, array<string, mixed>>
Parameters
- $template : InvoiceTemplate
Return values
array<int, array<string, mixed>>lineDefaults()
private
lineDefaults(iterable<string|int, InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod> $lines, bool $withId) : array<int, array<string, mixed>>
Parameters
- $lines : iterable<string|int, InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod>
- $withId : bool
Return values
array<int, array<string, mixed>>lineRow()
private
lineRow(InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod $line, bool $withId) : array<string, mixed>
Parameters
- $line : InvoiceTemplateItem|InvoiceTemplateShipper|InvoiceTemplatePaymentMethod
- $withId : bool
Return values
array<string, mixed>loadInvoiceTemplateSupplyKinds()
Supply kind options of items plus the default kind (the form and the client prototype of a new item, {@see getInvoiceTemplateSupplyKindProto()}).
private
loadInvoiceTemplateSupplyKinds() : void
ownedLineId()
Returns the form row id only if it belongs to this template; a foreign or made-up id is dropped (the row is saved as new, a foreign row is never adopted or overwritten).
private
ownedLineId(mixed $idValue, array<int, mixed> $ownedIds) : int|null
Parameters
- $idValue : mixed
- $ownedIds : array<int, mixed>
Return values
int|nullpickedId()
Reads the picked id safely from the hidden picker field (after submit).
private
pickedId(Form $form, string $field) : int
Parameters
- $form : Form
- $field : string
Return values
intpickerRefreshButton()
private
pickerRefreshButton(Form $form, string $name, callable $apply) : void
Parameters
- $form : Form
- $name : string
- $apply : callable
resolveSupplyKindSellerCountryCode()
Returns the portal seller country (`7/invoice.default.sellerId`) as a fallback for a region without a country; null when the seller is not found.
private
resolveSupplyKindSellerCountryCode() : string|null
Return values
string|nullrows()
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>>saveInvoiceTemplateForm()
private
saveInvoiceTemplateForm(ArrayHash<string|int, mixed> $values) : bool
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
boolsetInvoiceTemplateFormDefaults()
private
setInvoiceTemplateFormDefaults(Form $form) : void
Parameters
- $form : Form
snapshotTemplateLineIdentity()
Returns what belongs to the template before the collections are overwritten: ids of items/gifts/vouchers and the first shipping and payment (the form renders just one container without id).
private
snapshotTemplateLineIdentity(InvoiceTemplate $template) : InvoiceTemplatePaymentMethod}
Parameters
- $template : InvoiceTemplate
Return values
InvoiceTemplatePaymentMethod}voucherDefaults()
private
voucherDefaults(InvoiceTemplate $template) : array<int, array<string, mixed>>
Parameters
- $template : InvoiceTemplate