Přeskočit na hlavní obsah

Kapitola 5: Technická Reference - Business Logika

5.1 Výpočetní Jádro InvoiceLike

Třída: Classes\Abstract\Services\InvoiceLike (Invoice, ProformaInvoice, CreditNote, Quote, SalesOrder, PurchaseOrder, SupplierInvoice).

  • Načítá record listy (items, additionalCosts, advanceDeductions, summaryVatRates) podle potřeby, aby výpočty vycházely z uložených dat.
  • Položky nákladů: Core\Hooks\AbstractRecalculate materializuje shippingCost / wrappingCost do samostatných řádků (typ shipping/wrapping) a při nulové částce je odstraní.
  • Položky slev: Procentní slevy z linku discounts se převádějí do záporných řádků v pořadí (typ discount) proti nediskontním položkám.
  • Alokace vedlejších nákladů: calculatePurchasePrice + computeAdditionalCostAllocation rozdělují vedlejší náklady metodou největšího zbytku tak, aby zaokrouhlené alokace přesně seděly na celkovou částku.
  • Výpočet položek (recalculateItem): Umí ceny s/bez DPH, slevy, cenovou marži %, reverse charge, zahraniční fakturaci (taxRate = 0), zaokrouhlení po řádcích, hmotnost z Product a nákupní cenu položky.
  • Součty (recalculateTotals): Agreguje DPH podle sazeb na zaokrouhlených základech, skládá summaryVatRatesRecordList, nastavuje preDiscountedAmount, discountAmount, amount, taxAmount, grandTotalAmount.
  • Zaokrouhlení (handleTotalAmountRounding): Aplikuje roundToCrowns/10h/50h s matematickým/nahoru/dolů; rozdíl ukládá do rounding a přidává do summaryVatRatesRecordList jako nulovou sazbu.
  • Platby/zálohy (recalculatePaidAmounts): Sčítá napojené Payment (včetně konverze měn), zálohové odpočty, nastavuje paid, paidAdvances, remainingToPay, invoicedAmount.

Diagram Přepočtu

Klikněte pro zobrazení Diagramu Přepočtu

5.2 Platby a Práce se Statusem

Služba: Services\Payment

  • createPaymentForInvoice|SupplierInvoice|ProformaInvoice:
    • Nastaví status rodiče na Uhrazeno, jinak Částečně uhrazeno (podle markAsPaid).
    • Vytvoří Payment s amount, amountCurrency, date (paidOn), variableSymbol, parentId/parentType, assignedUserId.
    • Spustí recalculate rodiče, uloží; konverze částky využívá uložené currencyRates, takže platby v jiné měně správně doplní paid.
  • Proforma navíc: orderNumber se při platbě proformy čísluje sekvenčně (Hooks\Payment\SetOrderNumber). Pokud je createTaxDocumentHint a firma je plátce DPH, vytvoří se IssuedTaxDocument se sloučenými položkami po sazbách (unitPrice = placená částka podle sazby).
  • Pojmenování/soulad: Common\SetInvoiceName razítkuje referenceIdentifier a datePaid při stavu Uhrazeno; ManageDuzp hlídá povinné duzp, je-li zapnuto.

Diagram Plateb

Klikněte pro zobrazení toku plateb

5.3 Odpočty Záloh (Invoice ⇆ Proforma)

  • Propojení Proformy na Fakturu spouští Hooks\Invoice\ProformaInvoiceCreateAdvanceProformaInvoice::onInvoiceLink, které vytvoří AdvanceDeductionItem navázaný na oba doklady a přepočítá Fakturu. Odpojení položku smaže a znovu přepočítá.
  • RecordHooks\Invoice\ProformaItems blokuje připojení nezaplacených proforem (BadRequest, pokud některá proforma není Uhrazená).
  • Odpočty záloh vstupují do remainingToPay a paidAdvances.

Diagram Odpočtu Záloh

Klikněte pro zobrazení toku odpočtů

5.4 Hlídání Splatnosti

Komponenta: Tools\Invoice\InvoiceLikeOverdueChecker (+ Hooks\Invoice\CheckOverdue, cron Jobs\CheckOverdueOrders)

  • Aplikuje se jen pokud je dueDate a stav je v povoleném seznamu:
    • Invoice/SupplierInvoice: Potvrzeno, Částečně uhrazeno.
    • ReceivedTaxDocument: Přijato.
  • Nastavuje isOverdue, isDueSoon (parametr dueSoonDays z clientDefs/entityDefs, výchozí 5) a numberOfOverdueDays; pokud chybí dueDate nebo stav nevyhovuje, příznaky resetuje.

5.5 Automatizace Objednávek a Vliv Položek

  • Zámky statusu: Hooks\PurchaseOrder\PreventInvalidStatusChange nedovolí změnu z finálních stavů ani přechod Objednáno → Připraveno/Návrh.
  • Data: Hooks\PurchaseOrder\SetDefaultFields doplní dateOrdered při stavu Ordered.
  • Položky: Hooks\PurchaseOrder\SetItemsStatus nastaví položky na WaitingForDelivery při Ordered a na Delivered při Delivered rodiče; Hooks\PurchaseOrderItem\ProcessPurchaseOrderItem označí položku za Delivered při quantityDelivered ≥ quantity, nastaví deliveryDate, synchronizuje data do Production integrace; Hooks\PurchaseOrderItem\UpdateStatus může posunout rodiče na PartiallyDelivered/Delivered, pokud je zapnuté automateStatusChange.
  • Integrita: Hooks\PurchaseOrderItem\PreventInvalidStatusChange brání vracet finalizované položky; DeleteOnChangeSupplier smaže osiřelé položky při deleteId.
  • Náklady/slevy: Doprava/balení a procentní slevy se vkládají jako samostatné řádky přes AbstractRecalculate stejně jako u faktur.

Diagram Životního Cyklu Objednávky

Klikněte pro zobrazení průběhu objednávky

5.6 Integrace Prodejní Objednávky

  • Synchronizace nabídky: Hooks\SalesOrder\SetQuoteStatus nastaví navázaný Quote na Ordered při uložení SalesOrder.
  • Automatická tvorba projektu (volitelné): Při zapnutém enableAutomaticProjectCreation a nainstalovaném Project Managementu Hooks\SalesOrder\ProjectManagementIntegration vytvoří Project se stavem InRealization a klonovanými položkami a propojí Quote/SalesOrder.

5.7 Stavové Strojky (klíčové entity)

Invoice / Proforma / SupplierInvoice / CreditNote

Klikněte pro zobrazení stavů Invoice rodiny

Pravidla & automatizace:

  • Proforma nelze připojit k Faktuře, pokud není ve stavu Uhrazená (RecordHooks/Invoice/ProformaItems).
  • Příznaky overdue jen pro stavy {Potvrzeno, Částečně uhrazeno} (Invoice/SupplierInvoice) nebo ReceivedTaxDocument: Přijato.
  • ManageDuzp doplňuje/omezuje duzp na typech: Invoice, SupplierInvoice, CreditNote, ReceivedProformaInvoice, ReceivedTaxDocument.

PurchaseOrder & PurchaseOrderItem

Klikněte pro zobrazení toku PurchaseOrder
  • Zámky: zákaz z finálních stavů a Objednáno→Připraveno/Návrh (Hooks/PurchaseOrder/PreventInvalidStatusChange).
  • Položky: Čeká na dodání při Objednáno, Přijato při Dodáno rodiče (Hooks/PurchaseOrder/SetItemsStatus); položka s qtyDelivered ≥ qty přepne na Přijato a může posunout rodiče (Hooks/PurchaseOrderItem/ProcessPurchaseOrderItem, UpdateStatus).

SalesOrder

  • Návrh → Připraveno → Aktivní → Dokončeno, plus Zamítnuto/Zrušeno. Připojený Quote se nastaví na Objednáno automaticky.

5.8 Automatizační Matice (Hooky/Služby)

SpouštěčKomponentaEfekt
Uložení invoice-like s dopravou/balením/slevamiCore/Hooks/AbstractRecalculateVloží položky nákladů/slev, aktualizuje položky, pak InvoiceLike::recalculate
Propojení/odpojení Proformy s FakturouHooks/Invoice/ProformaInvoiceCreateAdvance, ProformaInvoice::onInvoiceLink/UnlinkVytvoří/odstraní AdvanceDeductionItem, přepočítá Fakturu
Uložení Invoice/Proforma/SupplierInvoiceHooks/Invoice/CheckOverdue, Tools/Invoice/InvoiceLikeOverdueCheckerNastaví isOverdue, isDueSoon, numberOfOverdueDays
Vytvoření platbyServices/PaymentNastaví status rodiče Uhrazeno/Částečně uhrazeno, přepočítá; platby proformy dostanou sekvenční orderNumber; volitelně IssuedTaxDocument
Status = UhrazenoHooks/Common/SetInvoiceNameDoplní datePaid, razítkuje reference/name při prázdných hodnotách
Uložení invoice-like s auto duzpHooks/Common/ManageDuzpDoplní/omezí duzp podle dateInvoiced (max 14 dní zpět)
Uložení SalesOrder s QuoteHooks/SalesOrder/SetQuoteStatusStatus nabídky => Objednáno
Uložení SalesOrder (první) s feature flagemHooks/SalesOrder/ProjectManagementIntegrationVytvoří Project s klonovanými položkami
Uložení PurchaseOrderPO hooky (SetDefaultFields, SetItemsStatus, UpdateStatusFromItems, PreventInvalidStatusChange)Auto dateOrdered, sladění stavů položek/rodiče, ochrana finálních přechodů

5.9 Plánované Joby & Background Procesy

JobLogikaMěněná pole
Classes/Jobs/CheckOverdueOrdersSpustí kontrolu splatnosti pro Invoice, SupplierInvoice, ReceivedTaxDocumentisOverdue, isDueSoon, numberOfOverdueDays
Classes/Jobs/RecalculateBudgetsPřepočítá agregace BusinessUnitBudgetSoučty rozpočtových položek
Classes/Jobs/RefreshPayerStatusAktualizuje stav nespolehlivých plátců z registruData UnreliablePayer
Classes/Jobs/DownloadUnreliablePayersStáhne aktuální seznam nespolehlivých plátcůDataset nespolehlivých plátců
Classes/Jobs/SendAutomaticInvoiceGeneruje automatické faktury dle konfiguraceVytváří AutomaticInvoice

5.10 Výpočet na Řádcích & Součty (Detail InvoiceLike)

Vstupy: unitPrice, quantity, withTax, taxRate, discount, priceMarginPercentage, reverseCharge, foreignInvoicing, additionalCostsRecordList, itemsRecordList.

Tok (na řádek):

  1. Normalizace ceny: převod z brutto na netto při withTax, aplikace slevy (0–100).
  2. Vedlejší náklady: alokace (nebo allocatedAdditionalCost z metody největšího zbytku) → nákupní cena.
  3. Násobení množstvím → základ.
  4. Marže %: položková má přednost, zvyšuje základ.
  5. Reverse charge: taxAmount=0, amountWithTax=amount; foreignInvoicing + reverseCharge nastaví taxRate=0.
  6. Zaokrouhlení po řádku: round(currencyDecimalPlaces) na netto a DPH; u withTax=true se nejdřív zaokrouhlí brutto, netto = brutto/(1+rate).
  7. Hmotnost: hmotnost produktu * quantity.

Součty:

  • DPH po sazbách z zaokrouhlených základů (ignoruje řádky z proformy) → summaryVatRatesRecordList.
  • preDiscountedAmount = součet unitPrice*quantity před slevami; discountAmount zahrnuje procentní slevy i záporné řádky slev.
  • grandTotalAmount = netto + DPH ± zaokrouhlení.
  • Ukládá vypočtená pole na položkách (skip hooks).

5.11 Alokace Vedlejších Nákladů (Metoda největšího zbytku)

Zdroj: InvoiceLike::computeAdditionalCostAllocation.

  1. Sečte additionalCostsRecordList.
  2. Seskupí základy položek podle sazby DPH; ignoruje slevové/negativní řádky.
  3. Alokuje celkové náklady na sazby proporčně, zaokrouhlí dolů na centy, pak rozdělí zbytky (largest remainder).
  4. V rámci sazby alokuje na položky stejným způsobem; uloží allocatedAdditionalCost.
  5. calculatePurchasePrice použije alokaci pro per-unit vedlejší náklad, aby zaokrouhlené součty přesně seděly.

5.12 Platba Proformy → Issued Tax Document

Zdroj: Services/Payment::createTaxDocumentFromProforma.

  • Vypočítá amountRatio = proformaGrandTotal / paymentAmount (fallback 1 při 0 hodnotách) pro rozdělení placené částky podle sazeb.
  • Seskupí proforma položky podle (taxRate, withTax); na skupinu vytvoří položku s unitPrice += round(item.amountWithTax / amountRatio), quantity=1, withTax=true.
  • Kopíruje billing/adresy/vatId/orderNumber/variableSymbol/payment metadata; měna z platby.
  • Uloží IssuedTaxDocument navázaný na proformu+platbu; finální faktura odečte přes AdvanceDeductionItem.

5.13 Konfigurační Přepínače (chování)

  • enableAutomaticProjectCreation (SalesOrder clientDefs): auto Project při prvním uložení.
  • automateStatusChange (PurchaseOrder clientDefs): dovolí přechod Delivered z položek.
  • allowStatusChangeInAnyState (PurchaseOrder clientDefs): vypne ochrany stavů.
  • sendThankYouEmail + thankYouEmailTemplateId: po stavu Uhrazeno na Fakturě pošle e-mail.
  • Zaokrouhlení: pole roundTo + totalAmountRounding řídí politiku.
  • DueSoon: dueSoonDays per entita (clientDefs/entityDefs, default 5).
  • Auto DUZP: autoDuzpEnabled per entita.
  • Vlastní názvy: enableCustomName v clientDefs; jinak SetInvoiceName doplní reference/name z automatického číslování.