Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tito 314 posts 623 karma points
    Mar 13, 2017 @ 12:07
    Tito
    0

    Merchello inventory count is resetted to zero

    I am using Merchello 1.14.3 and im having weird situations regarding inventory. The store owner is creating some articles and setting the inventory quantity and checking it is ok. I am showing in the front end article list an icon if the inventory is zero if he is logged as an administrator.

    Then after some days the article inventory becomes zero. I have used the LogHelper in the methods i decrease the inventory (when the article is buyed and paid) but it is not there. I am logging every time a Merchello article is saved checking its inventory count to check next time it will happen. Is there a way i could track why is it happening? like in the save event log from where is this event triggering?

    BTW, i am using Azure apps, and as i check the logs i see sometimes they change the machine name. Could it be some Examine data lose the cause? may Merchello query examine and if fails query database and reset the inventory?

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Mar 13, 2017 @ 15:59
    Rusty Swayne
    0

    Can you reproduce the issue locally? You might try removing the Machine name token {machinename} from the ExamineIndex.config and see if that makes a difference.

    For logging, you could query the product directly from the ProductService (circumvent Examine) if the first result is zero to assert that the database record is also zero and log the values. That way you could see if there was a discrepancy.

    Generally iventory does not get decremented unless an order is shipped.

  • Tito 314 posts 623 karma points
    Mar 13, 2017 @ 17:58
    Tito
    0

    Thanks Rusty, i will remove the machinename from the examine index config. I think the issue may be, when azure changes the local storage and examine index is not found, then when the store owner edits a product and saves it, then Merchello sets zero to the inventory? you think this could be the issue? unfortunately i can not reproduce it on my local machine.

    i use useTempStorage="Sync" as recommended here: https://our.umbraco.org/Documentation/Getting-Started/Setup/Server-Setup/azure-web-apps

    But forgot to remove the machinename.

    For the logging i was using ProductService.Saved event, but, if i will use ProductService.Saving to check if zero the real value in db and compare it, isnt it?

  • Tito 314 posts 623 karma points
    Mar 14, 2017 @ 12:08
    Tito
    0

    Hi Rusty,

    I have updated examine configs and rebuild them. For logging i have set an event:

    ProductService.Saving += ProductServiceSaving;
    

    But when i access the db value is the same as the value i am saving, how could i retrieve the old value from db before saving? This is my code:

    private void ProductServiceSaving(IProductService sender, SaveEventArgs<IProduct> e)
        {
            var memberShipHelper = new Umbraco.Web.Security.MembershipHelper(Umbraco.Web.UmbracoContext.Current);
            string usuario = memberShipHelper.IsLoggedIn() ? memberShipHelper.CurrentUserName : "Anónimo";
            foreach (var item in e.SavedEntities)
            {
                if (item.CatalogInventories.Any())
                {
                    int stock = item.CatalogInventories.First().Count;
                    int dbStock = stock;
                    if(stock == 0)
                    {
                        var svc = Merchello.Core.MerchelloContext.Current.Services.ProductService;
                        var prod = svc.GetByKey(item.Key);
                        dbStock = prod.CatalogInventories.First().Count;
                    }
                    LogHelper.Warn(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType,
                        string.Format("{3}: Saving product {0} ({1}): {2} units, {4} in db",
                               item.Name,
                               item.Sku,
                               stock,
                               usuario,
                               dbStock
                               ));
    
                }
    
            }
        }
    
  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Mar 14, 2017 @ 15:25
    Rusty Swayne
    0

    I think you probably want to check what value is stored in the db not the object before saved.

    Check the product being saved to see if inventory is zero - if it is:

      // remove the product from runtime cache to assert you are not
      // getting a cached value.  
      var cacheKey = string.Format("{0}.{1}", typeof(IProduct).Name, product.key);
      ApplicationContext.ApplicationCache.RuntimeCache.ClearCacheItem(cacheKey);
    
      var productCheck = MerchelloContext.Current.Services.ProductService.GetByKey(product.key);
    
     /// check productCheck inventory here.
    
  • Tito 314 posts 623 karma points
    Mar 14, 2017 @ 16:24
    Tito
    0

    Yes thats what i want. But i have tested your code and the value i get is the same that i am saving. Could you test it?

  • Tito 314 posts 623 karma points
    Mar 14, 2017 @ 17:13
    Tito
    0

    BTW i am using the ProductService.Saving event, as i understand this is a pre saved method, so it doesnt make sense to get the saved value as i am querying the db value through the service api. Am i missing something? it seems to be firing after the value is saved, not before.

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Mar 14, 2017 @ 19:14
    Rusty Swayne
    0

    Hey Tito,

    Unfortunately, I'm not going to have time to test it in the next couple of days - also, I have never seen the inventory issue you've described so I'd need more information as to how I can reproduce the issue. e.g. are you using FastTrack a custom checkout work flow ... etc?

    I did verify that the Saving event IS being raised before the save:

    See: https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Core/Services/ProductService.cs#L272

  • Tito 314 posts 623 karma points
    Mar 15, 2017 @ 09:27
    Tito
    0

    Thanks Rusty, I am using Merchello v1.14.3 so no FastTrack, only bits from Bazaar. I have a lot of custom code, but i have checked every method where i modify the inventory and put a log line and it does not seem to be the issue.

    I made a custom RemoveOrderItemsFromInventoryTask chain that checks payment method and remove items from inventory if order is paid (only when method is card, when is bank transfer it is decremented at the moment). Apart from this i made a custom process in the backoffice where the owner uploads a csv with references and inventory quantities to massive update.

    But the thing is that this issue happens with recently created items, that are not buyed, and after a few days. At the moment only with products with no variants (size, etc), so i cant reproduce it locally and have not logged anything suspicious. Its the third time it happens in about 2 months.

    I guess is about something in our hosting (Azure web apps) because Examine gets rebuilt sometimes and not finishes. Now that i deleted the machinename from config i will check every now and then the examine status.

    I am logging, every time a product or variant is saved, the inventory quantity, but i would like to log the old db value too...

  • Tito 314 posts 623 karma points
    May 03, 2017 @ 15:11
    Tito
    0

    Hi Rusty, back to this issue again. I am sure that it has to do with Examine. As our site is hosted in Azure, there is sometimes issues with Examine. I changed configuration and this problem seems solved.

    But i have now an article that has inventory = 0 in the backoffice (i think in Merchello backoffice is checking the db directly, isnt it?)... but in the article public page, seems available, as i am querying the inventory using the merchellohelper:

    var merchelloHelper = new MerchelloHelper(MerchelloContext.Current.Services);
    var productData = merchelloHelper.Query.Product.GetByKey(guidProd);
    

    Then rebuilding merchello product indexer and refreshing the page shows the article is not available.. so... its a problem if examine is corrupted and Merchello takes prices and invetory from it. Is there an api method to query inventory from the db instead of examine?

  • Tito 314 posts 623 karma points
    May 03, 2017 @ 15:21
    Tito
    0

    This is my actual examine config:

        <Examine RebuildOnAppStart="false">
      <ExamineIndexProviders>
        <providers>
          <add name="InternalIndexer" useTempStorage="Sync" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine" supportUnpublished="true" supportProtected="true" analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net" />
          <add name="InternalMemberIndexer" useTempStorage="Sync" type="UmbracoExamine.UmbracoMemberIndexer, UmbracoExamine" supportUnpublished="true" supportProtected="true" analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net" />
          <!-- default external indexer, which excludes protected and unpublished pages-->
          <add name="ExternalIndexer" useTempStorage="Sync" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine" />
          <add name="MerchelloProductIndexer" useTempStorage="Sync" type="Merchello.Examine.Providers.ProductIndexer, Merchello.Examine" />
          <add name="MerchelloInvoiceIndexer" useTempStorage="Sync" type="Merchello.Examine.Providers.InvoiceIndexer, Merchello.Examine" />
          <add name="MerchelloOrderIndexer" useTempStorage="Sync" type="Merchello.Examine.Providers.OrderIndexer, Merchello.Examine" />
          <add name="MerchelloCustomerIndexer" useTempStorage="Sync" type="Merchello.Examine.Providers.CustomerIndexer, Merchello.Examine" />
        </providers>
      </ExamineIndexProviders>
      <ExamineSearchProviders defaultProvider="ExternalSearcher">
        <providers>
          <add name="InternalSearcher" useTempStorage="Sync" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine" analyzer="Lucene.Net.Analysis.WhitespaceAnalyzer, Lucene.Net" />
          <add name="ExternalSearcher" useTempStorage="Sync" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine" />
          <add name="InternalMemberSearcher" useTempStorage="Sync" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine" analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net" enableLeadingWildcard="true" />
          <add name="MerchelloProductSearcher" useTempStorage="Sync" type="Examine.LuceneEngine.Providers.LuceneSearcher, Examine" />
          <add name="MerchelloInvoiceSearcher" useTempStorage="Sync" type="Examine.LuceneEngine.Providers.LuceneSearcher, Examine" />
          <add name="MerchelloOrderSearcher" useTempStorage="Sync" type="Examine.LuceneEngine.Providers.LuceneSearcher, Examine" />
          <add name="MerchelloCustomerSearcher" useTempStorage="Sync" type="Examine.LuceneEngine.Providers.LuceneSearcher, Examine" />
        </providers>
      </ExamineSearchProviders>
    </Examine>
    

    May it be with the RebuildOnAppStart="false" part? before rebuilding it was not optimized but seemed build ok

  • Tito 314 posts 623 karma points
    May 04, 2017 @ 08:07
    Tito
    0

    My client has told me there are lots of productos resetted to zero. So it has to be a Examine configuration problem. Every now and then examine is not updated and as merchello checks first examine using merchellohelper so it returns a different value and if admin saves product it saves with wrong data.

    So Rusty please, i need your help to solve this as its becoming and important issue. I would like to know:

    • If my above examine configuration is ok for Azure
    • If in backoffice merchello is checking examine before db for getting the inventory
    • If there is an api method to check db directly bypassing examine only for inventory (and may be price) for products and variants.

    Possible solutions:

    • Change examine configuration, rebuild indexes.
    • Make a web page that compares merchello helper inventory and db inventory for each product and show if differs.
    • If problem is not solved query db for inventory both in front end and Merchello backoffice (i dont know how). Disabling examine only for the product indexer could serve?
      • Update Umbraco to 7.5.x. The problem is i am using Merchello 1.14.3 and can not upgrade as i have lots of custom code. Is compatible with 7.5.x versions?
  • Rusty Swayne 1655 posts 4993 karma points c-trib
    May 04, 2017 @ 13:30
    Rusty Swayne
    0

    Hey Tito

    I'm out of town at the moment so am not in a position to deep dive. You had the useTempStorage="Sync" which is what I would have looked for - maybe change that to localOnly?

    I'm not sure if this will help, but Sebastian wrote a post about this a while ago:

    https://cultiv.nl/blog/making-sure-your-umbraco-site-performs-on-azure/

  • Tito 314 posts 623 karma points
    May 04, 2017 @ 13:56
    Tito
    0

    Thanks Rusty, i already read that article. Also thought about adding this:

    tempStorageDirectory="UmbracoExamine.LocalStorage.AzureLocalStorageDirectory, UmbracoExamine"
    

    As read on https://our.umbraco.org/documentation/Getting-Started/Setup/Server-Setup/load-balancing/flexible

    While I try these configs i will make a page that compares merchello helper inventory and db inventory for each product and show if differs. I will use petapoco to query "merchCatalogInventory" datatable.

    About disabling examine only for the product indexer would make the merchello helper query the db directly? if so, how could i disable it? deleting the line from the examine config throws an error and tried enableDefaultEventHandler = "false" and RebuildOnAppStart="false" on the index but it keeps rebuilding the product index.

  • Tito 314 posts 623 karma points
    May 09, 2017 @ 12:02
    Tito
    0

    Rusty i think i have solved the problem!!

    As you will remember, in this store i create the product automatically when the content product is saved in Umbraco. Well the first time i create the merchello product i associate it with the catalog this way:

            var warehouse = merchelloServices.WarehouseService.GetDefaultWarehouse();
            var catalog = warehouse.WarehouseCatalogs.FirstOrDefault(
                    x => x.Key == Merchello.Core.Constants.DefaultKeys.Warehouse.DefaultWarehouseCatalogKey);
            articulo.AddToCatalogInventory(catalog);
            articulo.CatalogInventories.First().Count = 0;
    

    I was doing it after this line:

    articulo = merchelloServices.ProductService.CreateProduct(nombre, sku, precio);
    

    Doing it this way seems to work fine in cache, i create the product you change the inventory in the merchello backoffice and it seems saved. But if i look in the "merchCatalogInventory" table, the count field is zero.

    So i guess when the cache is cleaned the item count is back to zero, as it its the value of the data base.

    So i have solved the issue saving first the product:

    articulo.OnSale = false;
                    articulo.SalePrice = 0;
                    articulo.Shippable = bool.Parse(MerchelloContext.Current.Services.StoreSettingService.GetByKey(Merchello.Core.Constants.StoreSettingKeys.GlobalShippableKey).Value);
                    articulo.Taxable = bool.Parse(MerchelloContext.Current.Services.StoreSettingService.GetByKey(Merchello.Core.Constants.StoreSettingKeys.GlobalTaxableKey).Value);
                    articulo.TrackInventory = bool.Parse(MerchelloContext.Current.Services.StoreSettingService.GetByKey(Merchello.Core.Constants.StoreSettingKeys.GlobalTrackInventoryKey).Value);
    
    
    
                    merchelloServices.ProductService.Save(articulo, true);
    
                    //Catálogo
                    var warehouse = merchelloServices.WarehouseService.GetDefaultWarehouse();
                    var catalog = warehouse.WarehouseCatalogs.FirstOrDefault(
                            x => x.Key == Merchello.Core.Constants.DefaultKeys.Warehouse.DefaultWarehouseCatalogKey);
                    articulo.AddToCatalogInventory(catalog);
                    articulo.CatalogInventories.First().Count = 0;
    

    And now it works! so i guess this is the issue why the examine data was wrong, what do you think?

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    May 11, 2017 @ 13:58
    Rusty Swayne
    0

    Hey Tito,

    Examine should always reflect what is in the database - it syncs when the product is saved, which explains why your value was resetting to 0.

    It's interesting that previous way updated examine and not the database. It may be there is a little bug - what I'm thinking is that the IProduct, which get's cached in the runtime cache is created and saved to the database without the inventory and then you add it to the warehouse without saving again. That might be updating the runtime cache before the event is handled to index the product ...

Please Sign in or register to post replies

Write your reply to:

Draft