ISP network management tools for blocking/unblocking internet access based on AbraFlexi invoice status.
abraflexi-reminder (3rd reminder sent)
│
│ emits: invoice.reminder.sent
▼
multiflexi-event-processor
│ rule: invoice.reminder.sent → mark-defaulters runtemplate
▼
abraflexi-mark-defaulters
- finds customers with UPOMINKA3 + active internet contract (typSmlouvy.INTERNET)
- sets ODPOJENO label in AbraFlexi
│
│ AbraFlexi webhook: adresar updated
▼
multiflexi-event-processor
│ rule: adresar update → blocknet runtemplate
▼
blocknet
- disconnects all customers with ODPOJENO label
Payment clears → abraflexi-reminder-clean-labels removes UPOMINKA* →
multiflexi-event-processor triggers unblocknet → internet restored.
AbraFlexi: new record in banka or pokladna evidence
│
│ webhook via abraflexi-webhook-acceptor → changes_cache
▼
multiflexi-event-processor
│ rule: banka/pokladna create → match-received-payment runtemplate
│ env_mapping: {"DOCUMENTID": "recordid"}
▼
abraflexi-match-received-payment
exit 0: payment matched to invoice
│
│ AbraFlexi: faktura-vydana updated (linked to payment)
│ webhook: faktura-vydana, update
▼
multiflexi-event-processor
│ rule: faktura-vydana update → potvrzeni-prijeti-uhrady runtemplate
│ env_mapping: {"DOCID": "recordid"}
▼
abraflexi-potvrzeni-prijeti-uhrady
- sends tax document confirmation to customer
exit 2: payment found but not matched (unknown varsym / under/overpayment)
│
│ rule: payment.unmatched → potvrzeni-prijeti-bankovni-platby runtemplate
│ env_mapping: {"DOCID": "recordid"}
▼
abraflexi-potvrzeni-prijeti-bankovni-platby
- notifies customer their payment was received but awaits manual matching
This project provides three MultiFlexi applications:
Identifies customers with the UPOMINKA3 label (3rd reminder sent) who also
have an active internet service contract and marks them for disconnection by
adding the ODPOJENO label. Triggered by the invoice.reminder.sent event.
Customers with only VoIP, IpTV, Hosting or Housing contracts are not marked
for internet disconnection even if their invoices are overdue. Set INET_CONTRACT_TYPE
to the AbraFlexi typSmlouvyK code of internet contracts to enable precise filtering.
Blocks internet access for all clients with the ODPOJENO (DISCONNECTED) label in AbraFlexi.
Unblocks internet access for all clients who are not in debt according to AbraFlexi invoices.
composer installCopy .env.example to .env and configure your connections:
cp .env.example .envABRAFLEXI_URL- Your AbraFlexi server URL (e.g.,https://your-server.com:5434)ABRAFLEXI_LOGIN- AbraFlexi usernameABRAFLEXI_PASSWORD- AbraFlexi passwordABRAFLEXI_COMPANY- Company code in AbraFlexi
EASE_LOGGER- Logging configuration (default:console|syslog)RESULT_FILE- Output file for results (default:isp_tools_result.json)APP_DEBUG- Debug mode (default:false)
LABEL_DISCONNECTED- Label for disconnected customers (default:ODPOJENO)LABEL_NODISCONNECTED- Label for customers not to disconnect (default:NEODPOJOVAT)LABEL_VIP- VIP customer label (default:VIP)
SVNUSER- Subversion repository usernameSVNPASS- Subversion repository passwordSVNURL- Subversion repository URLSVNBIN- Path to subversion binary (default:/usr/bin/svn)LOGFILE- Path to log file for operations
NETBOXURL- NetBox server URL (e.g.,https://netbox.yourdomain.com)NETBOXTOKEN- NetBox API token for authentication
bin/abraflexi-mark-defaultersbin/blocknetbin/unblocknetThese applications are designed to work with MultiFlexi for automated scheduling and execution.
The MultiFlexi application definitions are located in the multiflexi/ directory:
mark_defaulters.multiflexi.app.json- MarkDefaulters application definitionblocknet.multiflexi.app.json- BlockNet application definitionunblocknet.multiflexi.app.json- UnblockNet application definition
After registering all apps in MultiFlexi and creating their runtemplates,
configure the event processor rules via multiflexi-cli:
# ── Pipeline A: Reminder → Disconnection ──────────────────────────────────
# Rule 1: after 3rd reminder → mark customers for disconnection
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "invoice.reminder.sent" \
--operation "any" \
--runtemplate_id <MARK_DEFAULTERS_RUNTEMPLATE_ID> \
--priority 10 \
--enabled 1
# Rule 2: after ODPOJENO is set (adresar webhook) → block internet
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "adresar" \
--operation "update" \
--runtemplate_id <BLOCKNET_RUNTEMPLATE_ID> \
--priority 5 \
--enabled 1
# Rule 3: after UPOMINKA* labels removed (adresar webhook) → unblock internet
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "adresar" \
--operation "update" \
--runtemplate_id <UNBLOCKNET_RUNTEMPLATE_ID> \
--priority 5 \
--enabled 1
# ── Pipeline B: Bank Payment → Matching → Confirmation ────────────────────
# Rule 4: new bank record → run payment matcher
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "banka" \
--operation "create" \
--runtemplate_id <MATCHER_RUNTEMPLATE_ID> \
--priority 20 \
--enabled 1 \
--env_mapping '{"DOCUMENTID":"recordid"}'
# Rule 5: new cash record → run payment matcher
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "pokladna" \
--operation "create" \
--runtemplate_id <MATCHER_RUNTEMPLATE_ID> \
--priority 20 \
--enabled 1 \
--env_mapping '{"DOCUMENTID":"recordid"}'
# Rule 6: invoice updated (= matched payment) → send tax document confirmation
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "faktura-vydana" \
--operation "update" \
--runtemplate_id <POTVRZENI_PRIJETI_UHRADY_RUNTEMPLATE_ID> \
--priority 10 \
--enabled 1 \
--env_mapping '{"DOCID":"recordid"}'
# Rule 7: unmatched payment (exit 2 from matcher) → notify customer
multiflexi-cli eventrule create \
--event_source_id 1 \
--evidence "payment.unmatched" \
--operation "any" \
--runtemplate_id <POTVRZENI_PRIJETI_BANKOVNI_PLATBY_RUNTEMPLATE_ID> \
--priority 10 \
--enabled 1 \
--env_mapping '{"DOCID":"recordid"}'Set to typSmlouvy.INTERNET for Spoje.net deployment to restrict disconnection
to customers with active internet contracts only (typSmlouvy code INTERNET).
Leave empty to match all contract types.
| Label | Set by | Meaning |
|---|---|---|
UPOMINKA3 |
abraflexi-reminder | 3rd payment reminder sent |
ODPOJENO |
abraflexi-mark-defaulters | Customer marked for disconnection |
NEODPOJOVAT |
Manual | Never disconnect this customer |
VIP |
Manual | Skip disconnection for VIP customers |
For modern infrastructure management, the system supports NetBox as an alternative backend to Subversion.
Add NetBox settings to your .env file:
# NetBox API Configuration
NETBOXURL=https://your-netbox-instance.com
NETBOXTOKEN=your-api-token-here- IP Address Management: Ensure your customer IP addresses are registered in NetBox IPAM
- Custom Fields: Add a custom field named
speedto IP addresses:- Type: Integer
- Label: Speed
- Description: Internet connection speed in Mbps
To switch from Subversion-based management to NetBox:
-
Update
DeBlocker.phpconstructor to useNetBoxerinstead ofSubVersioner:$this->adapter = new NetBoxer();
-
Ensure all customer IPs are properly configured in NetBox with speed custom fields
-
Test blocking/unblocking operations
- NetBox API access with token authentication
- IP addresses must have custom field
speedfor speed management - Blocking sets speed to 0, unblocking restores the configured speed
The project includes comprehensive unit tests for all components.
composer install
vendor/bin/phpunitFor testing the Subversion backend, a test repository is included in tests/svn/ containing:
- Subversion repository with sample hosts file
- Working copy for testing operations
- Documentation in
tests/svn/README.md
The test repository allows testing blocking/unblocking operations without affecting production systems.
- PHP >= 8.1
- AbraFlexi account
- MultiFlexi Core library
- NetBox (optional, for modern infrastructure management)
MIT