incrementing the count of an item in a datagrid

Posts   
 
    
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 29-Dec-2005 12:41:08   

hiya,

I'll try and keep this brief.

I have to try and implement a solution where a user adds items to a delivery by "scanning" barcode labels into my app.

I have a datagrid that is populated with the following columns:

productId productName price qty

<Snipped schema>

tblProduct productId PK productName price

tblDelivery productId FK qty

<\Snipped schema>

I think my main problem is that I don't know how to implement the "count".

You see, if the product that has been scanned ALREADY exists in tblDelivery, then I simply increment the "qty" field

If not, then I obviously have to:

1) insert the new product row into tblDeliery 2) increment the "qty" field

Before buying Llbgenpro, I'd have used user defined functions with T SQL, but I'm hoping that Llbgenpro can give me a hand.

Any suggestions appreciated.

many thanks,

yogi stuck_out_tongue_winking_eye

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 29-Dec-2005 14:48:38   

I would have done the following:

Design wise:

D1- If there is no other reason for the Delivery table, drop it adn add the Qty field to the Products table with a default value of 0, as it seems that their relation is 1-1. D2- Or Leave the tables as they are, and Insert a new delivery row for each Insert of a product with Qty of 0. D3- Or Insert a delivery row only when needed, and have a value of 1 as the default of the Qty field.

Implementation wise:

1- for D1- just fetch the ProductEntity in question and increment the Qty field and Save the Entity back

2- for D2- fetch the ProductEntity with its related DeliveryEntity (using PrefetchPaths) Increment the Qty field inside the DeliveryEntity, and re-save the ProductEntity. Or just fetch the DeliveryEntity, increment and save it.

3- for D3- Fetch the DeliveryEntity, increment and save and create a new DeliveryEntity if nothing was fetched and save. Or Fetch the ProductEntity with its related DeliveryEntity, increment and save either of them.

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 02-Mar-2006 16:06:02   

hi Walaa, Sorry for letting this one slip, I'm getting pulled all over the place, project -wisefrowning

I would have done the following:

Design wise: D3- Or Insert a delivery row only when needed, and have a value of 1 as the default of the Qty field.

3- for D3- Fetch the DeliveryEntity, increment and save and create a new DeliveryEntity if nothing was fetched and save. Or Fetch the ProductEntity with its related DeliveryEntity, increment and save either of them.

Ok, I think that's the way to go. At the moment, I have an entityCollection that is filtered by deliveryId.

IPredicateExpression filter = new PredicateExpression();
            filter.Add(PredicateFactory.CompareValue(TblDeliveryProductsFieldIndex.DeliveryId, ComparisonOperator.Equal, delieveryIdVariable));

            currDeliveries.GetMulti(filter);
            tblDeliveryProductsCollectionBindingSource.DataSource = currDeliveries;
            dgvDeliveryProducts.DataSource = tblDeliveryProductsCollectionBindingSource;

So, now that I have the correct delivery details, I now have to check to see if the productId that has been input via a tetBox ALREADY exists in the entityCollection:

1) if it exists, I should incerement the qty and save (because the entity already exists in the entityCollection) 2) if it doesn't exist, then I should create this entity (with a qty of 1), add this entity to the entityCollection and save.

I'm unsure how to implement the following logic in LlblGenPro:

< does this product exist in this entityCollection(productId) >

Any suggestions much appreciated.

many thanks,

                  yogi
bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 03-Mar-2006 02:47:51   

Well you could use a prefetch path to also bring in your product entities that are related to deliveries. You could then compare these products to what is entered in the textbox. Another possibity would be to perform the query with the product criteria. If you do not receive anything then you would add this product.

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 03-Mar-2006 22:19:36   

hiya,

Ok, I have 2 potential scenarios:

1) user is creating a NEW delivery.Therefore, there is nothing in the database associated with this delivery (because it doesn't exist yet) At what stage should I send details to the database, so that it can return an sqlServer identity field which uniquely identifies the newly created delivery?

2) the delivery already exists in the database.So, I have an entityCollection that is filtered by deliveryId.I will simply be adding products / incrementing the qty of the products that already exist in this entityCollection.

you recommended a choice of 2 approaches:

1) use a prefetch path to also bring in your product entities that are related to deliveries. You could then compare these products to what is entered in the textbox.

2) perform the query with the product criteria. If you do not receive anything then you would add this product.

Now, bearing in mind what I mentioned about the 2 different scenarios that I have to handle, would you now be inclined to plump for approach #1 or #2?

Many thanks for any suggestions stuck_out_tongue_winking_eye Please let me know if I should clarify anything

yogi

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 04-Mar-2006 04:15:12   

How do you know what the PK of the delivery is? Does the person entering the product know or does the barcode indicate it's delivery? Are you using adapter or selfservicing?

1) If it is a new delivery then you setup the new delivery entity. I will assume we have a DeliveryItem table that each of these will exist in. So Delivery -> DeliveryItem

Next you will add the products for the delivery to a hashtable that you can use to discover duplicates and increment a quantity. This won't compile since I'm not exactly sure of your implementation.

                DeliveryEntity delivery = new DeliveryEntity();
                Hashtable products = new Hashtable();
                foreach(product in grid)
                {
                    if (products.ContainsKey(product.productid))
                    {
                        ((DeliveryItemEntity)products[productid]).Quantity++;
                    }
                    else
                    {
                        DeliveryItemEntity item = new DeliveryItemEntity();
                        item.ProductId = productid;
                        item.Quantity = 1;
                        products.Add(productid, item);
                    }
                }
                foreach(DeliveryItemEntity item in products)
                {
                    delivery.DeliveryItem.Add(item);
                }
                delivery.Save(true);

Now option 2 would be very similar, but would check the existing DeliveryItems before it added an item the the hashlist. If the DeliveryItem already existed for that product then it would be incrememnted.


                IPrefetchPath path = new PrefetchPath((int)EntityType.DeliveryEntity);
                path.Add(DeliveryEntity.PrefetchPathDeliveryItem);
                DeliveryEntity delivery = new Delivery(deliveryId, path);
                Hashtable products = new Hashtable();
                foreach(product in grid)
                {
                    bool existing = false;
                    foreach(DeliveryItem item in delivery.DeliveryItem)
                    {
                        if(item.ProductId == product.ProductId)
                        {
                            item.Quantity++;
                            existing = true;
                            break;
                        }
                    }
                    if(!existing)
                    {
                        if (products.ContainsKey(productid))
                        {
                            ((DeliveryItemEntity)products[productid]).Quantity++;
                        }
                        else
                        {
                            DeliveryItemEntity item = new DeliveryItemEntity();
                            item.ProductId = productid;
                            item.Quantity = 1;
                            products.Add(productid, item);
                        }
                    }
                }
                foreach(DeliveryItemEntity item in products)
                {
                    delivery.DeliveryItem.Add(item);
                }
                delivery.Save(true);

Your implementation may need to modify this, but hopefully this gives you a good start. Let me know if there are any questions.

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 04-Mar-2006 11:03:02   

hiya,

Many thanks for the reply.The code is a great place to make progress and explain my scenario.Let's ignore option 2 for the moment.That way, I can get my head round option 1 :-)

How do you know what the PK of the delivery is?

If it is a:

1) NEW delivery, then it won't have a PK.

2)EXISTING delivery, then it will have been selected from another datagridView...thereby grabbing the PK... I'm not too worried about the implimentation of this for the moment.

I'm using the latest self-servicing.

OK,

now I'm going thru the code that you posted.... The productId is supplied by txtBarcode.text..Well, the actual field that denotes the productId is called "barCode".



            TblDeliveryEntity delivery = new TblDeliveryEntity();  //understood
            Hashtable products = new Hashtable();   //understood
            
    
          foreach (TblProductEntity product in dgvDeliveryProducts)  //ERROR
            {
                if (products.ContainsKey(product.barCode))
                {
                    ((TblDeliveryProductsEntity)products[txtBarcode.Text]).qty++;
                }

I thought I'd stop there. I get an error at "dgvDeliveryProducts".Have I followed you correctly so far?

<error> foreach statement cannot operate on variables of type 'System.Windows.Forms.DataGridView' because 'System.Windows.Forms.DataGridView' does not contain a public definition for 'GetEnumerator' </error>

many thanks,

yogi

sparmar2000 avatar
Posts: 341
Joined: 30-Nov-2003
# Posted on: 04-Mar-2006 19:53:16   

Hi Yogi

Have a look at http://msdn2.microsoft.com/en-us/library/4wszzzc7.aspx on methods of accessing the data in te DGV

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 05-Mar-2006 15:59:01   

hiya,

Thanks for the help.I've made a bit of progress..

Unable to cast object of type 'System.Collections.DictionaryEntry' to type 'dalProject.EntityClasses.TblDeliveryProductsEntity'."

hmm, this is where I am trying to assign the contents of the hashTable to TblDeliveryProductsEntity...


foreach (TblDeliveryProductsEntity item in products)  //error
               {
                   if (item != null)
                   {
                       delivery.TblDeliveryProducts.Add(item);
                   }
               }
               delivery.Save(true);
           }

Can anyone help?

many thanks,

yogi

Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 06-Mar-2006 12:13:59   

Hi,

I think each time you add a new product item, your logic have to be:


existing = false;

 foreach(DeliveryItem item in delivery.DeliveryItem)
      {
         if(item.ProductId == TextboxProductId.Text)
            {
                item.Quantity++;
                existing = true;
                break;
            }
       }

if(!existing)
   {
       DeliveryItemEntity item = new DeliveryItemEntity();
       item.ProductId = TextboxProductId.Text;
       item.Quantity = 1;
       delivery.DeliveryItem.Add(item);
   }

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 11-Mar-2006 13:18:44   

hiya,

many thanks for all the replies..Here is a rough draft of the code that I came up with, based on your suggestions.I thought I'd include it, ncase anyone was curious:

I have a couple of related questions, but they're for a different post :-)



if (currDeliveries.Count == 0)
            {
                CreateDeliveryProduct();
            }
            //there are no items in the collection.
            //create a new deliveryProduct.
            //DisplayDeliveries
            else
            {

                //LOOP THRU ALL THE ITEMS IN DGV...REMEMBER THAT INITIALLY THERE WILL BE NO ROWS IF THE USER IS INITIALLY CREATING A DELIVERY.
                foreach (DataGridViewRow row in this.dgvDeliveryProducts.Rows)
                {
                    TblDeliveryProductsEntity product = new TblDeliveryProductsEntity();

                    product = (TblDeliveryProductsEntity)row.DataBoundItem; 

                    //yogi:if there is no products in the datagrid, then it should be invisible.
                    if (product != null)
                    {
                        string barCode;
                        barCode = txtBarcode.Text;
                        
                        if (product.BarCode == barCode)
                        {
                            product.Qty++;
                            currDeliveries.SaveMulti(true);
                            break;
                        }
                        else
                        {
                            CreateDeliveryProduct();
                        }
                    }
                }
            } 
            
               DisplayDeliveries();
           }

 private void CreateDeliveryProduct()
        {
            TblDeliveryProductsEntity newProduct = new TblDeliveryProductsEntity();         
            newProduct.DeliveryId = 0;
            newProduct.BarCode = txtBarcode.Text;
            newProduct.Qty = 1;

            newProduct.Save();
        }