Where have I gone wrong

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

Re: Where have I gone wrong

Post by grindstone »

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: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where have I gone wrong

Post by badidea »

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: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

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: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

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: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where have I gone wrong

Post by badidea »

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: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

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: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

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: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

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: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

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: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

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: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

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: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Where have I gone wrong

Post by grindstone »

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: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Where have I gone wrong

Post by counting_pine »

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: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where have I gone wrong

Post by Gablea »

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: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Where have I gone wrong

Post by counting_pine »

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.
Post Reply