Scrierea unui fisier dintr-o aplicatie web pe hdd-ul clientului

Salutare!

Am urmatorul scenariu pentru care incerc sa gasesc o solutie: se da o aplicatie PHP/MySQL de tip Point Of Sale care ruleaza pe un server web.

Clientul final este proprietarul de cafenea care foloseste aplicatia pentru a elibera la final un bon fiscal cu ajutorul casei de marcat.

Aplicatia trebuie sa scrie datele bonului fiscal intr-un fisier de tip txt pe care apoi sa-l salveze intr-un director predefinit de unde casa de marcat stie sa-l preia si sa-l printeze.

Problema este urmatoarea: cum pot face in asa fel incat din aplicatia web sa scriu local pe calculatorul clientului (care ruleaza Windows)?

Singura solutie gasita pana in prezent a fost folosirea API-ului de Dropbox, scrierea fisierului si salvarea lui in Dropbox, iar apoi setarea casei de marcat sa citeasca dintr-un folder local care se sincronizeaza cu Dropbox. In principiu functioneaza, dar delay-ul este destul de mare (30-40 secunde).

Daca nu te incurca prea mult, un mic server local pe POS ar putea face treaba asta. Limbajul Go ti-ar fi de mare folos aici :sunglasses:.
Multe case fiscale au Bluetooth. Nu am incercat dar am vazut pe undeva incercari de folosire din aplicatia ta web (in fine, e de studiat).

Aplicatia e de tip SaaS, ruleaza in cloud. Ideal ar fi sa nu mai instalez nimic pe calculatorul clientului desi cu cat ma documentez mai mult pe acest subiect cu atat constat ca nu prea am alta varianta.

Vezi ca sunt si case de marcat care lucreaza wireless, ar putea fi de folos. Totusi, idea e ca tu lucrezi cu bonuri fiscale si orice intrerupere justificata sau nu se lasa cu probleme, corectii, intarzieri, balamuc la casa (iese bonul, nu iese, s-a inregistrat tranzactia sau nu,etc). E mai ok ca aplicatia ta sa lucreze local si sa trimita doar tranzactiile efectuate in cloud pentru alte operatii financiar contabile.

1 Like

Exista varianta asta (demo) daca poti seta browser-ul folosit sa downloadeze automat in folderul dorit (pe Chrome se poate).

Simple source:

function fileDownload(name, mime, content) {
	const link = document.createElement("a");

	link.download = name;
	link.href = "data:" + mime + "," + content;
	link.target = "_blank";

	document.body.appendChild(link);
	link.click();
	document.body.removeChild(link);
}

fileDownload("fisier.html", "text/html", "<h1>hello ladies</h1>");
5 Likes

Dar asta ar insemna ca folder-ul scanat de casa de marcat sa fie folosit pentru toate download-urile.

Nu cred ca ar imbratisa prea multi clienti varianta asta.

Well, chrome / firefox extension cu file system permissions, alta varianta mai flexibila nu vad sa ai.

2 Likes

Salutare!
Cu acceasi problema ne-am confruntat si noi.
Solutia: am facut o mica app in csharp care verifica la 10 secunde un mic serviciu web din online si salveaza raspunsul intr-un fisier in formatul si structura dorita.
Asta a fost rezolvarea noastra, nu stiu daca buna sau rea sau ideala, insa a mers.

O alta solutie, daca aplicatia POS ruleaza in subnet-ul clientului, atunci instalezi un server local, cu samba faci share la folder-ul in care salvezi fisierul din aplicatie, apoi casele le confgurezi sa se uite in acel folder.

Asta este solutie mai ok, nu depinzi de accesul la internet si viteza acestuia, mai mult, ptr. restaurant, poti administra casa de marca si imprimata de note de comanda …

Spor
ps: ceva de genul:

2 Likes

cred ca ti-ar fi mult mai usor sa faci o aplicatie desktop pt asta. aplicatiile web n-au voie sa scrie nimic pe hdd fara acordul utilizatorului. (PS, te-ai uita la js cum sa faci asta, nu la php/mysql). Sau sa incerci sa faci o extensie pt browser care sa scrie fieierele. dar nu cred ca se poate, te-ai lovi de aceleasi restrictii.

1 Like

Convertesti aplicatia web intr-o aplicatie electron (pui doar url sau tot site-ul) in 10 minute si dupa ai acces prin rpc (ipc) la node, cu care poti face ce vrei tu cu fisierele de pe calculator.

pe web

// if electron si aplicatia are cookie-ul x (vezi cum vezi mai exact)
ipcRenderer.send('printeazaBonFiscal', 'json-serializat-cu-bonul')
in electron : 
ipcMain.on('printeazaBonFiscal', (event, arg) => {
  console.log('se salveaza bonul cu node') // prints "ping"
  // aici implementezi scrierea in fisier/handler-ul la casa de marcat cu arg.
  event.sender.send('raspunsPrintare', 'success/error')
})
2 Likes

casa de marcat apare ca printer in calculator? daca e definita ca printer atunci ii poti da share si din aplicatia web poti trimite comanda de print pe \hostname\printer-name

Acum mai este si varianta sa le propui sa foloseasca un browser gen Brave bazat pe Chromium pe care-l setezi special pt. aplicatie. Asta mi se pare cea mai fast si simpla solutie, comparat cu extensie Chrome sau Electron app.

Imi place ca toate lumea iti sugereaza solutii bazate pe ce tehnologii stiu oamenii sa lucreze si nu pe ce e mai simplu si mai rapid de implementat.

O alternativa mai simpla ar fi sa faci un mic script sa ruleze periodic pe calculatorul clientului. Scriptul respectiv poate fi un fisier .bat amarat care se uita in folderul de download al browserului si care muta fisierele (care respecta o anumita masca pe care o decizi tu astfel incat sa fie unica) in directorul de la printer. Acel mic script poate fi programat sa ruleze periodic direct prin Task Scheduler de la Windows.

@echo off

move /Y C:\Downloads\BON*.txt D:\printer\

Ca un extra probabil poti crea un mic installer pentru asta care ii configureaza totul clientului. El va trebui doar sa ruleze installerul si totul ar fi gata.

Nu vrei sa stii cati iti vor configura un task scheduler corect in windows ca sa porneasca si la restart si la log-out/login + nu ai error handling. Adica nu stii daca s-a printat ceva sau nu, sa nu mai zic ca nu poti sa faci task-ul sa ruleze la fiecare secunda, deci astepti dupa bon aiurea ca si imprimanta mai are ceva delay pana citeste fisierul.

Cu electron de exemplu poti trimite fisierul la imprimanta direct si sa ai un job cu un raspuns. Poate imprimanta se blocheaza si trebuie sa listezi bonul din nou sau se termina hartia. Eventual nu functioneaza imprimanta si ar fi bine sa dai o eroare sa o bage in priza. In plus poti sa ii dai un job imprimantei inainte sa printeze ceva ca sa se incalzeasca si sa printeze instant cum vin datele daca nu da eroare.

  • daca ai casa de marcat si nu imprimanta, nu vrei sa listezi acelasi bon de 2 ori fara sa precizezi imprimantei ca ai anulat celalalt bon. (aici nu sunt sigur, imi amintesc ca am citit ceva similar legat de memoria fiscala)

Si eu as mege pe solutia cu o aplicatie separata,nu o simpla copiere intr-un folder,de multe ori este nevoie sa stii si dc listarea a fost ok,poti avea cazuri in care se opreste listare bonului la jumatate dintr-un anume motiv,sau clientul nu a scos Z-ul zilei precedente si casa nu mai porneste in ziua curente,etc

Multumesc tuturor pentru raspunsuri. Cel mai probabil vom construi o aplicatie separata pentru salvarea bonului.

In Firefox si Chrome ai un API non standard
https://developer.mozilla.org/en-US/docs/Web/API/File_and_Directory_Entries_API

60% of the time, works everytime

S-ar putea ca o extensie pentru Chrome sa se poata sincroniza cu o baza de date. Extensia Chrome poate scrie fisiere locale.
Mi se pare o solutie un pic mai putin complexa decat scrierea unei aplicatii sau instalarea unui server local.
Aplicatia sau serverul local s-ar putea sa se intalneasca cu probleme de compatibilitate,

Daca mergi pe varianta cu o aplicatie C# poti incerca HttpListener
o idee de utilizare