public async Task <Sync> GetMbeSyncPreview(string projectId, string userId)
        {
            var result = new Sync(projectId, userId);

            var _projectService = ObjectLocator.ProjectService;
            var progProject     = await _projectService.GetProject(projectId);

            var mbeProjectId = progProject?.MBEProjectId;

            if (mbeProjectId == null)
            {
                return(null);
            }

            var _mbeProjectService = ObjectLocator.MbeProjectService;
            var fieldHeaders       = await _mbeProjectService.GetMbeProjectFieldHeaders(mbeProjectId);

            var _doorImportAdapter = ObjectLocator.DoorImportAdapter;
            var engDoors           = await _doorImportAdapter.GetDoorsByEngProjectId(mbeProjectId);

            //// Validate duplicate door nrs
            ///
            var isDuplicateDoorNrExists = false;

            foreach (var engDoor in engDoors)
            {
                isDuplicateDoorNrExists = engDoors.Any(x => x.Id != engDoor.Id && x.DoorNo == engDoor.DoorNo);

                if (isDuplicateDoorNrExists)
                {
                    break;
                }
            }
            if (isDuplicateDoorNrExists)
            {
                result.IsInvalid = true;
                /* "MicroBuild Engineering prosjektet har dører med like dørnummer. Vi kan derfor ikke importere/synkronisere prosjektet" */
                /* "This Engineering project has different doors with similar door numbers. Please make them unique and try syncing again." */
                result.Error = "MicroBuild Engineering prosjektet har dører med like dørnummer. Vi kan derfor ikke synkronisere prosjektet.";
                return(result);
            }

            engDoors.RemoveAll(x => x.DoorQty == 0);

            var _doorRepository = DataUnitOfWork.DoorRepository;
            var progDoors       = await _doorRepository.GetDoorsByProjectIdAsync(projectId);

            var normalIntFieldNameList = new List <string>()
            {
                "DoorQty", "D11Qty"
            };
            var normalFieldNameList = new List <string>()
            {
                "DoorId", "Building", "Comment", "RoomNo", "Func", "LR",
                "D3", "D4", "D10", "D11", "D20", "D21", "D22", "D23", "D24", "D25", "D26", "D27", "D28",
                "DC1", "DC2", "DC3", "DC4", "Floor", "Fly", "Panel", "ExternalId1", "ExternalId2", "Secure", "URF1", "URF2", "URF3", "Status",
                "HB", "DoorBundle",
                "H26", "HC",
                "URF4", "URF5", "URF6", "URF7", "URF8"
            };
            var roomTypeFieldName       = "RoomType";
            var doorObjectFieldNameList = new List <string>()
            {
                "D2", "D5", "D6", "D7", "D8", "D9"
            };
            var hardwareFieldNameList = new List <string>()
            {
                "H1", "H10", "H11", "H12", "H13", "H14", "H15",
                "H16", "H17", "H19", "H2", "H22", "H23", "H24",
                "H25", "H27", "H28", "H29", "H3", "H30", "H31",
                "H32", "H33", "H35", "H5", "H6", "H7", "H8", "H9",
                "H40", "H41", "H42", "H43", "H44",
                "H45", "H46", "H47", "H48", "H49"
            };

            foreach (var engDoor in engDoors)
            {
                var progDoor = progDoors.FirstOrDefault(d => !string.IsNullOrWhiteSpace(d.DoorNo) && d.DoorNo.Equals(engDoor.DoorNo));

                DoorSyncChange change;

                if (progDoor == null)
                {
                    progDoor        = new Door();
                    progDoor.DoorNo = engDoor.DoorNo;
                    change          = new DoorSyncChange(progDoor);
                }
                else
                {
                    change = new DoorSyncChange(progDoor.DoorNo, progDoor.Id);
                }

                foreach (var fieldName in normalIntFieldNameList)
                {
                    AddNormalIntFieldChange(fieldName, engDoor, progDoor, change, fieldHeaders);
                }

                foreach (var fieldName in normalFieldNameList)
                {
                    AddNormalFieldChange(fieldName, engDoor, progDoor, change, fieldHeaders);
                }

                AddRoomTypeChange(roomTypeFieldName, engDoor, progDoor, change, fieldHeaders);

                foreach (var fieldName in doorObjectFieldNameList)
                {
                    AddDoorObjectFieldChange(fieldName, engDoor, progDoor, change, fieldHeaders);
                }

                foreach (var fieldName in hardwareFieldNameList)
                {
                    AddDoorHardwareChange(fieldName, engDoor, progDoor, change, fieldHeaders);
                }

                if ((change.FieldChanges != null && change.FieldChanges.Count() > 0))
                {
                    result.DoorChanges.Add(change);
                }
            }

            var    deletedProgDoors   = progDoors.Where(pd => !engDoors.Any(ed => ed.DoorNo.Equals(pd.DoorNo)));
            string doorQtyFieldName   = "DoorQty";
            string doorQtyFieldHeader = GetFieldHeader(doorQtyFieldName, fieldHeaders);

            foreach (var deletedDoor in deletedProgDoors)
            {
                if (deletedDoor.DoorQty != null && deletedDoor.DoorQty > 0)
                {
                    var change = new DoorSyncChange(deletedDoor.DoorNo, deletedDoor.Id);
                    change.IsDoorDeletion = true;
                    change.FieldChanges.Add(new DoorSyncChangeField(doorQtyFieldName, doorQtyFieldHeader, deletedDoor.DoorQty, 0));
                    result.DoorChanges.Add(change);
                }
            }

            return(result);
        }
        private void AddDoorHardwareChange(string fieldName, Door engDoor, Door progDoor, DoorSyncChange change, List <FieldHeader> fieldHeaders)
        {
            var engValue  = engDoor[fieldName] as Hardware;
            var progValue = progDoor[fieldName] as Hardware;

            if (progValue != engValue && !(string.IsNullOrEmpty(engValue.Content) && string.IsNullOrEmpty(progValue.Content)) && (progValue == null || !progValue.Equals(engValue)))
            {
                if (progValue.Content != engValue.Content && !(string.IsNullOrEmpty(engValue.Content) && string.IsNullOrEmpty(progValue.Content)) && (progValue.Content == null || !progValue.Content.Equals(engValue.Content)))
                {
                    var fname  = $"{fieldName}.Content";
                    var header = GetFieldHeader(fname, fieldHeaders);

                    if (progValue.IsMaintained)
                    {
                        change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Content, engValue.Content, false));
                    }
                    else
                    {
                        change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Content, engValue.Content, true));
                    }
                }

                if (progValue.Qty != engValue.Qty && (progValue.Qty == null || !progValue.Qty.Equals(engValue.Qty)))
                {
                    var fname  = $"{fieldName}.Qty";
                    var header = GetFieldHeader(fname, fieldHeaders);

                    if (progValue.IsMaintained)
                    {
                        change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Qty, engValue.Qty, false));
                    }
                    else
                    {
                        change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Qty, engValue.Qty, true));
                    }
                }

                if (progValue.Surf != engValue.Surf && !(string.IsNullOrEmpty(engValue.Surf) && string.IsNullOrEmpty(progValue.Surf)) && (progValue.Surf == null || !progValue.Surf.Equals(engValue.Surf)))
                {
                    var fname  = $"{fieldName}.Surf";
                    var header = GetFieldHeader(fname, fieldHeaders);

                    if (progValue.IsMaintained)
                    {
                        change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Surf, engValue.Surf, false));
                    }
                    else
                    {
                        change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Surf, engValue.Surf, true));
                    }
                }
            }
        }
        private void AddNormalFieldChange(string fieldName, Door engDoor, Door progDoor, DoorSyncChange change, List <FieldHeader> fieldHeaders)
        {
            string engValue  = engDoor[fieldName] as string;
            string progValue = progDoor[fieldName] as string;

            if (progValue != engValue && !(string.IsNullOrEmpty(engValue) && string.IsNullOrEmpty(progValue)) && (progValue == null || !progValue.Equals(engValue)))
            {
                var header = GetFieldHeader(fieldName, fieldHeaders);

                change.FieldChanges.Add(new DoorSyncChangeField(fieldName, header, progValue, engValue));
            }
        }
        private void AddDoorObjectFieldChange(string fieldName, Door engDoor, Door progDoor, DoorSyncChange change, List <FieldHeader> fieldHeaders)
        {
            var engValue  = engDoor[fieldName] as DoorField;
            var progValue = progDoor[fieldName] as DoorField;

            if (progValue != engValue && !(string.IsNullOrEmpty(engValue.Content) && string.IsNullOrEmpty(progValue.Content)) && (progValue == null || !progValue.Equals(engValue)))
            {
                var fname  = $"{fieldName}.Content";
                var header = GetFieldHeader(fname, fieldHeaders);

                change.FieldChanges.Add(new DoorSyncChangeField(fname, header, progValue.Content, engValue.Content, true));
            }
        }
        private void AddNormalIntFieldChange(string fieldName, Door engDoor, Door progDoor, DoorSyncChange change, List <FieldHeader> fieldHeaders)
        {
            int?engValue  = engDoor[fieldName] as int?;
            int?progValue = progDoor[fieldName] as int?;

            if (progValue != engValue && (progValue == null || !progValue.Equals(engValue)))
            {
                var header = GetFieldHeader(fieldName, fieldHeaders);

                change.FieldChanges.Add(new DoorSyncChangeField(fieldName, header, progValue, engValue));
            }
        }