Where have I gone wrong
Re: Where have I gone wrong
@grindstone
Hi,
the tills and server run on either 10MB or 100MB network (depending on the switch that is in place)
I have been thinking about using a function that copy data from the Server (to for example c:\PoS\Data) and if the PoS can not see the shared drive on the windows Machine (or linux at some point) it will switch to local data files (and display a little icon showing no network)
I have some code from this forum that shows me how I can read the last updated date and time and i was going to use that to see what files are needed to be copied down to the local data folder at the end of each sale (as well as sending data to the Back office system)
I'm still trying to work out how I could make a universal function that would work will all the data files that my systems uses they are listed below
Age Refual File
Credit Note
Discount File
Gurantee File
Lottery File
Multivsaer File
Man Dept
No Sale Reason
PLU Menu
PLU List
Payout Reason
Product Libary
Product File - Code has been given but trying to get it to work with a universal interface for all files
Product Messages
Refund Reasons
Scanning Coupons
Cashier Database - Code has been given but trying to get it to work with a universal interface for all files
VAT Codes
As you can see it would be so much easier if I have a way of reading the files in with out having to create 100's of unique functions for each file.
I know It would be easier if I droped my DOS support but I just can not do that at the moment while I can get machines from NCR for less then $200 each and I can sell them with full software etc for $900+ (I do use FreeDOS on my Tills)
Hi,
the tills and server run on either 10MB or 100MB network (depending on the switch that is in place)
I have been thinking about using a function that copy data from the Server (to for example c:\PoS\Data) and if the PoS can not see the shared drive on the windows Machine (or linux at some point) it will switch to local data files (and display a little icon showing no network)
I have some code from this forum that shows me how I can read the last updated date and time and i was going to use that to see what files are needed to be copied down to the local data folder at the end of each sale (as well as sending data to the Back office system)
I'm still trying to work out how I could make a universal function that would work will all the data files that my systems uses they are listed below
Age Refual File
Credit Note
Discount File
Gurantee File
Lottery File
Multivsaer File
Man Dept
No Sale Reason
PLU Menu
PLU List
Payout Reason
Product Libary
Product File - Code has been given but trying to get it to work with a universal interface for all files
Product Messages
Refund Reasons
Scanning Coupons
Cashier Database - Code has been given but trying to get it to work with a universal interface for all files
VAT Codes
As you can see it would be so much easier if I have a way of reading the files in with out having to create 100's of unique functions for each file.
I know It would be easier if I droped my DOS support but I just can not do that at the moment while I can get machines from NCR for less then $200 each and I can sell them with full software etc for $900+ (I do use FreeDOS on my Tills)
Re: Where have I gone wrong
Some of my thoughts:
A) Even if you can can connect from a msdos / freedos client to a mysql server, a significant change to the code is needed I think. mysql is normally not used for files but for individual records or values base on some query. Clear interfaces need to be define. The last time I looked at your code, it did not seem very well structured. Going from a bunch of files to a real database could be a lot of work.
B) An alternative to mysql could be your own client - server implementation via TCP/IP. This is doable, but some work. And the points mentioned at (A) are apply to this as well. So even more work.
C) A whole till could probably run on a Raspberry Pi with linux, which costs probably less then your msdos hardware. Then connecting to mysql is probably easier, but still the work required mentioned at (A).
There are probably work-arounds possible with the current local and centralised data files. Lock file access for a certain time to synchronise everything. Work with mutation files maybe. The locking mechanism / messaging could even be via a certain shared file. But in the end, such a system will likely give problems and probably difficult to maintain. The nice thing with using a real database, is that other tools can be used on this database. A web-interface or your own tool for analysis or accounting.
Do you have any experience with setting up a mysql database and with doing mysql queries?
A) Even if you can can connect from a msdos / freedos client to a mysql server, a significant change to the code is needed I think. mysql is normally not used for files but for individual records or values base on some query. Clear interfaces need to be define. The last time I looked at your code, it did not seem very well structured. Going from a bunch of files to a real database could be a lot of work.
B) An alternative to mysql could be your own client - server implementation via TCP/IP. This is doable, but some work. And the points mentioned at (A) are apply to this as well. So even more work.
C) A whole till could probably run on a Raspberry Pi with linux, which costs probably less then your msdos hardware. Then connecting to mysql is probably easier, but still the work required mentioned at (A).
There are probably work-arounds possible with the current local and centralised data files. Lock file access for a certain time to synchronise everything. Work with mutation files maybe. The locking mechanism / messaging could even be via a certain shared file. But in the end, such a system will likely give problems and probably difficult to maintain. The nice thing with using a real database, is that other tools can be used on this database. A web-interface or your own tool for analysis or accounting.
Do you have any experience with setting up a mysql database and with doing mysql queries?
Re: Where have I gone wrong
I start wondering if it wasn't sufficient to simply translate the csv into a two-dimensional string array. Ultra-fast and convenient.
Re: Where have I gone wrong
@badidea
Yes I use MySQL all the time with in the Visual Basic.net version of my EPoS systems.
I have managed to get Linux installed on the tills and yes I did even manage to get it to recall some data from a MySQL server. But I never seem to get it to recall the correct data (always seemed to bring back the previous sql query)
I know if I did move to MySQL interface for my till clents a lot of re working would be needed on the till source code and I’m not afraid to do that.
Yes I use MySQL all the time with in the Visual Basic.net version of my EPoS systems.
I have managed to get Linux installed on the tills and yes I did even manage to get it to recall some data from a MySQL server. But I never seem to get it to recall the correct data (always seemed to bring back the previous sql query)
I know if I did move to MySQL interface for my till clents a lot of re working would be needed on the till source code and I’m not afraid to do that.
Could you explain more? If you require examples of the csv data files I can upload them to my web server.jj2007 wrote:I start wondering if it wasn't sufficient to simply translate the csv into a two-dimensional string array. Ultra-fast and convenient.
Re: Where have I gone wrong
Yes, that would be a good idea.Gablea wrote:Could you explain more? If you require examples of the csv data files I can upload them to my web server.
-
- Posts: 862
- Joined: May 05, 2015 5:35
- Location: Germany
Re: Where have I gone wrong
I didn't expect such a big amount of different data files. So here's a "one for all"-data access type:
Code: Select all
Type tRecord
As ZString*40 recordName
As Integer recordLength
As ZString*2 returnType
End Type
' return type-----------------------------------|
' field length------------------------------| |
' field name---------------| | |
Dim Shared As tRecord userTable(1 To ...) = {Type <tRecord>("CashierPassword", 4, "s") _
, Type <tRecord>("CashierName", 255, "s") _
, Type <tRecord>("CashierNameReceipit", 40, "s") _
, Type <tRecord>("ChangePassword", 1, "s") _
, Type <tRecord>("RestrictRefund", 1, "s") _
, Type <tRecord>("RestrictRefundValue", 10, "s") _
, Type <tRecord>("UserCanOverrideLockout", 1, "s") _
, Type <tRecord>("useraccesslevel", 255, "s") _
, Type <tRecord>("DUMMY", 4, "s") _
}
Dim Shared As tRecord productTable(1 To ...) = {Type <tRecord>("BarcodeNumber", 13, "s") _
, Type <tRecord>("posdescription", 30, "s") _
, Type <tRecord>("salelocation", 4, "s") _
, Type <tRecord>("agerestricted", 4, "i") _
, Type <tRecord>("agelimit", 2, "s") _
, Type <tRecord>("pricetype", 1, "s") _
, Type <tRecord>("retailprice", 10, "s") _
, Type <tRecord>("vatcode", 1, "s") _
, Type <tRecord>("vprint_guarantee_message", 4, "i") _
, Type <tRecord>("print_guarantee_code", 6, "s") _
, Type <tRecord>("displaymessage", 4, "i") _
, Type <tRecord>("messagenumber", 6, "s") _
, Type <tRecord>("sendtoppr", 4, "i") _
, Type <tRecord>("requestserial", 4, "i") _
, Type <tRecord>("itemnotallowed", 4, "i") _
, Type <tRecord>("itemnotallowed_reason", 255, "s") _
, Type <tRecord>("restrict_product_qty", 4, "i") _
, Type <tRecord>("product_qty_allowed", 4, "i") _
, Type <tRecord>("discount_not_allowed", 4, "i") _
, Type <tRecord>("no_refund_allowed", 4, "i") _
, Type <tRecord>("ask_for_qty_before_selling", 4, "i") _
, Type <tRecord>("healthy_start_voucher_ok", 4, "i") _
}
Type tDataAccess
Dim record As String
Dim As tRecord Ptr table
Dim As Integer tableSize
Declare Function dataRead(fieldName As String) As String
Declare Function dataRead(fieldName As String, fieldType As String) As Integer
Declare Sub dataWrite(fieldName As String, value As String)
Declare Sub dataWrite(fieldName As String, value As Integer)
Declare Function getReclength() As Integer
Declare Sub init(dataFile As String, extTable() As tRecord, thisArray() As tDataAccess)
Declare Sub save(dataFile As String, thisArray() As tDataAccess)
End Type
Sub tDataAccess.init(dataFile As String, extTable() As tRecord, thisArray() As tDataAccess)
Dim As Integer ff, recLen, count
this.table = @extTable(1) 'pointer to field table
this.tableSize = UBound(extTable) 'size of field table
recLen = getReclength()
ff = FreeFile
Open datafile For Binary Access Read As #ff
count = 0
Do Until Eof(ff)
count += 1
ReDim Preserve thisArray(count)
thisArray(count) = thisArray(0) 'copy field table pointer and -size
thisArray(count).record = Input(recLen, #ff) 'read one record from data file
Loop
Close
End Sub
Sub tDataAccess.save(dataFile As String, thisArray() As tDataAccess)
Dim As Integer ff
ff = FreeFile
Open dataFile For Output As #ff
For x As Integer = 1 To UBound(thisArray)
Print #ff, thisArray(x).record;
Next
End Sub
Function tDataAccess.DataRead(fieldName As String) As String
Dim As Integer x, start = 1
If this.table = 0 Then Return "" 'no field table defined
For x = 0 To this.tableSize - 1 'find requested field
If LCase(fieldName) = LCase((this.table + x)->recordName) Then
Exit For
EndIf
start += (this.table + x)->recordLength
Next
If x > tableSize Then 'record name not found
Return ""
ElseIf (this.table + x)->returnType <> "s" Then
Return ""
Else
Return Mid(this.record, start, (this.table + x)->recordLength)
EndIf
End Function
Function tDataAccess.dataRead(fieldName As String, fieldType As String) As Integer
Dim As Integer x, start = 1
If this.table = 0 Then Return 0 'no field table defined
For x = 0 To this.tableSize - 1 'find requested field
If LCase(fieldName) = LCase((this.table + x)->recordName) Then
Exit For
EndIf
start += (this.table + x)->recordLength
Next
If x > tableSize Then 'record name not found
Return 0
ElseIf (this.table + x)->returnType <> "i" Then
Return 0
Else
Return Val(Mid(this.record, start, 4))
EndIf
End Function
Sub tDataAccess.dataWrite(fieldName As String, value As String)
Dim As Integer x, start = 1
If this.table = 0 Then Return 'no field table defined
For x = 0 To this.tableSize - 1 'find requested field
If LCase(fieldName) = LCase((this.table + x)->recordName) Then
Exit For
EndIf
start += (this.table + x)->recordLength
Next
If x > tablesize Then 'field not found
Return
ElseIf (this.table + x)->returnType <> "s" Then
Return
EndIf
Mid(this.record, start, (this.table + x)->recordLength) = _
Left(value + Space((this.table + x)->recordLength), (this.table + x)->recordLength)
End Sub
Sub tDataAccess.dataWrite(fieldName As String, value As Integer)
Dim As Integer x, start = 1
If this.table = 0 Then Return 'no field table defined
For x = 0 To this.tableSize - 1 'find requested field
If LCase(fieldName) = LCase((this.table + x)->recordName) Then
Exit For
EndIf
start += (this.table + x)->recordLength
Next
If x > tablesize Then 'field not found
Return
ElseIf (this.table + x)->returnType <> "i" Then
Return
EndIf
Mid(this.record, start, 4) = Right(String(4, Chr(0)) + Str(value), 4)
End Sub
Function tDataAccess.getReclength() As Integer
Dim As Integer reclen
Dim As tRecord Ptr rp = table
For x As Integer = 0 To tableSize - 1
reclen += (table + x)->recordLength
Next
Return reclen
End Function
ReDim As tDataAccess user(0), product(0)
'setup array
user(0).init("users.dat", userTable(), user())
' | | |_______"users" record array
' | |_________________field table for "users"
' |_____________________________"users" data file
product(0).init("products.dat", productTable(), product())
'list of all user records
For x As Integer = 1 To UBound(user)
With user(x)
Print " CashierPassword ";.dataRead("CashierPassword")
Print " CashierName ";.dataRead("CashierName")
Print " CashierNameReceipit ";.dataRead("CashierNameReceipit")
Print " ChangePassword ";.dataRead("ChangePassword")
Print " RestrictRefund ";.dataRead("RestrictRefund")
Print " RestrictRefundValue ";.dataRead("RestrictRefundValue")
Print " UserCanOverrideLockout ";.dataRead("UserCanOverrideLockout")
Print " useraccesslevel ";.dataRead("useraccesslevel")
Print "---------------------------------------------"
Sleep
End With
Next
'list of all product records
For x As Integer = 1 To UBound(product)
With product(x)
Print " BarcodeNumber ";.dataRead("BarcodeNumber")
Print " posdescription ";.dataRead("posdescription")
Print " salelocation ";.dataRead("salelocation")
Print " agerestricted ";.dataRead("agerestricted", "i")
Print " agelimit ";.dataRead("agelimit")
Print " pricetype ";.dataRead("pricetype")
Print " retailprice ";.dataRead("retailprice")
Print " vatcode ";.dataRead("vatcode")
Print " vprint_guarantee_message ";.dataRead("vprint_guarantee_message", "i")
Print " print_guarantee_code ";.dataRead("print_guarantee_code")
Print " displaymessage ";.dataRead("displaymessage", "i")
Print " messagenumber ";.dataRead("messagenumber")
Print " sendtoppr ";.dataRead("sendtoppr", "i")
Print " requestserial ";.dataRead("requestserial", "i")
Print " itemnotallowed ";.dataRead("itemnotallowed", "i")
Print " itemnotallowed_reason ";.dataRead("itemnotallowed_reason")
Print " restrict_product_qty ";.dataRead("restrict_product_qty", "i")
Print " product_qty_allowed ";.dataRead("product_qty_allowed", "i")
Print " discount_not_allowed ";.dataRead("discount_not_allowed", "i")
Print " no_refund_allowed ";.dataRead("no_refund_allowed", "i")
Print "ask_for_qty_before_selling ";.dataRead("ask_for_qty_before_selling", "i")
Print " healthy_start_voucher_ok ";.dataRead("healthy_start_voucher_ok", "i")
Print "---------------------------------------------"
Sleep
End With
Next
'example for writing to array
product(1).datawrite("BarcodeNumber", "0123450")
product(1).datawrite("posdescription", "WODKA")
With product(1)
Print " BarcodeNumber ";.dataRead("BarcodeNumber")
Print " posdescription ";.dataRead("posdescription")
Print " salelocation ";.dataRead("salelocation")
Print " agerestricted ";.dataRead("agerestricted", "i")
Print " agelimit ";.dataRead("agelimit")
Print " pricetype ";.dataRead("pricetype")
Print " retailprice ";.dataRead("retailprice")
Print " vatcode ";.dataRead("vatcode")
Print " vprint_guarantee_message ";.dataRead("vprint_guarantee_message", "i")
Print " print_guarantee_code ";.dataRead("print_guarantee_code")
Print " displaymessage ";.dataRead("displaymessage", "i")
Print " messagenumber ";.dataRead("messagenumber")
Print " sendtoppr ";.dataRead("sendtoppr", "i")
Print " requestserial ";.dataRead("requestserial", "i")
Print " itemnotallowed ";.dataRead("itemnotallowed", "i")
Print " itemnotallowed_reason ";.dataRead("itemnotallowed_reason")
Print " restrict_product_qty ";.dataRead("restrict_product_qty", "i")
Print " product_qty_allowed ";.dataRead("product_qty_allowed", "i")
Print " discount_not_allowed ";.dataRead("discount_not_allowed", "i")
Print " no_refund_allowed ";.dataRead("no_refund_allowed", "i")
Print "ask_for_qty_before_selling ";.dataRead("ask_for_qty_before_selling", "i")
Print " healthy_start_voucher_ok ";.dataRead("healthy_start_voucher_ok", "i")
Print "---------------------------------------------"
Sleep
End With
'saving arrays to file
user(0).save("usersSave2.dat", user())
' | |______record array
' |_______________________file name to save to
product(0).save("productsSave2.dat", product())
? "OK"
Sleep
Re: Where have I gone wrong
Nice work.
But bloody heck, I have just noticed why my save was not working properly as first, I had forgot to put the semi colon behind print #1, ...
Thus I gathered up everything in a string and saved the string.
silly silly.
But bloody heck, I have just noticed why my save was not working properly as first, I had forgot to put the semi colon behind print #1, ...
Thus I gathered up everything in a string and saved the string.
silly silly.
-
- Posts: 862
- Joined: May 05, 2015 5:35
- Location: Germany
Re: Where have I gone wrong
Console yourself, I first forgot it, too. That's what test runs are good for. <grin>dodicat wrote:I had forgot to put the semi colon behind print #1, ...
BTW: I'd like to avoid the fieldType parameter in the dataRead(fieldName As String, fieldType As String) As Integer function. Is there a way to let the function dataRead(fieldName As String) return either a String or an Integer, according to the entry in the tRecord table ("s" or "i")? Overload doesn't work.
Re: Where have I gone wrong
I was just reading your previous topics on MySQL & MS-DOS with the conclusion that mysql-client on msdos close to impossible.Gablea wrote:Yes I use MySQL all the time with in the Visual Basic.net version of my EPoS systems.
But, thinking out loud, what if you run a LAMP stack (Linux Apache MySQL PHP), and interface via web request / reply? Where PHP on the server does the MySQL calls. It maybe a bit crazy idea, but it could be done if MS-DOS can do web-requests. Or do I miss something?
Sounds like a problem that should be solvable.Gablea wrote:I have managed to get Linux installed on the tills and yes I did even manage to get it to recall some data from a MySQL server. But I never seem to get it to recall the correct data (always seemed to bring back the previous sql query)
Re: Where have I gone wrong
@badidea
if I can find the old mySQL version of the PoS would you like me to post a sample of the code I am using?
I have acually found the project i was working on when I thought moving the PoS to the text files would be a good idea
http://www.algpos.co.uk/freebasic/MySQL_PoS.bas
if I can find the old mySQL version of the PoS would you like me to post a sample of the code I am using?
I have acually found the project i was working on when I thought moving the PoS to the text files would be a good idea
http://www.algpos.co.uk/freebasic/MySQL_PoS.bas
Last edited by Gablea on Sep 24, 2018 21:40, edited 1 time in total.
Re: Where have I gone wrong
Yes, why not. I am certainly not an MySQL expert, but I have played with it in the past.Gablea wrote:@badidea
if I can find the old mySQL version of the PoS would you like me to post a sample of the code I am using?
I plan the set-up a MySQL server anyway for other reasons (mediawiki installation).
Re: Where have I gone wrong
I have also uploaded to the server a data dump of one of my Databases
http://www.algpos.co.uk/freebasic/SparePoSDataFile.sql
i hope this can help if I can move to live MySQL interface and have it working then I would dump the DOS version as a TUI version of Linux would run with no sweat on a 600MHz with 512MB RAM (Plus the hard drive is like 60GB the only thing I would need to work out at some point of offline support)
http://www.algpos.co.uk/freebasic/SparePoSDataFile.sql
i hope this can help if I can move to live MySQL interface and have it working then I would dump the DOS version as a TUI version of Linux would run with no sweat on a 600MHz with 512MB RAM (Plus the hard drive is like 60GB the only thing I would need to work out at some point of offline support)
Re: Where have I gone wrong
@Paul Doe:
I have had a chance to examine your code. Its slick. Very nice.
I have had a chance to examine your code. Its slick. Very nice.
Re: Where have I gone wrong
I note positions 0,2 and 6 all have length 4 but are strings.(Both tables)grindstone wrote:Console yourself, I first forgot it, too. That's what test runs are good for. <grin>dodicat wrote:I had forgot to put the semi colon behind print #1, ...
BTW: I'd like to avoid the fieldType parameter in the dataRead(fieldName As String, fieldType As String) As Integer function. Is there a way to let the function dataRead(fieldName As String) return either a String or an Integer, according to the entry in the tRecord table ("s" or "i")? Overload doesn't work.
something like
if (this.table + x)->recordLength=4 and x<>0 and x<>2 and x<>6 then (it is an integer)
Re: Where have I gone wrong
Doesn't look like a csv file. MySQL can't export csv?Gablea wrote:I have also uploaded to the server a data dump of one of my Databases
http://www.algpos.co.uk/freebasic/SparePoSDataFile.sql
jj2007 wrote:Yes, that would be a good idea.Gablea wrote:Could you explain more? If you require examples of the csv data files I can upload them to my web server.