Skip to content

Releases: 360booking/fiscal-bridge

v0.3.20

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 13:44
feat(gui): Probleme frecvente button + smarter probe report

Lessons from today's field session where NAK-on-every-baud×dialect
finally turned out to be an unverified cash register (no ANAF
activation). Built that + other common failure modes into the app so
future users self-diagnose faster:

1. bridge/probe.py — format_report() now detects the "all NAK"
   pattern and promotes the most-likely cause (neverified register)
   to the top of the recommendation. Checklist also gained:
     • physical display readout interpretation
     • "try a different USB cable" tip (charge-only cables mimic this)
     • Datecs PrintProxy shutdown steps
     • paper-stuck / C-key recovery
     • proprietary Datecs tool cross-check

2. bridge/gui.py — new "❓ Probleme frecvente" button opens a
   standalone scrollable Troubleshooting dialog. Covers the 8
   top patterns we hit today (NAK everywhere, 90s flap, Save doesn't
   persist, status dots gray, 'Conexiune PC' display, wrong port,
   wrong baud, CAM0x codes, dezinstalare). Also:
     • Dedicated _show_scroll_text helper — replaces tk.messagebox
       for long reports. Text is selectable + has a "Copiază tot"
       button so users can paste into a support ticket.
     • Probe button now uses the scrollable dialog too, so nothing
       gets cut off on a low-resolution screen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.19

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 13:26
fix(bridge): Save in Setări actually persists; local config always wins

Two root-causes of today's "am salvat, dar tot nu se aplică" loop:

1. Local config was not authoritative. The merge in ws_client.py let
   server-pushed values overwrite some keys. Swapped the logic: now
   every key the GUI can touch (serial_port, serial_baud, baud,
   operator, operator_password, protocol, encoding_offset, bcc_algo,
   bcc_coverage, cmd_width) is NEVER taken from the server — server
   push only fills keys the local config doesn't provide (effectively
   just cmd_codes).

2. Save button appeared to work but the new values never hit the file.
   config.json had been created by LocalSystem during --install, so
   the ProgramData inheritance gave regular user accounts only Read.
   The write failed silently. Now:
     - Atomic write via .tmp + os.replace
     - After write, reload and compare every user-edited field; any
       mismatch surfaces a RED message with actionable fix ("run bridge
       as administrator, or icacls /grant Users:(M)")
     - config.py's save() + the GUI save both grant BUILTIN\Users
       Modify on the file immediately after writing, so the NEXT save
       from a regular user account always succeeds without admin

Companion: Setări dialog geometry bumped to 480×540 (Save button was
off-screen after v0.3.17 added the Protocol dialect dropdown).

Unit tests still pass (13/13).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.18

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 13:10
fix(bridge): probe sweeps bauds + lists ports; Setări dialog shows Save

Two user-visible issues:

1. The v0.3.17 probe at a single baud (configured) showed NAK on both
   fp55 and fp700 against the user's DP-25 — ruling out dialect but
   leaving them without a next step. Now probe_all() sweeps the common
   bauds (9600, 115200, 19200, 38400, 57600, 4800 × fp55+fp700) and
   stops at the first ACK. Also lists every COM port visible to the OS
   with description + manufacturer so the user can confirm COM4 really
   is the Datecs and not some other USB gadget. Report formatting
   rewritten: table per baud + explicit "Setează în Setări: baud=X,
   dialect=Y" recommendation when a working combo is found.

2. In the Setări imprimantă dialog the Save button had drifted off the
   bottom edge — v0.3.17 added two rows (Protocol dialect dropdown +
   hint) but the dialog was still 460×360. Bumped to 480×540 and made
   vertically resizable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.17

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 12:58
feat(datecs): FP-55/FP-700 dialect probe + switcher + unit tests

Today's field log had open_fiscal NAK even after the password fix — the
frame is syntactically perfect (LEN=14, CMD=0x0030, SUM-BCC correct,
TAB separators) but the DP-25 still rejects it. The remaining likely
cause is a dialect mismatch: this specific unit may speak FP-700
(nibble+0x30, XOR BCC, 1-byte CMD) rather than the modern FP-55
(nibble+0x20, SUM BCC, 4-byte CMD) we default to.

Changes:

1. bridge/probe.py (new) — exercises cmd=0x4A (STATUS) in both
   dialects against the configured COM port and reports which (if any)
   the printer ACKs. STATUS is safe — read-only, prints nothing.

2. main.py: new `--probe-printer` CLI. Runs the probe, prints a human-
   readable report, exits 0 when either dialect responds, 2 otherwise.

3. gui.py: new "🔧 Test comunicare" button wired to the same probe +
   Protocol dialect dropdown (fp55 / fp700) in the Setări dialog, so
   switching does not need a new build.

4. config.py: new `protocol_variant: "fp55"` field, persisted via
   config.json.

5. ws_client.py: when the user set fp700 locally, all four wire knobs
   (protocol/encoding_offset/bcc_algo/cmd_width) are force-set via
   _FP700_PARAMS and then kept local-wins so the server's fp55 push
   doesn't clobber them.

6. datecs_fp.py: log line on each send now includes the active dialect
   + offset + bcc + cmd_width so it's obvious from the log what wire
   protocol is actually going on the port.

7. tests/test_datecs_fp.py (new, 13 tests passing): pins
   _encode_4nibbles, _calc_bcc (SUM/XOR), _build_frame end-to-end for
   both FP-55 and FP-700, SEQ increment + wrap, and that open_fiscal
   uses TAB (never comma). Includes the exact BCC the real NAK'd
   frame had (20 21 2d 2c for "1\t0000\t1") as a regression guard.

How the user applies this:

   a. Install v0.3.17.
   b. In GUI click "🔧 Test comunicare" — pops a dialog with which
      dialect the printer speaks.
   c. If fp700 recommended → Setări → Protocol dialect → fp700 →
      Save. Test print.
   d. CLI equivalent: `360booking-bridge.exe --probe-printer`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.16

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 12:39
feat(ws-client): log the effective printer config at every connect

After v0.3.15 the user still saw 'operator_password: 0000' in the
"Protocol config from server" line and was convinced the wrong password
was being used, even though the outgoing frame carried 0001. Now we
also log a diagnostic line with the effective merged config, so the
user can see immediately what operator/baud the printer instance is
actually configured with (password masked to first char + asterisks).

Companion to backend cd92cc1 which removes those keys from the server
push entirely.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.15

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 11:38
fix(datecs-dp25): use TAB as field separator in open_fiscal (not comma)

Today's log confirms my v0.3.14 fix made operator_password=0001 flow
into the actual wire frame:
  → cmd=0x30 data=b'1,0001,1'
…but the DP-25 still NAK'd the frame. Cross-referencing the Datecs
DP-25 integrator manual + register_item already using TAB, the correct
separator for open_fiscal is TAB too. Comma is the FP-700 dialect;
DP-25's FP-55 firmware rejects it.

Ships as v0.3.15 so the next Test Print should finally open the
fiscal receipt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.14

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 11:31
fix(bridge): stop 9600 baud override + hide flashing console windows

Two bugs isolated from today's field log:

1. baud 115200 saved in Setări was silently overwritten by server-push
   of baud=9600 on every reconnect. Root cause: _LOCAL_WINS excluded
   "serial_baud" from merge, but the server sends the key as "baud"
   (no prefix). The driver reads cfg.get("baud") or cfg.get("serial_baud"),
   so "baud" wins. Now both spellings are in _LOCAL_WINS — server
   push for the wire baud is ignored; the GUI-configured value takes
   effect on next reconnect.

2. A black cmd.exe window was flashing on top of the GUI every 2s.
   The _refresh timer shells out to tasklist and sc query to decide
   whether the bridge process is running, and _task_state shells out
   to schtasks. None of these calls were passing CREATE_NO_WINDOW +
   STARTUPINFO(SW_HIDE), so Python on Windows opened a brief console
   for each. Added a _run_hidden() helper and routed every subprocess
   call in gui.py through it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.13

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 11:18
fix(gui): recognize running bridge + single-instance for settings window

Two bugs causing the user-visible confusion in today's session:

1. _bridge_process_running() was hard-coded to look for
   "360booking-bridge-setup.exe", but after the --install flow the
   binary lives in Program Files as "360booking-bridge.exe" (no
   -setup suffix). Result: GUI always showed "Proces: oprit" with
   grey/red dots even though services.msc correctly reported RUNNING.
   Now checks both names AND falls back to `sc query` of the service
   so a non-admin user session that can't see LocalSystem processes
   in tasklist still gets the right answer.

2. Every click on tray → "Deschide setări bridge" spawned a fresh
   subprocess of `<exe> --gui`, piling up windows ("refreshul ala
   ciudat se tot deschide o fereastra"). Added a single-instance
   check via FindWindowW — if a window with the "360booking Fiscal
   Bridge" title already exists, raise it to front and exit instead
   of creating a second copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.12

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 11:09
fix(gui): rebuild StatusPanel with plain tk.Frame cards — always visible

v0.3.10/0.3.11 left the Stare / Detalii conexiune / Acțiuni LabelFrames
invisible on certain Windows themes — user saw only the title "360booking
Fiscal Bridge" and empty space below. The root cause is that ttk
LabelFrame rendering is theme-dependent and my style tweaks perturbed
it beyond what I could see on a Linux dev box.

Switch the whole panel to manually drawn cards:
  - tk.Frame with bg="#e0e0e5" as a 1-px "border", nested tk.Frame
    with bg="#ffffff" for the card surface
  - tk.Label for titles + key/value rows (ttk styling doesn't affect
    plain tk.Label so themes can't hide it)
  - ttk.Button kept for the action buttons (needed for Accent/Danger
    styles)
  - Soft grey page bg (#f5f6f8), indigo #4f46e5 accent, red #ef4444
    danger — matches the billing tab's recent refresh

Also consolidates the 8 action buttons into a 3×3 grid driven by a
list, so adding/removing one is a one-line change in the future.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

v0.3.11

Choose a tag to compare

@ovidiubistrian ovidiubistrian released this 24 Apr 11:02
fix(gui): restore visible layout — roll back aggressive theme overrides

v0.3.10 set TFrame + TLabelFrame backgrounds globally and zeroed the
labelframe border; on Windows vista/clam this hid the LabelFrame boxes,
so after opening the tray's "Deschide setări bridge" the user saw only
the title "360booking" with no Stare / Detalii / Acțiuni cards.

This revert keeps the critical v0.3.10 fixes:
  - tray -> subprocess launch of the GUI (Tk main-thread rule)
  - config reload on every WS reconnect + per-job
  - --gui CLI arg
And keeps a light visual polish:
  - Accent.TButton = indigo brand (#4f46e5) with white text
  - Danger.TButton = red text for destructive actions
  - Tighter typography (Segoe UI, slightly larger headings)
But stops fighting the native frame theme, so LabelFrames render again.
Size returns to 680×640 (the 720×720 experiment needed the new layout).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>