Preview of the invoice in advance

Preview of the invoice in advance

Postby Otto » Thu Oct 24, 2024 6:29 am

Hello friends,
Just a task from daily life.
A customer would like to show a preview of the invoice in advance to the customer on their mobile phone.
The customer should then be able to start the print job by pressing OK.

Actually, it's an application you can program in an hour.

But the customer doesn’t have a web server.
For you as a developer, it's also important that the solution you create is future-proof.

Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby Antonio Linares » Thu Oct 24, 2024 9:03 am

Dear Otto,

He could get an email with an attached PDF, just an idea :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Preview of the invoice in advance

Postby Otto » Thu Oct 24, 2024 10:16 am

Dear Antonio, thank you.
Here is the problem: many people don’t want to share their email address.

I’ve also started a topic here where I mention that the users of our software are very afraid of having their own web server.
I think we need to first show the advantages in small steps.

For the above problem, I believe we don’t need to make any setup configurations. The simplest way, in addition to the option of using email, which would be best for us from a marketing perspective, would be to send it over HTTPS. I already have a draft, and it’s working so far.

Best regards,
Otto


function RG_Preview_html()
local cText := ""
local cCustomer := "SampleCustomer"
local cInvoiceNumber := "INV-1001"
local cTotal := "256"

// HTML structure (dynamically inserting data)
cText += '<!DOCTYPE html>' + CRLF
cText += '<html lang="en">' + CRLF
cText += '<head><meta charset="UTF-8"><title>Local Invoice Preview</title></head>' + CRLF
cText += '<body>' + CRLF
cText += '<h2>Hotel Invoice Preview</h2>' + CRLF
cText += '<p>Customer: ' + cCustomer + '</p>' + CRLF
cText += '<p>Invoice: ' + cInvoiceNumber + '</p>' + CRLF
cText += '<p>Total: ' + cTotal + ' EUR</p>' + CRLF

// Add a Send button to send data via JSON
cText += '<button onclick="sendData()">Send Invoice</button>' + CRLF

// Add JavaScript to send the JSON data to the server
cText += '<script>' + CRLF
cText += 'function sendData() {' + CRLF
cText += ' const invoiceData = {' + CRLF
cText += ' customer: "' + cCustomer + '",' + CRLF
cText += ' invoiceNumber: "' + cInvoiceNumber + '",' + CRLF
cText += ' total: "' + cTotal + '"' + CRLF
cText += ' };' + CRLF
cText += ' fetch("https://test.space/previewrechnung/submitinvoice.php", {' + CRLF
cText += ' method: "POST",' + CRLF
cText += ' headers: {' + CRLF
cText += ' "Content-Type": "application/json"' + CRLF
cText += ' },' + CRLF
cText += ' body: JSON.stringify(invoiceData)' + CRLF
cText += ' }).then(response => response.text()).then(result => {' + CRLF
cText += ' alert("Invoice sent successfully!");' + CRLF
cText += ' }).catch(error => console.error("Error:", error));' + CRLF
cText += '}' + CRLF
cText += '</script>' + CRLF

cText += '</body>' + CRLF
cText += '</html>' + CRLF

// Write the HTML content to a local file
memowrit("invoice_preview.html", cText)

// Batch command to open the local HTML file in Chrome
cText := ""
cText += 'cd\' + CRLF
cText += 'cd C:\Windows\System32' + CRLF
// cText += 'start chrome --new-window --app="file:///C:/xtest/invoice_preview.html" --window-position=200,100 --window-size=950,930' + CRLF
cText += 'start "" "C:\Program Files\Mozilla Firefox\firefox.exe" "file:///C:/xtest/invoice_preview.html" --new-window' + CRLF

// Write the batch file to start the HTML preview
memowrit("startpreview.bat", cText)

// Execute the batch file to open the local HTML
waitrun("startpreview.bat", 0)

return nil


//----------------------------------------------------------------------------//


********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby TimStone » Fri Oct 25, 2024 7:06 pm

My clients all use locally based networks and the server is "in house". It's incredibly secure.

They also have had the ability to do what you describe for the past couple of years.

My program creates a PDF of the Preview created within the program ( using standard FWH functions ). This can be attached to a text message ( or email ) right from the preview, and sent to the client. They can receive the text, open the PDF, and respond with any changes or an approval.

The program interfaces with an SMS service to do this. It is very secure, and fast, and acceptable with clients. It also uses any modality the client prefers ( view at the business, text, email, or print ).

No special programming is necessary. It's 100% FWH code.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Preview of the invoice in advance

Postby Otto » Fri Oct 25, 2024 9:24 pm

Dear Tim,

I have now programmed a kind of carousel, and it works great.
The important thing is that I don’t need any firewall settings; when I install this update for a client, I don’t need help from the system administrators.
When you’re dependent on others, updates and upgrades become difficult.

System Summary:

Sending Invoice Preview:

Fivewin sends an invoice preview in JSON format to the web server.
Fivewin also generates the HTML to send the data.
HTML Launch:

The HTML is called with WaitRun().
Simultaneously, a timer starts to check if a response is received from the client.
Response Check in HTML:

In the HTML, a JavaScript INTERVAL (similar to a timer) regularly queries the web server to see if a response has arrived.
Automatic Download:

When the response is ready on the server, the download of the response file starts automatically.
Due to browser security restrictions, the user must click the "Download" button.
Window Closure:

Once Fivewin detects the downloaded file, the browser window is automatically closed by the Fivewin invoice program with PostMessage(hWnd, WM_CLOSE).
System Advantage:

Data exchange with the client occurs without any changes to the firewall.
The client only needs to log in to receive the response.
The system is pragmatic and avoids complex setups at the client side.

Best regards,
Otto

Image
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby cmsoft » Fri Oct 25, 2024 11:30 pm

Tim's option is good if you have an SMS service, since the phone will receive a notification that will call it to action. Even if you need the buyer to validate the receipt, in the same text of the message there could be a URL directed to your server (not the client's) where the buyer will do this validation.
If the buyer is present at the time you want to do the prior authorization, you could also show a QR in your system with the same url that will do the validation.
Since you have control of your server, you could display a button to download the receipt in pdf and an approval button that instructs the system to generate the printed receipt.
(Google Translate)
User avatar
cmsoft
 
Posts: 1290
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Preview of the invoice in advance

Postby Otto » Sat Oct 26, 2024 7:07 am

Hello Cesar,

Thank you. I’m already doing it that way. But the issue is that customers don’t want to give you their email address or phone number.

Guests or customers want a certain level of privacy.

The solution I now have – if you had self-hosting or access to the firewall – then you could program a lot of things more easily. But as I said, your competitors, who are constantly trying to poach your customers, are often also the server administrators and hardware resellers.

We sell our software through hardware resellers.

On one hand, they don’t like our SERVERBOOK concept, as we deliver an ALL-IN-ONE solution that’s better suited for the purpose than the big boxes, and at a price that’s only a fraction of what a traditional server would cost. With SERVERBOOKS ALL-IN-ONE, we’ve already handled all setup configurations with PowerShell, so we can set up a server – a series product! – in an hour.

On the other hand, these resellers are often also distributors of similar software and would like to replace us.

If we get our customers accustomed to online solutions in this way, then they’ll want the transition themselves and put pressure on the resellers.

These are issues that those offering in-house solutions or who are both hardware and software providers don’t face.

This merry-go-round I’ve developed here really works well.


Best regards,
Otto


Image
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby TimStone » Sun Oct 27, 2024 9:15 pm

Otto,

My systems are all based on the client's location. One computer in a local network stores the data files. It can be both a server for other workstations, and a workstation for one of the users.

My clients can use an SMS service to send their texts. We integrated to Twillio because it costs them very little. All of their texting can be done through them. There are no firewalls to setup, and no security issues.

In the US I rarely encounter a person who does not want to give out their phone number for a service follow up. Our clients only text related to the service they are rendering, or asked to render, so the client never receives unwanted texts. Thus they are happy to give out the number. Of course, if they don't want texts, that is noted and texts are not available to the employee to use. However, a phone number is needed to contact the client about any issues that arise.

It's a very simple process here. The only setup required is for our customer to setup an SMS account with Twillio, and enter the codes into the program. Everything else works "out of the box".

I fully understand all of your concerns about "competitors". Most of my clients have been with me for a very long time, and I'm not trying to "grow my business" at this stage in my life. Many won't even talk to a salesperson because I provide direct, personal, support. No phone trees. No outsourced support person who has no understanding of the business or our software, but only a script to read. Problems are solved in minutes, and fixes are immediate. The software was designed based on how my clients work, and is comfortable to use. It's a very different situation for me so the easy solutions are the best.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Preview of the invoice in advance

Postby Otto » Mon Oct 28, 2024 11:08 am

Dear Tim,

When I had the podcast created by Google NotebookLM today and saw - heard - the result, I sat frozen in front of the screen for a few minutes, somehow feeling a bit frightened. I’m also uncertain about how programming will continue.

https://mybergland.com/fwforum/fw2web.m4a

Our situation is similar to yours. I may have started software development a few years later than you. The first WINHOTEL version was released with FiveWin in 1995.

Direct, personal support will certainly be the pillars upon which small companies like ours must continue to build. We will have to help customers find products tailored specifically to them from the abundance of options available.

But what I am convinced of is that we absolutely need web programs.

For example, you write SMS messages. SMS here has almost entirely been replaced by WhatsApp messages.

However, with this invoice preview, it’s also about direct feedback.

In our case, the guest receives an invoice preview, checks it, and can immediately correct any errors, like a wrong address.
As soon as they press the "Invoice Reviewed" button, everything automatically flows back into the billing program.

Imagine if, on a hotel checkout day, you had to read all incoming emails that might concern invoices, then manually assign and adjust everything.
Just to give you an idea: in a hotel, there are often 50 or more checkouts in a very short time on departure days.

Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby Otto » Mon Oct 28, 2024 9:40 pm

Hello friends,
Please look at the source code (Harbour).
I think the system will explain itself then.
Best regards,
Otto

Code: Select all  Expand view

function RG_Preview_html()
    local cText := ""
    local cCustomer := "SampleCustomer"
    local cInvoiceNumber := "INV-1001"
    local cTotal := "256"
    local cCargoTest := "Hier ein Datenplatzhalter" +  dtoc(date())
    local hInvoiceData := {=>}
    local cJSON
    local aItems := {}            // Items als Array von assoziativen Arrays definieren
    local hItem := {=>}
   
    // Item 1
    aadd(aItems, { "description" => "Room 101 - 2 nights", "quantity" => 2, "unitPrice" => 100 })
    // Item 2
    aadd(aItems, { "description" => "Room Service", "quantity" => 1, "unitPrice" => 50 })
    // Item 3
    aadd(aItems, { "description" => "City Tax", "quantity" => 2, "unitPrice" => 3 })
   
    hItem[ "description" ] := "assoziativen Arrays"
    hItem[ "quantity" ] := 2
    hItem[ "unitPrice" ] := 55
   
    aadd( aItems, hItem )
   
    // Items dem Hauptarray hinzufügen
    hInvoiceData["items"] := aItems
   
    // JSON-String aus dem Array erstellen
    cJSON := hb_jsonEncode( hInvoiceData )
   
    // HTML-Struktur
    cText += '<!DOCTYPE html>' + CRLF
    cText += '<html lang="en">' + CRLF
    cText += '<head><meta charset="UTF-8"><title>Local Invoice Preview</title></head>' + CRLF
    cText += '<body>' + CRLF
    cText += '<h2>Hotel Invoice Preview</h2>' + CRLF
    cText += '<p>Customer: ' + cCustomer + '</p>' + CRLF
    cText += '<p>Invoice: ' + cInvoiceNumber + '</p>' + CRLF
    cText += '<p>Total: ' + cTotal + ' EUR</p>' + CRLF
    cText += '<p>CargoTest: ' + cCargoTest + ' EUR</p>' + CRLF
   
    // JavaScript zur Datenübertragung
    cText += '<script>' + CRLF
    cText += 'function sendData() {' + CRLF
    cText += '    const invoiceData = {' + CRLF
    cText += '        customer: "' + cCustomer + '",' + CRLF
    cText += '        invoiceNumber: "' + cInvoiceNumber + '",' + CRLF
    cText += '        total: "' + cTotal + '",' + CRLF
   
    cText += "        cJSON: '" + cJSON + "'," + CRLF
   
    cText += '        description: "' + cCargoTest + '"' + CRLF
    cText += '    };' + CRLF
    cText += '    fetch("https://test.com/previewrechnung/submitInvoice.php", {' + CRLF
    cText += '        method: "POST",' + CRLF
    cText += '        headers: {' + CRLF
    cText += '            "Content-Type": "application/json"' + CRLF
    cText += '        },' + CRLF
    cText += '        body: JSON.stringify(invoiceData)' + CRLF
    cText += '    }).then(response => response.json())' + CRLF
    cText += '      .then(data => console.log("Response:", data))' + CRLF
    cText += '      .catch(error => console.error("Error sending invoice:", error));' + CRLF
    cText += '}' + CRLF
   
    // Direkt nach Laden der Seite die Daten senden
    cText += 'window.onload = sendData;' + CRLF
   
    // JavaScript für das Überprüfen der Dateiexistenz und Auslösen des Downloads
    cText += 'var fileCheckInterval = setInterval(checkFileExists, 3000);' + CRLF
   
    // Funktion zum Überprüfen der Dateiexistenz
    cText += 'function checkFileExists() {' + CRLF
    cText += '   fetch("https://test.com/previewrechnung/check_response.php")' + CRLF
    cText += '       .then(response => response.json())' + CRLF
    cText += '       .then(data => {' + CRLF
    cText += '           if (data.exists) {' + CRLF
    cText += '               clearInterval(fileCheckInterval);' + CRLF
    cText += '               var downloadButton = document.getElementById("downloadButton");' + CRLF
    cText += '               downloadButton.disabled = false;' + CRLF
    cText += '               downloadButton.textContent = "Download starten";' + CRLF
    cText += '           }' + CRLF
    cText += '       })' + CRLF
    cText += '       .catch(error => console.error("Error checking file existence:", error));' + CRLF
    cText += '}' + CRLF
   
    // Funktion zum Herunterladen der Datei
    cText += 'function downloadFile() {' + CRLF
    cText += '    var a = document.createElement("a");' + CRLF
    cText += '    a.style.display = "none";' + CRLF
    cText += '    a.href = "https://test.com/previewrechnung/download_response.php";' + CRLF // Geänderter Link
    cText += '    a.download = "response_data.json";' + CRLF
    cText += '    document.body.appendChild(a);' + CRLF
    cText += '    a.click();' + CRLF
    cText += '    document.body.removeChild(a);' + CRLF
    cText += '}' + CRLF
   
    cText += '</script>' + CRLF
    cText += '<button id="downloadButton" onclick="downloadFile()" disabled>Antwort warten...</button>' + CRLF
    cText += '</body>' + CRLF
    cText += '</html>' + CRLF
   
    // Schreiben des HTML-Inhalts in eine lokale Datei
    memowrit("invoice_preview.html", cText)
   
    // Batch-Befehl zum Öffnen der HTML-Seite
    cText := ""
    cText += 'cd' + CRLF
    cText += '
cd C:\Windows\System32' + CRLF
    cText += '
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" "file:///C:/test/invoice_preview.html" --new-window' + CRLF  
    memowrit("startpreview.bat", cText)
   
    StartTimer()
   
    // Ausführen der Batch-Datei
    waitrun("startpreview.bat", 0)
   
return nil

//----------------------------------------------------------------------------//

function StartTimer()
    DEFINE TIMER oTimer ;
        INTERVAL 2000 ;
            ACTION ( check_response() )
   
    ACTIVATE TIMER oTimer
return nil
//----------------------------------------------------------------------------//

function check_response()
    local aWnd := {}
    local cTitle := ""
    local hWnd := GETWINDOW(GETDESKTOPWINDOW(), GW_CHILD)
    local n
    local aDir := {}
   
    oTimer:Deactivate()
    aDir := directory("C:\Users\Administrator\Desktop\Downloads\*.json", "DHS")
   
    if len(aDir) > 0
        WHILE hWnd != 0
            aadd(aWnd, GETWINDOWTEXT(hWnd))
            hWnd = GETWINDOW(hWnd, GW_HWNDNEXT)
        ENDDO
       
        for n := 1 to Len(aWnd)
            if left(aWnd[n], 13) == "Local Invoice"
                if !Empty(hWnd := FindWnd(aWnd[n]))
                    PostMessage(hWnd, WM_CLOSE)
                    SysWait(0.1)
                endif
            endif
        next
    endif
   
    oTimer:Activate()
return nil
//----------------------------------------------------------------------------//





********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby Otto » Mon Oct 28, 2024 9:42 pm

Here's how it continues:
Here you can see the endpoint (PHP), for example.
Then you have your data at the endpoint on the web server.

Code: Select all  Expand view


<?php
header('Access-Control-Allow-Origin: *');
 
// Allgemeine logArray Funktion, die JSON-Strings automatisch dekodiert und rekursiv loggt
function logArray($label, $data, $lineNumber) {
    // Wenn der Wert ein Array oder Objekt ist, rekursiv durchlaufen
    if (is_array($data) || is_object($data)) {
        foreach ($data as $key => $value) {
            if (is_array($value) || is_object($value)) {
                logline($label . " -> " . $key, "[Array/Object]", $lineNumber);
                logArray($label . " -> " . $key, (array)$value, $lineNumber);
            } elseif (is_string($value)) {
                // Überprüfen, ob der String JSON-codiert ist
                $decodedValue = json_decode($value, true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    logline($label . " -> " . $key, "[Decoded JSON]", $lineNumber);
                    logArray($label . " -> " . $key, $decodedValue, $lineNumber); // Rekursiv dekodierte Struktur loggen
                } else {
                    logline($label . " -> " . $key, $value, $lineNumber);
                }
            } else {
                logline($label . " -> " . $key, $value, $lineNumber);
            }
        }
    } else {
        // Wenn kein Array/Objekt, direkt den Wert loggen
        logline($label, $data, $lineNumber);
    }
}

$timestamp = date('Y-m-d H:i:s');
logline("Start", $timestamp, __LINE__);

// Read the raw POST data (JSON)
$inputData = json_decode(file_get_contents('php://input'), true);

logline("Received data", json_encode($inputData), __LINE__);


// Log each key-value pair in $inputData
logArray("stored tokens", $inputData, __LINE__);



 


Here you see the log from WebServer (Endpoint)

Image
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby Otto » Mon Oct 28, 2024 9:45 pm

Next step:

I am extending the Harbour code to store the billing address in a hash (hAddress).

To transmit this hash’s data to the endpoint in JavaScript, the hash is first converted into a JSON string with hb_jsonEncode(hAddress) and stored as cJSONAddress.

This encoded string is then added to the JavaScript object containing the billing data:

javascript
Code: Select all  Expand view
function sendData() {
    const invoiceData = {
        customer: cCustomer,
        invoiceNumber: cInvoiceNumber,
        total: cTotal,
        cJSONAddress: cJSONAddress,
        cJSON: cJSON
    };
}



This JavaScript is then sent to the endpoint using the fetch method.
The object `invoiceData` is converted into a JSON string with `JSON.stringify(invoiceData)` and included in the body of the HTTP request.
Image

Image

Image
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby Otto » Thu Oct 31, 2024 7:37 am

Hello friends,

the system is working well.
If anyone is interested in the source code, please let me know.

Best regards,
Otto

Image
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm

Re: Preview of the invoice in advance

Postby Ruth » Thu Oct 31, 2024 10:30 am

Dear Otto,

I would be interested in the code. Thank you for all the details.
Right now, I’m trying to understand a few parts of the carousel mechanism, specifically sendData() and checkFileExists().

Code: Select all  Expand view
// JavaScript zur Datenübertragung
    cText += '<script>' + CRLF
    cText += 'function sendData() {' + CRLF
    cText += '    const invoiceData = {' + CRLF
    cText += '        customer: "' + cCustomer + '",' + CRLF
    cText += '        invoiceNumber: "' + cInvoiceNumber + '",' + CRLF
    cText += '        total: "' + cTotal + '",' + CRLF
   
    cText += "        cJSON: '" + cJSON + "'," + CRLF
   
    cText += '        description: "' + cCargoTest + '"' + CRLF
    cText += '    };' + CRLF
    cText += '    fetch("https://test.com/previewrechnung/submitInvoice.php", {' + CRLF
    cText += '        method: "POST",' + CRLF
    cText += '        headers: {' + CRLF
    cText += '            "Content-Type": "application/json"' + CRLF
    cText += '        },' + CRLF
    cText += '        body: JSON.stringify(invoiceData)' + CRLF
    cText += '    }).then(response => response.json())' + CRLF
    cText += '      .then(data => console.log("Response:", data))' + CRLF
    cText += '      .catch(error => console.error("Error sending invoice:", error));' + CRLF
    cText += '}' + CRLF



Code: Select all  Expand view
 cText += 'function checkFileExists() {' + CRLF
    cText += '   fetch("https://test.com/previewrechnung/check_response.php")' + CRLF
    cText += '       .then(response => response.json())' + CRLF
    cText += '       .then(data => {' + CRLF
    cText += '           if (data.exists) {' + CRLF
    cText += '               clearInterval(fileCheckInterval);' + CRLF
    cText += '               var downloadButton = document.getElementById("downloadButton");' + CRLF
    cText += '               downloadButton.disabled = false;' + CRLF
    cText += '               downloadButton.textContent = "Download starten";' + CRLF
    cText += '           }' + CRLF
    cText += '       })' + CRLF
    cText += '       .catch(error => console.error("Error checking file existence:", error));' + CRLF
    cText += '}' + CRLF


I was wondering why both sendData() and checkFileExists() are needed. Please give me some more context for this.
From just glimpsing at it I thought maybe one could also use the promise of sendData for checking?

Thank you again for all the support and explanations and kind regards to all :-)
Ruth

PS: would it be possible to use some other syntax instead of cText += .... for the multiline?
User avatar
Ruth
 
Posts: 169
Joined: Fri Dec 07, 2007 1:26 pm

Re: Preview of the invoice in advance

Postby Otto » Thu Oct 31, 2024 11:18 am

Dear Ruth,

We generate an HTML page with Fivewin, which we then call using waitrun().

The functions for sending the data are all embedded in this HTML.
There is an event handler, window.onload, to automatically call sendData when the HTML document is fully loaded.

The data is sent via the local web browser to the endpoint using fetch.

In the HTML, we also have an interval that queries the endpoint check_response.php, and as soon as the guest (client) approves the invoice online—this creates the response file on the server—the "Download" button in the local web browser is activated.

In the FIVEWIN application, there is a TIMER() that checks if the file has been downloaded.
If so, FIVEWIN closes the local instance of the web browser.

That's why I called it merry-go-round. It goes in a circle.

But the most important thing is that we don’t have to configure any firewall settings.

I’ve sent you the download link.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6332
Joined: Fri Oct 07, 2005 7:07 pm


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 40 guests