public virtual async Task <DeliveryChargeEntity> CalculateAsync(int addressId, int deliveryScheduleId, float subtotal, bool hasPromotion = false)
        {
            var addrE = await AddressRepository.FindAsync(addressId) ?? throw new EntityNotFoundException();

            var dScheduleE = await DeliveryScheduleRepository.FindAsync(deliveryScheduleId) ?? throw new EntityNotFoundException();

            var riderEs = await RiderRepository.GetRidersForTheCity(addrE.CityID);

            var meanDistance    = GetMeanDistance(addrE, riderEs);
            var distanceChargeE = await AsyncExecutor.LastOrDefaultAsync(DistanceChargeRepository
                                                                         .Where(e => e.From < meanDistance)
                                                                         .OrderBy(e => e.From));

            var subtotalPercentageE = await AsyncExecutor.LastOrDefaultAsync(SubtotalPercentageRepository.Where(e => e.From < subtotal)
                                                                             .OrderBy(e => e.From));

            var charge = subtotal * subtotalPercentageE.Percentage;

            charge += (hasPromotion)? 0 : distanceChargeE.Charge;

            charge += charge * dScheduleE.CostIncreasePercentage;

            return(new DeliveryChargeEntity(charge, distanceChargeE.Id, subtotalPercentageE.Id, dScheduleE.Id));
        }