public async Task <IActionResult> UpdateItemDetail(Guid employeeId, [FromBody] ItemDetailModel itemDetail)
        {
            ItemDetail updateItemDetail = new ItemDetail(); // need for catch part

            try
            {
                updateItemDetail         = context.ItemDetail.Find(itemDetail.itemDetailId);
                updateItemDetail.ItemId  = itemDetail.itemId;
                updateItemDetail.SizeId  = itemDetail.sizeId;
                updateItemDetail.ColorId = itemDetail.colorId;
                // if Sold (2) or Lost (6) then quantity is negative
                updateItemDetail.Quantity     = (itemDetail.itemActionId == 2 || itemDetail.itemActionId == 6) ? (-1) * Math.Abs(itemDetail.quantity) : Math.Abs(itemDetail.quantity); // not null
                updateItemDetail.ItemActionId = itemDetail.itemActionId;
                // if Sold (2) or Returned (3) then add CustomerId
                updateItemDetail.CustomerId = (itemDetail.itemActionId == 2 || itemDetail.itemActionId == 3) ? itemDetail.customerId : null;

                await context.SaveChangesAsync();

                #region AdminLog

                AdminLog adminLog = new AdminLog();
                adminLog.TableName        = "ItemDetail";
                adminLog.FieldName        = "ItemDetailId";
                adminLog.FieldValue       = itemDetail.itemDetailId.ToString();
                adminLog.AdminLogActionId = (int)AdminLogActionEnum.Update;
                adminLog.Notes            = null;
                adminLog.EmployeeId       = employeeId;
                adminLog.Timestamp        = DateTime.Now;
                analyticsRepo.InsertAdminLog(adminLog);

                #endregion

                return(NoContent());
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "UpdateItemDetail";
                errorLog.MethodParams    = "(Guid employeeId, [FromBody] ItemDetailModel itemDetail)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to update ItemDetail";
                errorLog.DetailedComment = ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(updateItemDetail).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);

                #endregion
                return(BadRequest());
            }
        }
        public async Task <IActionResult> DeleteItemDetail(Guid employeeId, Guid itemDetailId)
        {
            ItemDetail itemDetail = new ItemDetail(); // need for catch part

            try
            {
                itemDetail = await context.ItemDetail
                             .Where(x => x.ItemDetailId == itemDetailId)
                             .FirstOrDefaultAsync();

                context.ItemDetail.Remove(itemDetail);
                context.SaveChanges();

                #region AdminLog

                AdminLog adminLog = new AdminLog();
                adminLog.TableName        = "ItemDetail";
                adminLog.FieldName        = "ItemDetailId";
                adminLog.FieldValue       = itemDetailId.ToString();
                adminLog.AdminLogActionId = (int)AdminLogActionEnum.Delete;
                adminLog.Notes            = "Delete single row from ItemDetail by ItemDetailId";
                adminLog.EmployeeId       = employeeId;
                adminLog.Timestamp        = DateTime.Now;
                analyticsRepo.InsertAdminLog(adminLog);

                #endregion

                return(NoContent());
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "DeleteItemDetail";
                errorLog.MethodParams    = "(Guid employeeId, Guid itemDetailId)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to delete row from ItemDetail";
                errorLog.DetailedComment = "ItemDetailId: " + itemDetailId.ToString() + ". Message:" + ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(itemDetail).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);

                #endregion ErrorLog
                return(BadRequest());
            }
        }
        public async Task <IActionResult> UpdateItemActivity(Guid employeeId, Guid itemId, bool isActive)
        {
            Item updateItem = new Item(); // need for catch part

            try
            {
                updateItem          = context.Item.Find(itemId);
                updateItem.IsActive = isActive;
                await context.SaveChangesAsync();

                #region AdminLog

                AdminLog adminLog = new AdminLog();
                adminLog.TableName        = "Item";
                adminLog.FieldName        = "ItemId";
                adminLog.FieldValue       = itemId.ToString();
                adminLog.AdminLogActionId = (int)AdminLogActionEnum.Update;
                adminLog.Notes            = (isActive) ? "Item was activated" : "Item was deactivated";
                adminLog.EmployeeId       = employeeId;
                adminLog.Timestamp        = DateTime.Now;
                analyticsRepo.InsertAdminLog(adminLog);

                #endregion

                return(NoContent());
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "UpdateItemActivity";
                errorLog.MethodParams    = "(Guid employeeId, Guid itemId, bool isActive)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to update item's isActive field";
                errorLog.DetailedComment = ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(updateItem).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);

                #endregion
                return(BadRequest());
            }
        }
        public async Task <IActionResult> DeleteItem(Guid employeeId, Guid itemId)
        {
            Item item = new Item(); // need for catch part

            try
            {
                List <ItemDetail> itemDetails = await context.ItemDetail
                                                .Where(x => x.ItemId == itemId)
                                                .ToListAsync();

                List <ItemImage> itemImages = await context.ItemImage
                                              .Where(x => x.ItemId == itemId)
                                              .ToListAsync();

                item = await context.Item
                       .Where(x => x.ItemId == itemId)
                       .FirstOrDefaultAsync();

                context.ItemDetail.RemoveRange(itemDetails);
                context.ItemImage.RemoveRange(itemImages);
                context.Item.Remove(item);
                context.SaveChanges();

                #region AdminLog

                AdminLog adminLog1 = new AdminLog();
                adminLog1.TableName        = "ItemDetail";
                adminLog1.FieldName        = "ItemId";
                adminLog1.FieldValue       = itemId.ToString();
                adminLog1.AdminLogActionId = (int)AdminLogActionEnum.Delete;
                adminLog1.Notes            = "Delete from ItemDetail, ItemImage and Item simultaneously";
                adminLog1.EmployeeId       = employeeId;
                adminLog1.Timestamp        = DateTime.Now;
                analyticsRepo.InsertAdminLog(adminLog1);

                AdminLog adminLog2 = new AdminLog();
                adminLog2.TableName        = "ItemImage";
                adminLog2.FieldName        = adminLog1.FieldName;
                adminLog2.FieldValue       = adminLog1.FieldValue;
                adminLog2.AdminLogActionId = adminLog1.AdminLogActionId;
                adminLog2.Notes            = adminLog1.Notes;
                adminLog2.EmployeeId       = adminLog1.EmployeeId;
                adminLog2.Timestamp        = adminLog1.Timestamp;
                analyticsRepo.InsertAdminLog(adminLog2);

                AdminLog adminLog3 = new AdminLog();
                adminLog3.TableName        = "Item";
                adminLog3.FieldName        = adminLog1.FieldName;
                adminLog3.FieldValue       = adminLog1.FieldValue;
                adminLog3.AdminLogActionId = adminLog1.AdminLogActionId;
                adminLog3.Notes            = adminLog1.Notes;
                adminLog3.EmployeeId       = adminLog1.EmployeeId;
                adminLog3.Timestamp        = adminLog1.Timestamp;
                analyticsRepo.InsertAdminLog(adminLog3);

                #endregion

                return(NoContent());
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "DeleteItem";
                errorLog.MethodParams    = "(Guid employeeId, Guid itemId)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to delete item from Item, ItemDetail and ItemImage";
                errorLog.DetailedComment = "ItemId: " + itemId.ToString() + ". Message:" + ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(item).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);


                #endregion ErrorLog
                return(BadRequest());
            }
        }
        public async Task <IActionResult> UpdateItem(Guid employeeId, [FromBody] ItemModel item)
        {
            #region serverside validation
            if (String.IsNullOrWhiteSpace(item.name))
            {
                return(BadRequest("Name can't be empty"));
            }
            if (item.name.Length > 50)
            {
                return(BadRequest("Name shouldn't exceed 50 characters"));
            }
            if (String.IsNullOrWhiteSpace(item.description))
            {
                return(BadRequest("Description can't be empty"));
            }
            if (item.description.Length > 2000)
            {
                return(BadRequest("Description shouldn't exceed 2000 characters"));
            }

            #endregion

            Item updateItem = new Item(); // need for catch part
            try
            {
                updateItem             = context.Item.Find(item.itemId);
                updateItem.Name        = item.name;        // not null
                updateItem.Description = item.description; // not null
                updateItem.BrandId     = item.brandId;     // not null
                updateItem.CategoryId  = item.categoryId;  // not null
                updateItem.GenderId    = item.genderId;    // not null
                updateItem.Price       = item.price;       // not null
                await context.SaveChangesAsync();

                #region AdminLog

                AdminLog adminLog = new AdminLog();
                adminLog.TableName        = "Item";
                adminLog.FieldName        = "ItemId";
                adminLog.FieldValue       = item.itemId.ToString();
                adminLog.AdminLogActionId = (int)AdminLogActionEnum.Update;
                adminLog.Notes            = null;
                adminLog.EmployeeId       = employeeId;
                adminLog.Timestamp        = DateTime.Now;
                analyticsRepo.InsertAdminLog(adminLog);

                #endregion

                return(NoContent());
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "UpdateItem";
                errorLog.MethodParams    = "(Guid employeeId, [FromBody] ItemModel item)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to update Item";
                errorLog.DetailedComment = ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(updateItem).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);

                #endregion
                return(BadRequest());
            }
        }
        public async Task <IActionResult> InsertItemImage(Guid employeeId, [FromBody] ItemImageModel[] itemImage)
        {
            int       count        = 0;
            ItemImage newItemImage = new ItemImage(); // need it for catch part

            try
            {
                Guid?itemId = itemImage.Select(x => x.itemId).First();
                // Step 1. Delete all old images
                List <ItemImage> itemImages = await context.ItemImage
                                              .Where(x => x.ItemId == itemId)
                                              .ToListAsync();

                context.ItemImage.RemoveRange(itemImages);
                context.SaveChanges();
                // Step 2. Add/readd images
                foreach (ItemImageModel img in itemImage)
                {
                    #region serverside validation

                    // skip images if size exceedes  100 MB
                    if (img.size > 104857600) // 100 MB = 104 857 600 KB
                    {
                        continue;
                    }
                    // skip if type is not image
                    if (!img.imageType.StartsWith("image"))
                    {
                        continue;
                    }

                    #endregion serverside validation

                    newItemImage = new ItemImage();// emptify for each new image
                    // newItemImage.ItemImageId will be generated by default
                    newItemImage.ItemId    = (Guid)itemId;
                    newItemImage.Src       = img.src;
                    newItemImage.IsMain    = (bool)img.isMain;
                    newItemImage.Size      = img.size;
                    newItemImage.ImageType = img.imageType;

                    context.ItemImage.Add(newItemImage);
                    await context.SaveChangesAsync();

                    count++;

                    #region AdminLog

                    AdminLog adminLog = new AdminLog();
                    adminLog.TableName        = "ItemImage";
                    adminLog.FieldName        = "ItemImageId";
                    adminLog.FieldValue       = newItemImage.ItemImageId.ToString();
                    adminLog.AdminLogActionId = (int)AdminLogActionEnum.Create;
                    adminLog.Notes            = null;
                    adminLog.EmployeeId       = employeeId;
                    adminLog.Timestamp        = DateTime.Now;
                    analyticsRepo.InsertAdminLog(adminLog);

                    #endregion
                }

                return(Ok("Number of successfully save images is " + count));
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "InsertItemImage";
                errorLog.MethodParams    = "(Guid employeeId, [FromBody] ItemImageModel[] itemImage)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to insert into ItemImage";
                errorLog.DetailedComment = ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(newItemImage).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);

                #endregion
                return(BadRequest());
            }
        }
        public async Task <IActionResult> InsertItemDetail(Guid employeeId, [FromBody] ItemDetailModel itemDetail)
        {
            #region serverside validation

            if (itemDetail.quantity > 1000000000 || itemDetail.quantity < -1000000000)
            {
                return(BadRequest("Quantity must fall within range between minus billion and plus billion"));
            }

            #endregion

            ItemDetail newItemDetail = new ItemDetail();
            try
            {
                // newItemDetail.ItemDetailId will be generated by default
                newItemDetail.ItemId  = itemDetail.itemId;                                                                                                    // not null
                newItemDetail.SizeId  = itemDetail.sizeId;                                                                                                    // not null
                newItemDetail.ColorId = itemDetail.colorId;                                                                                                   // not null
                // if Sold (2) or Lost (6) then quantity is negative
                newItemDetail.Quantity     = (itemDetail.itemActionId == 2 || itemDetail.itemActionId == 6)? (-1) * itemDetail.quantity: itemDetail.quantity; // not null
                newItemDetail.ItemActionId = itemDetail.itemActionId;                                                                                         // not null
                // if Sold (2) or Returned (3) then add CustomerId
                newItemDetail.CustomerId = (itemDetail.itemActionId == 2 || itemDetail.itemActionId == 3) ? itemDetail.customerId : null;
                context.ItemDetail.Add(newItemDetail);
                await context.SaveChangesAsync();

                #region AdminLog

                AdminLog adminLog = new AdminLog();
                adminLog.TableName        = "ItemDetail";
                adminLog.FieldName        = "ItemDetailId";
                adminLog.FieldValue       = newItemDetail.ItemDetailId.ToString();
                adminLog.AdminLogActionId = (int)AdminLogActionEnum.Create;
                adminLog.Notes            = null;
                adminLog.EmployeeId       = employeeId;
                adminLog.Timestamp        = DateTime.Now;
                analyticsRepo.InsertAdminLog(adminLog);

                #endregion

                return(Ok(newItemDetail.ItemDetailId));
            }
            catch (Exception ex)
            {
                #region ErrorLog

                ErrorLog errorLog = new ErrorLog();
                errorLog.Namespace       = "PapaJohnsCloneApi.Controllers";
                errorLog.Class           = "AnalyticsController";
                errorLog.Method          = "InsertItemDetail";
                errorLog.MethodParams    = "(Guid employeeId, [FromBody] ItemDetailModel itemDetail)";
                errorLog.ErrorLogTypeId  = (int)ErrorLogTypeEnum.Error;
                errorLog.ShortComment    = "Failed to insert into ItemDetail";
                errorLog.DetailedComment = ex.InnerException.Message;
                errorLog.Exception       = XmlManipulation.ConvertObjectToXml <Exception>(ex.InnerException);
                errorLog.EmployeeId      = employeeId;
                errorLog.Timestamp       = DateTime.Now;
                // clean Exception before saving AdminLog in db
                context.Entry(newItemDetail).State = EntityState.Detached;
                analyticsRepo.InsertErrorLog(errorLog);

                #endregion
                return(BadRequest());
            }
        }