[go: up one dir, main page]

Menu

[r27]: / keeping / SCN.java  Maximize  Restore  History

Download this file

283 lines (242 with data), 11.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
package keeping;
import database.*;
import java.util.ArrayList;
/**
Tbis class includes the quantities of of inventory items which are currently in stock. It also records zero quantities.
<p>
The can be multiple different times of delivery/purchase for each item name. This is because some goods are perishable.
<p>
This class includes all dates and all quantities for all inventory items -- so it is pretty big. As an added extra, it also includes the purchase prices for the "batch" of stock, so you would have four different fields as follows:
<p>
goodName, quantity, dateTime, price
<p>
There could, for example, be three such rows, all with the same goodName. The total available for sale would be the sum of their quantities.
*/
public class SCN
// please change from abstract to final
{
/**
Loads the data from disk.
*/
private DB scnData;
public SCN()
{
// not implemented.
scnData = new DB("scn");
}
/**
Check how much is available for sale.
@param goodName the name of an inventory item. Name are stored in {@link keeping.SSI}.
@return The sum of all available quantities.
*/
protected float quantity(String goodName)
{
float sum = 0;
int[] indecies = indecies(goodName);
//Get quantity from record in SCN file at every index in indecies, and add to sum.
for(int i=0; i<indecies.length; i++)
{
sum = sum + scnData.getFloat(1,indecies[i]);
}
return sum;
}
private int[] indecies(String goodName)
{
// I highly recommend you write this function.
// It will be used a lot in your class.
// for example in the above procedure.
// It will return all dattabase positions for a given name. Position == offset == index
ArrayList<Integer> listOfIndecies = new ArrayList<Integer>();
//Loop through SCN file, compare the good name at every index in the file to goodName, and if they match, added i to the ArrayList listOfIndecies and increment numberOfIndecies.
for(int i=0; i<scnData.length(); i++)
{
if(scnData.getString(0,i).equals(goodName))
{
listOfIndecies.add(i);
}
}
//Initialize int array indecies using numberOfIndecies
int[] indecies = new int[listOfIndecies.size()];
//Add every int in the ArrayList listOfIndecies to the int array indecies
for(int i=0; i<listOfIndecies.size(); i++)
{
indecies[i] = listOfIndecies.get(i);
}
return indecies;
}
/**
When stock is purchase.
<p>
A completely new record is added to the database, using the current date and time.
@param goodName Name of a good.
@param price How much each unit was purchased for.
*/
public void receive(String goodName, float price) // Use System.currentTimeMillis()); as part of your new record.
{
//initialize Object array using goodName, price, System.currentTimeMillis(), and 1 for quantity
Object[] values = {goodName, 1, System.currentTimeMillis(), price};
//Pass Object array to DB object to be written to file
scnData.add(values);
}
/**
When a sale is reversed.
<p>
It's exact stock entries are also re-added. The old record will be searched out and incremented -- provided it matches both dateTime and price.
@param goodName The good being returned.
@param price The price at which the good was sold.
@param dateTime The time at which the "batch" of goods was purchased! The time at which it was bought from suppliers, NOT the time at which part of itwas sold to a customer.
*/
public void receive(String goodName, float price, long dateTime)
{
//Get indecies for all batches of goodName
int[] indecies = indecies(goodName);
/*For the records on file at each index in indecies, the price and date are compared to price and dateTime, and if they match, the DB object's setFloat method is used to increase the quantity for that record by 1*/
for(int i=0; i<indecies.length; i++)
{
if(scnData.getFloat(3,indecies[i]) == price && ((long)scnData.getFloat(2,indecies[i])) == dateTime)
{
scnData.setFloat(1,indecies[i], scnData.getFloat(1,indecies[i])+1);
}
}
}
/**
Loop through all batches and subtract, part by part, the desired quantity.
<p>
If their is too little available, create a new batch with a negative quantity. Later, when we next receive() new stock, we can zero it and subtract from our latest batch.
@param goodName The name of an inventory item.
@param quantity The quantity which will be subtracted.
*/
public void sell(String goodName, float quantity)
{
//Get indecies for all batches of goodName
int[] indecies = indecies(goodName);
//To be used to store each batch's quantity
float currentBatchQuantity;
for(int i=0; i<indecies.length; i++)
{
//Get the quantity of the record on file at the index at index i of indecies and store it in currentBatchQuantity
currentBatchQuantity = scnData.getFloat(1,indecies[i]);
//If the current batch's quantity is greater than or equal to the quantity to be subtracted, simply subtract that quantity from the current batch's quantity and set quantity to 0
if(currentBatchQuantity >= quantity)
{
scnData.setFloat(1,indecies[i],currentBatchQuantity-quantity);
quantity = 0;
}
//If the current batch's quantity is less than the quantity to be subtracted, subtract it from quantity, and set that record's quantity to 0
else if(currentBatchQuantity < quantity)
{
quantity = quantity - currentBatchQuantity;
scnData.setFloat(1,indecies[i],0);
}
}
/*If after all the batches have been subtracted from, if there are still goods left to be subtracted, use receive(the first one) to create a new record for goodName, and setRecount to change that new record's quantity to the negative equivalent of the current value of quantity*/
if(quantity != 0)
{
receive(goodName, 0);
setRecount(goodName, indecies.length+1, -1*quantity);
}
/*NOTE: I am not sure if this was the intended functionality of the method - I'm not sure if this is what was meant by "Loop through all batches and subtract, part by part, the desired quantity". Also, it leaves records of batches with quantity 0 on file, as there is no provided way to delete a record*/
}
/**
This returns general information abouut a specific batch.
<p>
The idea would be for it to be used for editing in a graphical table.
@param goodName The name of a good, as defined in {@link keeping.SSI}.
@param batchIndex Each inventory item may have multiple records, or even none! The caller should try each one in turn, starting at zero.
@return General information about this batch, or null if no more batches are available.
<p>
The returned array is comprised as follows: dateTime, price, quantity, quantity
<p>
There are two entries for quantity. They are identical. The reason for this is that the user will have, in his UI, two coloumns: old and new.
<p>
He may later set the new value (the new quantity) using setRecount(..., float);
*/
public String[] getRecount(String goodName, int batchNumber)
{
//Initialize String array
String[] data = new String[4];
//Get indecies for all batches of goodName
int[] indecies = indecies(goodName);
//Get index for batchNumber
int index = indecies[batchNumber-1];
//Get Date/Time, price, quantity, and quantity info for the record at index and store it in the String array
//The getLong method didn't retrieve the Date/Time correctly, it came back as 0, so I had to use getFloat and than cast it to long
data[0] = (long)scnData.getFloat(2,index)+"";
data[1] = scnData.getString(3,index);
data[2] = scnData.getString(1,index);
data[3] = scnData.getString(1,index);
return data;
}
/**
Replace the quantity value for a specific batch.
<p>
For when stock has been lost, or has perished, or somebody has just made a mistake.
@param goodName The name of an inventory item.
@param batchNumber The visual row number.
@param newQuantity The absolute quantity which the user has entered.
*/
public void setRecount(String goodName, int batchNumber, float newQuantity)
{
//Get indecies for all batches of goodName
int[] indecies = indecies(goodName);
//Changes the quantity at the record at the index in indecies at the index specified by batchNumber, to newQuantity
scnData.setFloat(1,indecies[batchNumber-1],newQuantity);
}
/** Test case. */
public static void main(String[] ignore)
{
//All methods are tested here, except for setRecount, which is called in the sell method, and as such is tested when the sell method is tested
//Create SCN Object
SCN testSCN = new SCN();
/*Test first receive method by adding 11 records for 5 different goods - only do this if SCN is blank - this is for testing purposes so that the records aren't added again every time I want to test the other methods*/
if(testSCN.quantity("Good #1") == 0)
{
testSCN.receive("Good #1", 50);
testSCN.receive("Good #2", 20);
testSCN.receive("Good #3", 40);
testSCN.receive("Good #2", 20);
testSCN.receive("Good #4", 30);
testSCN.receive("Good #1", 50);
testSCN.receive("Good #5", 10);
testSCN.receive("Good #3", 40);
testSCN.receive("Good #5", 10);
testSCN.receive("Good #4", 30);
testSCN.receive("Good #2", 20);
}
//Test the indecies, quantity, and getRecount methods to display the data for all the goods on file, grouped by good(i.e. all "Good #1"s first, all "Good #2"s, etc.
String[] batchData;
int[] indecies;
//Because the date/time in the array returned by getRecount is a string, a long object must be created in order to take the string as parameter and convert it to a long
Long date;
for(int i=1; i<6; i++)
{
indecies = testSCN.indecies("Good #"+i);
System.out.println("Quantity of Good #"+i+": "+testSCN.quantity("Good #"+i));
for(int j=0; j<indecies.length; j++)
{
batchData = testSCN.getRecount("Good #"+i, j+1);
date = new Long(batchData[0]);
System.out.println("Good "+i+" "+batchData[2]+" "+batchData[1]+" "+DB.getDateTime(date.longValue()));
}
}
//Test the second receive method, to increase the quantity for a specific batch
batchData = testSCN.getRecount("Good #2",2);
date = new Long(batchData[0]);
testSCN.receive("Good #2", 20, date.longValue());
System.out.println("New Good #2");
batchData = testSCN.getRecount("Good #2",2);
//Result should be 2
System.out.println("New Quantity: "+batchData[2]);
/*NOTE: In this instance, the receive method will end up changing the quantity on multiple records because all of the records were written out at the same exact time. In practice, unless two batches
of the same good are written to file at the same exact time, the receive method will only change the quantity for the one batch written out at that time*/
//Test the sell method, to decrease the quantity of that good from any available batch(s).
System.out.println("Selling 7 'Good #2's'");
//7 of Good #2 is subtracted, and at this point, there aren't 7 total Good #2's, so the result should be new record with a negative quantity
testSCN.sell("Good #2",7);
//The newly added batch of Good #2 is the 4th batch(because 3 already existed and are only written out once)
batchData = testSCN.getRecount("Good #2",4);
//Result should be -1
System.out.println("Quantity of Added Good #2 Batch: "+batchData[2]);
// Please write.
}
}