# Calculate order price # angular.module('EssayApp.services') .service('orderLogic', ['PriceType', '$filter', (PriceType, $filter) -> # Calculate order price # class OrderPriceLogic base_word_price: 0 base_price: 0 total_language_price: 0 total_base_price: 0 package_price: 0 _language_rates: [] _service_rate: 0 _words_count: 0 _selected_features: {} _urgency_rate: 1 _urgency_division: 1 _package: null _discount: null _onUpdateTotalCost: null _features_rates: [] _capacity_rate: null _settings: { deadline_percentage: 25 # 25% deadline_hours: 12 # 12hrs order_min_base_price: 20 # full order min price is 20$ language_pair_min_price: 10 # any language pair min price is 10$ language_pair_manage_hours: 2 # any extra language pair extra manage time } # # setters: setLanguageRates: (rates)-> @_language_rates = rates @calcTotalCost() setServiceRate: (rate)-> @_service_rate = rate @calcTotalCost() setWordsCount: (count)-> @_words_count = count || 0 @calcTotalCost() setUrgency: (urgency)-> @__urgency = urgency @_urgency_rate = @__urgency?.price || 1 @calcTotalCost() # @_urgency_division = @__urgency?.urgency_division || 1 setPackage: (pkg)-> @_package = pkg @calcTotalCost() setDiscount: (discount)-> @_discount = discount @calcTotalCost() setFeaturesRates: (rates)-> @_features_rates = rates # @calcTotalCost() setSelectedFeatures: (features = {})-> @_selected_features = features @calcTotalCost() setCapacityRate: (rate)-> @_capacity_rate = rate setSettings: (settings = {})-> angular.extend @_settings, settings setOnUpdateTotalCost: (cb = null)-> @_onUpdateTotalCost = cb # # calculations: calcBase: -> _base_word_price = 0 @warn_min_price_applied = false @warn_pair_min_price_applied = false if @_language_rates?.length > 0 _total_language_price = 0 for item, index in @_language_rates _word_price = item.price * @_service_rate || 1 _base_word_price += _word_price if @_package?.price? _package_price = PriceType.calc( @_package.price_type_id, @_package.price, { base: _word_price * (@_urgency_rate || 1) } ) else _package_price = 0 _total_word_price = _word_price * (@_urgency_rate || 1) + _package_price item.base_price = _total_word_price _item_total_price = _total_word_price * @_words_count # with 13.11.2018 update # no need to override language pair total price item.total_price = _item_total_price # but count language_pair_min_price in total price if @_settings.language_pair_min_price > 0 and _item_total_price < @_settings.language_pair_min_price _item_total_price = @_settings.language_pair_min_price item.warn_min_price_applied = true @warn_pair_min_price_applied = true else item.warn_min_price_applied = false _total_language_price += _item_total_price # apply min order price setting if @_settings.order_min_base_price > 0 and _total_language_price < @_settings.order_min_base_price _total_language_price = @_settings.order_min_base_price @warn_min_price_applied = true @total_language_price = _total_language_price @base_word_price = _base_word_price @base_price = _base_word_price * @_words_count * @_urgency_rate # @base_price = @total_language_price if @_package?.price? @package_price = PriceType.calc( @_package.price_type_id, @_package.price, { base: @base_price * (@_urgency_rate || 1) } ) else @package_price = 0 # @total_base_price = @base_price * @_urgency_rate + @package_price @total_base_price = @total_language_price if @language_rates?.length <= 0 @base_word_price = 0 @total_base_price = 0 hasDiscountOffer: -> _base_price = @base_price * @_urgency_rate (@_discount?.price > 0 && @_discount?.min_amount <= _base_price) calcDiscountOffer: -> offer = 0 _base_price = @base_price * @_urgency_rate if @_discount?.price > 0 and @_discount?.min_amount <= _base_price @discount_offer = PriceType.calc( @_discount.price_type_id, @_discount.price, { base: _base_price } ) else @discount_offer = 0 recountFeaturesRates: -> return unless @_features_rates?.length > 0 && @base_price > 0 for rate in @_features_rates options = $.extend { base: @total_base_price }, rate rate.total_price = PriceType.calc(rate.price_type_id, rate.price, options) false calcTotalFeaturesCost: -> return 0 unless @_features_rates?.length > 0 && @_selected_features? _total_features_cost = 0 for rate in @_features_rates if @_selected_features[rate.feature_type_id]?.id == rate.id _total_features_cost += rate.total_price @total_features_cost = _total_features_cost getPackagePrice: (pkg)-> _base = @base_word_price * (@_urgency_rate || 1) _base + PriceType.calc(pkg.price_type_id, pkg.price || 0, { base: _base }) calcTotalCost: -> @calcBase() @recountFeaturesRates() @calcTotalFeaturesCost() @calcDiscountOffer() _total_cost = @total_base_price || 0 _total_cost -= @discount_offer || 0 _total_cost += @total_features_cost || 0 # @total_cost = Math.round(_total_cost * 100 + Number.EPSILON) * 0.01 if @total_cost isnt _total_cost @_onUpdateTotalCost?.call?(@, _total_cost, @total_cost) @total_cost = _total_cost # # dynamic urgency logic countBaseUrgency: -> return null unless @_words_count > 0 && @_capacity_rate? time = { writer: 0 manage: 0 proofread: 0 dayless: false } _urg = @_words_count * 24.0 / @_capacity_rate.words_count / @_capacity_rate.working_hours time.writer = _urg time.dayless = (_urg <= 24) _extra_manage_time = (@_language_rates.length - 1) * @_settings.language_pair_manage_hours _extra_manage_time = 0 unless _extra_manage_time > 0 time.manage = @_settings.deadline_hours + _extra_manage_time time.proofread = time.writer * @_settings.deadline_percentage * 0.01 time countBaseUrgency2: -> return null unless @_words_count > 0 && @_capacity_rate? time = { writer: 0 manage: 0 proofread: 0 dayless: false } _urg = Math.ceil(@_words_count * 1.0 / @_capacity_rate.words_count) if _urg <= @_capacity_rate.working_hours time.dayless = true time.writer = _urg else time.writer = Math.floor(_urg / @_capacity_rate.working_hours) * 24.0 + _urg % @_capacity_rate.working_hours _proofread = Math.ceil(_urg * @_settings.deadline_percentage * 0.01) if _proofread <= @_capacity_rate.working_hours time.proofread = _proofread else time.proofread = Math.floor(_proofread / @_capacity_rate.working_hours) * 24.0 + _proofread % @_capacity_rate.working_hours time.manage = @_settings.deadline_hours time _getUTHours: (time, division)-> ans = time.proofread + time.writer / (if time.dayless then 1 else division) ans += time.manage / (if time.dayless then division else 1) ans recountUrgencyHours: (urgency_rates, free_quote_only = false)-> return unless urgency_rates?.length > 0 _base_time = @countBaseUrgency() for urgency in urgency_rates if _base_time? && urgency.price > 0 _hrs = @_getUTHours(_base_time, urgency.urgency_division) urgency.hours = Math.ceil(_hrs) urgency.days = Math.ceil(_hrs / 24) urgency.pretty_title = $filter('formattedHours')(urgency.hours) else urgency.hours = null urgency.days = null urgency.pretty_title = null urgency.disabled = urgency.price > 0 && (!_base_time? || free_quote_only) { build: () -> new OrderPriceLogic() } ])