/// <summary>
        /// reusable method
        /// </summary>
        /// <param name="fileAsZipInUTF8"></param>
        /// <param name="OverwriteMethod"></param>
        /// <param name="SubTypeID">
        ///     usually empty value.
        ///     we use the parameter for sub types
        ///         eg, sales order that derive from transaction
        ///         eg, invoice     that derive from transaction
        ///         eg, visit       that derive from activity
        ///     in that case we take the SubTypeID from the metadata endpoint (see GetSubTypesMetadata method)
        ///     The custom fields are TSA fields
        ///     </param>
        /// <returns></returns>
        /// <remarks>
        /// 1. the post body is in UTF8
        /// </remarks>
        private BulkUploadResponse BulkUploadOfZip(byte[] fileAsZipInUTF8, eOverwriteMethod OverwriteMethod, string SubTypeID = null)
        {
            string RequestUri =
                (SubTypeID == null || SubTypeID.Length == 0) ?
                string.Format("bulk/{0}/csv_zip", ResourceName) :
                string.Format("bulk/{0}/{1}/csv_zip", ResourceName, SubTypeID);                                    //eg, for transaction or activity

            Dictionary <string, string> dicQueryStringParameters = new Dictionary <string, string>();

            dicQueryStringParameters.Add("overwrite", OverwriteMethod.ToString());


            byte[] postBody    = fileAsZipInUTF8;
            string contentType = "application/zip";
            string accept      = "application/json";

            PepperiHttpClient         PepperiHttpClient         = new PepperiHttpClient(this.Authentication, this.Logger);
            PepperiHttpClientResponse PepperiHttpClientResponse = PepperiHttpClient.PostByteArraycontent(
                ApiBaseUri,
                RequestUri,
                dicQueryStringParameters,
                postBody,
                contentType,
                accept
                );

            PepperiHttpClient.HandleError(PepperiHttpClientResponse);

            BulkUploadResponse result = PepperiJsonSerializer.DeserializeOne <BulkUploadResponse>(PepperiHttpClientResponse.Body);

            return(result);
        }
        private BulkUploadResponse BulkUpload_OfJson(IEnumerable <TModel> data, eOverwriteMethod OverwriteMethod, IEnumerable <string> fieldsToUpload)
        {
            FlatModel FlatModel = PepperiFlatSerializer.MapDataToFlatModel(data, fieldsToUpload, "''");

            string RequestUri = string.Format("bulk/{0}/json", ResourceName);

            Dictionary <string, string> dicQueryStringParameters = new Dictionary <string, string>();

            dicQueryStringParameters.Add("overwrite", OverwriteMethod.ToString());

            string postBody    = PepperiJsonSerializer.Serialize(FlatModel);                      //null values are not serialzied.
            string contentType = "application/json";
            string accept      = "application/json";

            PepperiHttpClient         PepperiHttpClient         = new PepperiHttpClient(this.Authentication, this.Logger);
            PepperiHttpClientResponse PepperiHttpClientResponse = PepperiHttpClient.PostStringContent(
                ApiBaseUri,
                RequestUri,
                dicQueryStringParameters,
                postBody,
                contentType,
                accept
                );

            PepperiHttpClient.HandleError(PepperiHttpClientResponse);

            BulkUploadResponse result = PepperiJsonSerializer.DeserializeOne <BulkUploadResponse>(PepperiHttpClientResponse.Body);

            return(result);
        }
        private BulkUploadResponse BulkUploadOfZip(IEnumerable <TModel> data, eOverwriteMethod OverwriteMethod, IEnumerable <string> fieldsToUpload, string FilePathToStoreZipFile, string SubTypeID = null)
        {
            FlatModel FlatModel = PepperiFlatSerializer.MapDataToFlatModel(data, fieldsToUpload, "''");

            string CsvFileAsString = PepperiFlatSerializer.FlatModelToCsv(FlatModel);

            byte[] CsvFileAsZipInUTF8 = PepperiFlatSerializer.UTF8StringToZip(CsvFileAsString, FilePathToStoreZipFile);

            BulkUploadResponse result = BulkUploadOfZip(CsvFileAsZipInUTF8, OverwriteMethod, SubTypeID);

            return(result);
        }
        public BulkUploadResponse BulkUpload(string csvFilePath, eOverwriteMethod OverwriteMethod, Encoding fileEncoding, string SubTypeID = "", string FilePathToStoreZipFile = null)
        {
            byte[] fileAsBinary = File.ReadAllBytes(csvFilePath);
            bool   isToAddBOM   = true;

            // UTF8 byte order mark is: 0xEF,0xBB,0xBF
            if (fileAsBinary[0] == 0xEF && fileAsBinary[1] == 0xBB && fileAsBinary[2] == 0xBF)
            {
                isToAddBOM = false;
            }
            byte[] fileAsUtf8       = Encoding.Convert(fileEncoding, Encoding.UTF8, fileAsBinary);
            string fileAsUtf8String = System.Text.Encoding.UTF8.GetString(fileAsUtf8);

            byte[] fileAsZipInUTF8 = PepperiFlatSerializer.UTF8StringToZip(fileAsUtf8String, FilePathToStoreZipFile, isToAddBOM);

            BulkUploadResponse result = BulkUploadOfZip(fileAsZipInUTF8, OverwriteMethod, SubTypeID);

            return(result);
        }
        /// <summary>
        /// Upsert of collection As json or csv zip
        /// </summary>
        /// <param name="data"></param>
        /// <param name="OverrideMethod"></param>
        /// <param name="BulkUploadMethod"></param>
        /// <param name="fieldsToUpload"></param>
        /// <param name="FilePathToStoreZipFile">Optional. We can store the generated zip file for debugging purpose.</param>
        /// <returns></returns>
        public BulkUploadResponse BulkUpload(IEnumerable <TModel> data, eOverwriteMethod OverrideMethod, eBulkUploadMethod BulkUploadMethod, IEnumerable <string> fieldsToUpload, bool SaveZipFileInLocalDirectory = false, string SubTypeID = "")
        {
            //validate input
            if (fieldsToUpload == null || fieldsToUpload.Count() == 0)
            {
                throw new PepperiException("No header fields  are specified.");
            }


            BulkUploadResponse BulkUploadResponse = null;

            switch (BulkUploadMethod)
            {
            case eBulkUploadMethod.Json:
            {
                BulkUploadResponse = BulkUpload_OfJson(data, OverrideMethod, fieldsToUpload);
                break;
            }

            case eBulkUploadMethod.Zip:
            {
                string FilePathToStoreZipFile = null;
                if (SaveZipFileInLocalDirectory)
                {
                    string AssemblyLocation = Assembly.GetExecutingAssembly().Location;
                    string AssemblyPath     = Path.GetDirectoryName(AssemblyLocation);
                    string zipDirectory     = AssemblyPath;
                    string zipFileName      = "BulkUpload_" + this.ResourceName + ".zip";
                    FilePathToStoreZipFile = Path.Combine(zipDirectory, zipFileName);
                }

                BulkUploadResponse = BulkUploadOfZip(data, OverrideMethod, fieldsToUpload, FilePathToStoreZipFile, SubTypeID);
                break;
            }

            default:
            {
                throw new PepperiException("Invalid argument: the upload method is not supported.");
            }
            }

            return(BulkUploadResponse);
        }