internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: inventree/InvenTree

Issue:
Error exporting BOM in YAML format
The error is:

![Error](https://user-images.githubusercontent.com/14631/113969183-5db13200-97e9-11eb-918c-c84d23a8eb21.png "Error")


Discussion:
Quick investigation leads to a lack of representation for decimal format in the PyYAML library, and `safe_dump` fails.

To reproduce:
``` python
>>> import yaml, decimal
>>> dec = decimal.Decimal('7')
>>> print(dec)
7
>>> type(dec)
<class 'decimal.Decimal'>
>>> yaml.safe_dump(dec)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/francois/Desktop/github/InvenTree/env-inventree/lib/python3.8/site-packages/yaml/__init__.py", line 216, in safe_dump
    return dump_all([data], stream, Dumper=SafeDumper, **kwds)
  File "/home/francois/Desktop/github/InvenTree/env-inventree/lib/python3.8/site-packages/yaml/__init__.py", line 188, in dump_all
    dumper.represent(data)
  File "/home/francois/Desktop/github/InvenTree/env-inventree/lib/python3.8/site-packages/yaml/representer.py", line 26, in represent
    node = self.represent_data(data)
  File "/home/francois/Desktop/github/InvenTree/env-inventree/lib/python3.8/site-packages/yaml/representer.py", line 57, in represent_data
    node = self.yaml_representers[None](self, data)
  File "/home/francois/Desktop/github/InvenTree/env-inventree/lib/python3.8/site-packages/yaml/representer.py", line 229, in represent_undefined
    raise RepresenterError("cannot represent an object", data)
yaml.representer.RepresenterError: ('cannot represent an object', Decimal('7'))
```

Resolving patch:
diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py
--- a/InvenTree/part/admin.py
+++ b/InvenTree/part/admin.py
@@ -16,8 +16,6 @@
 from .models import PartTestTemplate
 from .models import PartSellPriceBreak
 
-from InvenTree.helpers import normalize
-
 from stock.models import StockLocation
 from company.models import SupplierPart
 
@@ -180,7 +178,7 @@ def dehydrate_quantity(self, item):
 
         Ref: https://django-import-export.readthedocs.io/en/latest/getting_started.html#advanced-data-manipulation-on-export
         """
-        return normalize(item.quantity)
+        return float(item.quantity)
 
     def before_export(self, queryset, *args, **kwargs):
 


Test patch:
Repository: inventree/InvenTree

Issue:
use instance name in title and views?
@SchrodingersGat this is just a suggestion - close this if you disagree, no hard feelings.

There are a few views and (meta) titles where 'InvenTree' is used where it could make sense to use the instance name. I currently have a few instances deployed in places where English is not widely used or known. A few users, especially in manufacturing, are confused by the 'InvenTree' as they are used to only use the internal system names (for exampel 'TeilDB').

I would make a PR replacing 'InvenTree' with the instance name in all end-user facing parts. About, version and setting-views should keep 'InvenTree' in my opinion as to show what system is used.


Discussion:
I'm not opposed to this, feel free to submit a PR showing how you would like to see it implemented

Resolving patch:
diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py
--- a/InvenTree/InvenTree/version.py
+++ b/InvenTree/InvenTree/version.py
@@ -19,6 +19,14 @@ def inventreeInstanceName():
     return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")
 
 
+def inventreeInstanceTitle():
+    """ Returns the InstanceTitle for the current database """
+    if common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE_TITLE", False):
+        return common.models.InvenTreeSetting.get_setting("INVENTREE_INSTANCE", "")
+    else:
+        return 'InvenTree'
+
+
 def inventreeVersion():
     """ Returns the InvenTree version string """
     return INVENTREE_SW_VERSION
diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -58,6 +58,13 @@ class InvenTreeSetting(models.Model):
             'description': _('String descriptor for the server instance'),
         },
 
+        'INVENTREE_INSTANCE_TITLE': {
+            'name': _('Use instance name'),
+            'description': _('Use the instance name in the title-bar'),
+            'validator': bool,
+            'default': False,
+        },
+
         'INVENTREE_COMPANY_NAME': {
             'name': _('Company name'),
             'description': _('Internal company name'),
diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -71,6 +71,12 @@ def inventree_instance_name(*args, **kwargs):
     return version.inventreeInstanceName()
 
 
+@register.simple_tag()
+def inventree_title(*args, **kwargs):
+    """ Return the title for the current instance - respecting the settings """
+    return version.inventreeInstanceTitle()
+
+
 @register.simple_tag()
 def inventree_version(*args, **kwargs):
     """ Return InvenTree version string """


Test patch:
Repository: inventree/InvenTree

Issue:
Question about part selling
Use cases:
1. Create a sale order.
2. Add part with quantity 2.
3. Assign parts using serial number (SN001 and SN002).
4. Send to customer.
5. Return 1 of the part with serial number SN002 to a location (Office).
6. Send a replacement to customer with serial number SN003 (probably create a new sale order for this).
7. SN002 able to assign to another customer. (but currently is not working, it is not showing at Parts/Stock/Location)

SN002 only appear using search at the top menu bar. Although the stock tracking information showing "Returned to location Office", but it doesn't list at Parts/Stock/Location.

Just want to know the item sent to a customer and returned from them able to re-sell to another customer or not?
If support, may I know how to achieve it?



Discussion:

Resolving patch:
diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -634,6 +634,7 @@ def returnFromCustomer(self, location, user=None):
 
         self.customer = None
         self.location = location
+        self.sales_order = None
 
         self.save()
 


Test patch:
Repository: inventree/InvenTree

Issue:
[BUG] no attribute MPN 
# System

Version: 0.2.2 pre
Commit-Date: 2021-04-27
Commit-Hash: 4d2e23f
Plattform: Win H2 - WSL2 Debian Buster
Deployment Method: runserver

# Steps to reproduce
- open supplier part
- add price break (button)
- enter data (does not matter, in my case: number 1, price 1)
-> results in 'Internal Server Error' Error Code 500

# Message
AttributeError at /price-break/new/
'SupplierPart' object has no attribute 'MPN'


Discussion:

Resolving patch:
diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py
--- a/InvenTree/company/models.py
+++ b/InvenTree/company/models.py
@@ -675,4 +675,4 @@ class Meta:
         db_table = 'part_supplierpricebreak'
 
     def __str__(self):
-        return f'{self.part.MPN} - {self.price} @ {self.quantity}'
+        return f'{self.part.SKU} - {self.price} @ {self.quantity}'


Test patch:
Repository: inventree/InvenTree

Issue:
Set user language per session
Support setting the user language in the settings (like the theme). On a per-session basis using the included [Django tools](https://docs.djangoproject.com/en/3.2/topics/i18n/translation/#the-set-language-redirect-view).


Discussion:

Resolving patch:
diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py
--- a/InvenTree/InvenTree/urls.py
+++ b/InvenTree/InvenTree/urls.py
@@ -39,7 +39,7 @@
 
 from .views import IndexView, SearchView, DatabaseStatsView
 from .views import SettingsView, EditUserView, SetPasswordView
-from .views import ColorThemeSelectView, SettingCategorySelectView
+from .views import AppearanceSelectView, SettingCategorySelectView
 from .views import DynamicJsView
 
 from common.views import SettingEdit
@@ -79,7 +79,8 @@
 settings_urls = [
 
     url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'),
-    url(r'^theme/?', ColorThemeSelectView.as_view(), name='settings-theme'),
+    url(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
+    url(r'^i18n/?', include('django.conf.urls.i18n')),
    
     url(r'^global/?', SettingsView.as_view(template_name='InvenTree/settings/global.html'), name='settings-global'),
     url(r'^report/?', SettingsView.as_view(template_name='InvenTree/settings/report.html'), name='settings-report'),
diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py
--- a/InvenTree/InvenTree/views.py
+++ b/InvenTree/InvenTree/views.py
@@ -769,12 +769,12 @@ def get_context_data(self, **kwargs):
         return ctx
 
 
-class ColorThemeSelectView(FormView):
+class AppearanceSelectView(FormView):
     """ View for selecting a color theme """
 
     form_class = ColorThemeSelectForm
-    success_url = reverse_lazy('settings-theme')
-    template_name = "InvenTree/settings/theme.html"
+    success_url = reverse_lazy('settings-appearance')
+    template_name = "InvenTree/settings/appearance.html"
 
     def get_user_theme(self):
         """ Get current user color theme """
@@ -788,7 +788,7 @@ def get_user_theme(self):
     def get_initial(self):
         """ Select current user color theme as initial choice """
 
-        initial = super(ColorThemeSelectView, self).get_initial()
+        initial = super(AppearanceSelectView, self).get_initial()
 
         user_theme = self.get_user_theme()
         if user_theme:


Test patch:
Repository: inventree/InvenTree

Issue:
Embed information on 3rd-party libraries
I would like to create a place (I suggest the "about" modal) where all the great used libraries get mentioned and their licenses linked. The legal depts. in bigger organisations like to see something like that to be sure there is nothing bad going on licensing wise ([like this](https://www.theregister.com/2021/03/25/ruby_rails_code/)).

@SchrodingersGat 
Thoughts / did I oversee that there already is something like that? I made a tech-demo (not polished) how it could look in [my public repo](https://github.com/matmair/InvenTree/tree/3rdparty-info).


Discussion:
I like this idea. I would suggest that we add it to the inventree documentation (https://inventree.readthedocs.io) and then add:

- A link from the "about" modal in InvenTree
- A link from README.md


👍That is a way better way than my tech-demo. Will submit a PR today.
Made a start here:

https://inventree.readthedocs.io/en/latest/credits/

Still needs to be linked from InvenTree

Resolving patch:
diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -116,6 +116,12 @@ def inventree_docs_url(*args, **kwargs):
     return "https://inventree.readthedocs.io/"
 
 
+@register.simple_tag()
+def inventree_credits_url(*args, **kwargs):
+    """ Return URL for InvenTree credits site """
+    return "https://inventree.readthedocs.io/en/latest/credits/"
+
+
 @register.simple_tag()
 def setting_object(key, *args, **kwargs):
     """


Test patch:
Repository: inventree/InvenTree

Issue:
[BUG] invoke: too many arguments
When running any invoke-command in an WSL-Enviroment I get the following error:
`/bin/bash: line 0: cd: too many arguments`


Discussion:

Resolving patch:
diff --git a/tasks.py b/tasks.py
--- a/tasks.py
+++ b/tasks.py
@@ -65,7 +65,7 @@ def manage(c, cmd, pty=False):
         cmd - django command to run
     """
 
-    c.run('cd {path} && python3 manage.py {cmd}'.format(
+    c.run('cd "{path}" && python3 manage.py {cmd}'.format(
         path=managePyDir(),
         cmd=cmd
     ), pty=pty)


Test patch:
Repository: inventree/InvenTree

Issue:
Add purchase price to Part Stock table
Add column `purchase_price` to "Part Stock" table and make it sortable.


Discussion:

Resolving patch:
diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py
--- a/InvenTree/stock/serializers.py
+++ b/InvenTree/stock/serializers.py
@@ -161,6 +161,13 @@ def annotate_queryset(queryset):
 
     required_tests = serializers.IntegerField(source='required_test_count', read_only=True, required=False)
 
+    purchase_price = serializers.SerializerMethodField()
+
+    def get_purchase_price(self, obj):
+        """ Return purchase_price (Money field) as string (includes currency) """
+
+        return str(obj.purchase_price) if obj.purchase_price else '-'
+
     def __init__(self, *args, **kwargs):
 
         part_detail = kwargs.pop('part_detail', False)
@@ -215,6 +222,7 @@ class Meta:
             'tracking_items',
             'uid',
             'updated',
+            'purchase_price',
         ]
 
         """ These fields are read-only in this context.


Test patch:
Repository: inventree/InvenTree

Issue:
BOM-price pie: Error when no Price on item
@matmair the error still exists, it errors out when you have one or more BOM items which do not have any pricing information:

```python
x = [True for a in bom_items if len(set(a['price'])) == 2]
```
But if `a['price'] is None`:

![image](https://user-images.githubusercontent.com/10080325/122405737-a3496280-cfc3-11eb-8498-0aa7ff531194.png)

_Originally posted by @SchrodingersGat in https://github.com/inventree/InvenTree/issues/1634#issuecomment-863239204_


Discussion:

Resolving patch:
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -846,17 +846,26 @@ def get_pricing(self, quantity=1, currency=None):
             ctx['price_history'] = ret
 
         # BOM Information for Pie-Chart
-        bom_items = [{'name': str(a.sub_part), 'price': a.sub_part.get_price_range(quantity), 'q': a.quantity} for a in part.bom_items.all()]
-        if [True for a in bom_items if len(set(a['price'])) == 2]:
-            ctx['bom_parts'] = [{
-                'name': a['name'],
-                'min_price': str((a['price'][0] * a['q']) / quantity),
-                'max_price': str((a['price'][1] * a['q']) / quantity)} for a in bom_items]
-            ctx['bom_pie_min'] = True
-        else:
-            ctx['bom_parts'] = [{
-                'name': a['name'],
-                'price': str((a['price'][0] * a['q']) / quantity)} for a in bom_items]
+        if part.has_bom:
+            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), 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
 
         return ctx
 


Test patch:
Repository: inventree/InvenTree

Issue:
Stock part with price zero
Stock with purchase price zero doesn't show the price (zero) this is useful when part came from a sample order.


Discussion:
To clarify - do you mean the price has been manually entered as zero, or the price has been left blank?

Can you share a screenshot of where you are seeing the issue?
I mean setting the part with explicitly zero cost doesn't get the price to show up as zero it is instead hidden.
![image](https://user-images.githubusercontent.com/15521303/122682102-737ea280-d1ef-11eb-9739-e359a3c1bca7.png)
![image](https://user-images.githubusercontent.com/15521303/122682120-87c29f80-d1ef-11eb-9ea4-4773c3e1b099.png)


Resolving patch:
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -814,7 +814,7 @@ def get_pricing(self, quantity=1, currency=None):
         part = self.get_part()
         # Stock history
         if part.total_stock > 1:
-            ret = []
+            price_history = []
             stock = part.stock_entries(include_variants=False, in_stock=True)  # .order_by('purchase_order__date')
             stock = stock.prefetch_related('purchase_order', 'supplier_part')
 
@@ -841,9 +841,9 @@ def get_pricing(self, quantity=1, currency=None):
                     line['date'] = stock_item.purchase_order.issue_date.strftime('%d.%m.%Y')
                 else:
                     line['date'] = stock_item.tracking_info.first().date.strftime('%d.%m.%Y')
-                ret.append(line)
+                price_history.append(line)
 
-            ctx['price_history'] = ret
+            ctx['price_history'] = price_history
 
         # BOM Information for Pie-Chart
         if part.has_bom:


Test patch:
Repository: inventree/InvenTree

Issue:
Table ordering not working for any parameter
![image](https://user-images.githubusercontent.com/15521303/122682048-35817e80-d1ef-11eb-92d5-8b41370cd088.png)

Table ordering not working for any parameter
![image](https://user-images.githubusercontent.com/15521303/122682048-35817e80-d1ef-11eb-92d5-8b41370cd088.png)



Discussion:

Resolving patch:
diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py
--- a/InvenTree/part/api.py
+++ b/InvenTree/part/api.py
@@ -706,6 +706,7 @@ def filter_queryset(self, queryset):
         'creation_date',
         'IPN',
         'in_stock',
+        'category',
     ]
 
     # Default ordering


Test patch:
Repository: inventree/InvenTree

Issue:
Add option to hide "related parts" tab



Discussion:

Resolving patch:
diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -219,6 +219,13 @@ class InvenTreeSetting(models.Model):
             'validator': bool,
         },
 
+        'PART_SHOW_RELATED': {
+            'name': _('Show related parts'),
+            'description': _('Display related parts for a part'),
+            'default': True,
+            'validator': bool,
+        },
+
         'PART_INTERNAL_PRICE': {
             'name': _('Internal Prices'),
             'description': _('Enable internal prices for parts'),


Test patch:
Repository: inventree/InvenTree

Issue:
Add ability to filter stock by "has purchase price"
- Add another filter to the stock table
- Boolean


Discussion:

Resolving patch:
diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py
--- a/InvenTree/stock/api.py
+++ b/InvenTree/stock/api.py
@@ -858,6 +858,17 @@ def filter_queryset(self, queryset):
                 print("After error:", str(updated_after))
                 pass
 
+        # Filter stock items which have a purchase price set
+        has_purchase_price = params.get('has_purchase_price', None)
+
+        if has_purchase_price is not None:
+            has_purchase_price = str2bool(has_purchase_price)
+
+            if has_purchase_price:
+                queryset = queryset.exclude(purchase_price=None)
+            else:
+                queryset = queryset.filter(purchase_price=None)
+
         # Optionally, limit the maximum number of returned results
         max_results = params.get('max_results', None)
 


Test patch:
Repository: inventree/InvenTree

Issue:
Add "issued_by" and "resposible_for" fields to Build Order table



Discussion:

Resolving patch:
diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py
--- a/InvenTree/build/api.py
+++ b/InvenTree/build/api.py
@@ -47,6 +47,8 @@ class BuildList(generics.ListCreateAPIView):
         'target_date',
         'completion_date',
         'quantity',
+        'issued_by',
+        'responsible',
     ]
 
     search_fields = [
diff --git a/InvenTree/build/serializers.py b/InvenTree/build/serializers.py
--- a/InvenTree/build/serializers.py
+++ b/InvenTree/build/serializers.py
@@ -10,11 +10,12 @@
 
 from rest_framework import serializers
 
-from InvenTree.serializers import InvenTreeModelSerializer, InvenTreeAttachmentSerializerField
+from InvenTree.serializers import InvenTreeModelSerializer, InvenTreeAttachmentSerializerField, UserSerializerBrief
 
 from stock.serializers import StockItemSerializerBrief
 from stock.serializers import LocationSerializer
 from part.serializers import PartSerializer, PartBriefSerializer
+from users.serializers import OwnerSerializer
 
 from .models import Build, BuildItem, BuildOrderAttachment
 
@@ -31,6 +32,10 @@ class BuildSerializer(InvenTreeModelSerializer):
 
     overdue = serializers.BooleanField(required=False, read_only=True)
 
+    issued_by_detail = UserSerializerBrief(source='issued_by', read_only=True)
+
+    responsible_detail = OwnerSerializer(source='responsible', read_only=True)
+
     @staticmethod
     def annotate_queryset(queryset):
         """
@@ -84,6 +89,10 @@ class Meta:
             'target_date',
             'notes',
             'link',
+            'issued_by',
+            'issued_by_detail',
+            'responsible',
+            'responsible_detail',
         ]
 
         read_only_fields = [


Test patch:
Repository: inventree/InvenTree

Issue:
Navigate to next/previous serial number button
When on the stock item page for a given serial number, a button to navigate to the next serial number stock item would be handy, especially if it stayed on the same subpage (e.g. tests).


Discussion:

Resolving patch:
diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py
--- a/InvenTree/stock/views.py
+++ b/InvenTree/stock/views.py
@@ -86,6 +86,29 @@ class StockItemDetail(InvenTreeRoleMixin, DetailView):
     queryset = StockItem.objects.all()
     model = StockItem
 
+    def get_context_data(self, **kwargs):
+        """ add previous and next item """
+        data = super().get_context_data(**kwargs)
+
+        if self.object.serialized:
+            serial_elem = {a.serial: a for a in self.object.part.stock_items.all() if a.serialized}
+            serials = [int(a) for a in serial_elem.keys()]
+            current = int(self.object.serial)
+
+            # previous
+            for nbr in range(current - 1, -1, -1):
+                if nbr in serials:
+                    data['previous'] = serial_elem.get(str(nbr), None)
+                    break
+
+            # next
+            for nbr in range(current + 1, max(serials) + 1):
+                if nbr in serials:
+                    data['next'] = serial_elem.get(str(nbr), None)
+                    break
+
+        return data
+
 
 class StockItemNotes(InvenTreeRoleMixin, UpdateView):
     """ View for editing the 'notes' field of a StockItem object """


Test patch: