public SaveEmpMonthlyEnteredRecordRequestValidation() { this.CascadeMode = CascadeMode.Stop; RuleFor(x => x.YearMonth).NotEmpty().WithMessage(ValiationErrors.YEAR_MONTH_NULL_ERROR) .Must(x => YearMonth.TryParse(x)).WithMessage(ValiationErrors.YEAR_MONTH_INVALID_FORMAT_ERROR); RuleFor(x => x.Key).NotEmpty().WithMessage(ValiationErrors.KEY_EMPTY_ERROR); RuleFor(x => x.StandardWorkingDays).GreaterThanOrEqualTo(1).WithMessage(ValiationErrors.STANDARD_WORKING_DAY_MIN_ERROR) .LessThanOrEqualTo(23).WithMessage(ValiationErrors.STANDARD_WORKING_DAY_MAX_ERROR); RuleFor(x => x.Records).Must(x => !x.GroupBy(y => y.Email).Any(g => g.Count() > 1)) .WithMessage(ValiationErrors.RECORD_DUPLICATED_ERROR); RuleForEach(x => x.Records).ChildRules(record => { record.CascadeMode = CascadeMode.Stop; record.RuleFor(y => y.Email).EmailAddress().WithMessage(ValiationErrors.EMAIL_INVALID_ERROR); record.RuleFor(y => y.Fullname).NotEmpty().WithMessage(ValiationErrors.FULLNAME_EMPTY_ERROR); record.RuleFor(y => y.Currency).NotEmpty().WithMessage(ValiationErrors.CURRENCY_EMPTY_ERROR); record.RuleFor(y => y.GrossContractSalary).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.GROSS_CONTRACT_SALARY_NEGATIVE_ERROR); record.RuleFor(y => y.ProbationWorkingDays).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.PROBATION_WORKING_DAY_NEGATIVE_ERROR); record.RuleFor(y => y.ActualWorkingDays).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.ACTUAL_WORKING_DAY_NEGATIVE_ERROR); record.RuleFor(y => y.NonTaxableAllowance).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.NON_TAXABLE_ALLOWANCE_NEGATIVE_ERROR); record.RuleFor(y => y.TaxableAnnualLeave).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.TAXABLE_ANNUAL_LEAVE_NEGATIVE_ERROR); record.RuleFor(y => y.Taxable13MonthSalary).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.TAXABLE_13_MONTH_SALARY_NEGATIVE_ERROR); record.RuleFor(y => y.TaxableOthers).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.TAXABLE_OTHERS_NEGATIVE_ERROR); record.RuleFor(y => y.PaymentAdvance).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.PAYMENT_ADVANCE_NEGATIVE_ERROR); record.RuleFor(y => y.AdjustmentAddition).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.ADJUSTMENT_ADDITION_NEGATIVE_ERROR); record.RuleFor(y => y.AdjustmentDeduction).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.ADJUSTMENT_DEDUCTION_NEGATIVE_ERROR); record.RuleFor(y => y.Currency).NotEmpty().WithMessage(ValiationErrors.CURRENCY_EMPTY_ERROR); }); }
public async Task <Result <List <EmployeeProfile> > > GetAsync(string yearMonth) { try { if (YearMonth.TryParse(yearMonth, out YearMonth selectedYearMonth) is false) { _logger.LogError(Errors.EmployeeProfile.GetProfileYearMonthInvalidError.Message); return(Errors.EmployeeProfile.GetProfileYearMonthInvalidError); } //todo enhancement var profiles = await _dbContext.SyncEmployeeProfiles.ToListAsync(); var filteredProfiles = profiles.Where(x => x.TerminatedDate == null || (x.TerminatedDate != null && new YearMonth(x.TerminatedDate.Value) >= selectedYearMonth)).ToList(); if (filteredProfiles.Count == 0) { _logger.LogError(Errors.EmployeeProfile.GetProfileEmptyError.Message); return(Errors.EmployeeProfile.GetProfileEmptyError); } return(Result <List <EmployeeProfile> > .Ok(filteredProfiles.Select(x => { var dependantEndDates = string.IsNullOrEmpty(x.DependantEndDates) ? Array.Empty <DateTime>() : JsonSerializer.Deserialize <DateTime[]>(x.DependantEndDates); return new EmployeeProfile( email: x.Email, fullname: x.FullName, employeeType: x.EmployeeType, position: x.Position, dependantEndDates: dependantEndDates.Length == 0 ? dependantEndDates : dependantEndDates.Where(x => x == DateTime.MinValue || new YearMonth(x) > new YearMonth(DateTime.UtcNow)) .ToArray(), inUnion: x.InUnion, terminatedDate: x.TerminatedDate, isForeigner: x.IsForeigner); }).ToList())); } catch (SqlException ex) { _logger.LogError(ex, Errors.EmployeeProfile.GetProfileDatabaseError.Message); return(Errors.EmployeeProfile.GetProfileDatabaseError); } }
public SaveSalaryConfigRequestValidation() { this.CascadeMode = CascadeMode.Stop; RuleFor(x => x.YearMonth).NotEmpty().WithMessage(ValiationErrors.YEAR_MONTH_NULL_ERROR) .Must(x => YearMonth.TryParse(x)).WithMessage(ValiationErrors.YEAR_MONTH_INVALID_FORMAT_ERROR); RuleFor(x => x.ProgressiveTaxRates).NotEmpty().WithMessage(ValiationErrors.PROGRESSIVE_TAX_RATE_EMPTY_ERROR) .Must(x => !x.GroupBy(y => y.Rate).Any(g => g.Count() > 1)).WithMessage(ValiationErrors.PROGRESSIVE_TAX_RATE_DUPLICATED_ERROR); RuleForEach(x => x.ProgressiveTaxRates).ChildRules(rate => { rate.RuleFor(y => y.TaxRateLevel).IsInEnum().WithMessage(ValiationErrors.PROGRESSIVE_TAX_RATE_LEVEL_INVALID_ENUM_ERROR); }); RuleForEach(x => x.ProgressiveTaxRates).ChildRules(rate => { rate.RuleFor(y => y.LowerBound).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.LOWER_BOUND_NEGATIVE_ERROR); }); RuleForEach(x => x.ProgressiveTaxRates).ChildRules(rate => { rate.RuleFor(y => y.UpperBound).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.UPPER_BOUND_NEGATIVE_ERROR); }); RuleForEach(x => x.ProgressiveTaxRates).ChildRules(rate => { rate.RuleFor(y => y.Rate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.PROGRESSIVE_TAX_RATE_NEGATIVE_ERROR); }); RuleFor(x => x.SalarySetting).NotNull().WithMessage(ValiationErrors.SALARY_SETTING_NULL_ERROR); RuleFor(x => x.SalarySetting.Id).NotEmpty().WithMessage(ValiationErrors.ID_EMPTY_ERROR); RuleFor(x => x.SalarySetting.CommonMinimumWage).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.COMMON_MINIUM_WAGE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.RegionalMinimumWage).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.REGIONAL_MINIUM_WAGE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.MinimumNonWorkingDay).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.MINIUM_NON_WORKING_DAY_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.DefaultProbationTaxRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.DEFAULT_TAX_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.CoefficientSocialCare).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.COEFFICIENT_SOCIAL_CARE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployeeSocialInsuranceRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYEE_SOCIAL_INSURANCE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployeeHealthCareInsuranceRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYEE_HEALTHCARE_INSURANCE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployeeUnemploymentInsuranceRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYEE_UNEMPLOYMENT_INSURANCE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployeeUnionFeeRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYEE_UNION_FEE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployerSocialInsuranceRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYEE_UNION_FEE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployerHealthCareInsuranceRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_HEALTHCARE_INSURANCE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployerUnemploymentInsuranceRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_UNEMPLOYMENT_INSURANCE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.EmployerUnionFeeRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_UNION_FEE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.MaximumUnionFeeRate).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_UNION_FEE_RATE_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.PersonalDeduction).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_PERSONAL_DEDUCTION_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.DependantDeduction).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_DEPENDANT_DEDUCTION_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.InsurancePaidAmount).GreaterThanOrEqualTo(0).WithMessage(ValiationErrors.EMPPLOYER_DEPENDANT_DEDUCTION_NEGATIVE_ERROR); RuleFor(x => x.SalarySetting.Currency).NotEmpty().WithMessage(ValiationErrors.CURRENCY_EMPTY_ERROR); }
int standardWorkingDays)> > GetAsync(string yearMonth, string key) { try { if (YearMonth.TryParse(yearMonth, out YearMonth selectedYearMonth) is false) { _logger.LogError(Errors.EmpMonthlyEnteredRecord.GetRecordYearMonthInvalidError.Message); return(Errors.EmpMonthlyEnteredRecord.GetRecordYearMonthInvalidError); } if ((await _dbContext.EncryptedEmpMonthlyEnteredRecords.AnyAsync()) is false) { return(Result <(List <EmployeeMonthlyEnteredRecord>, int standardWorkingDays)> .Ok( (new List <EmployeeMonthlyEnteredRecord>(), new MonthlyWorkingDay(yearMonth).CalculatedMonthlyWorkingDays()))); } var existingRecord = await _dbContext.EncryptedEmpMonthlyEnteredRecords .FirstOrDefaultAsync(x => x.EncryptedYearMonth == yearMonth); var newYearMonth = false; if (existingRecord == null) { var closestMonthRecord = await _dbContext.EncryptedEmpMonthlyEnteredRecords .OrderByDescending(x => x.CreatedDate).FirstOrDefaultAsync(); if (closestMonthRecord == null) { _logger.LogError(Errors.EmpMonthlyEnteredRecord.GetRecordNotFoundError.Message); return(Errors.EmpMonthlyEnteredRecord.GetRecordNotFoundError); } //if user selects previous year-month, then check if the closetYearMonth is after or before selectedYearMonth var closestYearMonth = new YearMonth(closestMonthRecord.EncryptedYearMonth); // return empty if it is after, means that previous year-month havent's any record. if (closestYearMonth > selectedYearMonth) { return(Result <(List <EmployeeMonthlyEnteredRecord>, int standardWorkingDays)> .Ok( (new List <EmployeeMonthlyEnteredRecord>(), new MonthlyWorkingDay(yearMonth).CalculatedMonthlyWorkingDays()))); } // use closest monthly salary record for current monthly salary month record existingRecord = closestMonthRecord; newYearMonth = true; } var decruptedJson = _dataProtectionProvider.CreateProtector(key).Unprotect(existingRecord.EncryptedRecord); var decryptedRecords = JsonSerializer.Deserialize <List <DecryptedEmpMonthlyEnteredRecord> >( decruptedJson ); var newMonthlyWorkingDays = new MonthlyWorkingDay(yearMonth).CalculatedMonthlyWorkingDays(); var result = newYearMonth switch { true => (decryptedRecords.Select(x => { var currency = new Currency(x.Currency); return(new EmployeeMonthlyEnteredRecord( fullname: x.Fullname, email: x.Email, grossContractSalary: new GrossContractedSalary(new Money(value: x.GrossContractSalary, currency)), probationGrossContractSalary: new GrossContractedSalary(new Money(value: x.ProbationGrossContractSalary, currency)), actualWorkingDays: newMonthlyWorkingDays, probationWorkingDays: 0, taxableAnnualLeave: new TaxableAllowance(name: x.TaxableAnnualLeave.Name, amount: new Money(0, currency)), taxable13MonthSalary: new TaxableAllowance(name: x.Taxable13MonthSalary.Name, amount: new Money(0, currency)), taxableOthers: new TaxableAllowance(name: x.TaxableOthers.Name, amount: new Money(0, currency)), nonTaxableAllowances: x.NonTaxableAllowances.Select(y => new NonTaxableAllowance(amount: new Money(0, currency), name: y.Name)).ToArray(), paymentAdvance: new PaymentAdvance(new Money(0, currency)), adjustmentAdditions: x.AdjustmentAdditions.Select(y => new AdjustmentAddition(new Money(0, currency))).ToArray(), adjustmentDeductions: x.AdjustmentDeductions.Select(y => new AdjustmentDeduction(new Money(0, currency))).ToArray() )); }).ToList(), newMonthlyWorkingDays), _ => (decryptedRecords.Select(x => { var currency = new Currency(x.Currency); return(new EmployeeMonthlyEnteredRecord( fullname: x.Fullname, email: x.Email, grossContractSalary: new GrossContractedSalary(new Money(value: x.GrossContractSalary, currency)), probationGrossContractSalary: new GrossContractedSalary(new Money(value: x.ProbationGrossContractSalary, currency)), actualWorkingDays: x.ActualWorkingDays, probationWorkingDays: x.ProbationWorkingDays, taxableAnnualLeave: new TaxableAllowance(name: x.TaxableAnnualLeave.Name, amount: new Money(x.TaxableAnnualLeave.Amount, currency)), taxable13MonthSalary: new TaxableAllowance(name: x.Taxable13MonthSalary.Name, amount: new Money(x.Taxable13MonthSalary.Amount, currency)), taxableOthers: new TaxableAllowance(name: x.TaxableOthers.Name, amount: new Money(x.TaxableOthers.Amount, currency)), nonTaxableAllowances: x.NonTaxableAllowances.Select(y => new NonTaxableAllowance(amount: new Money(y.Amount, currency), name: y.Name)).ToArray(), paymentAdvance: new PaymentAdvance(new Money(x.PaymentAdvance, currency)), adjustmentAdditions: x.AdjustmentAdditions.Select(y => new AdjustmentAddition(new Money(y, currency))).ToArray(), adjustmentDeductions: x.AdjustmentDeductions.Select(y => new AdjustmentDeduction(new Money(y, currency))).ToArray() )); }).ToList(), existingRecord.StandardWorkingDays) }; return(Result <(List <EmployeeMonthlyEnteredRecord>, int standardWorkingDays)> .Ok(result)); } catch (CryptographicException ex) { _logger.LogError(ex, Errors.EmpMonthlyEnteredRecord.GetRecordKeyInvalidError.Message); return(Errors.EmpMonthlyEnteredRecord.GetRecordKeyInvalidError); } catch (SqlException ex) { _logger.LogError(ex, Errors.EmpMonthlyEnteredRecord.GetRecordDatabaseError.Message); return(Errors.EmpMonthlyEnteredRecord.GetRecordDatabaseError); } }