mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-11-04 15:15:42 +00:00 
			
		
		
		
	Now displaying item match table
This commit is contained in:
		@@ -20,8 +20,8 @@ class FileManager:
 | 
				
			|||||||
    # Fields which are absolutely necessary for valid upload
 | 
					    # Fields which are absolutely necessary for valid upload
 | 
				
			||||||
    REQUIRED_HEADERS = []
 | 
					    REQUIRED_HEADERS = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Fields which are used for part matching (only one of them is needed)
 | 
					    # Fields which are used for item matching (only one of them is needed)
 | 
				
			||||||
    PART_MATCH_HEADERS = []
 | 
					    ITEM_MATCH_HEADERS = []
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    # Fields which would be helpful but are not required
 | 
					    # Fields which would be helpful but are not required
 | 
				
			||||||
    OPTIONAL_HEADERS = []
 | 
					    OPTIONAL_HEADERS = []
 | 
				
			||||||
@@ -83,7 +83,7 @@ class FileManager:
 | 
				
			|||||||
    def update_headers(self):
 | 
					    def update_headers(self):
 | 
				
			||||||
        """ Update headers """
 | 
					        """ Update headers """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.HEADERS = self.REQUIRED_HEADERS + self.PART_MATCH_HEADERS + self.OPTIONAL_HEADERS
 | 
					        self.HEADERS = self.REQUIRED_HEADERS + self.ITEM_MATCH_HEADERS + self.OPTIONAL_HEADERS
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
    def setup(self):
 | 
					    def setup(self):
 | 
				
			||||||
        """ Setup headers depending on the file name """
 | 
					        """ Setup headers depending on the file name """
 | 
				
			||||||
@@ -96,7 +96,7 @@ class FileManager:
 | 
				
			|||||||
                'Quantity',
 | 
					                'Quantity',
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.PART_MATCH_HEADERS = [
 | 
					            self.ITEM_MATCH_HEADERS = [
 | 
				
			||||||
                'Manufacturer_MPN',
 | 
					                'Manufacturer_MPN',
 | 
				
			||||||
                'Supplier_SKU',
 | 
					                'Supplier_SKU',
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,18 +119,40 @@ class MatchItem(forms.Form):
 | 
				
			|||||||
        # Item selection
 | 
					        # Item selection
 | 
				
			||||||
        for row in row_data:
 | 
					        for row in row_data:
 | 
				
			||||||
            for col in row['data']:
 | 
					            for col in row['data']:
 | 
				
			||||||
                print(f'{row["index"]=} | {col["column"]["guess"]=}')
 | 
					                if col['column']['guess'] in file_manager.REQUIRED_HEADERS:
 | 
				
			||||||
                if col['column']['guess']:
 | 
					                    field_name = col['column']['guess'].lower() + '-' + str(row['index'] - 1)
 | 
				
			||||||
                    if col['column']['guess'] in file_manager.PART_MATCH_HEADERS:
 | 
					                    if 'quantity' in col['column']['guess'].lower():
 | 
				
			||||||
 | 
					                        self.fields[field_name] = forms.CharField(
 | 
				
			||||||
 | 
					                            required=True,
 | 
				
			||||||
 | 
					                            widget=forms.NumberInput(attrs={
 | 
				
			||||||
 | 
					                                'name': 'quantity' + str(row['index']),
 | 
				
			||||||
 | 
					                                'class': 'numberinput',
 | 
				
			||||||
 | 
					                                'type': 'number',
 | 
				
			||||||
 | 
					                                'min': '1',
 | 
				
			||||||
 | 
					                                'step': 'any',
 | 
				
			||||||
 | 
					                                'value': row['quantity'],
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        self.fields[field_name] = forms.Input(
 | 
				
			||||||
 | 
					                            required=True,
 | 
				
			||||||
 | 
					                            widget=forms.Select(attrs={
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                elif col['column']['guess'] in file_manager.ITEM_MATCH_HEADERS:
 | 
				
			||||||
 | 
					                    print(f'{row["index"]=} | {col["column"]["guess"]=} | {row.get("item_match", "No Match")}')
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                    # Get item options
 | 
					                    # Get item options
 | 
				
			||||||
                        item_options = row['item_options']
 | 
					                    item_options = [(option.id, option) for option in row['item_options']]
 | 
				
			||||||
                    # Get item match
 | 
					                    # Get item match
 | 
				
			||||||
                    item_match = row['item_match']
 | 
					                    item_match = row['item_match']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        field_name = col['column']['guess'].lower() + '_' + str(row['index'])
 | 
					                    field_name = col['column']['guess'].lower() + '-' + str(row['index'] - 1)
 | 
				
			||||||
                    self.fields[field_name] = forms.ChoiceField(
 | 
					                    self.fields[field_name] = forms.ChoiceField(
 | 
				
			||||||
                            choices=item_options,
 | 
					                        choices=[('', '-' * 10)] + item_options,
 | 
				
			||||||
                        required=True,
 | 
					                        required=True,
 | 
				
			||||||
 | 
					                        widget=forms.Select(attrs={'class': 'bomselect'})
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    if item_match:
 | 
					                    if item_match:
 | 
				
			||||||
                            self.fields[field_name].initial = item_match
 | 
					                        print(f'{item_match=}')
 | 
				
			||||||
 | 
					                        self.fields[field_name].initial = item_match.id
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@ from . import models
 | 
				
			|||||||
from . import forms
 | 
					from . import forms
 | 
				
			||||||
from .files import FileManager
 | 
					from .files import FileManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from part.models import SupplierPart
 | 
					from company.models import ManufacturerPart, SupplierPart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SettingEdit(AjaxUpdateView):
 | 
					class SettingEdit(AjaxUpdateView):
 | 
				
			||||||
@@ -195,12 +195,41 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
    def get_context_data(self, form, **kwargs):
 | 
					    def get_context_data(self, form, **kwargs):
 | 
				
			||||||
        context = super().get_context_data(form=form, **kwargs)
 | 
					        context = super().get_context_data(form=form, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.steps.current == 'fields':
 | 
					        if self.steps.current == 'fields' or self.steps.current == 'items':
 | 
				
			||||||
            # Get columns and row data
 | 
					            # Get columns and row data
 | 
				
			||||||
            columns = self.file_manager.columns()
 | 
					            columns = self.file_manager.columns()
 | 
				
			||||||
            rows = self.file_manager.rows()
 | 
					            rows = self.file_manager.rows()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            key_item_select = ''
 | 
				
			||||||
 | 
					            key_quantity_select = ''
 | 
				
			||||||
 | 
					            if self.steps.current == 'items':
 | 
				
			||||||
 | 
					                # Get file manager
 | 
				
			||||||
 | 
					                self.getFileManager()
 | 
				
			||||||
 | 
					                # Find column key for item selection
 | 
				
			||||||
 | 
					                for item in self.file_manager.ITEM_MATCH_HEADERS:
 | 
				
			||||||
 | 
					                    item = item.lower()
 | 
				
			||||||
 | 
					                    for key in form.fields.keys():
 | 
				
			||||||
 | 
					                        print(f'{item=} is in {key=} ?')
 | 
				
			||||||
 | 
					                        if item in key:
 | 
				
			||||||
 | 
					                            key_item_select = item
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Find column key for quantity selection
 | 
				
			||||||
 | 
					                key_quantity_select = 'quantity'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Optimize for template
 | 
					            # Optimize for template
 | 
				
			||||||
            for row in rows:
 | 
					            for row in rows:
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                # Add item select field
 | 
				
			||||||
 | 
					                if key_item_select:
 | 
				
			||||||
 | 
					                    row['item_select'] = key_item_select + '-' + str(row['index'])
 | 
				
			||||||
 | 
					                    print(f'{row["item_select"]}')
 | 
				
			||||||
 | 
					                # Add quantity select field
 | 
				
			||||||
 | 
					                if key_quantity_select:
 | 
				
			||||||
 | 
					                    row['quantity_select'] = key_quantity_select + '-' + str(row['index'])
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                row_data = row['data']
 | 
					                row_data = row['data']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                data = []
 | 
					                data = []
 | 
				
			||||||
@@ -209,12 +238,16 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
                    data.append({
 | 
					                    data.append({
 | 
				
			||||||
                        'cell': item,
 | 
					                        'cell': item,
 | 
				
			||||||
                        'idx': idx,
 | 
					                        'idx': idx,
 | 
				
			||||||
                        'column': columns[idx]
 | 
					                        'column': columns[idx],
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                row['data'] = data
 | 
					                row['data'] = data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                print(f'\n{row=}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            context.update({'rows': rows})
 | 
					            context.update({'rows': rows})
 | 
				
			||||||
 | 
					            if self.steps.current == 'items':
 | 
				
			||||||
 | 
					                context.update({'columns': columns})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Load extra context data
 | 
					        # Load extra context data
 | 
				
			||||||
        print(f'{self.extra_context_data=}')
 | 
					        print(f'{self.extra_context_data=}')
 | 
				
			||||||
@@ -393,14 +426,14 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Check that at least one of the part match field is present
 | 
					        # Check that at least one of the part match field is present
 | 
				
			||||||
        part_match_found = False
 | 
					        part_match_found = False
 | 
				
			||||||
        for col in self.file_manager.PART_MATCH_HEADERS:
 | 
					        for col in self.file_manager.ITEM_MATCH_HEADERS:
 | 
				
			||||||
            if col in self.column_selections.values():
 | 
					            if col in self.column_selections.values():
 | 
				
			||||||
                part_match_found = True
 | 
					                part_match_found = True
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        # If not, notify user
 | 
					        # If not, notify user
 | 
				
			||||||
        if not part_match_found:
 | 
					        if not part_match_found:
 | 
				
			||||||
            for col in self.file_manager.PART_MATCH_HEADERS:
 | 
					            for col in self.file_manager.ITEM_MATCH_HEADERS:
 | 
				
			||||||
                missing_columns.append(col)
 | 
					                missing_columns.append(col)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Store extra context data
 | 
					        # Store extra context data
 | 
				
			||||||
@@ -425,15 +458,16 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
        The pre-fill data are then passed through to the part selection form.
 | 
					        The pre-fill data are then passed through to the part selection form.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        match_supplier = False
 | 
				
			||||||
 | 
					        match_manufacturer = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Fields prefixed with "Part_" can be used to do "smart matching" against Part objects in the database
 | 
					        # Fields prefixed with "Part_" can be used to do "smart matching" against Part objects in the database
 | 
				
			||||||
        q_idx = self.getColumnIndex('Quantity')
 | 
					        q_idx = self.getColumnIndex('Quantity')
 | 
				
			||||||
        s_idx = self.getColumnIndex('Supplier_SKU')
 | 
					        s_idx = self.getColumnIndex('Supplier_SKU')
 | 
				
			||||||
        # m_idx = self.getColumnIndex('Manufacturer_MPN')
 | 
					        m_idx = self.getColumnIndex('Manufacturer_MPN')
 | 
				
			||||||
        # p_idx = self.getColumnIndex('Unit_Price')
 | 
					        # p_idx = self.getColumnIndex('Unit_Price')
 | 
				
			||||||
        # e_idx = self.getColumnIndex('Extended_Price')
 | 
					        # e_idx = self.getColumnIndex('Extended_Price')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.allowed_items = SupplierPart.objects.all()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for row in self.rows:
 | 
					        for row in self.rows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Initially use a quantity of zero
 | 
					            # Initially use a quantity of zero
 | 
				
			||||||
@@ -442,9 +476,6 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
            # Initially we do not have a part to reference
 | 
					            # Initially we do not have a part to reference
 | 
				
			||||||
            exact_match_part = None
 | 
					            exact_match_part = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # A list of potential Part matches
 | 
					 | 
				
			||||||
            item_options = self.allowed_items
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Check if there is a column corresponding to "quantity"
 | 
					            # Check if there is a column corresponding to "quantity"
 | 
				
			||||||
            if q_idx >= 0:
 | 
					            if q_idx >= 0:
 | 
				
			||||||
                q_val = row['data'][q_idx]['cell']
 | 
					                q_val = row['data'][q_idx]['cell']
 | 
				
			||||||
@@ -464,7 +495,10 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            # Check if there is a column corresponding to "Supplier SKU"
 | 
					            # Check if there is a column corresponding to "Supplier SKU"
 | 
				
			||||||
            if s_idx >= 0:
 | 
					            if s_idx >= 0:
 | 
				
			||||||
                sku = row['data'][s_idx]
 | 
					                sku = row['data'][s_idx]['cell']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Match for supplier
 | 
				
			||||||
 | 
					                match_supplier = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    # Attempt SupplierPart lookup based on SKU value
 | 
					                    # Attempt SupplierPart lookup based on SKU value
 | 
				
			||||||
@@ -473,17 +507,27 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
                    exact_match_part = None
 | 
					                    exact_match_part = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Check if there is a column corresponding to "Manufacturer MPN"
 | 
					            # Check if there is a column corresponding to "Manufacturer MPN"
 | 
				
			||||||
            # if m_idx >= 0:
 | 
					            if m_idx >= 0:
 | 
				
			||||||
            #     row['part_mpn'] = row['data'][m_idx]
 | 
					                mpn = row['data'][m_idx]['cell']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #     try:
 | 
					                # Match for manufacturer
 | 
				
			||||||
            #         # Attempt ManufacturerPart lookup based on MPN value
 | 
					                if not match_supplier:
 | 
				
			||||||
            #         exact_match_part = ManufacturerPart.objects.get(MPN=row['part_mpn'])
 | 
					                    match_manufacturer = True
 | 
				
			||||||
            #     except (ValueError, ManufacturerPart.DoesNotExist):
 | 
					
 | 
				
			||||||
            #         exact_match_part = None
 | 
					                try:
 | 
				
			||||||
 | 
					                    # Attempt ManufacturerPart lookup based on MPN value
 | 
				
			||||||
 | 
					                    exact_match_part = ManufacturerPart.objects.get(MPN__contains=mpn)
 | 
				
			||||||
 | 
					                except (ValueError, ManufacturerPart.DoesNotExist, ManufacturerPart.MultipleObjectsReturned):
 | 
				
			||||||
 | 
					                    exact_match_part = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Check if matching for supplier or manufacturer parts
 | 
				
			||||||
 | 
					            if match_supplier:
 | 
				
			||||||
 | 
					                self.allowed_items = SupplierPart.objects.all()
 | 
				
			||||||
 | 
					            elif match_manufacturer:
 | 
				
			||||||
 | 
					                self.allowed_items = ManufacturerPart.objects.all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Supply list of part options for each row, sorted by how closely they match the part name
 | 
					            # Supply list of part options for each row, sorted by how closely they match the part name
 | 
				
			||||||
            row['item_options'] = item_options
 | 
					            row['item_options'] = self.allowed_items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Unless found, the 'part_match' is blank
 | 
					            # Unless found, the 'part_match' is blank
 | 
				
			||||||
            row['item_match'] = None
 | 
					            row['item_match'] = None
 | 
				
			||||||
@@ -502,6 +546,16 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return valid
 | 
					        return valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def checkPartSelection(self, form):
 | 
				
			||||||
 | 
					        """ Check part matching """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Extract form data
 | 
				
			||||||
 | 
					        self.getFormTableData(form.data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        valid = len(self.extra_context_data.get('missing_columns', [])) == 0 and not self.extra_context_data.get('duplicates', [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def validate(self, step, form):
 | 
					    def validate(self, step, form):
 | 
				
			||||||
        """ Validate forms """
 | 
					        """ Validate forms """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -519,11 +573,10 @@ class FileManagementFormView(MultiStepFormView):
 | 
				
			|||||||
                form.add_error(None, 'Fields matching failed')
 | 
					                form.add_error(None, 'Fields matching failed')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif step == 'items':
 | 
					        elif step == 'items':
 | 
				
			||||||
            # valid = self.checkPartSelection(form)
 | 
					            valid = self.checkPartSelection(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # if not valid:
 | 
					            if not valid:
 | 
				
			||||||
            #     form.add_error(None, 'Items matching failed')
 | 
					                form.add_error(None, 'Items matching failed')
 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return valid
 | 
					        return valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@
 | 
				
			|||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
        </thead>
 | 
					        </thead>
 | 
				
			||||||
        <tbody>
 | 
					        <tbody>
 | 
				
			||||||
            {% for row in form %}
 | 
					            {% for row in rows %}
 | 
				
			||||||
            <tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'>
 | 
					            <tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'>
 | 
				
			||||||
                <td>
 | 
					                <td>
 | 
				
			||||||
                    <button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='{% trans "Remove row" %}'>
 | 
					                    <button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='{% trans "Remove row" %}'>
 | 
				
			||||||
@@ -48,13 +48,18 @@
 | 
				
			|||||||
                </td>
 | 
					                </td>
 | 
				
			||||||
                <td></td>
 | 
					                <td></td>
 | 
				
			||||||
                <td>
 | 
					                <td>
 | 
				
			||||||
                {% comment %} {% add row.index 1 %} {% endcomment %}
 | 
					                {% add row.index 1 %}
 | 
				
			||||||
                </td>
 | 
					                </td>
 | 
				
			||||||
                <td>
 | 
					                <td>
 | 
				
			||||||
                    {{ row }}
 | 
					                    <button class='btn btn-default btn-create'  onClick='newPartFromBomWizard()' id='new_part_row_{{ row.index }}' title='{% trans "Create new part" %}' type='button'>
 | 
				
			||||||
                    {% comment %} <button class='btn btn-default btn-create'  onClick='newPartFromBomWizard()' id='new_part_row_{{ row.index }}' title='{% trans "Create new part" %}' type='button'>
 | 
					 | 
				
			||||||
                        <span row_id='{{ row.index }}' class='fas fa-plus icon-green'/>
 | 
					                        <span row_id='{{ row.index }}' class='fas fa-plus icon-green'/>
 | 
				
			||||||
                    </button>
 | 
					                    </button>
 | 
				
			||||||
 | 
					                    {% for field in form.visible_fields %}
 | 
				
			||||||
 | 
					                        {% if field.name == row.item_select %}
 | 
				
			||||||
 | 
					                            {{ field }}
 | 
				
			||||||
 | 
					                        {% endif %}
 | 
				
			||||||
 | 
					                    {% endfor %}
 | 
				
			||||||
 | 
					                    {% comment %} 
 | 
				
			||||||
                    <select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'>
 | 
					                    <select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'>
 | 
				
			||||||
                        <option value=''>--- {% trans "Select Part" %} ---</option>
 | 
					                        <option value=''>--- {% trans "Select Part" %} ---</option>
 | 
				
			||||||
                        {% for part in row.part_options %}
 | 
					                        {% for part in row.part_options %}
 | 
				
			||||||
@@ -69,16 +74,20 @@
 | 
				
			|||||||
                </td>
 | 
					                </td>
 | 
				
			||||||
                {% for item in row.data %}
 | 
					                {% for item in row.data %}
 | 
				
			||||||
                <td>
 | 
					                <td>
 | 
				
			||||||
                    {% comment %} 
 | 
					 | 
				
			||||||
                    {% if item.column.guess == 'Quantity' %}
 | 
					                    {% if item.column.guess == 'Quantity' %}
 | 
				
			||||||
                    <input name='quantity_{{ row.index }}' class='numberinput' type='number' min='1' step='any' value='{% decimal row.quantity %}'/>
 | 
					                    {% for field in form.visible_fields %}
 | 
				
			||||||
 | 
					                        {% if field.name == row.quantity_select %}
 | 
				
			||||||
 | 
					                            {{ field }}
 | 
				
			||||||
 | 
					                        {% endif %}
 | 
				
			||||||
 | 
					                    {% endfor %}
 | 
				
			||||||
 | 
					                    {% comment %} <input name='quantity_{{ row.index }}' class='numberinput' type='number' min='1' step='any' value='{% decimal row.quantity %}'/> {% endcomment %}
 | 
				
			||||||
                    {% if row.errors.quantity %}
 | 
					                    {% if row.errors.quantity %}
 | 
				
			||||||
                    <p class='help-inline'>{{ row.errors.quantity }}</p>
 | 
					                    <p class='help-inline'>{{ row.errors.quantity }}</p>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
                    {{ item.cell }}
 | 
					                    {{ item.cell }}
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                    <input type='hidden' name='row_{{ row.index }}_col_{{ forloop.counter0 }}' value='{{ item.cell }}'/> {% endcomment %}
 | 
					                    <input type='hidden' name='row_{{ row.index }}_col_{{ forloop.counter0 }}' value='{{ item.cell }}'/>
 | 
				
			||||||
                </td>
 | 
					                </td>
 | 
				
			||||||
                {% endfor %}
 | 
					                {% endfor %}
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user