def save(self, *args, **kwargs): if self.annual_income_from and (self.id is None or self._original_annual_income_from != self.annual_income_from): self.annual_income_from_in_base_currency = convert_money( self.annual_income_from, settings.BASE_CURRENCY) if self.annual_income_to and ( self.id is None or self._original_annual_income_to != self.annual_income_to): self.annual_income_to_in_base_currency = convert_money( self.annual_income_to, settings.BASE_CURRENCY) return super().save(*args, **kwargs)
def convert(money, currency): """ Convert money object `money` to `currency`.""" if hasattr(currency, 'code'): currency = currency.code if money.currency.code == currency: return money if money.currency.code != settings.BASE_CURRENCY and currency != settings.BASE_CURRENCY: money = convert_money(money, settings.BASE_CURRENCY) return convert_money(money, currency)
def get_value(self, obj): to_currency = self.context.get('to_currency', None) try: search_term = obj.integralfilter.name.data.values() except AttributeError: search_term = str(obj.integralfilter.name) if to_currency and ('Price' in search_term): original_prices = obj.integralfilter.integral_choices.values_list( 'room_characteristics__price_currency__code', 'selected_number') converted_prices = [] for from_currency, original_price in original_prices: if not from_currency: from_currency = 'USD' converted_prices.append( int( convert_money(Money(original_price, from_currency), to_currency).amount)) self.min_value = min(converted_prices) self.max_value = max(converted_prices) else: aggregate_min_max = obj.integralfilter.integral_choices.aggregate( django_models.Max('selected_number'), django_models.Min('selected_number')) self.min_value = aggregate_min_max['selected_number__min'] self.max_value = aggregate_min_max['selected_number__max'] return [self.min_value, self.max_value]
def totalamount(self): global_preferences = global_preferences_registry.manager() return sum([ convert_money(c.amount_formatted(), global_preferences["contributions__currency"]) for c in self.contributions.all() ])
def get_prices_converted_cases(filtered_rooms): filtered_rooms_ids = filtered_rooms.values_list('id', flat=True) original_prices = IntegralChoice.objects.filter( related_filter__name__contains='Price', room_characteristics__id__in=filtered_rooms_ids).values_list( 'room_characteristics__id', 'selected_number') price_whens = [ django_models.When(id=k, then=v) for k, v in original_prices ] original_price_cases = django_models.Case( *price_whens, default=0, output_field=django_models.IntegerField()) prices_to_convert = filtered_rooms.annotate( original_price=original_price_cases).values_list( 'id', 'original_price', 'price_currency__code') converted_prices = {} for id, original_price, from_currency in prices_to_convert: #print(id, original_price, from_currency) converted_prices[id] = int( convert_money(Money(original_price, from_currency), to_currency).amount) whens = [ django_models.When(id=k, then=v) for k, v in converted_prices.items() ] new_prices_cases = django_models.Case( *whens, default=0, output_field=django_models.IntegerField()) return new_prices_cases
def post(self, request): serializer = ItemOrderSerializer(data=request.data) serializer.is_valid(raise_exception=True) item = serializer.validated_data['item'] amount = serializer.validated_data['amount'] price = convert_money(Money(item.price.amount, item.price.currency), DEFAULT_CURRENCY) stock = item.stock if stock is not None: price -= price * stock.percent serializer = ItemOrderSerializer({ 'item': item, 'vendor_code': item.vendor_code, 'name': item.name, 'amount': amount, 'unit': item.unit, 'price': price.amount, 'price_currency': price.currency, }) items = request.session.get(BASKET_KEY, {}) items[str(serializer.data['item'])] = serializer.data request.session[BASKET_KEY] = items request.session.modified = True item_order = items[str(item.pk)].copy() item_order['item'] = item serializer = ItemOrderReadOnlySerializer(item_order) return Response(serializer.data)
def convert_price(price, currency, decimal_places=4): """ Convert price field, returns Money field """ price_adjusted = None # Get default currency from settings default_currency = InvenTreeSetting.get_setting( 'INVENTREE_DEFAULT_CURRENCY') if price: if currency and default_currency: try: # Get adjusted price price_adjusted = convert_money(Money(price, currency), default_currency) except MissingRate: # No conversion rate set price_adjusted = Money(price, currency) else: # Currency exists if currency: price_adjusted = Money(price, currency) # Default currency exists if default_currency: price_adjusted = Money(price, default_currency) if price_adjusted and decimal_places: price_adjusted.decimal_places = decimal_places return price_adjusted
def income(request): if request.method == 'POST': form = IncomeForm(request.POST) if form.is_valid(): amount = form.cleaned_data['amount'] tx_date = form.cleaned_data['date'] source = form.cleaned_data['source'] user = request.user # only save as USD, but note what the original amount was # also store original amount and flip converted to true if amount.currency != Currency('USD'): fxamount = amount converted = True amount = convert_money(amount, 'USD') Income.objects.create(amount=amount, date=tx_date, source=source, user=user, fxamount=fxamount, converted=converted) else: Income.objects.create(amount=amount, date=tx_date, source=source, user=user) return HttpResponseRedirect(reverse('record:index')) context = {'form': IncomeForm(), 'form_type': 'income'} return render(request, 'record/record.html', context=context)
def get(self, request): user = request.user room_id = request.GET.get('room_id', None) currency = request.GET.get('display_currency', None) check_in = request.GET.get('checkin') check_in_date = datetime.datetime.strptime(check_in, '%Y-%m-%d') check_out = request.GET.get('checkout') check_out_date = datetime.datetime.strptime(check_out, '%Y-%m-%d') if check_out else None guests_total = request.GET.get('adults') room = Room.objects.prefetch_related( 'bedroom_set', 'bath_set', 'review_set', 'roomimage_set' ).get(id=room_id) user_currency = UserProfile.objects.get(user=user).currency.name if user else "USD" price = room.price if currency: backend = OpenExchangeRatesBackend(OPEN_EXCHANGE_RATES_URL) price_currency = convert_money(Money(room.price, user_currency), currency) price_split = str(price_currency).replace(',', '').split(' ') price_numeric = re.sub("[^0-9.]", "", price_split[0]) price = str(int(float(price_numeric))) + " " + currency num_beds = 0 for bedroom in room.bedroom_set.all(): num_beds += bedroom.bed_set.aggregate(Sum('quantity'))['quantity__sum'] ratings_dict = room.review_set.aggregate(\ *[Avg(field) for field in ['rating__cleanliness', 'rating__communication', \ 'rating__check_in', 'rating__accuracy', 'rating__location', 'rating__value']]) overall_rating = 0 if None in ratings_dict.values() else sum(ratings_dict.values())/6 booking_information = { 'room_id' : room.id, 'title' : room.title, 'room_picture' : room.roomimage_set.values_list('image_url', flat=True)[0], 'check_in_time' : room.check_in.strftime("%-I:%M"), 'check_out_time' : room.check_out.strftime("%-I:%M"), 'check_in_date' : check_in, 'check_out_date' : check_out, 'place_type' : room.place_type.name, 'guests_total' : guests_total, 'bedrooms' : room.bedroom_set.count(), 'beds' : num_beds, 'baths' : room.bath_set.count(), 'currency' : currency if currency else user_currency, 'price' : price, 'discount_rate' : calculate_discounts(room, check_in_date, check_out_date), 'rules' : room.rules, 'overall_rating' : overall_rating, 'num_reviews' : room.review_set.count(), 'host_name' : room.host.fullname, 'host_avatar' : room.host.profile.avatar_image, 'profile_header' : room.host.profile.profile_header, 'user_since' : room.host.created_at.strftime("%Y"), 'payment_methods' : list(PaymentMethod.objects.values_list('name', flat=True)) } return JsonResponse({'booking_information':booking_information}, status=200)
def to_representation(self, instance): representation = super(ServiceAreaSerializer, self).to_representation(instance) representation['provider'] = '/api/v1/providers/{}/'.format( instance.provider.id) representation['price'] = convert_money( instance.price, instance.provider.currency).amount return representation
def expense(request): # save new transaction information to database or load expense form if request.method == 'POST': # expense submission form = ExpenseForm(request.POST) if form.is_valid(): # save the input amount = form.cleaned_data['amount'] tx_date = form.cleaned_data['date'] cat = form.cleaned_data['category'] method = form.cleaned_data['method'] comment = form.cleaned_data['comment'] tag = form.cleaned_data['tag'] user = request.user # only save as USD, but note what the original amount was # also store original amount and flip converted to true if amount.currency != Currency('USD'): fxamount = amount converted = True comment = comment + ' *ORIGINAL [' + str(amount) + ']*' amount = convert_money(amount, 'USD') Expense.objects.create(amount=amount, date=tx_date, category=cat, method=method, comment=comment, tag=tag, user=user, fxamount=fxamount, converted=converted) else: # otherwise store as submitted Expense.objects.create(amount=amount, date=tx_date, category=cat, method=method, comment=comment, tag=tag, user=user) # change to new month, if different from current. also adds new month to navbar set_month(request, tx_date.year, tx_date.month) # load the index page return HttpResponseRedirect(reverse('record:index')) context = { 'message': f'Error. Form did not properly validate. Errors: {form.errors}', 'message_type': 'danger' } return render(request, 'record/index.html', context=context) # if not POST, load form context = {'form': ExpenseForm(), 'form_type': 'expense'} return render(request, 'record/record.html', context=context)
def total_limit_shekels(self): total = Money(0, 'ILS') for card in self.credit_cards.all(): if card.spending_limit_currency != 'ILS': converted = convert_money(card.spending_limit, 'ILS') total += converted else: total += card.spending_limit return total
def total_due_dollars(self): total = Money(0, 'USD') for card in self.credit_cards.all(): if card.spending_limit_currency != 'USD': converted = convert_money(card.balance_due, 'USD') total += converted else: total += card.balance_due return total
def total_bank_shekels(self): total = Money(0, 'ILS') for account in self.bank_accounts.all(): if account.currency.name != 'ILS': converted = convert_money(account.balance, 'ILS') total += converted else: total += account.balance return total
def save(self, *args, **kwargs): if self.id is None: self.profile_id = self.generate_profile_id() if self.annual_income and ( self.id is None or self._original_annual_income != self.annual_income): self.annual_income_in_base_currency = convert_money( self.annual_income, settings.BASE_CURRENCY) super().save(*args, **kwargs) _, created = MatrimonyProfileStats.objects.get_or_create(profile=self) _, created = Expectation.objects.get_or_create(profile=self)
def save(self, *args, **kwargs): if not self.currency or self.currency == 'USD': self.currency = self.chain_instance.currency for field in ( 'reward_per_click', 'remaining_balance', 'initial_budget', ): if getattr(self, field, False): value = Money(getattr(self, field).amount, 'USD') setattr(self, field, convert_money(value, self.chain_instance.currency)) return super(Task, self).save(*args, **kwargs)
def convert_to(self, currency_code): """ Convert the unit-price at this price break to the specified currency code. Args: currency_code - The currency code to convert to (e.g "USD" or "AUD") """ try: converted = convert_money(self.price, currency_code) except MissingRate: print(f"WARNING: No currency conversion rate available for {self.price_currency} -> {currency_code}") return self.price.amount return converted.amount
def get_total_balance_of(queryset: QuerySet, currency: str) -> Money: """ This function sums all balances in `queryset` according to their currencies. And converts them to one `currency`. And it returns a Money object with `currency` and a convertible balance. """ balance_in_currency = Money(0, currency) balances_in_currencies = queryset.values('balance_currency').annotate( balance=Sum('balance')) for balance in balances_in_currencies: balance = Money(balance['balance'], balance['balance_currency']) balance_in_currency += convert_money(balance, currency) return round(balance_in_currency, 2)
def incomes_by_category_statistic(queryset: QuerySet, currency='UAH'): """ """ # aggregate data grouped by categories and their currencies data = queryset \ .values('amount_currency', 'category') \ .annotate(sum=Sum('amount')) result = defaultdict(list) result_sum = Decimal() categories = defaultdict(list) # item_id: [ # {'item_currency1': ..., 'item_amount1': ... }, # {'item_currency2': ..., 'item_amount2': ... }, # ... # ] for item in data: item_category_id = item['category'] item_currency = item['amount_currency'] item_amount = item['sum'] categories[item_category_id].append({ 'currency': item_currency, 'amount': item_amount }) for key, value in categories.items(): sum_money = Money(0, currency) for amount in value: amount = Money(amount['amount'], amount['currency']) sum_money += convert_money(amount, currency) result_sum += sum_money.amount result['categories'].append({ 'id': key, 'amounts': value, 'sum': round(sum_money.amount, 2) }) result['sum'] = round(result_sum, 2) result['currency'] = currency return (result)
def get_queryset(self): user_currency = User.objects.filter( pk=self.request.user.id).values_list('currency') user_currency = user_currency[0][0] print(user_currency) queryset = Product.objects.get_queryset() for product in queryset: pk = product.pk price = product.price print(pk, price) converted_price = str(convert_money(price, user_currency)) print(converted_price) Product.objects.filter(pk=pk).update( customer_price=converted_price) return queryset
def get(self, request): item_orders = request.session.get(BASKET_KEY, {}) bill_items = [] total = Money('0', DEFAULT_CURRENCY) for item, item_order in item_orders.items(): cost = convert_money(Money(item_order['price'], item_order['price_currency']) * item_order['amount'], DEFAULT_CURRENCY) bill_items.append({ 'id': item, 'name': item_order['name'], 'amount': item_order['amount'], 'unit': item_order['unit'], 'cost': cost.amount, 'cost_currency': cost.currency, }) total += cost serializer = BasketOrderSerializer({ 'order': request.session.get(ORDER_KEY, defaultdict(lambda: None)), 'bill': { 'cost': total.amount, 'cost_currency': total.currency }, 'items': bill_items, }) return Response(serializer.data)
def test_rates(self): # Initially, there will not be any exchange rate information rates = Rate.objects.all() self.assertEqual(rates.count(), 0) # Without rate information, we cannot convert anything... with self.assertRaises(MissingRate): convert_money(Money(100, 'USD'), 'AUD') with self.assertRaises(MissingRate): convert_money(Money(100, 'AUD'), 'USD') update_successful = False # Note: the update sometimes fails in CI, let's give it a few chances for idx in range(10): InvenTree.tasks.update_exchange_rates() rates = Rate.objects.all() if rates.count() == len(currency_codes()): update_successful = True break else: # pragma: no cover print("Exchange rate update failed - retrying") time.sleep(1) self.assertTrue(update_successful) # Now that we have some exchange rate information, we can perform conversions # Forwards convert_money(Money(100, 'USD'), 'AUD') # Backwards convert_money(Money(100, 'AUD'), 'USD') # Convert between non base currencies convert_money(Money(100, 'CAD'), 'NZD') # Convert to a symbol which is not covered with self.assertRaises(MissingRate): convert_money(Money(100, 'GBP'), 'ZWL')
def get_pricing(self, quantity=1, currency=None): """Returns context with pricing information.""" ctx = PartPricing.get_pricing(self, quantity, currency) part = self.get_part() default_currency = inventree_settings.currency_code_default() # Stock history if part.total_stock > 1: price_history = [] stock = part.stock_entries(include_variants=False, in_stock=True).\ order_by('purchase_order__issue_date').prefetch_related('purchase_order', 'supplier_part') for stock_item in stock: if None in [stock_item.purchase_price, stock_item.quantity]: continue # convert purchase price to current currency - only one currency in the graph try: price = convert_money(stock_item.purchase_price, default_currency) except MissingRate: continue line = {'price': price.amount, 'qty': stock_item.quantity} # Supplier Part Name # TODO use in graph if stock_item.supplier_part: line['name'] = stock_item.supplier_part.pretty_name if stock_item.supplier_part.unit_pricing and price: line[ 'price_diff'] = price.amount - stock_item.supplier_part.unit_pricing line[ 'price_part'] = stock_item.supplier_part.unit_pricing # set date for graph labels if stock_item.purchase_order and stock_item.purchase_order.issue_date: line[ 'date'] = stock_item.purchase_order.issue_date.isoformat( ) elif stock_item.tracking_info.count() > 0: line['date'] = stock_item.tracking_info.first().date.date( ).isoformat() else: # Not enough information continue price_history.append(line) ctx['price_history'] = price_history # BOM Information for Pie-Chart if part.has_bom: # get internal price setting use_internal = InvenTreeSetting.get_setting( 'PART_BOM_USE_INTERNAL_PRICE', False) ctx_bom_parts = [] # iterate over all bom-items for item in part.bom_items.all(): ctx_item = {'name': str(item.sub_part)} price, qty = item.sub_part.get_price_range( quantity, internal=use_internal), item.quantity price_min, price_max = 0, 0 if price: # check if price available price_min = str((price[0] * qty) / quantity) if len(set(price)) == 2: # min and max-price present price_max = str((price[1] * qty) / quantity) ctx['bom_pie_max'] = True # enable showing max prices in bom ctx_item['max_price'] = price_min ctx_item['min_price'] = price_max if price_max else price_min ctx_bom_parts.append(ctx_item) # add to global context ctx['bom_parts'] = ctx_bom_parts # Sale price history sale_items = PurchaseOrderLineItem.objects.filter(part__part=part).order_by('order__issue_date').\ prefetch_related('order', ).all() if sale_items: sale_history = [] for sale_item in sale_items: # check for not fully defined elements if None in [sale_item.purchase_price, sale_item.quantity]: continue try: price = convert_money(sale_item.purchase_price, default_currency) except MissingRate: continue line = { 'price': price.amount if price else 0, 'qty': sale_item.quantity, } # set date for graph labels if sale_item.order.issue_date: line['date'] = sale_item.order.issue_date.isoformat() elif sale_item.order.creation_date: line['date'] = sale_item.order.creation_date.isoformat() else: line['date'] = _('None') sale_history.append(line) ctx['sale_history'] = sale_history return ctx
def test_bad_configuration(settings): settings.INSTALLED_APPS.remove("djmoney.contrib.exchange") with pytest.raises(ImproperlyConfigured): convert_money(Money(1, "USD"), "EUR")
def test_bad_configuration(settings): settings.INSTALLED_APPS.remove('djmoney.contrib.exchange') with pytest.raises(ImproperlyConfigured): convert_money(Money(1, 'USD'), 'EUR')
def search_and_match(self, manufacturer_part, quantity=1, currency=None): manufacturer = manufacturer_part.manufacturer manufacturer_part_number = manufacturer_part.manufacturer_part_number if manufacturer: manufacturer_list = self.api.get_manufacturer_list() # TODO: possibly get manufacturer id from manufacturer list, do a fuzzy lookup using manufacturer name # to reduce results mfg_id = manufacturer_list[ manufacturer. name] if manufacturer.name in manufacturer_list else None if mfg_id: results = self.api.search_part_and_manufacturer( part_number=manufacturer_part_number, manufacturer_id=mfg_id) else: results = self.api.search_part( part_number=manufacturer_part_number) else: results = self.api.search_part( part_number=manufacturer_part_number) mouser_parts = [] optimal_part = None seller_parts = [] for part in results['Parts']: seller = Seller(name='Mouser') try: quantity_available = [ int(s) for s in part['Availability'].split() if s.isdigit() ][0] mouser_part = { 'part_number': part['ManufacturerPartNumber'], 'manufacturer': part['Manufacturer'], 'description': part['Description'], 'data_sheet': part['DataSheetUrl'], 'stock': part['Availability'], 'stock_parsed': quantity_available, 'lead_time': part['LeadTime'], 'seller_parts': [], 'product_detail_url': part['ProductDetailUrl'], } lead_time_days = [ int(s) for s in part['LeadTime'].split() if s.isdigit() ][0] # TODO: Make sure it's actually days for pb in part['PriceBreaks']: moq = int(pb['Quantity']) unit_price_raw = parse_number(pb['Price']) unit_currency = pb['Currency'] unit_cost = Money(unit_price_raw, unit_currency) if currency: unit_cost = convert_money(unit_cost, currency) seller_part = SellerPart( seller=seller, manufacturer_part=manufacturer_part, minimum_order_quantity=moq, minimum_pack_quantity=1, data_source='Mouser', unit_cost=unit_cost, lead_time_days=lead_time_days, nre_cost=Money(0, currency), ncnr=True) mouser_part['seller_parts'].append(seller_part.as_dict()) seller_parts.append(seller_part) mouser_parts.append(mouser_part) except (KeyError, AttributeError, IndexError): continue local_seller_parts = list(manufacturer_part.seller_parts()) seller_parts.extend(local_seller_parts) return { 'mouser_parts': mouser_parts, 'optimal_seller_part': SellerPart.optimal(seller_parts, quantity), }
def change_currency(money_object, currency_code): return convert_money(money_object, currency_code)
def test_rates(self): # Initially, there will not be any exchange rate information rates = Rate.objects.all() self.assertEqual(rates.count(), 0) # Without rate information, we cannot convert anything... with self.assertRaises(MissingRate): convert_money(Money(100, 'USD'), 'AUD') with self.assertRaises(MissingRate): convert_money(Money(100, 'AUD'), 'USD') currencies = settings.CURRENCIES InvenTree.tasks.update_exchange_rates() rates = Rate.objects.all() self.assertEqual(rates.count(), len(currencies)) # Now that we have some exchange rate information, we can perform conversions # Forwards convert_money(Money(100, 'USD'), 'AUD') # Backwards convert_money(Money(100, 'AUD'), 'USD') # Convert between non base currencies convert_money(Money(100, 'CAD'), 'NZD') # Convert to a symbol which is not covered with self.assertRaises(MissingRate): convert_money(Money(100, 'GBP'), 'ZWL')
def convertMoney(moneyobject, currency): return convert_money(moneyobject, currency)
class AssignmentForm(forms.Form): title = _("Assignment") layout = hg.BaseElement( _layout.datatable.DataTable( columns=( _layout.datatable.DataTableColumn(_("Date"), hg.C("row.date"), None), _layout.datatable.DataTableColumn(_("Note"), hg.C("row.note"), None), _layout.datatable.DataTableColumn(_("Account"), hg.C("row.debitaccount"), None), _layout.datatable.DataTableColumn(_("Cost Center"), hg.C("row.creditaccount"), None), _layout.datatable.DataTableColumn( _("Person Number"), hg.C("row.person.personnumber"), None), _layout.datatable.DataTableColumn(_("Donor Number"), hg.C("row.donornumber"), None), _layout.datatable.DataTableColumn( _("Assignment state"), hg.If( hg.C("row.person"), _layout.icon.Icon( "checkmark--filled", size=16, style="fill: currentColor; color: green;", ), _layout.icon.Icon( "warning", size=16, style="fill: currentColor; color: red;", ), ), None, ), _layout.datatable.DataTableColumn(_("Amount"), hg.C("row.amount_formatted"), None), ), row_iterator=hg.C("contributions"), ).with_toolbar(_("Overview of contributions to import"), hg.C("importfile")), hg.DIV( hg.DIV( hg.DIV( hg.F(lambda c: len(c["contributions"])), " ", _("contributions"), _class="bx--batch-summary", ), hg.DIV( _("Sum"), hg.SPAN("|", style="margin-left: 1rem; margin-right: 1rem"), hg.F(lambda c: sum([ convert_money( Money(contr.amount, contr.currency), global_preferences["contributions__currency"], ) for contr in c["contributions"] ]) or Money(0, global_preferences["contributions__currency" ])), style= "position: absolute; right: 0; margin-right: 1rem; color: #ffffff", ), _class="bx--batch-actions--active bx--batch-actions", ), _class="bx--table-toolbar", style="margin-bottom: 4rem", ), hg.DIV(style="margin-bottom: 2rem"), hg.If( hg.C("unassigned_contributions"), _layout.notification.InlineNotification( hg.BaseElement( hg.F(lambda c: len([ c for c in c.get("contributions", ()) if not c.person ])), _(" contributions could not been assigned"), ), _("Please make sure that each entry has contributor number " "which matches with a person number and do the import again" ), kind="error", lowcontrast=True, action=( _("Cancel import"), "window.location = window.location.pathname + '?reset=1'", ), style="max-width: 100%", ), _layout.notification.InlineNotification( _("Assignment complete"), _("Continue in order to complete the import"), kind="success", style="max-width: 100%", ), ), )