Where have I gone wrong

General FreeBASIC programming questions.
grindstone
Posts: 650
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Postby grindstone » Oct 29, 2018 19:48

So what you mean is a program that acts as an interface between the clients (tills) and the server (data base) and whose purpose it is to process things like monitoring of goods in stock, bargain offers, bulk discount, request to deliver goods, staff settlement and such stuff?

Of course this can be done with FB.
badidea
Posts: 1545
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where have I gone wrong

Postby badidea » Oct 29, 2018 20:30

Gablea wrote:I understand that but my VB.net version it uses a in memory table to control the receipt data as well as any promotions and i have almost all the code created for all the offers etc so I would like if possible to replicate the function with FreeBASIC

Maybe I misunderstand, but it sounds like a big mess to me. Why the products in a database, but other product information locally? How does that work with multiple clients?
But still, you can get the product name or product id from the database and check this against the local data for promotions and the other receipt thing. But to me, that seems to complicate things unnecessary.
grindstone
Posts: 650
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Postby grindstone » Oct 29, 2018 21:00

badidea wrote:
Gablea wrote:Why the products in a database, but other product information locally?
I agree. If that really was your intention it would be begging for trouble. And if it was the conception in the past (I know, "grown" programs tend to become chaotic over time, although they work), this here would be a good opportunity to clean it up.
Gablea
Posts: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Postby Gablea » Oct 29, 2018 21:08

The only thing that is stored is the current sale (so if a item is voided it will be removed from the list)

as Items are scanned they are added to the promo table and once the cashier press the Total key then the Local PoS app performs the promotions (ie buy one get one free etc)

if for any reason the cashier press back and scans another items the promo info is lost and re calculated.

all data is stored on the central database the only think that is local is the current sale at that point in time once the transaction is completed the PoS sends the sale information to the back office and then the PoS would clear the locally stored data table (as this is used to print the receipt if needed)

@grindstone
yes the PoS is a interface between the product table on the system as well as the cashier table and promotional data
say say for example Pepsi max is 2 for £2.00 each they cost £1.50 so until the Total key has been pressed the Till will show a balance due of £3.00
once the Total key is pressed the till would use the in memory table to do the calculations it need to work out to take £1 off for savings and then the cashier would see the total show as £2.00

The receipt would look a little like this

Pepsi Max
2 @ £1.50 £3.00

SUB TOTAL £3.00
==============================
Pepsi max offer 1 £1.00
TOTAL SAVED £1.00
==============================
TOTAL TO PAY £2.00
CASH £2.00
Change £0.00

and grindstone as I am starting a new with the program (figuring out MySQL interface) I thought it would be a ideal time to use better and cleaner programming styles as well as up to date coding practise (hence why I have been asking for advice with MySQL)

In VB.net my PoS application is running perfectly using the MySQL Central database (just have to work out offline support you know in case someone unplugs the server) but the machines I normally supply can not handles Windows 7 (even with RAM upgrade etc) so the FreeBASIC version will be at some point in its life the straight replacement for the VB System (and then I can drop windows from my Front of house systems)
badidea
Posts: 1545
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where have I gone wrong

Postby badidea » Oct 29, 2018 21:21

Ah, the art of making the customer think he/she saved money while they walk out of the store with less money :-)

I understand now. A local list of items currently being sold. Apply all changes to the database once the money is paid. Should not be to hard, but there are always annoying details.
Gablea
Posts: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Postby Gablea » Oct 29, 2018 21:39

lol yea I know what you mean but I have most of the code working in the VB version so it would not be hard to convert once I get the link working with MySQL
grindstone
Posts: 650
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Postby grindstone » Oct 30, 2018 7:03

Gablea wrote:just have to work out offline support you know in case someone unplugs the server
So you're thinking about implementing a mirror server on every till?
Gablea
Posts: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Postby Gablea » Oct 30, 2018 10:14

Most EPoS systems I have seen do have a offline mode

But maybe I should get the system working first before I start to add new functions (unless I can get it to keep the local data in sync with the main database server)
grindstone
Posts: 650
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Postby grindstone » Oct 31, 2018 7:00

Gablea wrote:Most EPoS systems I have seen do have a offline mode
Then it probably would be a better conception to let every till work with its own (copy of the) database while in the background all the databases are permanently synchronized. For this purpose there could be added a timestamp to every table entry (row), so the currently newest entry is valid.
Gablea
Posts: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Postby Gablea » Oct 31, 2018 7:09

That sounds like a good idea and then use a small app that runs in the background to do the syncing

I will look into this once I can get the cashier sign on to work.

It shows the server information and then does nothing.
Gablea
Posts: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Postby Gablea » Nov 01, 2018 20:53

I have found the problem


on my code i was using Dim PasswordChange As Integer = *row[4] but it was returning the value of 48. so I used the Val() Function and it works fine now

This is my new code

Code: Select all

Dim SQLQuery       As String
Dim db             As MYSQL Ptr
Dim res             As Integer

Dim restab          As mysql_res Ptr
Dim row             As mysql_row
      
SQLQuery = ""
SQLQuery += "select "
SQLQuery += "userid, "                        '0
SQLQuery += "userpassword, "                  '1
SQLQuery += "username, "                     '2
SQLQuery += "usernameposrecipit, "            '3
SQLQuery += "changepassword, "               '4
SQLQuery += "useraccesslevel "               '5
SQLQuery += "from usertable "
SQLQuery += "where userid='" & CashierNumberLocal & "' and userpassword='"  & CashierPasswordLocal & "';"

 'Initialize the API. db points to the MySQL system.
 db = mysql_init(NULL)

 'Connect to the MySQL system.
IF( mysql_real_connect( db, ServerAddress, ServerUserName, ServerUserPassword, ServerDatabaseName, ServerDatabasePort, NULL, 0 ) = 0 ) THEN
    PRINT "Can't connect to the mysql server on port"; MYSQL_PORT
    mysql_close( db )
    Sleep
    End 1
Else
    PRINT "Connected to the mysql server on port"; MYSQL_PORT       
END IF

    'Select a data base.
If (mysql_select_db( db, ServerDatabaseName)) Then
   Print "Can't select the "; ServerDatabaseName; " database !"
   mysql_close(db)
   Sleep
   End 1
Else
   Print "Selected the "; ServerDatabaseName; " database !"
End If

    'Print informations about the RDBMS host and the data base.
    PRINT "Client info : "; *mysql_get_client_info()
    PRINT "  Host info : "; *mysql_get_host_info(db)
    PRINT "Server info : "; *mysql_get_server_info(db)


    'Submit a SQL query.
    res = mysql_query(db, SQLQuery)

    'Declare a pointer to the result table
   restab = mysql_store_result(db)

   IF res = 0 Then
      Print res
      
       If mysql_num_rows(restab) > 0 Then
          Print mysql_num_rows(restab)
          row = mysql_fetch_row(restab)
          
          Print *ROW[0]
          Print *ROW[1]
          Print *ROW[2]
          Print *ROW[3]
          Print *ROW[4]
          Print *ROW[5]
          
                   
         Dim PasswordChange As Integer = Val(*row[4])

          Print "Password Change : "; PasswordChange
          
          Select Case PasswordChange
             Case 0 'No Change required
                         KeyPadInput = ""
                    CashierNamePrint = Trim(*row[3])
                         CashierAccess = Trim(*row[5])    'Set the system to use the signed on cashier
               CashierOverrideAccess = 0
                  PriceOverridePrice = 0                                 'Clears the Entered Price
                             TotalDue = 0                                  'Resets sale value
                            ItemsSold = 0                                  'Resets item count
                       TotalTendered = 0                                 'Resert the total tendered value
                         RecipitClear = 1                                 'Set the recipit so a new one can be produced for sale
                             SaleMode = "Sale"                           'Sets the salemode back to sale
                   'RecallInProgress = "No"                              'Resets the Recall trigger so the system will run in normal mode
                      ShowTaskBarItems = 1
                     SubTotalPressed = 0
                        DisplayLine1 = ""
                        DisplayLine2 = ""      
                        
                   'Close the API access.
               mysql_close(db)
               Salescreen          
             
             Case 1   ' Password needs to be changed
               mysql_close(db)
                   updateCashierScreen(CashierDisplayComSettings, "PASSWORD EXPIRED", 0, "PRESS CLEAR TO CHANGE" & KeyPadInPutPassword, 1, 0)
                  'PasswordChange1
          End Select
       Else
          updateCashierScreen(CashierDisplayComSettings, "USER OR PASSWORD", 0, "NOT FOUND. PRESS CLEAR" & KeyPadInPutPassword, 1, 0)
            Do : Dim KeyPress As Long = GetKeyNB
               Select Case KeyPress
                  Case Key_Clear
                     KeyPadInput = ""
                     RequestCashierID
                     Exit Sub
               End Select
            Loop
       End If
   End If



Now I just need to start to add support for the Product scanning etc :)

Thank you so much to everyone who has help with this.
grindstone
Posts: 650
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Postby grindstone » Nov 02, 2018 6:51

So why didn't the compiler throw an error or at least a "different pointer types" or "implicit conversion" warning, because *row[x] is a ZString*4 Ptr, not an integer?
counting_pine
Site Admin
Posts: 6172
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Where have I gone wrong

Postby counting_pine » Nov 02, 2018 10:31

It looks like FB is treating a deref+assign to int on a zstring ptr, the same way it would a ubyte ptr.

Code: Select all

dim i as integer, pz as zstring ptr, pb as ubyte ptr
pz = @"Hi": pb = pz

i = *pb: print i, *pb
i = *pz: print i, asc(*pz)
I suspect the underlying problem is that a zstring ptr is basically a magic ubyte ptr. If you dereference it, you usually get a zstring, which is *also* basically a magic ubyte ptr. But different kinds of magic...

But I thought we fixed this bug, or a similar one, some time ago...

Incidentally, I cannot parse '*row[4]' in my head. It either works out as (*row)[4] = row[0][4] or *(row[4]) = row[4][0], which are very different, and I cannot intuit which one would be more sensible. I have a slight preference for the first one, but not enough to be confident.
Gablea
Posts: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Postby Gablea » Nov 02, 2018 10:32

I have no idea. But lucky I found it so at least I know if I use the val() command it will work.


Now have to ask what is quicker

Select case or if else end if?
counting_pine
Site Admin
Posts: 6172
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Where have I gone wrong

Postby counting_pine » Nov 02, 2018 10:56

I've made a bug report at https://github.com/freebasic/fbc/issues/111 .

valint() is usually better to use than val() when you want an Integer result, so there are no intermediate floating-point values.

Gablea wrote:Now have to ask what is quicker

Select case or if else end if?
You should find the GCC backend can optimise them the same way. (Not Select Case As Const though, that's done differently.)
But if it's not in a performance-critical inner loop, just use whichever's clearer. Otherwise you'll probably waste more "brain cycles" on understanding the code, than you would ever save in CPU cycles.

Return to “General”

Who is online

Users browsing this forum: No registered users and 15 guests