Exemple #1
0
 public ActionResult Edit(AirbnbAccount model)
 {
     if (ModelState.IsValid)
     {
         _dbContext.Entry(model).State = EntityState.Modified;
         _dbContext.SaveChanges();
         return(RedirectToAction("Index"));
     }
     return(View(model));
 }
        public int UpdatePayoutMethodByOwner(string owner, string payoutMethodName)
        {
            int updateCount = 0;

            try
            {
                if (string.IsNullOrEmpty(owner)) // case of removing payout method from property account
                {
                    var payoutMethodModel = _context.PayoutMethods.Where(x => x.PayoutMethodName == payoutMethodName).FirstOrDefault();
                    if (payoutMethodModel != null)
                    {
                        var entities = _context.PropertyAccountPayoutMethods.Where(x => x.PayoutMethodId == payoutMethodModel.PayoutMethodId);
                        if (entities != null && entities.Count() > 0)
                        {
                            _context.PropertyAccountPayoutMethods.RemoveRange(entities);
                            _context.SaveChanges();
                        }
                    }
                }
                else
                {
                    var entity = _context.PropertyAccounts.Where(x => x.OwnerName == owner).FirstOrDefault();
                    if (entity != null)
                    {
                        var entityId           = entity.PropertyAccountId;
                        var payoutMethodEntity = (from pm in _context.PropertyAccountPayoutMethods.Where(x => x.PropertyAccountId == entityId)
                                                  join m in _context.PayoutMethods
                                                  on pm.PayoutMethodId equals m.PayoutMethodId
                                                  select m)
                                                 .FirstOrDefault();

                        if (payoutMethodEntity == null) // add only when it does not exist
                        {
                            var model = _context.PayoutMethods.Where(x => x.PayoutMethodName == payoutMethodName).FirstOrDefault();
                            if (model != null)
                            {
                                _context.PropertyAccountPayoutMethods.Add(new PropertyAccountPayoutMethod
                                {
                                    PropertyAccountId = payoutMethodEntity.PayoutMethodId,
                                    PayoutMethodId    = entityId
                                });
                                _context.SaveChanges();

                                updateCount = 1;
                            }
                        }
                    }
                }
                return(updateCount);
            }
            catch
            {
                throw;
            }
        }
Exemple #3
0
 public ActionResult Edit(CPL cpl)
 {
     if (ModelState.IsValid)
     {
         _dbContext.Entry(cpl).State = EntityState.Modified;
         _dbContext.SaveChanges();
         return(RedirectToAction("Index"));
     }
     ViewBag.Accounts = (new AirbnbAccountProvider(_dbContext)).AggregatedAccounts();
     return(View(cpl));
 }
        public bool AddOrUpdate(Senstay.Dojo.Fantastic.PropertyMap map, bool commit = false)
        {
            bool changed = true;
            var  entity  = _context.PropertyFantasticMaps.Where(x => x.PropertyCode == map.nickname).FirstOrDefault();

            if (entity != null)                 // update
            {
                if (entity.ListingId != map.id) // only update if listing id has changed
                {
                    entity.ListingId = map.id;
                    this.Update(entity.PropertyFantasticMapId, entity);
                }
                else
                {
                    changed = false;
                }
            }
            else // create
            {
                entity = new PropertyFantasticMap {
                    PropertyCode = map.nickname, ListingId = map.id
                };
                this.Create(entity);
            }

            if (changed && commit)
            {
                _context.SaveChanges();
            }

            return(changed);
        }
        public int UpdatePropertyCodeByName(string name, string propertyCode)
        {
            int updateCount = 0;

            try
            {
                if (string.IsNullOrEmpty(name)) // case of removing roperty code from payout method
                {
                    var entities = _context.PropertyPayoutMethods.Where(x => x.PropertyCode == propertyCode);
                    if (entities != null && entities.Count() > 0)
                    {
                        _context.PropertyPayoutMethods.RemoveRange(entities);
                        _context.SaveChanges();
                    }
                }
                else
                {
                    var entity = _context.PayoutMethods.Where(x => x.PayoutMethodName == name).FirstOrDefault();
                    if (entity != null)
                    {
                        var entityId = entity.PayoutMethodId;
                        var count    = (from pm in _context.PropertyPayoutMethods.Where(x => x.PropertyCode == propertyCode)
                                        join m in _context.PayoutMethods
                                        on pm.PayoutMethodId equals m.PayoutMethodId
                                        select m.PayoutMethodId)
                                       .Count();

                        if (count == 0) // add only when it does not exist
                        {
                            _context.PropertyPayoutMethods.Add(new PropertyPayoutMethod
                            {
                                PropertyCode   = propertyCode,
                                PayoutMethodId = entityId
                            });
                            _context.SaveChanges();

                            updateCount = 1;
                        }
                    }
                }
                return(updateCount);
            }
            catch
            {
                throw;
            }
        }
Exemple #6
0
        public ActionResult OwnerApprovalInfo(InquiriesValidation inquiriesValidation)
        {
            try
            {
                InquiriesValidation strng = _dbContext.InquiriesValidations.Single(nc => nc.Id == inquiriesValidation.Id);

                var selectedProperty = _dbContext.CPLs.Find(strng.PropertyCode);
                strng.CPL = selectedProperty;
                strng.Doesitrequire2pricingteamapprovals = inquiriesValidation.Doesitrequire2pricingteamapprovals;
                strng.PricingApprover1 = inquiriesValidation.PricingApprover1;
                strng.PricingApprover2 = inquiriesValidation.PricingApprover2;
                strng.PricingDecision1 = inquiriesValidation.PricingDecision1;
                strng.PricingReason1   = inquiriesValidation.PricingReason1;
                strng.ApprovedbyOwner  = inquiriesValidation.ApprovedbyOwner;
                _dbContext.SaveChanges();
                return(RedirectToAction("Index"));
            }
            catch (Exception ex)
            {
                this.ModelState.AddModelError("", ex);
                return(View());
            }
        }
Exemple #7
0
        /// <summary>
        /// Audit the log directly.
        /// </summary>
        /// <param name="auditLog"></param>
        /// <param name="eventType"></param>
        /// <param name="tableName"></param>
        /// <param name="keyValue"></param>
        /// <param name="columnName"></param>
        /// <param name="origValue"></param>
        /// <param name="newValue"></param>
        /// <param name="auditMessage"></param>
        /// <param name="modifiedBy"></param>
        public static void WriteAuditLog(string eventType, string tableName, string keyValue,
                                         string columnName, string origValue, string newValue, string auditMessage, string modifiedBy)
        {
            var db = new DojoDbContext();

            AuditLog log = new AuditLog()
            {
                EventDate     = DateTime.UtcNow,
                EventType     = eventType,
                TableName     = tableName,
                RecordId      = keyValue,
                ColumnName    = columnName,
                OriginalValue = origValue,
                NewValue      = newValue,
                AuditMessage  = auditMessage,
                ModifiedBy    = modifiedBy
            };

            db.AuditLog.Add(log);
            db.SaveChanges();
        }
Exemple #8
0
        public void Import(byte[] content)
        {
            MemoryStream excelStream = new MemoryStream(content);

            using (var package = new ExcelPackage(excelStream))
            {
                ExcelWorkbook workBook = package.Workbook;
                if (workBook != null)
                {
                    if (workBook.Worksheets.Count > 0)
                    {
                        int startRow   = 2;
                        int startCol   = 1;
                        int errorCount = 0;

                        ExcelWorksheet currentWorksheet = workBook.Worksheets[1];
                        for (int row = startRow; row <= currentWorksheet.Dimension.End.Row; row++)
                        {
                            try
                            {
                                if (currentWorksheet.Cells[row, startCol].Value == null)
                                {
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                errorCount++;
                                // ignore and continue;
                            }
                        }
                        if (errorCount == 0)
                        {
                            _context.SaveChanges();
                        }
                    }
                }
            }
        }
Exemple #9
0
 private void CommitChanges()
 {
     _dbContext.SaveChanges();
 }
        public int ImportExcel(Stream excelData, bool newVersion)
        {
            int    startRow            = 2; // starting row for reservation data
            int    errorCount          = 0;
            string currentProperty     = string.Empty;
            string currentPayee        = string.Empty;
            string inputSource         = "Job Cost Excel";
            int    totalCols           = newVersion ? 25 : 23;
            int    billingStatusOffset = newVersion ? 0 : -2;

            _costSkip10Col  += billingStatusOffset;
            _costAmountCol  += billingStatusOffset;
            _costSkip11Col  += billingStatusOffset;
            _costBalanceCol += billingStatusOffset;

            List <JobCost> jobCosts         = new List <JobCost>();
            var            propertyProvider = new PropertyProvider(_context);

            using (var package = new ExcelPackage(excelData))
            {
                // storage for parsed data
                List <InputError> errorRows = new List <InputError>();

                ExcelWorkbook workBook = package.Workbook;
                if (workBook != null)
                {
                    if (workBook.Worksheets.Count > 0)
                    {
                        ExcelWorksheet currentWorksheet = workBook.Worksheets[1];

                        for (int row = startRow; row <= currentWorksheet.Dimension.End.Row; row++)
                        {
                            if (currentWorksheet.Dimension.End.Column != totalCols)
                            {
                                var message    = string.Format("The total number of columns {0:d} does not match {1:d}", currentWorksheet.Dimension.End.Column, totalCols);
                                var inputError = CreateInputError(inputSource, row, "Parse", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }

                            try
                            {
                                JobCostRow costRow = ParseJobCostExcelRow(currentWorksheet.Cells, row, inputSource);

                                // the last row has 'Total' on the first column
                                if (IsLastRow(costRow))
                                {
                                    break;
                                }

                                if (IsPropertyRow(costRow))
                                {
                                    currentProperty = costRow.PropertyCode != string.Empty ? costRow.PropertyCode : costRow.JobCostProperty2;
                                }
                                else if (IsOwnerRow(costRow))
                                {
                                    currentPayee = costRow.JobCostPayee;
                                }
                                else if (IsCostRow(costRow))
                                {
                                    costRow.OriginalPropertyCode = currentProperty;
                                    if (propertyProvider.PropertyExist(currentProperty))
                                    {
                                        costRow.PropertyCode = currentProperty;
                                    }
                                    else
                                    {
                                        costRow.PropertyCode = AppConstants.DEFAULT_PROPERTY_CODE;
                                    }

                                    costRow.JobCostPayoutTo = currentPayee;
                                    jobCosts.Add(MapJobCost(costRow));
                                }
                                else if (IsOwnerTotalRow(costRow) || IsSubTotalRow(costRow))
                                {
                                    continue;
                                }
                            }
                            catch (Exception ex)
                            {
                                var message    = "Data parse exception: " + ex.Message;
                                var inputError = CreateInputError(inputSource, row, "Exception", message, "Job Cost Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }
                        }

                        try
                        {
                            // save job cost if there is no error
                            if (errorCount == 0 && jobCosts.Count > 0)
                            {
                                _context.JobCosts.AddRange(jobCosts);
                                _context.SaveChanges(); // save job costs
                            }
                        }
                        catch (Exception ex)
                        {
                            var message    = "Job Cost saving error: " + ex.Message;
                            var inputError = CreateInputError(inputSource, 0, "Exception", message, "Database saving");
                            _context.InputErrors.Add(inputError);
                            _context.SaveChanges(); // save errors
                            errorCount = 100000;    // a large number
                        }
                    }
                    else
                    {
                        var message    = "Input file error: Cannot detect workbook in the import file.";
                        var inputError = CreateInputError(inputSource, 0, "Input File", message, "Job Cost Excel file");
                        errorRows.Add(inputError);
                        errorCount++;
                    }
                }
                else
                {
                    var message    = "Input file error: Cannot detect worksheet in the import file.";
                    var inputError = CreateInputError(inputSource, 0, "Input File", message, "Job Cost Excel file");
                    errorRows.Add(inputError);
                    errorCount++;
                }
            }

            return(errorCount == 0 ? jobCosts.Count * 10000 : -errorCount);
        }
        public int ImportExcel(Stream excelData)
        {
            int      errorCount    = 0;
            int      notFoundCount = 0;
            int      entityCount   = 0;
            int      totalCols     = 3;
            int      startRow      = 2; // starting row to read data
            string   inputSource   = "Property Fees and Taxes";
            DateTime today         = DateTime.UtcNow;

            using (var package = new ExcelPackage(excelData))
            {
                ExcelWorkbook workBook = package.Workbook;
                if (workBook != null)
                {
                    if (workBook.Worksheets.Count > 0)
                    {
                        ExcelWorksheet currentWorksheet = workBook.Worksheets[1];

                        // storage for parsed data
                        List <InputError>  errorRows    = new List <InputError>();
                        List <PropertyFee> propertyFees = new List <PropertyFee>();

                        for (int row = startRow; row <= currentWorksheet.Dimension.End.Row; row++)
                        {
                            if (currentWorksheet.Dimension.End.Column != totalCols)
                            {
                                var message    = string.Format("The total number of Property Fees & Taxes columns {0:d} does not match {1:d}", currentWorksheet.Dimension.End.Column, totalCols);
                                var inputError = CreateInputError(inputSource, row, "Parse", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }

                            try
                            {
                                var p = ParseExcelRow(currentWorksheet.Cells, row, today, inputSource);

                                // if property is not fund, we use a placehoder property so it can be fixed later
                                if (!EnsurePropertyCode(p.PropertyCode))
                                {
                                    var message    = string.Format("Property '{0}' does not exist.", p.PropertyCode);
                                    var inputError = CreateInputError(inputSource, row, inputSource, message, "Excel row");
                                    errorRows.Add(inputError);
                                    notFoundCount++;
                                }
                                else
                                {
                                    propertyFees.Add(p);
                                    entityCount++;
                                }
                            }
                            catch (Exception ex)
                            {
                                var message    = "Data parse exception: " + ex.Message;
                                var inputError = CreateInputError(inputSource, row, "Exception", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }
                        }

                        try
                        {
                            // save reservations and resoutions for future payout if there is no error
                            if (errorCount == 0)
                            {
                                if (propertyFees != null && propertyFees.Count > 0)
                                {
                                    _context.PropertyFees.AddRange(propertyFees);
                                }

                                if (errorRows.Count() > 0)
                                {
                                    _context.InputErrors.AddRange(errorRows);
                                }

                                _context.SaveChanges(); // Save Reservations
                            }
                        }
                        catch (Exception ex)
                        {
                            var message    = "Data saving error: " + ex.Message;
                            var inputError = CreateInputError(inputSource, 0, "Exception", message, "Database saving");
                            _context.InputErrors.Add(inputError);
                            _context.SaveChanges(); // save errors
                            errorCount = 100000;    // a large number
                        }
                    }
                }
            }

            return(errorCount == 0 ? entityCount * 10000 + notFoundCount : -errorCount);
        }
        public int ImportExcel(Stream excelData)
        {
            int      errorCount       = 0;
            int      notFoundCount    = 0;
            int      ownerPayoutCount = 0;
            int      totalCols        = 29;
            int      startRow         = 2; // starting row for off-airbnb reservation data
            string   inputSource      = "Off Airbnb Excel";
            DateTime today            = DateTime.UtcNow;

            using (var package = new ExcelPackage(excelData))
            {
                ExcelWorkbook workBook   = package.Workbook;
                OffAirbnbRow  currentRow = null;
                if (workBook != null)
                {
                    if (workBook.Worksheets.Count > 0)
                    {
                        ExcelWorksheet currentWorksheet = workBook.Worksheets[1];

                        // storage for parsed data
                        var errorRows    = new List <InputError>();
                        var ownerPayouts = new List <OwnerPayout>();

                        for (int row = startRow; row <= currentWorksheet.Dimension.End.Row; row++)
                        {
                            if (currentWorksheet.Dimension.End.Column != totalCols)
                            {
                                var message    = string.Format("The total number of columns {0:d} does not match {1:d}", currentWorksheet.Dimension.End.Column, totalCols);
                                var inputError = CreateInputError(inputSource, row, "Parse", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }

                            try
                            {
                                OffAirbnbRow r = ParseOffAirbnbExcelRow(currentWorksheet.Cells, row);
                                if (r == null)
                                {
                                    continue;            // skip the row that does not have checkin date or night
                                }
                                currentRow = r;

                                // if property is not fund, we write to input error table to deal with it.
                                if (!EnsurePropertyCode(r.PropertyCode))
                                {
                                    var message    = string.Format("Property {0} does not exist.", r.PropertyCode);
                                    var inputError = CreateInputError(inputSource, row, "Off-Airbnb", message, "Excel row");
                                    errorRows.Add(inputError);
                                    notFoundCount++;
                                }
                                else
                                {
                                    // create an owner payout for each reservation
                                    var ownerPayout = MapToOwnerPayout(r);
                                    ownerPayout.Reservations.Add(MapToReservation(r));
                                    ownerPayouts.Add(ownerPayout);
                                    ownerPayoutCount++;
                                }
                            }
                            catch (Exception ex)
                            {
                                var message    = "Data parse exception: " + ex.Message;
                                var inputError = CreateInputError(inputSource, row, "Exception", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }
                        }

                        try
                        {
                            // save reservations and resoutions for future payout if there is no error
                            if (errorCount == 0)
                            {
                                if (ownerPayouts != null && ownerPayouts.Count > 0)
                                {
                                    _context.OwnerPayouts.AddRange(ownerPayouts);
                                }

                                if (errorRows.Count() > 0)
                                {
                                    _context.InputErrors.AddRange(errorRows);
                                }

                                _context.SaveChanges(); // Save owner payouts and reservations
                            }
                            else
                            {
                                _context.InputErrors.AddRange(errorRows);
                                _context.SaveChanges(); // save errors
                            }
                        }
                        catch (Exception ex)
                        {
                            var message    = "Data saving error: " + ex.Message;
                            var inputError = CreateInputError(inputSource, 0, "Exception", message, "Database saving");
                            _context.InputErrors.Add(inputError);
                            _context.SaveChanges(); // save errors
                            errorCount = 100000;    // a large number
                        }
                    }
                }
            }

            return(errorCount == 0 ? ownerPayoutCount * 10000 + notFoundCount : -errorCount);
        }
        public int ImportExcel(Stream excelData, DateTime targetDate)
        {
            int    errorCount    = 0;
            int    notFoundCount = 0;
            int    propertyCount = 0;
            int    totalCols     = 2;
            int    startRow      = 2; // starting row to read data
            string inputSource   = "Begin Balance Sweep";
            int    month         = targetDate.Month;

            // if target date given is not after 07/01/2017, set the month to the prior month of today
            if (targetDate < new DateTime(2017, 7, 1))
            {
                month = DateTime.Today.Date.AddMonths(-1).Month;
            }

            using (var package = new ExcelPackage(excelData))
            {
                ExcelWorkbook workBook = package.Workbook;
                if (workBook != null)
                {
                    if (workBook.Worksheets.Count > 0)
                    {
                        ExcelWorksheet currentWorksheet = workBook.Worksheets[1];

                        // storage for parsed data
                        var errorRows       = new List <InputError>();
                        var propertyBalance = new List <PropertyBalance>();

                        for (int row = startRow; row <= currentWorksheet.Dimension.End.Row; row++)
                        {
                            if (currentWorksheet.Dimension.End.Column != totalCols)
                            {
                                var message    = string.Format("The total number of Begin Balance columns {0:d} does not match {1:d}", currentWorksheet.Dimension.End.Column, totalCols);
                                var inputError = CreateInputError(inputSource, row, "Parse", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }

                            try
                            {
                                var p = ParseExcelRow(currentWorksheet.Cells, row, month);

                                // if property is not fund, we use a placehoder property so it can be fixed later
                                if (!EnsurePropertyCode(p.PropertyCode))
                                {
                                    var message    = string.Format("Property '{0}' does not exist.", p.PropertyCode);
                                    var inputError = CreateInputError(inputSource, row, inputSource, message, "Excel row");
                                    errorRows.Add(inputError);
                                    notFoundCount++;
                                }
                                else
                                {
                                    propertyBalance.Add(p);
                                    propertyCount++;
                                }
                            }
                            catch (Exception ex)
                            {
                                var message    = "Data parse exception: " + ex.Message;
                                var inputError = CreateInputError(inputSource, row, "Exception", message, "Excel row");
                                errorRows.Add(inputError);
                                errorCount++;
                            }
                        }

                        try
                        {
                            // save reservations and resoutions for future payout if there is no error
                            if (errorCount == 0)
                            {
                                if (propertyBalance != null && propertyBalance.Count > 0)
                                {
                                    _context.PropertyBalances.AddRange(propertyBalance);
                                }

                                if (errorRows.Count() > 0)
                                {
                                    _context.InputErrors.AddRange(errorRows);
                                }

                                _context.SaveChanges(); // Save Reservations
                            }
                        }
                        catch (Exception ex)
                        {
                            var message    = "Data saving error: " + ex.Message;
                            var inputError = CreateInputError(inputSource, 0, "Exception", message, "Database saving");
                            _context.InputErrors.Add(inputError);
                            _context.SaveChanges(); // save errors
                            errorCount = 100000;    // a large number
                        }
                    }
                }
            }

            return(errorCount == 0 ? propertyCount * 10000 + notFoundCount : -errorCount);
        }
        public int ImportFromExcel(string excelFile, DateTime reportDate, bool isCompleted)
        {
            int    errorCount       = 0;
            int    payoutCount      = 0;
            int    reservationCount = 0;
            int    resolutionCount  = 0;
            string channel          = "Airbnb";
            string account          = GetAccountFromFilename(excelFile);
            string inputSource      = string.Format("{0} {1}", reportDate.ToString("yyyy-MM-dd"), GetInputSourceFromFilePath(excelFile));
            string excelPath        = Path.Combine(UrlHelper.DataRootUrl(), excelFile);

            if (!File.Exists(excelPath))
            {
                var inputError = new InputError
                {
                    InputSource  = inputSource,
                    Row          = 0,
                    Section      = "Input File Check",
                    Message      = string.Format("Input file '{0}' does not exist.", excelPath),
                    OriginalText = excelPath,
                    CreatedTime  = DateTime.UtcNow
                };
                _context.InputErrors.Add(inputError);
                _context.SaveChanges(); // save errors

                return(-1000000);       // large number of error
            }

            FileInfo excelFileInfo = new FileInfo(excelPath);

            using (var package = new ExcelPackage(excelFileInfo))
            {
                ExcelWorkbook workBook = package.Workbook;
                if (workBook != null)
                {
                    if (workBook.Worksheets.Count > 0)
                    {
                        int totalCols           = 14;
                        int startRow            = 2; // starting row for reservation data
                        int payoutDateCol       = 1;
                        int typeCol             = 2;
                        int confirmationCodeCol = 3;
                        int checkinDateCol      = 4;
                        int nightCol            = 5;
                        int guestCol            = 6;
                        int listingCol          = 7;
                        int detailCol           = 8;
                        int referenceCol        = 9;
                        int currencyCol         = 10;
                        int amountCol           = 11;
                        int payoutCol           = 12;
                        //int hostFeeCol = 13;
                        //int cleanFeeCol = 14;

                        ExcelWorksheet currentWorksheet = workBook.Worksheets[1];

                        bool isOwnerRow             = false;
                        bool isRowError             = false;
                        List <InputError> errorRows = new List <InputError>();

                        OwnerPayout        payout           = null;
                        List <Reservation> reservations     = null;
                        List <Resolution>  resolutions      = null;
                        DateTime           today            = DateTime.UtcNow;
                        PropertyProvider   propertyProvider = new PropertyProvider(_context);
                        for (int row = startRow; row <= currentWorksheet.Dimension.End.Row; row++)
                        {
                            if (currentWorksheet.Dimension.End.Column != totalCols)
                            {
                                errorRows.Add(new InputError
                                {
                                    InputSource  = inputSource,
                                    Row          = row,
                                    Section      = "Parse",
                                    Message      = string.Format("The total number of columns {0:d} does not match {1:d}", currentWorksheet.Dimension.End.Column, totalCols),
                                    OriginalText = "Excel row",
                                    CreatedTime  = DateTime.UtcNow
                                });
                            }

                            try
                            {
                                if (isCompleted && currentWorksheet.Cells[row, payoutDateCol].Value == null)
                                {
                                    if (payout != null && isOwnerRow && !isRowError)
                                    {
                                        QueuePayout(payout, reservations, resolutions);
                                        payoutCount++;
                                    }
                                    break; // exit loop at the end of row
                                }

                                string type       = GetSafeCellString(currentWorksheet.Cells[row, typeCol].Value);
                                var    payoutType = type.StartsWith("Payout") ? PayoutType.Payout :
                                                    (type.StartsWith("Reservation") ? PayoutType.Reservation :
                                                     (type.StartsWith("Resolution") ? PayoutType.Resolution : PayoutType.Other));

                                if (payoutType == PayoutType.Payout)
                                {
                                    if (isCompleted && payout != null && !isOwnerRow && !isRowError)
                                    {
                                        QueuePayout(payout, reservations, resolutions);
                                        payoutCount++;
                                    }

                                    isOwnerRow   = true;
                                    isRowError   = false;
                                    payout       = new OwnerPayout();
                                    reservations = new List <Reservation>();
                                    resolutions  = new List <Resolution>();

                                    payout.PayoutDate    = GetSafeDate(currentWorksheet.Cells[row, payoutDateCol].Value);
                                    payout.PayoutDate    = ConversionHelper.EnsureUtcDate(payout.PayoutDate);
                                    payout.AccountNumber = GetAccountNumber(currentWorksheet.Cells[row, detailCol].Value);
                                    payout.Source        = account;
                                    payout.PayoutAmount  = GetSafeNumber(currentWorksheet.Cells[row, payoutCol].Value);
                                    payout.CreatedDate   = today;
                                    payout.ModifiedDate  = today;
                                    payout.InputSource   = inputSource;
                                }
                                else if (payoutType == PayoutType.Resolution)
                                {
                                    // business rule: one resolution per reservastion
                                    resolutionCount++;
                                    isOwnerRow = false;
                                    Resolution resolution = new Resolution();
                                    resolution.ResolutionDate        = GetSafeDate(currentWorksheet.Cells[row, payoutDateCol].Value);
                                    resolution.ResolutionDate        = ConversionHelper.EnsureUtcDate(resolution.ResolutionDate);
                                    resolution.ResolutionType        = GetSafeCellString(currentWorksheet.Cells[row, typeCol].Value);
                                    resolution.ResolutionDescription = GetSafeCellString(currentWorksheet.Cells[row, detailCol].Value);
                                    resolution.ResolutionAmount      = GetSafeNumber(currentWorksheet.Cells[row, amountCol].Value);
                                    resolution.ConfirmationCode      = string.Empty;
                                    resolution.Impact       = string.Empty; // fill in later
                                    resolution.CreatedDate  = today;
                                    resolution.ModifiedDate = today;
                                    resolution.InputSource  = inputSource;

                                    if (!isCompleted)
                                    {
                                        resolution.OwnerPayoutId = 0;               // link to Owner Payout placeholder record for future payout
                                    }
                                    if (resolutions != null)
                                    {
                                        resolutions.Add(resolution);
                                    }
                                }
                                else if (payoutType == PayoutType.Reservation)
                                {
                                    if (!isCompleted && reservations == null)
                                    {
                                        reservations = new List <Reservation>();
                                    }

                                    reservationCount++;
                                    isOwnerRow = false;
                                    Reservation r = new Reservation();
                                    r.ListingTitle = GetSafeCellString(currentWorksheet.Cells[row, listingCol].Value);
                                    string propertyCode = propertyProvider.GetPropertyCodeByListing(account, Unquote(r.ListingTitle));
                                    r.TransactionDate  = GetSafeDate(currentWorksheet.Cells[row, payoutDateCol].Value);
                                    r.TransactionDate  = ConversionHelper.EnsureUtcDate(r.TransactionDate);
                                    r.PropertyCode     = propertyCode;
                                    r.ConfirmationCode = GetSafeCellString(currentWorksheet.Cells[row, confirmationCodeCol].Value);
                                    r.CheckinDate      = GetSafeDate(currentWorksheet.Cells[row, checkinDateCol].Value);
                                    r.CheckinDate      = ConversionHelper.EnsureUtcDate(r.CheckinDate);
                                    r.Nights           = (int)GetSafeNumber(currentWorksheet.Cells[row, nightCol].Value);
                                    r.CheckoutDate     = r.CheckinDate.Value.AddDays(r.Nights);
                                    r.TotalRevenue     = GetSafeNumber(currentWorksheet.Cells[row, amountCol].Value);
                                    //r.HostFee = GetSafeNumber(currentWorksheet.Cells[row, hostFeeCol].Value); // not needed per Jason
                                    //r.CleanFee = GetSafeNumber(currentWorksheet.Cells[row, cleanFeeCol].Value); // not needed per Jason
                                    r.GuestName = GetSafeCellString(currentWorksheet.Cells[row, guestCol].Value);
                                    r.Reference = GetSafeCellString(currentWorksheet.Cells[row, referenceCol].Value);
                                    CurrencyType currency;
                                    if (Enum.TryParse(GetSafeCellString(currentWorksheet.Cells[row, currencyCol].Value), true, out currency) == true)
                                    {
                                        r.Currency = currency;
                                    }
                                    else
                                    {
                                        r.Currency = CurrencyType.USD;
                                    }

                                    // non-input fields
                                    r.Source             = account;
                                    r.Channel            = channel;
                                    r.LocalTax           = 0;
                                    r.DamageWaiver       = 0;
                                    r.AdminFee           = 0;
                                    r.PlatformFee        = 0;
                                    r.TaxRate            = 0;
                                    r.IsFutureBooking    = isCompleted ? false : true;
                                    r.IncludeOnStatement = false;
                                    r.ApprovalStatus     = RevenueApprovalStatus.NotStarted;

                                    // house keeping fields
                                    r.CreatedDate  = today;
                                    r.ModifiedDate = today;
                                    r.InputSource  = inputSource;

                                    if (!isCompleted)
                                    {
                                        r.OwnerPayoutId = 0;               // link to Owner Payout placeholder record for future payout
                                    }
                                    // if property is not fund, we use a placehoder property so it can be fixed later
                                    if (string.IsNullOrEmpty(propertyCode))
                                    {
                                        errorRows.Add(new InputError
                                        {
                                            InputSource  = inputSource,
                                            Row          = row,
                                            Section      = "Reservation",
                                            Message      = string.Format("Property from listing title '{0}' and account '{1}' does not exist", Unquote(r.ListingTitle), account),
                                            OriginalText = "Excel row",
                                            CreatedTime  = DateTime.UtcNow
                                        });
                                        r.PropertyCode = AppConstants.DEFAULT_PROPERTY_CODE;
                                        //isRowError = true;
                                        //errorCount++;
                                    }

                                    if (reservations != null && !string.IsNullOrEmpty(r.PropertyCode))
                                    {
                                        reservations.Add(r);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                errorRows.Add(new InputError
                                {
                                    InputSource  = inputSource,
                                    Row          = row,
                                    Section      = "Exception",
                                    Message      = "Data parse exception: " + ex.Message,
                                    OriginalText = "Excel row",
                                    CreatedTime  = DateTime.UtcNow
                                });
                                isRowError = true;
                                errorCount++;
                            }
                        }

                        try
                        {
                            // save reservations and resoutions for future payout if there is no error
                            if (errorCount == 0 && !isCompleted)
                            {
                                if (resolutions != null && resolutions.Count() > 0)
                                {
                                    _context.Resolutions.AddRange(resolutions);
                                }

                                if (reservations != null && reservations.Count() > 0)
                                {
                                    _context.Reservations.AddRange(reservations);
                                }

                                _context.SaveChanges(); // Save Reservations
                            }
                            else if (errorCount == 0 && isCompleted)
                            {
                                _context.SaveChanges(); // save OwnerPayouts, Reservations, and Resolutions
                            }

                            if (errorRows.Count > 0)
                            {
                                _context.InputErrors.AddRange(errorRows);
                                _context.SaveChanges(); // Save errors
                            }
                        }
                        catch (Exception ex)
                        {
                            var inputError = new InputError
                            {
                                InputSource  = inputSource,
                                Row          = 0,
                                Section      = "Exception",
                                Message      = "Data saving error: " + ex.Message,
                                OriginalText = "Database saving",
                                CreatedTime  = DateTime.UtcNow
                            };
                            _context.InputErrors.Add(inputError);
                            _context.SaveChanges(); // save errors
                            errorCount = 100000;    // a large number
                        }
                    }
                }
            }

            try
            {
                excelFileInfo.Delete();
            }
            catch
            {
                // ignore if cannot delete
            }

            if (errorCount > 0)
            {
                return(-errorCount);
            }
            else if (isCompleted)
            {
                return(payoutCount);
            }
            else
            {
                return(reservationCount);
            }
        }