Need advice

Need advice

Old forum URL: forums.lhotka.net/forums/t/1281.aspx


ajj3085 posted on Wednesday, September 20, 2006

Hi,

I have an odd use case..

The case is that a user can edit a contact.  The contact must have a company and department entered before its considered valid.  To this end, the contact has a DepartmentId public property.  Since a department is tied to a company, company is not stored.

The part I'm having problems with is this; the user, when editing the contact, can enter a company and / or department which does not yet exist.  The system should accept this and when the contact is saved, the company and / or department are created.

Currently the UI handles this by looking at the SelectedIndex of the dropdown displaying the department.  If this index is -1, it knows the department doesn't exist and will use the Company and Department business classes before continuing to save the contact.

For the DepartmentId property, if the combobox's text is null or empty, DepartmentId is set to -1.  If its not, and the item is not in the list (selectedIndex = -1) the DepartmentId is set to int.MaxValue.  The reason for this is that the business rule is defined such that DepartmentId must be > -1. 

This works, but has the drawback that since I cannot bind the ComboBox directly to DepartmentId, I must create a Textbox bound to that property so that the ErrorProvider shows.  In the old layout, that text box is 'behind' the combobox so the user can't see it.  In the new layout, this can't be done because all the controls are now contained within a TableLayoutContainer control.

This problem has lead me to rethink if the public DepartmentId property is a good idea or not.  Ideally, my solution would allow me to bind the combobox directly to the property on the contact for the department. 

Anyone have better ideas on how to handle this scenario?  Should the UI be responsible for creating companies and departments which don't exist?  Or should that be part of the contact object's responsiblity?

Thanks
Andy

SonOfPirate replied on Wednesday, September 20, 2006

The question of whether you should allow new companies/departments to be created when adding/editing contacts is really a question for your users/customers but I would lean away from it if possible.  If you want users to have the ability to add companies/departments from this interface, consider adding an ellipsis button (...) next to the drop-down control that will display a list editor when clicked.

Then, if you want to enforce security so that only certain users may add/remove/modify the list of companies/departments, you can bind this button's Visible or Enabled property instead if trying to implement all kinds of additional logic to handle it the way you've described.

This would also eliminate the mess with DepartmentID being -1 or Int32.MaxValue by always limiting the user to selecting from the drop-down list from your main interface.  So, SelectedIndex will always be >= -1.

You can bind the drop-down list and the list editor to the same collection object so that any changes to the collection through the list editor can be carried over to the drop-down list by simply rebinding the control when the list editor is closed.  Then, you can still bind DepartmentID to the SelectedIndex property of the drop-down list as you indicated.

Obviously this adds to your UI requirements, but may be a cleaner way to code it unless your business requirements prevent this approach.

Hope that helps.

ajj3085 replied on Wednesday, September 20, 2006

SonOfPirate:
The question of whether you should allow new companies/departments to be created when adding/editing contacts is really a question for your users/customers but I would lean away from it if possible.  If you want users to have the ability to add companies/departments from this interface, consider adding an ellipsis button (...) next to the drop-down control that will display a list editor when clicked.


The way things are now is what is required; they want to be able to type anything they want, whether it exists or not, without other forms appearing..

SonOfPirate:
Then, if you want to enforce security so that only certain users may add/remove/modify the list of companies/departments, you can bind this button's Visible or Enabled property instead if trying to implement all kinds of additional logic to handle it the way you've described.

Fortunately for right now, the users that can create contacts can create companies, and users that cannot create contacts cannot create companies.  Only Sales people can modify those aspects of the data.

SonOfPirate:
You can bind the drop-down list and the list editor to the same collection object so that any changes to the collection through the list editor can be carried over to the drop-down list by simply rebinding the control when the list editor is closed.  Then, you can still bind DepartmentID to the SelectedIndex property of the drop-down list as you indicated.

Obviously this adds to your UI requirements, but may be a cleaner way to code it unless your business requirements prevent this approach.

I would like to go this route, but the requirements are such that they want 'one form' when creating a contact.    Originally I had required the users to create the company / department first, then it would appear in the comboboxes.. however Sales people are on the phone and must capture all the info at once.  They found they were writing things down, then maybe going to the app to enter the data later..

The way it works now, the users are happy and enter directly into the application while they are on the phone.  Which is good.. its just my end of things are more complicated..  I did float the elipsises idea by them, and they were instant that it was all one form.

SonOfPirate replied on Wednesday, September 20, 2006

Oh, boy.  I've been down that road before.  Have they considered what safeguards are to be in place to prevent one user from entering "Ford", another from entering "Ford Motor", a third from entering "Ford Motor Co." and fourth from entering "Ford Motor Company"?  (Been there, done that!).

This is the obvious pitfall in not enforcing selection from a list, but if they are comfortable with the risk or have incorporated some additional logic to prevent such things, then who's to tell them otherwise, eh?  Just wait until they try to run a report and bring up all sales for "Ford" and the list is missing some items!!!

If this is to be the case, then your work is a bit more complicated because, as you said, there is a problem trying to bind the DepartmentId to the drop-down list.  If I understand your original post correctly, you are going to have the following type of code in the Save routine (pardon the rough semi-code):

if (CompanyList.SelectedIndex == -1)
{
    if (String.IsNullOrEmpty(CompanyList.Text))
    {
        DataSource.DepartmentId = -1;
    }
    else
    {
        Company c = new Company(CompanyList.Text);
        c.Save();
        DataSource.DepartmentId = c.Id;
    }
}
else
    DataSource.DepartmentId = CustomerList.SelectedIndex;

Is that close?  I guess the only questionable area is creating the new company and saving it all in one shot, but if that's what you've got to do, ya know?

Sounds like you are on the right track given the requirements you've been handed.

 

ajj3085 replied on Wednesday, September 20, 2006

SonOfPirate:
Oh, boy.  I've been down that road before. 


Yes, I'm certainly not the first I'm sure.  Smile [:)]

SonOfPirate:
Have they considered what safeguards are to be in place to prevent one user from entering "Ford", another from entering "Ford Motor", a third from entering "Ford Motor Co." and fourth from entering "Ford Motor Company"?  (Been there, done that!).

This is the obvious pitfall in not enforcing selection from a list, but if they are comfortable with the risk or have incorporated some additional logic to prevent such things, then who's to tell them otherwise, eh?  Just wait until they try to run a report and bring up all sales for "Ford" and the list is missing some items!!!

Yes, I did explain these problems.  Their answer was that it doesn't change the fact that need to enter data very quickly, and having more forms opened slows them down, which, to be fair, is a valid point.

To prevent the problems you describe, I've set the company / department comboboxes SuggestList.  Changing the company changes the SuggestList on the department (or nulls it, if the company doesn't exist).  Additionally, there is functionality to merge companies, departments and even contacts, since they do have some duplicates of those too!

I don't have any reports yet; only the contact management piece is done.  But I am working on quoting, invoicing and ordering, and reports will be part of that phase and those issues will be brought to light.  If its a big problem, I can try pushing them to the elipsis button route..  unless someone has another solution!  Big Smile [:D]

SonOfPirate:
If this is to be the case, then your work is a bit more complicated because, as you said, there is a problem trying to bind the DepartmentId to the drop-down list.  If I understand your original post correctly, you are going to have the following type of code in the Save routine (pardon the rough semi-code):

if (CompanyList.SelectedIndex == -1)
{
    if (String.IsNullOrEmpty(CompanyList.Text))
    {
        DataSource.DepartmentId = -1;
    }
    else
    {
        Company c = new Company(CompanyList.Text);
        c.Save();
        DataSource.DepartmentId = c.Id;
    }
}
else
    DataSource.DepartmentId = CustomerList.SelectedIndex;

Is that close?  I guess the only questionable area is creating the new company and saving it all in one shot, but if that's what you've got to do, ya know?

That more or less is what I have done.

SonOfPirate:
Sounds like you are on the right track given the requirements you've been handed.

I was hoping there may be a simplier solution, like creating a Company and Department properties on Contact.  Behind the scenes when the contact is saved, it would look up the company / department from the text entered. 

My concern there is that it doesn't pick the 'right company' because there could be duplicates... but OTOH duplicates would likely be the same company anyway and so it wouldn't matter, and the problem goes away when they finally merge the duplciates.

Thoughts on that approach?  Is the contact doing 'too much' at that point?  I hear people talking about the single responsibility principal or something.. would that be a violation? (Even if it handed the actual work of creating off the the proper classes?)

Copyright (c) Marimer LLC