public static ObjectId DeepCreate(DynamicRecord parentRecord, DynamicRecord record, SchemaView view, ObjectId tenantId, ObjectId loggedUser, string roleCode, IDynamicService <DynamicRecord> dynamicService, ISchemaService schemaService, bool allowUpdate = false) { var complexRecords = record.Values().Where(v => view.Schema.Attributes.ContainsKey(v.Key) && (view.Schema.Attributes[v.Key].IsComplex || view.Schema.Attributes[v.Key].IsSubCatalog)); complexRecords.ToList().ForEach(r => { var subcatalogView = schemaService.GetView(view.Schema.Attributes[r.Key].DataType, ViewCategory.Create, tenantId, roleCode); //this should go to cache all of the time, it would be expensive not to. // When manually creating an invoice, we need to check if Count > 0, otherwise FindExisting throws an exception if (r.Value is Dictionary <string, object> && ((Dictionary <string, object>)r.Value).Count > 0) { var subRecord = new DynamicRecord().Initialize <DynamicRecord>((Dictionary <string, object>)r.Value, null, ViewCategory.Create); bool isValidInput = true; subRecord._id = FindExisting(subRecord, subcatalogView, tenantId, loggedUser, dynamicService, out isValidInput); if (subcatalogView != null && subcatalogView.Schema.AllowQuickCreate && subRecord._id == ObjectId.Empty && isValidInput) { var fieldId = DeepCreate(parentRecord ?? record, subRecord, subcatalogView, tenantId, loggedUser, roleCode, dynamicService, schemaService); var field = ((Dictionary <string, object>)r.Value); var arrayOfKeys = field.Keys.ToArray(); foreach (var k in arrayOfKeys) { if (subRecord.ContainsKey(k)) { field[k] = subRecord[k]; } } } else if (subRecord._id != ObjectId.Empty) { ((Dictionary <string, object>)r.Value)["_id"] = subRecord._id; } } else if (subcatalogView?.Schema != null && subcatalogView.Schema.AllowQuickCreate && r.Value is List <Dictionary <string, object> > && ((List <Dictionary <string, object> >)r.Value).Count > 0) { ((List <Dictionary <string, object> >)r.Value).ForEach(v => { var subRecord = new DynamicRecord().Initialize <DynamicRecord>(v, subcatalogView, ViewCategory.Create); var fieldId = DeepCreate(parentRecord ?? record, subRecord, subcatalogView, tenantId, loggedUser, roleCode, dynamicService, schemaService, true); var field = v; var arrayOfKeys = field.Keys.ToArray(); foreach (var k in arrayOfKeys) { if (subRecord.ContainsKey(k)) { field[k] = subRecord[k]; } } }); } }); if (record._id != ObjectId.Empty && allowUpdate) { record.ParentRecord = parentRecord; dynamicService.Update(record, view.Schema.CollectionName, view.Schema.Name, tenantId, loggedUser, roleCode); return(record._id); } else { var isValidInput = false; record._id = FindExisting(record, view, tenantId, loggedUser, dynamicService, out isValidInput); if (record._id == ObjectId.Empty) { record.ParentRecord = parentRecord; return(dynamicService.Add(record, view.Schema.Name, tenantId, loggedUser, roleCode)); } else if (allowUpdate) { record.ParentRecord = parentRecord; dynamicService.Update(record, view.Schema.CollectionName, view.Schema.Name, tenantId, loggedUser, roleCode); return(record._id); } else { return(ObjectId.Empty); } } }
public virtual async Task <JsonResult> SaveTableCellData(Guid?entityId, Guid?propertyId, Guid?rowId, string value) { var result = new ResultModel(); if (entityId == null || propertyId == null || rowId == null) { result.Errors.Add(new ErrorModel(string.Empty, "Not specified data")); return(Json(result)); } var entity = await _pagesContext.Table.Include(x => x.TableFields).FirstOrDefaultAsync(x => x.Id == entityId); if (entity == null) { result.Errors.Add(new ErrorModel(string.Empty, "Entity not found")); return(Json(result)); } if (entity.IsSystem || entity.IsPartOfDbContext) { result.Errors.Add(new ErrorModel(string.Empty, "The system entity can not be edited")); return(Json(result)); } var property = entity.TableFields.First(x => x.Id == propertyId); if (property == null) { result.Errors.Add(new ErrorModel(string.Empty, "Not found entity column")); return(Json(result)); } var row = await _service.GetById(entity.Name, rowId.Value); if (!row.IsSuccess) { result.Errors.Add(new ErrorModel(string.Empty, "Entry Not found")); return(Json(result)); } if (row.Result.ContainsKey(property.Name)) { switch (property.DataType) { case TableFieldDataType.Guid: { Guid.TryParse(value, out var parsed); row.Result[property.Name] = parsed; } break; case TableFieldDataType.Boolean: { bool.TryParse(value, out var val); row.Result[property.Name] = val; } break; case TableFieldDataType.Int: { try { row.Result[property.Name] = Convert.ToInt32(value); } catch { row.Result[property.Name] = value; } } break; case TableFieldDataType.Decimal: { try { row.Result[property.Name] = Convert.ToDecimal(value); } catch { row.Result[property.Name] = value; } } break; case TableFieldDataType.Date: case TableFieldDataType.DateTime: { DateTime.TryParseExact(value, "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsed); row.Result[property.Name] = parsed; } break; default: row.Result[property.Name] = value; break; } } if (row.Result.ContainsKey(nameof(BaseModel.Changed))) { row.Result[nameof(BaseModel.Changed)] = DateTime.Now.ToString(CultureInfo.InvariantCulture); } var req = await _service.Update(entity.Name, row.Result); if (!req.IsSuccess) { result.Errors.Add(new ErrorModel(string.Empty, "Fail to save data")); return(Json(result)); } result.IsSuccess = true; return(Json(result)); }