Repository: inventree/InvenTree

Issue:
Part BOM is not displayed #2
Seems to be BOM issue again.
If it matters: I changed my deployment to gunicorn + apache mod_proxy.

# Version Information:
InvenTree-Version: 0.3.1
Django Version: 3.2.4
Commit Hash: bcfb3ac
Commit Date: 2021-07-24
Database: mysql
Debug-Mode: True
Deployed using Docker: False

![изображение](https://user-images.githubusercontent.com/10057327/126893689-a5612e54-1353-48bf-ac56-48850828e4e8.png)
![изображение](https://user-images.githubusercontent.com/10057327/126893704-a2a48fc4-c3d6-4f53-8571-48801d58d6e0.png)



Discussion:
What page / view are you trying to access when you see this error? 

Part page with id 489. 
When part BOM did not load I opened dev console and saw this error. 
Cannot reproduce locally... anything special about this BoM?
I did a little research and found that this issue was caused by BOM item with stockitem whose `purchase_price` was more than specific amount. In my case, more than 140 RUB.
It looks like some kind of conversion error because if change `purchase_price` to lower value then Part BOM is displayed but with weird price.

stock_stockitem 
```
[
  {
    "id": 604,
    "serial": null,
    "link": "",
    "batch": null,
    "quantity": 3.00000,
    "updated": "2021-07-26",
    "stocktake_date": null,
    "review_needed": 0,
    "delete_on_deplete": 1,
    "status": 10,
    "notes": null,
    "infinite": 0,
    "belongs_to_id": null,
    "location_id": 3,
    "part_id": 490,
    "stocktake_user_id": null,
    "supplier_part_id": null,
    "purchase_order_id": null,
    "build_id": null,
    "level": 0,
    "lft": 1,
    "parent_id": null,
    "rght": 2,
    "tree_id": 404,
    "uid": "",
    "sales_order_id": null,
    "customer_id": null,
    "is_building": 0,
    "purchase_price": 100.0000,
    "purchase_price_currency": "RUB",
    "expiry_date": null,
    "owner_id": null,
    "packaging": null
  },
  {
    "id": 504,
    "serial": null,
    "link": "",
    "batch": null,
    "quantity": 1.00000,
    "updated": "2021-07-12",
    "stocktake_date": null,
    "review_needed": 0,
    "delete_on_deplete": 1,
    "status": 10,
    "notes": null,
    "infinite": 0,
    "belongs_to_id": null,
    "location_id": 3,
    "part_id": 490,
    "stocktake_user_id": null,
    "supplier_part_id": null,
    "purchase_order_id": null,
    "build_id": null,
    "level": 0,
    "lft": 1,
    "parent_id": null,
    "rght": 2,
    "tree_id": 317,
    "uid": "",
    "sales_order_id": null,
    "customer_id": null,
    "is_building": 0,
    "purchase_price": null,
    "purchase_price_currency": "USD",
    "expiry_date": null,
    "owner_id": null,
    "packaging": null
  }
]
```

/api/bom
```
{
        "allow_variants": false,
        "inherited": false,
        "note": "",
        "optional": false,
        "overage": "",
        "pk": 9,
        "part": 489,
        "purchase_price_avg": "7,393.1687 руб.",
        "purchase_price_max": "7393.168712",
        "purchase_price_min": "7393.168712",
        "purchase_price_range": "7,393.1687 руб.",
        "quantity": 1.0,
        "reference": "U2",
        "sub_part": 490,
        "sub_part_detail": {
            "pk": 490,
            "IPN": null,
            "name": "EPM1270T144C5N",
            "revision": null,
            "full_name": "EPM1270T144C5N",
            "description": "Altera MAX II CPLD",
            "thumbnail": "/media/part_images/part_490_image.thumbnail.png",
            "active": true,
            "assembly": false,
            "is_template": false,
            "purchaseable": true,
            "salable": false,
            "stock": 4.0,
            "trackable": false,
            "virtual": false
        },
        "price_range": null,
        "validated": true
    },

```
Umm yeah there is something fishy happening in the `price_range` calculation:

``` json
        "purchase_price_avg": "7,393.1687 руб.",
        "purchase_price_max": "7393.168712",
        "purchase_price_min": "7393.168712",
        "purchase_price_range": "7,393.1687 руб.",
```

Given `7,393.1687 руб.` is not a valid `Decimal` format, it will hit that error you reported when fetching the view.
I'll take a look.

Resolving patch:
diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py
--- a/InvenTree/part/api.py
+++ b/InvenTree/part/api.py
@@ -995,8 +995,9 @@ def filter_queryset(self, queryset):
 
         # Get values for currencies
         currencies = queryset.annotate(
+            purchase_price=F('sub_part__stock_items__purchase_price'),
             purchase_price_currency=F('sub_part__stock_items__purchase_price_currency'),
-        ).values('pk', 'sub_part', 'purchase_price_currency')
+        ).values('pk', 'sub_part', 'purchase_price', 'purchase_price_currency')
 
         def convert_price(price, currency, decimal_places=4):
             """ Convert price field, returns Money field """
@@ -1032,7 +1033,7 @@ def convert_price(price, currency, decimal_places=4):
             # Find associated currency (select first found)
             purchase_price_currency = None
             for currency_item in currencies:
-                if currency_item['pk'] == bom_item.pk and currency_item['sub_part'] == bom_item.sub_part.pk:
+                if currency_item['pk'] == bom_item.pk and currency_item['sub_part'] == bom_item.sub_part.pk and currency_item['purchase_price']:
                     purchase_price_currency = currency_item['purchase_price_currency']
                     break
             # Convert prices


Test patch: