You are used to creating scenarios for static situations such as creating functions for menu handlers. The program you started in week 4 started out as this type of problem, but if you look at the rental window you developed last week, the sequence of events when the user is processing a rental is not clear from the interface. To clearify the sequence of events for each of the processes, you will create a dynamic scenario. Before creating the standard scenario, write a script of what will occur during renting. Make sure to indicate things that should not be possible. This will not only give you an idea of how to write your functions, it will help find weaknesses in your interface.
Here is a first attempt at a script for processing a rental. Notes in red indicate restrictions on the interface discovered from the script.
When you begin a new rental, the confirm rental button should not be enabled
|
|
At this point you should have noticed that if the rental window is on the screen, you add a rental without calling the add rental menu item. You may be able to delete the Rental menu entirely. This may lead to a redesign of the main window. Maybe a small window with two buttons (one for the rental window and the other for the customer window) might be inorder.
Did you miss anything in this script? It is hard to tell by just looking at the script if anything is missing. One thing that is not obvious here is does the customer have a choice of prices? Prices should be included in the list of available condos. What if the same person wants to rent more than one item. You might want to freeze (disable) the id once it has been confirmed and add a Order Complete button that is pressed when the customer is done. This button would return both windows to their original state. While you're at it you might want to add a clear button to both windows to return them to their original state. The handler for this button can be called whenever you need to reset a window. You may also want to add a timer that pops up a dialog if the user fails to hit the Order Complete button after a given length of time.
Before committing too much energy to the final user interface and scenarios, you should check your script with the client. If there is more than one user, you may want to talk to each to see if the scripts are realistic. It might be even better if before you write your script you observe the current system in action.
In this section you will use an abbreviated version of the scenario to trace the actions sketched above.
Write a script that you think would be the sequence of events when filling out the customer form. Next create a scenario like the one above for the customer form. Notice that some of the items already appear in the scenario for the rental, but others are new since they involve checking new customers and double checking information. Some discussion of this and SQL is given in the page you get by clicking here . The rest is put off until week 7.
One thing the might come up when reviewing a script for taking customer information is the need to double check the information. While there is no way to ensure that the user will double check each piece of information, you can remind the user and make it difficult not to double check by putting checkboxes in front of each item. Then require all be checked before adding the user. This is important even when the user is a repeat customer since vital information may have changed since the last time the customer rented. If you have decided to use the zip code and last name for seaching, you will want both of these items at the top of the form. This is the new version of the customer form. Note that the hint for for the find button indicates that the user must have the last name and zip code entered. The hint for add customer is that you must have check boxes filled.
How will you communicate the confirmation of customer information in the rental window? One thing you can do is create a bool variable in the Rental window and set it to false when a new rental begins. You will need to create a function to set the variable and then the customer window confirm button handler can set the confirmation. You need only have a function, confirmed, since the only setting you would allow from outside is true (the customer information is confirmed. Both forms were created as subforms of the MainForm, so comunications are direct. The call to the customer window from the rental window illustrates the proper calls in this case.
//This call is from the CustomerForm to the RentalForm
void __fastcall TCustomerForm1::ConfirmBtnClick(TObject *Sender)
{
MainForm->RentalForm()->confirmed();
}
//---------------------------------------------------------------------------
//This call is from the RentalForm to the CustomerForm
void __fastcall TRentalForm::CheckCustomerClick(TObject *Sender)
{
MainForm->CustomerForm()->CustomerId->Text = CustomerId->Text;
MainForm->ShowCustomer1Click(Sender);
}
//---------------------------------------------------------------------------
In the RentalForm the Confirm Rental button cannot be pressed unless all of the appropriate entries are filled in and the customer is confirmed. When the function confirmed is called from the customer form, this might be the last thing that is needed to enable the Confirm Rental button, so the button enabler is called from confirmed. These functions are given below.
void confirmed() {_custConfirmed = true ; enableComplete();}
//---------------------------------------------------------------------------
void __fastcall TRentalForm::enableComplete()
{
Confirm->Enabled = _custConfirmed && CustomerId->Text != ""
&& StayLength->Text != ""
&&( (CondoRental->Checked && CondoNumber->Text != "" )
|| (BoatSlip->Checked && BoatLength->Text != "" ));
}
//---------------------------------------------------------------------------
One function is used to check to see if any of the components has been changed. This function is created for one of the fields (say CustomerId) and then chosen as the OnChange handler for the rest of the components. Numerical components have the usual filter put on the OnKeyClicked event.
Most of the OnChange handlers for TEdit and TEditMask components simply set the corresponding checkboxes Enable property true if there is something in the box. The state change must also check to see if this is a legal state abbreviation by searching the list of abbreviations. If the typed text is not in the abbreviation list, a messagebox indicate this. The checkbox is not enabled until a legal abbreviation is entered or selected.
void __fastcall TCustomerForm1::StateChange(TObject *Sender)
{
State->Text = State->Text.UpperCase(); // All abreviations upper case
StateCheckBox->Checked = false ; // change causes check to disappear
if (State->Text.Length() == 2)
{
int index = State->Items->IndexOf(State->Text); //See if the current text is a state
if (index >=0) //if it is set the ItemIndex
State->ItemIndex = index;
else
State->Text = String(State->Text[1]); // Otherwise delete last letter
}
else if (State->Text.Length() > 2) //too many letters
{
State->Text = State->Text.SubString(0,2); //delete the last one and see if you have a state
int index = State->Items->IndexOf(State->Text);
if (index >=0)
State->ItemIndex = index;
else
State->ItemIndex = -1; // otherwise not ok
}
StateCheckBox->Enabled = State->ItemIndex >=0; // Have you got a state
State->SelStart = State->Text.Length(); // Make sure cusor is at the end of the line.
_modified = true ;
}