public async Task <IActionResult> Edit(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _applicationDbContext.ProductTypes.Update(productTypes);
                await _applicationDbContext.SaveChangesAsync();

                TempData["edit"] = "Product type has been edited";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
示例#2
0
        public async Task <IActionResult> Edit(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _db.Update(productTypes);                            //Update  to db
                await _db.SaveChangesAsync();                        //savechangesasync

                TempData["edit"] = "Product type has been updated";  //this is for notification
                return(RedirectToAction(actionName: nameof(Index))); //RedirectToAction
            }
            return(View(productTypes));
        }
示例#3
0
        public async Task <IActionResult> Edit(int id, ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                // Use .Update if you want to save changes for all properties
                _db.Update(productTypes);
                await _db.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
        public async Task <IActionResult> Create(ProductTypes productTypes)// model binding here, when they submit it, productTypes is passed into this method
        {
            if (ModelState.IsValid)
            {
                _db.Add(productTypes);
                await _db.SaveChangesAsync();

                return(RedirectToAction(nameof(Index))); // Passes it back Index.
            }

            return(View(productTypes));
        }
        public IActionResult GetByProductType(string ProductType)
        {
            ProductTypes productType = (ProductTypes)System.Enum.Parse(typeof(ProductTypes), ProductType);
            var          result      = _ProductService.GetByProductType(productType);

            if (result.Success)
            {
                return(Ok(result.Data));
            }

            return(BadRequest(result.Message));
        }
示例#6
0
        public Game()
        {
            AddParameter(new Parameter(ParameterIds.HappinessSensitivity, "Happiness Sensitivity", 0.25, 0, 1));  // How quickly happiness follows Satisfaction, 0: never, 1: immediately

            Date = new Date(2013, 1, 1);

            ProductTypes.Add(new ProductType("Food", 0.5, 1));
            ProductTypes.Add(new ProductType("Clothes", 1, 1));

            Country = new Polity.Country(StartPopulation);

            Event e = new Event("Discovery");

            e.Condition = new ChanceCondition(0.01);
            e.Effect    = new MultipleEffects();
            e.AddEffect(new MessageEffect("New technologies increase productivity!"));
            e.AddEffect(new ChangeParameterEffect(Country, ParameterIds.Productivity, 1, 0.05));

            e             = new Event("MPs Propose to Lower Taxes");
            e.Condition   = new ChanceCondition(0.3);
            e.HappensOnce = true;
            Issues iss = new Issues();

            iss.AddIssue(IssueIds.Populism, 1);
            iss.AddIssue(IssueIds.BigGovernment, -1);
            e.Effect = new SubmitBillEffect(new Bill(iss, new ChangeParameterEffect(Country, ParameterIds.IncomeTaxRate, 1, -0.05)), Country.Parliament);
            Events.Add(e);

            Decision d = new Decision("Celebrate");

            d.DisplayCondition = new HasMoneyCondition(Country.Budget, 5);
            d.Effect           = new MessageEffect("We have lots of money! Hurray!");
            Decisions.Add(d);

            d   = new Decision("Decrease Income Tax");
            iss = new Issues();
            iss.AddIssue(IssueIds.Populism, 0.5);
            iss.AddIssue(IssueIds.BigGovernment, -0.5);
            d.Effect = new SubmitBillEffect(new Bill(iss, new ChangeParameterEffect(Country, ParameterIds.IncomeTaxRate, 1, -0.02)), Country.Parliament);
            Decisions.Add(d);

            d   = new Decision("Increase Income Tax");
            iss = new Issues();
            iss.AddIssue(IssueIds.Populism, -0.5);
            iss.AddIssue(IssueIds.BigGovernment, 0.5);
            d.Effect = new SubmitBillEffect(new Bill(iss, new ChangeParameterEffect(Country, ParameterIds.IncomeTaxRate, 1, 0.02)), Country.Parliament);
            Decisions.Add(d);

            d = new Decision("See Invisible Pink Unicorn");
            d.DisplayCondition = new ConstCondition(false);
            d.Effect           = new MessageEffect("Wow! Here it is: the invisible pink unicorn");
            Decisions.Add(d);
        }
示例#7
0
        public async Task <IActionResult> Edit(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _db.ProductTypes.Update(productTypes);
                await _db.SaveChangesAsync();

                TempData["Edit"] = "Product Data Updated Successfully";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                applicationDbContext.productTypes.Add(productTypes);
                await applicationDbContext.SaveChangesAsync();

                TempData["save"] = "Product Type Saved.";
                return(RedirectToAction(actionName: nameof(ProductType)));
            }
            return(View(productTypes));
        }
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (!ModelState.IsValid)
            {
                return(NotFound());
            }

            _db.ProductTypes.Add(productTypes);
            await _db.SaveChangesAsync();

            return(RedirectToAction(nameof(Index)));
        }
示例#10
0
        public async Task <IActionResult> Edit(ProductTypes product)
        {
            if (ModelState.IsValid)
            {
                _db.productTypes.Update(product);
                await _db.SaveChangesAsync();

                TempData["test"] = "Data has been Edit";
                return(RedirectToAction(nameof(Index)));
            }
            return(View());
        }
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            //if all poramiters which are required is ok(no nulls)
            if (ModelState.IsValid)
            {
                _db.Add(productTypes);
                await _db.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
        public async Task <IActionResult> Create(ProductTypes prdtType)
        {
            if (ModelState.IsValid)
            {
                repo.Create(prdtType);
                await repo.save();

                TempData["save"] = "Product Type has been saved succesfully.";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(prdtType));
        }
示例#13
0
        public async Task <IActionResult> Create([Bind("Id,ProductType")] ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _context.Add(productTypes);
                await _context.SaveChangesAsync();

                TempData["Save"] = "Product Type has been saved";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _db.ProductTypes.Add(productTypes);
                await _db.SaveChangesAsync();

                TempData["save"] = "Product type has been saved";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
示例#15
0
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                DB.Add(productTypes);
                await DB.SaveChangesAsync();

                SetFlashSuccess("Se ha creado de forma correcta.");
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
示例#16
0
        [ValidateAntiForgeryToken]  // проверка токена
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid) // Если required проходит
            {
                _db.Add(productTypes);
                await _db.SaveChangesAsync();

                return(RedirectToAction(nameof(Index))); //nameof что не печатать "Index" ошибки не проверяются
            }

            return(View(productTypes));
        }
示例#17
0
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _db.ProductTypes.Add(productTypes);
                await _db.SaveChangesAsync();

                Message = "Product type has been created successfully!";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
示例#18
0
        [ValidateAntiForgeryToken]// security mechanism -> in each req of HttpPost it checks if the token is
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid) // checks all the required conditions in our model " ProductTypes "
            {
                _db.Add(productTypes);
                //await _db.AddAsync(productTypes);
                await _db.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));// nameof is used to handle capital and small chars we can write it return RedirectToAction("Index");
            }
            return(View(productTypes));
        }
示例#19
0
 public List <ProductVM> GetProductByType(ProductTypes type)
 {
     try
     {
         var products = _productRepo.GetAll().Where(x => x.ProductType == type).ToList();
         return(_mapper.Map <List <Product>, List <ProductVM> >(products));
     }
     catch (Exception ex)
     {
         throw new Exception(ex.Message);
     }
 }
        public async Task <IActionResult> Edit(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                db.Update(productTypes);
                await db.SaveChangesAsync();

                TempData["save"] = "El tipo de producto ha sido editado exitosamente";
                return(RedirectToAction(actionName: nameof(Index)));
            }
            return(View(productTypes));
        }
示例#21
0
        public async Task <IActionResult> Delete(int?id, ProductTypes productType)
        {
            if (id != productType.Id)
            {
                return(NotFound());
            }

            _db.ProductTypeses.Remove(productType);
            await _db.SaveChangesAsync();

            return(RedirectToAction(nameof(Index)));
        }
示例#22
0
        public async Task <IActionResult> Create(ProductTypes model)
        {
            if (ModelState.IsValid)
            {
                _db.ProductTypes.Add(model);
                await _db.SaveChangesAsync();

                TempData["save"] = model.ProductType + " saved successfully!!!";
                return(RedirectToAction(nameof(Index)));
            }
            return(View());
        }
示例#23
0
 /// <summary>
 /// Initialize products from the data table fetched from the database.
 /// </summary>
 private void InitializeProducts(DataTable dataTable)
 {
     foreach (DataRow row in dataTable.Rows)
     {
         int          productId          = int.Parse(row[AppDefinition.PRODUCT_ID].ToString());
         string       productName        = row[AppDefinition.PRODUCT_NAME].ToString();
         ProductTypes productType        = _productTypesStringToTypeMap[row[AppDefinition.PRODUCT_TYPE].ToString()];
         int          productPrice       = int.Parse(row[AppDefinition.PRODUCT_PRICE].ToString());
         string       productDescription = row[AppDefinition.PRODUCT_DESCRIPTION].ToString();
         _products.Add(new Product(productId, productName, productType, productPrice, productDescription));
     }
 }
示例#24
0
        public async Task <IActionResult> Edit(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _db.Update(productTypes);
                await _db.SaveChangesAsync();

                TempData["update"] = "Product Type has been Updated";
                return(RedirectToAction(nameof(Index)));
            }
            return(View(productTypes));
        }
示例#25
0
        public async Task <IActionResult> Create(ProductTypes productTypes)
        {
            if (ModelState.IsValid)
            {
                _db.Add(productTypes);
                await _db.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }

            return(View(productTypes));
        }
        [AutoValidateAntiforgeryToken]                                      // security from asp.net that every request it will create a token and sent to the request
        public async Task <IActionResult> Create(ProductTypes productTypes) // the asp-for="name". The name will be delivered to the productTypes params from Create.cshtml
        {
            if (ModelState.IsValid)
            {
                _db.Add(productTypes);
                await _db.SaveChangesAsync();

                // returning to action and in params nameof. We can use just Index1 but just in case there is a capitalization error elsewhere this will help with it
                return(RedirectToAction(nameof(Index1)));
            }
            //if model is not valid, return the View with the productTypes
            return(View(productTypes));
        }
示例#27
0
        private async Task LoadProductTypeLookupAsync()
        {
            ProductTypes.Clear();
            ProductTypes.Add(new NullLookupItem {
                DisplayMember = " - "
            });
            var lookup = await _productTypeLookupDataService.GetProductTypeLookupAsync();

            foreach (var lookupItem in lookup)
            {
                ProductTypes.Add(lookupItem);
            }
        }
示例#28
0
        public IActionResult Details(int id, ProductTypes productTypes)
        {
            if (id != productTypes.id)
            {
                return(NotFound());
            }
            if (ModelState.IsValid)
            {
                return(RedirectToAction(nameof(Index)));
            }

            return(View());
        }
        public async Task <IActionResult> DeleteConfirmed(int id)
        {
            ProductTypes productTypes = await _db.ProductTypes.FindAsync(id);

            if (productTypes == null)
            {
                return(NotFound());
            }
            _db.ProductTypes.Remove(productTypes);
            await _db.SaveChangesAsync();

            return(RedirectToAction(nameof(Index)));
        }
/// <summary>
/// Update ProductTypes
/// </summary>
/// <param name="entity"></param>
/// <returns>Message</returns>
        public async Task <string> UpdateProductTypes(ProductTypes entity)
        {
            try
            {
                var result = await new ProductTypesRepository(logger).Update(entity);
                return(result);
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message);
                throw ex;
            }
        }
 public ProductData Convert(ProductTypes.Product p)
 {
     return new ProductData
     {
         id = p.id,
         title = p.name,
         description = _h.OrNull(p.description),
         type = p.productType,
         price = ConvertToPrice(p),
         rating = Convert(_h.OrNull(p.rating)),
         owner = p.owner,
         meta = Convert(_h.OrNull(p.metadata)),
         published = p.published
     };
 }
示例#32
0
 private static string GetProductName(ProductTypes productType)
 {
     switch (productType)
     {
         case ProductTypes.Tea:
             return App_GlobalResources.ProductResource.Tea;
         case ProductTypes.Coffee:
             return App_GlobalResources.ProductResource.Coffee;
         case ProductTypes.CoffeeWithMilk:
             return App_GlobalResources.ProductResource.CoffeeWithMilk;
         case ProductTypes.Juice:
             return App_GlobalResources.ProductResource.Juice;
         default:
             return App_GlobalResources.ProductResource.NoName;
     }
 }
示例#33
0
文件: gp_parts.cs 项目: Sciumo/gaigen
        private static string GetGPcodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, 
            ProductTypes T,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();
            bool resultIsScalar = (T == ProductTypes.SCALAR_PRODUCT);
            bool initResultToZero = true;
            SB.Append(GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));

            // get number of groups, and possible assurances that a group is always present:
            int nbGroups1 = (FAI[0].IsScalar()) ? 1 : gmv.NbGroups;
            int nbGroups2 = (FAI[1].IsScalar()) ? 1 : gmv.NbGroups;
            bool[] GroupAlwaysPresent1 = new bool[nbGroups1];
            bool[] GroupAlwaysPresent2 = new bool[nbGroups2];
            if (FAI[0].IsScalar()) GroupAlwaysPresent1[0] = true;
            if (FAI[1].IsScalar()) GroupAlwaysPresent2[0] = true;

            string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()";
            string bgu = (S.OutputC()) ? FAI[1].Name + "->gu" : FAI[1].Name + ".gu()";

            int g1Cond = -1; // grade 1 conditional which is open (-1 = none)
            int g2Cond = -1; // grade 2 conditional which is open (-1 = none)

            for (int g1 = 0; g1 < nbGroups1; g1++)
            {
                for (int g2 = 0; g2 < nbGroups2; g2++)
                {
                    for (int g3 = 0; g3 < gmv.NbGroups; g3++)
                    {
                        if (!zero(S, cgd, FT, M, g1, g2, g3, T))
                        {
                            // close conditionals if required
                            if ((((g1Cond != g1) && (g1Cond >= 0)) || (g2Cond != g2)) && (g2Cond >= 0))
                            {
                                SB.AppendLine("\t}");
                                g2Cond = -1;
                            }
                            if ((g1Cond != g1) && (g1Cond >= 0))
                            {
                                SB.AppendLine("}");
                                g1Cond = -1;
                            }

                            // open conditionals if required (group not currently open, and not guaranteed to be present)
                            if ((!GroupAlwaysPresent1[g1]) && (g1Cond != g1))
                            {
                                SB.AppendLine("if (" + agu + " & " + (1 << g1) + ") {");
                                g1Cond = g1;
                            }
                            if ((!GroupAlwaysPresent2[g2]) && (g2Cond != g2))
                            {
                                SB.AppendLine("\tif (" + bgu + " & " + (1 << g2) + ") {");
                                g2Cond = g2;
                            }

                            // get function name
                            string funcName = GetGPpartFunctionName(S, FT, M, g1, g2, g3);

                            SB.AppendLine("\t\t" + funcName + "(_" + FAI[0].Name + "[" + g1 + "], _" + FAI[1].Name + "[" + g2 + "], c + " + gmv.GroupStartIdx(g3) + ");");
                        }
                    }
                }
            }

            // close any open conditionals
            if (g2Cond >= 0)
            {
                SB.AppendLine("\t}");
                g2Cond = -1;
            }
            if (g1Cond >= 0)
            {
                SB.AppendLine("}");
                g1Cond = -1;
            }

            // compress / return result
            SB.Append(GetCompressCode(S, FT, FAI, resultName, T == ProductTypes.SCALAR_PRODUCT));

            return SB.ToString();
        }
示例#34
0
文件: gp_parts.cs 项目: Sciumo/gaigen
        /// <summary>
        /// Determines whether the group <c>g3</c> part of the geometric product of group <c>g1</c> and 
        /// group <c>g2</c> is zero for sure. 
        /// 
        /// This is done by checking whether a function is listed in 
        /// <c>cgd.m_gmvGPpartFuncNames</c>, so <c>WriteGmvGpParts()</c> should be called before using this
        /// function.
        /// </summary>
        /// <param name="S">Specification. Used to obtain general multivector type.</param>
        /// <param name="cgd">Used to check if code was generated for this combination of g1 and g2 (<c>m_gmvGPpartFuncNames</c>).</param>
        /// <param name="FT">Float type of function.</param>
        /// <param name="M">Metric used for function. Cannot be null.</param>
        /// <param name="g1">Grade/group of argument 1.</param>
        /// <param name="g2">Grade/group of argument 2.</param>
        /// <param name="g3">Grade/group of result.</param>
        /// <param name="T">Type of product (gp, op, etc)</param>
        /// <returns>true if this the g3 part of gp(g1, g2) is zero for sure.</returns>
        public static bool zero(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M,  
            int g1, int g2, int g3, ProductTypes T)
        {
            G25.GMV gmv = S.m_GMV;

            // get function name
            String funcName = GetGPpartFunctionName(S, FT, M, g1, g2, g3);

            // check if any code generated:
            Tuple<string, string, string> key = new Tuple<string, string, string>(FT.type, M.m_name, funcName);
            if (!cgd.m_gmvGPpartFuncNames.ContainsKey(key)) return true;
            if (!cgd.m_gmvGPpartFuncNames[key]) return true;

            // convert the groups into grades:
            g1 = gmv.Group(g1)[0].Grade();
            g2 = gmv.Group(g2)[0].Grade();
            g3 = gmv.Group(g3)[0].Grade();

            // filter on the product type:
            switch (T)
            {
                case ProductTypes.GEOMETRIC_PRODUCT:
                    return false;
                case ProductTypes.OUTER_PRODUCT:
                    return !((g1 + g2) == g3);
                case ProductTypes.LEFT_CONTRACTION:
                    return !((g1 <= g2) && ((g2-g1) == g3));
                case ProductTypes.RIGHT_CONTRACTION:
                    return !((g1 >= g2) && ((g1 - g2) == g3));
                case ProductTypes.HESTENES_INNER_PRODUCT:
                    if ((g1 == 0) || (g2 == 0)) return true;
                    else return !(Math.Abs(g1 - g2) == g3);
                case ProductTypes.MODIFIED_HESTENES_INNER_PRODUCT:
                    return !(Math.Abs(g1 - g2) == g3);
                case ProductTypes.SCALAR_PRODUCT:
                    return !((g3 == 0) && (g1 == g2));
                case ProductTypes.COMMUTATOR_PRODUCT:
                    { // note: not tested yet
                        for (int s = 0; s >= Math.Min(g1, g2); s++)
                        {
                            int f1 = g1-s;
                            int f2 = g2-s;
                            if ((f1 + f2) != g3) continue; // out of range
                            if (((f1 * f2) & 1) != 0) return false; // if grade*grade == odd, then non-zero
                        }
                        return true;
                    }
            }
            return true;
        }
示例#35
0
文件: gp_parts.cs 项目: Sciumo/gaigen
 /// <summary>
 /// Returns the code for a product. This can be a geometric, outer, inner or commutator product.
 /// The code is composed of calls to functions generated by <c>WriteGmvGpParts()</c>.
 /// 
 /// The returned code is only the body. The function declaration is not included.
 /// </summary>
 /// <param name="S">Specification of algebra (used for output language and to obtain general multivector type).</param>
 /// <param name="cgd">Used for <c>m_gmvGPpartFuncNames</c>.</param>
 /// <param name="FT">Floating point type.</param>
 /// <param name="M">Metric type.</param>
 /// <param name="T">The product (e.g., geometric, outer, etc)</param>
 /// <param name="FAI">Info about function arguments. Used to know whether arguments are general multivectors or scalars.</param>
 /// <param name="resultName">Name of variable where the result goes (in the generated code).</param>
 /// <returns>code for the requested product type.</returns>
 public static string GetGPcode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M,
     ProductTypes T,
     G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
 {
     if (S.OutputCppOrC())
         return GetGPcodeCppOrC(S, cgd, FT, M, T, FAI, resultName);
     else return GetGPcodeCSharpOrJava(S, cgd, FT, M, T, FAI, resultName);
 }
示例#36
0
文件: gp_parts.cs 项目: Sciumo/gaigen
        private static string GetGPcodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M,
            ProductTypes T,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();
            bool resultIsScalar = (T == ProductTypes.SCALAR_PRODUCT);
            bool initResultToZero = true;
            SB.Append(GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));

            // get number of groups
            int nbGroups1 = (FAI[0].IsScalar()) ? 1 : gmv.NbGroups;
            int nbGroups2 = (FAI[1].IsScalar()) ? 1 : gmv.NbGroups;
            bool[] GroupAlwaysPresent1 = new bool[nbGroups1];
            bool[] GroupAlwaysPresent2 = new bool[nbGroups2];
            if (FAI[0].IsScalar()) GroupAlwaysPresent1[0] = true;
            if (FAI[1].IsScalar()) GroupAlwaysPresent2[0] = true;

            if (resultIsScalar)
            {
                // make sure scalar part is present in result
                SB.AppendLine("cc[0] = new " + FT.type + "[" + gmv.Group(0).Length + "];");
            }

            int g1Cond = -1; // grade 1 conditional which is open (-1 = none)
            int g2Cond = -1; // grade 2 conditional which is open (-1 = none)

            for (int g1 = 0; g1 < nbGroups1; g1++)
            {
                for (int g2 = 0; g2 < nbGroups2; g2++)
                {
                    for (int g3 = 0; g3 < gmv.NbGroups; g3++)
                    {
                        if (!zero(S, cgd, FT, M, g1, g2, g3, T))
                        {
                            // close conditionals if required
                            if ((((g1Cond != g1) && (g1Cond >= 0)) || (g2Cond != g2)) && (g2Cond >= 0))
                            {
                                SB.AppendLine("\t}");
                                g2Cond = -1;
                            }
                            if ((g1Cond != g1) && (g1Cond >= 0))
                            {
                                SB.AppendLine("}");
                                g1Cond = -1;
                            }

                            // open conditionals if required (group not currently open, and not guaranteed to be present)
                            if ((!GroupAlwaysPresent1[g1]) && (g1Cond != g1))
                            {
                                SB.AppendLine("if (ac[" + g1 + "] != null) {");
                                g1Cond = g1;
                            }
                            if ((!GroupAlwaysPresent2[g2]) && (g2Cond != g2))
                            {
                                SB.AppendLine("\tif (bc[" + g2+ "] != null) {");
                                g2Cond = g2;
                            }

                            if (!(resultIsScalar && (g3 == 0))) // grade 0 is always allocated for scalar result
                                SB.AppendLine("\t\tif (cc[" + g3 + "] == null) cc[" + g3 + "] = new " + FT.type + "[" + gmv.Group(g3).Length + "];");

                            // get function name
                            string funcName = GetGPpartFunctionName(S, FT, M, g1, g2, g3);

                            SB.AppendLine("\t\t" + funcName + "(ac[" + g1 + "], bc[" + g2 + "], cc[" + g3 + "]);");
                        }
                    }
                }
            }

            // close any open conditionals
            if (g2Cond >= 0)
            {
                SB.AppendLine("\t}");
                g2Cond = -1;
            }
            if (g1Cond >= 0)
            {
                SB.AppendLine("}");
                g1Cond = -1;
            }

            if (resultIsScalar)
                SB.AppendLine("return cc[0][0];");
            else SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);");

            return SB.ToString();
        }
        public MetaData Convert(ProductTypes.Meta m)
        {
            if (m == null) return null;

            return new MetaData
            {
                name = m.key,
                value = m.value
            };
        }
        public PriceData ConvertToPrice(ProductTypes.Product p)
        {
            if (p == null) return null;

            return new PriceData
            {
                buy = _h.OrNulled(p.buyPrice, price => (uint)price),
                rent = _h.OrNulled(p.rentPrice, price => (uint)price)
            };
        }
        public ProductTypes.Product Merge(ProductTypes.Product src, ProductData update)
        {
            if (update == null) return src;
            if (src == null) return Convert(update);

            return new ProductTypes.Product
            (
                update.title ?? src.name,
                src.createDate,
                update.type ?? src.productType,
                update.owner ?? src.owner,
                new FSharpOption<ProductTypes.Rating>(Merge(_h.OrNull(src.rating), update.rating)),
                update.published == null ? src.published : (bool) update.published,
                src.id,
                new FSharpOption<FSharpMap<string, ProductTypes.Meta>>(Merge(_h.OrNull(src.metadata), update.meta)),
                update.description == null ? src.description : new FSharpOption<string>(update.description),
                update.price == null || update.price.rent == null ? src.rentPrice : FSharpOption<int>.Some((int) update.price.rent),
                update.price == null || update.price.buy == null ? src.buyPrice : FSharpOption<int>.Some((int) update.price.buy)
            );
        }
 public ProductTypes.Rating Merge(ProductTypes.Rating src, RatingData update)
 {
     return update == null ? src : Convert(update);
 }
        public ProductTypes.Meta Merge(ProductTypes.Meta src, MetaData update)
        {
            if (update == null) return src;
            if (src == null) return Convert(update);

            return new ProductTypes.Meta
            (
                update.name ?? src.key,
                update.value ?? src.value
            );
        }
        public RatingData Convert(ProductTypes.Rating r)
        {
            if (r == null) return new RatingData
            {
                score = 0,
                count = 0
            };

            return new RatingData
            {
                score = r.rating,
                count = (uint)r.votes
            };
        }