|
What happens if, during the KDS operation you realise it needs some more POS, do you send it back to the POS? You are REALLY going to have to look at your workflow carefully.
Personally I'd go with the polling a table solution, it being the simplest and probably the most robust.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Hi Mycroft,
Upon submission of data by the POS to the KDS, it cannot send back to POS. Just like those being used in fastfood chains, when you've already paid for your meal, you cannot make any changes, not unless you make a new transaction. Polling a table is another option. Is this what you mean: POS enters data to database, then the KDS queries the database for new entries every specified interval? isnt this cpu intensive? thanks! - Carlos
|
|
|
|
|
Member 8605543 wrote: when you've already paid for your meal,
Even more of a reason to put this stuff in the database without going to the RDS machine. Once you take customer money, losing their order is very unacceptable.
Member 8605543 wrote: isnt this cpu intensive?
You're making a small database query every 10 seconds, so no, it's not.
|
|
|
|
|
Thanks Dave! Ill do a research on how to poll a database every specified intervals. what would be an acceptable interval rate for this kind of application(fastfood)? 3 seconds?
I got your point. Indeed I would have to put it in a database so when the network is down, or KDS is unavailable, It can still fetch data as soon as it goes back.
|
|
|
|
|
I would have thought that 10 seconds would be fast enough.
|
|
|
|
|
Member 8605543 wrote: Just like those being used in fastfood chains, when you've already paid for your
meal, you cannot make any changes, not unless you make a new transaction
Not sure about fast food itself but in other types of restaurants you can adjust orders on the POS.
Member 8605543 wrote: isnt this cpu intensive?
Not as long as you put a small delay in it. Small is like a second.
|
|
|
|
|
I'm going to disagree with almost everyone else and say that you want to do this with sockets, albeit with the central server storing information in a database for audit/recovery reasons. That's because polling is almost always an inferior solution (you're transferring, at best, the same data, and generally the same data plus a large number of empty poll requests, while having a slower response time), and not necessary in this case.
The data recovery scenarios are:
- POS down: everything has to be manual anyway, in either case
- Server down: ditto
- KDS down: this is the one you have to worry about
The server should be in primary control of the data. The POS and KDS software should both keep a socket open to it, assuming you're running on hardware that can do that (unless you have 1000 tills you should be fine; if not, you might need to use a different approach, i.e. fire-and-forget web service calls for POS->server).
When you make an order, the POS should send messages to the server: make an order, order paid for, order modified (if applicable), and allow the front desk staff to post notes to a particular order. When an order is ready (I guess this is when it's made for a fast food place) the server should, as well as writing to its local data store (which it should do with every order status update for tracking purposes), also push a message to the KDS to add an item to its queue. When the kitchen finishes with an order they should be able to select the order on the KDS and that will cause a status update message to go back to the server, which the server will then forward to the appropriate till (if you want the information there).
If the kitchen rejects an order (for example if they're out of some ingredient), that should also be sent back to the till that sent it.
Data recovery: if the server goes down, you're fairly screwed, so make sure it has a UPS and safe shutdown mechanics. If the server loses connection with the KDS, or the KDS goes down and needs rebooting, it needs a special request it can send to the server to get the full list of things which should be on its queue (i.e. all orders which were 'in progress' the last time the server knew about it).
|
|
|
|
|
BobJanova wrote: I'm going to disagree with almost everyone else and say that you want to do this
with sockets, albeit with the central server storing information in a database
for audit/recovery reasons. That's because polling is almost always an inferior
solution (you're transferring, at best, the same data, and generally the same
data plus a large number of empty poll requests, while having a slower response
time), and not necessary in this case.
However polling almost always is a sufficient design.
And it is more than sufficient in this case because the traffic is very low.
Thus there is no point in making the design more complex.
|
|
|
|
|
Polling isn't really any less complex than persistent sockets, you still have to link the same components together and send the same messages. Generally it's more complex because you also have to worry about how to send data the other way, and how to detect a dropped connection. The exception is if there is an existing HTTP service that does what you want, so the socket solution is duplicating existing code, but that's clearly not the case here.
|
|
|
|
|
BobJanova wrote: Polling isn't really any less complex than persistent sockets,
Your solution requires clients, servers and a database.
Mine requires clients and a database.
Thus it is less complex.
|
|
|
|
|
Beim erstellen des Ordners in dem Pfad: Environment.SpecialFolder.ProgramFiles
kommt es immer zu dem Fehler UnauthorizedAccessException weiß auch leider nicht wie ich es umgehen kann OS (Windows 7)
|
|
|
|
|
I'm sure English is not your native language, but it is the default language for this site.
Please, either try to find a better translation of your question to English, or find a site in your own native language, as they may be able to help you better than we can!
Google translate gives:
When you create the folder in the path: Environment.SpecialFolder.ProgramFiles
it always comes up to the error UnauthorizedAccessException do not know how I can handle it, unfortunately OS (Windows 7)
You need to have Admin privileges to access the Program files folder: There is an article here which may help. Getting Elevated Privileges on Demand using C#[^]
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Tank you very much for the quick answer. I did not know that default language on this site is english but yet
|
|
|
|
|
No problem!
Google translate works wonders...
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Try and ask questions in English.
It will allow a larger user base to answer it.
As an example, I have no idea what this question is about.
|
|
|
|
|
A non-administrative user must not write into the ProgramFiles folder (translation hint: "must not" bedeutet "darf nicht").
Create an installation package - the "System " account used by the installer can write to that folder.
In case you want to write application data used by all users, the folder should go to CommonApplicationData , and data by a specific user to LocalApplicationData .
|
|
|
|
|
i need to create chart with data from my database by select product from checkbox in listbox and between date from datetimepicker bet when click the button for generate graph value in graph show same data for every series i don't know how to fix this problem
this is my code
if (row.Cells[1].Value != null && (bool)row.Cells[1].FormattedValue)
{
String idtoselect = row.Cells[0].Value.ToString();
String str1 = idtoselect.ToString();
try
{
string sql2 = "select NAME_Product from Product where Product.ID_Product = '"+str1+"' ";
SqlCommand testcommand2 = new SqlCommand(sql2, conn);
rdr = testcommand2.ExecuteReader();
while (rdr.Read())
{
test = rdr["NAME_Product"].ToString();
}
rdr.Close();
try
{
CultureInfo ci = new CultureInfo("th-TH");
string sql = "SELECT * FROM Order1 where ID_Product = '"+str1+"' AND DATE_Order BETWEEN '" + dateTimePicker1.Value.ToString("s") + "' AND '" + dateTimePicker2.Value.ToString("s") + "' ";
da = new SqlDataAdapter(sql, conn);
ds = new DataSet();
da.Fill(ds, "Order1");
chart1.DataSource = ds.Tables["Order1"];
chart1.ChartAreas["ChartArea1"].Area3DStyle.Enable3D = true;
chart1.Series.Add(test);
chart1.Series[test].ChartArea = "ChartArea1";
chart1.Series[test].BorderWidth = 4;
chart1.Series[test].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
chart1.Series[test].YValueMembers += "QUANTITY_Order";
chart1.Series[test].XValueMember += "DATE_Order";
chart1.DataBind();
MessageBox.Show("test :" );
}
catch (Exception ex)
{
MessageBox.Show("test :" + ex);
}
}
catch
{
MessageBox.Show("exception");
}
and this my output
http://image.ohozaa.com/view/80v2q]
i'm so sorry if i type a wrong word because my english is not good
Thank you for answer
|
|
|
|
|
There are a number of "silly" things going on there which it would be worth fixing before you start looking at the meat of your problem:
String idtoselect = row.Cells[0].Value.ToString();
String str1 = idtoselect.ToString(); Why?
idtoselect is already a string, so why convert it to a string in order to load it into another string? In fact you never reference idtoselect agains, so why not just use that throughout, where the name is a bit more meaningfull than str1 ?
string sql2 = "select NAME_Product from Product where Product.ID_Product = '"+str1+"' "; Is a bad idea - do not concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Use Parametrized queries instead.
while (rdr.Read())
{
test = rdr["NAME_Product"].ToString();
} test is a string - it can only hold a single value, so why use a loop? Use
if (rdr.Read()) instead.
CultureInfo ci = new CultureInfo("th-TH"); Does nothing at all unless you actually use it in a conversion.
string sql = "SELECT * FROM Order1 where ID_Product = '"+str1+"' AND DATE_Order BETWEEN '" + dateTimePicker1.Value.ToString("s") + "' AND '" + dateTimePicker2.Value.ToString("s") + "' "; Seriously, don't concatenate strings. You have the DateTime values as DateTime. SQL understands DateTime, and does not need it to be in any particular format. Unlike strings, where it does (SQL needs ISO format yyyy-MM-dd), and you aren't providing that, you are providing the short date form of your current culture.
string sql = "SELECT * FROM Order1 where ID_Product = @ID AND DATE_Order BETWEEN @D1 AND @D2";
da = new SqlDataAdapter(sql, conn);
da.SelectCommand.Parameters.AddWithValue("@ID", idtoselect);
da.SelectCommand.Parameters.AddWithValue("@D1", dateTimePicker1.Value);
da.SelectCommand.Parameters.AddWithValue("@D2", dateTimePicker2.Value);
And you may find that if you do all that, your problem may magically disappear! I suspect it might...
BTW: Stop using the Visual Studio default names for things. dateTimePicker1 , dateTimePicker2 don't mean a whole lot - try reading the above with them called startDate and endDate instead - see how much easier it is to read?
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Thank you for your answer
i have fix my code but my problem still show i don't know what what happen
|
|
|
|
|
So what does your code look like now?
What values are you giving it?
What values are in your DB?
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
my code is
string test = "";
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[1].Value != null && (bool)row.Cells[1].FormattedValue)
{
String idtoselect = row.Cells[0].Value.ToString();
try
{
string sql2 = "select NAME_Product from Product where Product.ID_Product = '"+idtoselect+"' ";
SqlCommand testcommand2 = new SqlCommand(sql2, conn);
rdr = testcommand2.ExecuteReader();
if (rdr.Read())
{
test = rdr["NAME_Product"].ToString();
}
rdr.Close();
try
{
CultureInfo ci = new CultureInfo("th-TH");
string sql = "SELECT * FROM Order1 where ID_Product = @ID AND DATE_Order BETWEEN @D1 AND @D2";
da = new SqlDataAdapter(sql, conn);
da.SelectCommand.Parameters.AddWithValue("@ID", idtoselect);
da.SelectCommand.Parameters.AddWithValue("@D1", dateTimePicker1.Value);
da.SelectCommand.Parameters.AddWithValue("@D2", dateTimePicker2.Value);
ds = new DataSet();
da.Fill(ds, "Order1");
chart1.DataSource = ds.Tables["Order1"];
chart1.ChartAreas["ChartArea1"].Area3DStyle.Enable3D = true;
chart1.Series.Add(test);
chart1.Series[test].ChartArea = "ChartArea1";
chart1.Series[test].BorderWidth = 4;
chart1.Series[test].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
chart1.Series[test].YValueMembers += "QUANTITY_Order";
chart1.Series[test].XValueMember += "DATE_Order";
chart1.DataBind();
MessageBox.Show("test :" );
}
catch (Exception ex)
{
MessageBox.Show("test :" + ex);
}
}
catch
{
MessageBox.Show("Exception");
}
}
i want to select quantity(QUANTITY_Order) that have been sold to show on my chart
if i select only one product chart will be show with correct value but if i choose two product in my list box for compare with two product value of first product will be wrong and it copy value of second product
this's my demo interface
http://image.ohozaa.com/view/8146d
it will show all product in database to list box and datetimepicker1 for select start date to find quantity in database and datetimepicker2 for select finish date
then when i select two data in listbox and i use MessageBox.Show("test :" ); for break to show my chart
this picture will show value of first product
http://image.ohozaa.com/view/8146t
then when i click on messagebox will show second product
http://image.ohozaa.com/view/81473
then you can see the value of first product in blue line will change value like second product
this is my database on mysqlserver 2005
http://image.ohozaa.com/view/8147g
thank you for your answer to much
|
|
|
|
|
I don't know what kind of charting component you are using nor how it works, however
chart1.DataSource = ds.Tables["Order1"];
looks very suspicious to me: the last row selected will set the final value of DataSource, so I am not surprised all series shown refer to it.
The chart probably needs a single table that holds all the data, so each series can point to one column of that one table.
Luc Pattyn [My Articles] Nil Volentibus Arduum
Fed up by FireFox memory leaks I switched to Opera and now CP doesn't perform its paste magic, so links will not be offered. Sorry.
|
|
|
|
|
thank you for all reply
now i'm try to use datatable but it have same problem
this is my code
datatb = new DataTable();
da.Fill(datatb);
chart1.DataSource = datatb;
i don't know why it's wrong
i really need your help i'm so new in c#
please
|
|
|
|
|
I would agree with Luc that a DataTable would be more use than a DataSet - if you only use one table, then there is no point in allowing for others.
But looking at your images, it looks right.
You have a limited range of dates, all of which fall within your start and end dates, and the graph looks right - assuming that you are only using an ID_product of 18 - your SELECT query will only return 3 rows (since I suspect the BETWEEN ignores the entry on the 29th because it is after the start of the day.
What did you expect it to look like?
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
i try to use data table but it show same problem i don,t know what's wrong
|
|
|
|