Skip to content

Feature: per invoice control for P_18A (MPP / split payment) and FP (faktura do paragonu) #29

@bartekimiol

Description

@bartekimiol

Context

Two FA(3) flags are currently emitted as static values, which forces an all or nothing behaviour per Dolibarr installation. In real world Polish accounting both flags must be decided per invoice, not per instance.

P_18A (Mechanizm podzielonej platnosci, MPP / split payment)

Location in code: class/fa3_builder.class.php line 1123

$adnotacje->appendChild($xml->createElement('P_18A', '2')); // Split payment

The value is hardcoded to 2 (no MPP). There is no path to emit 1 (MPP applies) even when the invoice clearly requires split payment (sales above 15 000 PLN gross containing goods/services from Annex 15 of the VAT Act). On my installation there is already a Dolibarr extrafield mpp (boolean, Mechanizm podzielonej platnosci) on the facture entity, but the builder does not read it.

FP (Faktura do paragonu)

Location in code: class/fa3_builder.class.php lines 611 to 614

if (getDolGlobalInt('KSEF_FA3_INCLUDE_FP')) {
    $fa->appendChild($xml->createElement('FP', '1'));
}

The FP marker is gated by a single global const KSEF_FA3_INCLUDE_FP. That is a per instance switch, so either every invoice in the system is flagged as faktura do paragonu, or none. In practice only a fraction of invoices are issued to a fiscal receipt (POS to invoice flow) and they need to coexist with standard invoices in the same Dolibarr instance.

What I would like to see

  1. Both P_18A and FP driven by per invoice state, not global constants.
  2. Source resolution following the same pattern that already exists for KSEF_NR_ZAMOWIENIA_SOURCE / KSEF_NR_UMOWY_SOURCE / KSEF_TP_SOURCE: each flag gets a configurable source const that points either to a fixed value, to an extrafield, or to disabled.
  3. UI on the invoice card: a quick toggle for MPP and FP that writes to the configured extrafield. If the extrafield does not exist yet, document the recommended convention (mpp boolean, fp boolean) so users can create them by hand. Long term a native checkbox in the KSeF tab would be even better.
  4. Reasonable defaults during XML build:
    • P_18A defaults to 2 when source is empty or false.
    • FP defaults to absent (current behaviour with the const off).
  5. PDF visualization: when MPP is on, the existing visualization should show the standard Mechanizm podzielonej platnosci note required by the VAT Act. When FP is on, mark the invoice as Faktura do paragonu in the header block.

Suggested implementation outline

Minimal viable slice, no schema migrations needed:

Settings (admin/setup_outgoing.php)

Add two new dropdown sources analogous to existing flag sources:

KSEF_FA3_MPP_SOURCE      = disabled | extrafield:<name> | always_on
KSEF_FA3_FP_SOURCE       = disabled | extrafield:<name> | always_on

Populate the dropdowns by iterating over facture extrafields of type boolean (and tolerate int/select 0/1 as a fallback). Deprecate KSEF_FA3_INCLUDE_FP with a one time migration into KSEF_FA3_FP_SOURCE = always_on so nobody loses behaviour after upgrade.

Builder (class/fa3_builder.class.php)

Replace lines 611 to 614 (FP) and 1123 (P_18A) with helper calls:

$mppOn = $this->resolveBooleanFlagSource($invoice, 'KSEF_FA3_MPP_SOURCE');
$adnotacje->appendChild($xml->createElement('P_18A', $mppOn ? '1' : '2'));

$fpOn = $this->resolveBooleanFlagSource($invoice, 'KSEF_FA3_FP_SOURCE');
if ($fpOn) {
    $fa->appendChild($xml->createElement('FP', '1'));
}

resolveBooleanFlagSource() reads the const, parses the source spec (same parser as for KSEF_TP_SOURCE), and returns a bool. Reuse fetch_optionals() to populate $invoice->array_options when needed.

Correction flow

For KOR invoices both flags should follow the corrected invoice line. P_18A typically inherits from the source invoice unless the correction changes the payment mechanism; FP usually does not propagate (a correction to a receipt invoice is its own document). Worth a short discussion in the PR.

Visualization (class/ksef_invoice_pdf.class.php)

In renderHeader add a single line conditional badge MPP and FP next to the invoice type. In the body, when MPP is on, append the mandatory note Mechanizm podzielonej platnosci near the totals.

Validation

I run a daily production instance with mixed invoice types (standard B2B, occasional POS to invoice, MPP relevant invoices above 15k PLN on Annex 15 goods). Happy to test a draft branch against TEST KSeF and provide sample XML before merge.

Related: #28 (Podmiot3 / Payer). The three flags together (MPP, FP, Payer) would close most of the per invoice metadata gaps I see in the current XML output.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions