private ExtSupplierDTO SupplierRecordAdded(SupplierDTO newRecord, Object additionalData)
        {
            SuppliersMergeParameter mergeParam = additionalData as SuppliersMergeParameter;

            ExtSupplierDTO supplierDetail = newRecord.Clone() as ExtSupplierDTO;

            supplierDetail.LastUpdateTime = AdjustClientUtcTimeToServerTime(newRecord.LastUpdateTime, mergeParam.ClientServerTimeDifference);
            supplierDetail.SystemUserID   = mergeParam.SystemUserID;

            try
            {
                mergeParam.DataAccessObject.AddSupplier(supplierDetail);
            }
            catch (SqlException ex)
            {
                switch (ex.Number)
                {
                // Duplicate record found.
                case 2627:

                    break;

                default:
                    // Re-throw the exception if we don't recognise the error code.
                    throw;
                }
            }

            return(supplierDetail);
        }
        private ExtSupplierDTO SupplierRecordUpdated(ExtSupplierDTO originalData, SupplierDTO updatedData, Object additionalData)
        {
            SuppliersMergeParameter mergeParam = additionalData as SuppliersMergeParameter;

            ExtSupplierDTO supplierDetail = updatedData.Clone() as ExtSupplierDTO;

            supplierDetail.LastUpdateTime = AdjustClientUtcTimeToServerTime(updatedData.LastUpdateTime, mergeParam.ClientServerTimeDifference);
            supplierDetail.SystemUserID   = mergeParam.SystemUserID;

            mergeParam.DataAccessObject.UpdateSupplier(supplierDetail);
            return(supplierDetail);
        }
        private void SupplierRecordDeleted(ExtSupplierDTO deletedRecord, Object additionalData)
        {
            SuppliersMergeParameter mergeParam = additionalData as SuppliersMergeParameter;

            mergeParam.DataAccessObject.RetireSupplier
            (
                mergeParam.SystemUserID,
                AdjustClientUtcTimeToServerTime(deletedRecord.LastUpdateTime, mergeParam.ClientServerTimeDifference),
                deletedRecord.SupplierID,
                true
            );
        }
        public UpdateSuppliersResponse UpdateSuppliers(UpdateSuppliersRequest supplierDataIn)
        {
            UpdateSuppliersResponse response = new UpdateSuppliersResponse();

            try
            {
                using (IDataAccess dataAccess = GetDataAccessObject())
                {
                    // Immediately get the time on the database server so that is will be close to the time when the request was sent.
                    DateTime serverUtcTime = dataAccess.GetDatabaseServerUtcTime();
                    TimeSpan clientServerTimeDifference = CalculateServerClientTimeDifference(serverUtcTime, supplierDataIn.ClientUtcTime);
                    #if DEBUG
                    // Some logging for debug puposes.
                    Utility.EventLogger.Log
                    (
                        LogLevel.Debug, String.Format
                        (
                            "Server UTC time is [{0}]   Client UTC time is [{1}]   Time difference (ms) is [{2}]",
                            serverUtcTime.ToString("yyyy-MM-dd HH:mm:ss.ffff"),
                            supplierDataIn.ClientUtcTime.ToString("yyyy-MM-dd HH:mm:ss.ffff"),
                            clientServerTimeDifference.Milliseconds
                        )
                    );
                    #endif // DEBUG

                    IOrderedEnumerable <SupplierDTO> updatedSuppliers = supplierDataIn.SupplierRecords.OrderBy(u => u.UniqueIdentifier);
                    using (Mutex accessMutex = new Mutex(false, Utilities.Utility.SupplierMutexName))
                    {
                        IEnumerable <Guid> recordIDs = updatedSuppliers.TransformElements(u => u.UniqueIdentifier);

                        // Prevent other instance from accessing the table until we are done.
                        accessMutex.WaitOne();
                        try
                        {
                            IOrderedEnumerable <ExtSupplierDTO> storedSuppliers = dataAccess.GetExistingSupplierRecords(recordIDs).OrderBy(u => u.UniqueIdentifier);

                            SuppliersMergeParameter mergeParameter = new SuppliersMergeParameter
                                                                     (
                                dataAccess,
                                1, // TODO replace with user ID from security module,
                                clientServerTimeDifference
                                                                     );

                            List <ExtSupplierDTO> updatedList = new List <ExtSupplierDTO>
                                                                (
                                Utility.MergeLists <ExtSupplierDTO, SupplierDTO, ExtSupplierDTO>
                                (
                                    storedSuppliers,
                                    updatedSuppliers,
                                    (s, u) => { return(s.UniqueIdentifier.CompareTo(u.UniqueIdentifier)); },
                                    SupplierRecordAdded,
                                    SupplierRecordDeleted,
                                    SupplierRecordUpdated,
                                    mergeParameter
                                )
                                                                );
                        }
                        finally
                        {
                            accessMutex.ReleaseMutex();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Utility.EventLogger.Log(LogLevel.Error, ex);

                response.ErrorCode        = ResponseErrorCode.ExceptionCaught;
                response.ErrorDescription = ex.Message;
            }

            return(response);
        }