Beispiel #1
0
    def post(self, request, *args, **kwargs):

        form = self.get_form()

        item = self.get_object()

        quantity = request.POST.get('quantity', 0)
        serials = request.POST.get('serial_numbers', '')
        dest_id = request.POST.get('destination', None)
        notes = request.POST.get('note', '')
        user = request.user

        valid = True

        try:
            destination = StockLocation.objects.get(pk=dest_id)
        except (ValueError, StockLocation.DoesNotExist):
            destination = None

        try:
            numbers = ExtractSerialNumbers(serials, quantity)
        except ValidationError as e:
            form.errors['serial_numbers'] = e.messages
            valid = False
            numbers = []

        if valid:
            try:
                item.serializeStock(quantity,
                                    numbers,
                                    user,
                                    notes=notes,
                                    location=destination)
            except ValidationError as e:
                messages = e.message_dict

                for k in messages.keys():
                    if k in ['quantity', 'destination', 'serial_numbers']:
                        form.errors[k] = messages[k]
                    else:
                        form.non_field_errors = [messages[k]]

                valid = False

        data = {
            'form_valid': valid,
        }

        return self.renderJsonResponse(request, form, data=data)
Beispiel #2
0
    def test_complete(self):

        self.allocate_stock(50, 50, 250)

        self.assertTrue(self.build.isFullyAllocated())

        # Generate some serial numbers!
        serials = ExtractSerialNumbers("1-10", 10)

        self.build.completeBuild(None, serials, None)

        self.assertEqual(self.build.status, status.BuildStatus.COMPLETE)

        # the original BuildItem objects should have been deleted!
        self.assertEqual(BuildItem.objects.count(), 0)

        # New stock items should have been created!
        # - Ten for the build output (as the part was serialized)
        # - Three for the split items assigned to the build
        self.assertEqual(StockItem.objects.count(), 16)

        A = StockItem.objects.get(pk=self.stock_1_1.pk)
        B = StockItem.objects.get(pk=self.stock_1_2.pk)
        C = StockItem.objects.get(pk=self.stock_2_1.pk)

        # Stock should have been subtracted from the original items
        self.assertEqual(A.quantity, 950)
        self.assertEqual(B.quantity, 50)
        self.assertEqual(C.quantity, 4750)

        # New stock items should have also been allocated to the build
        allocated = StockItem.objects.filter(build_order=self.build)

        self.assertEqual(allocated.count(), 3)

        q = sum([item.quantity for item in allocated.all()])

        self.assertEqual(q, 350)

        # And 10 new stock items created for the build output
        outputs = StockItem.objects.filter(build=self.build)

        self.assertEqual(outputs.count(), 10)
Beispiel #3
0
    def test_complete(self):

        self.allocate_stock(50, 50, 250)

        self.assertTrue(self.build.isFullyAllocated())

        # Generate some serial numbers!
        serials = ExtractSerialNumbers("1-10", 10)

        self.build.completeBuild(None, serials, None)

        self.assertEqual(self.build.status, status.BuildStatus.COMPLETE)

        # the original BuildItem objects should have been deleted!
        self.assertEqual(BuildItem.objects.count(), 0)

        # New stock items should have been created!
        # - Ten for the build output (as the part was serialized)
        # - Three for the split items assigned to the build
        self.assertEqual(StockItem.objects.count(), 16)

        # Stock should have been subtracted from the original items
        self.assertEqual(StockItem.objects.get(pk=1).quantity, 950)
        self.assertEqual(StockItem.objects.get(pk=2).quantity, 50)
        self.assertEqual(StockItem.objects.get(pk=3).quantity, 4750)

        # New stock items created and assigned to the build
        self.assertEqual(StockItem.objects.get(pk=4).quantity, 50)
        self.assertEqual(StockItem.objects.get(pk=4).build_order, self.build)
        self.assertEqual(StockItem.objects.get(pk=4).status, status.StockStatus.ASSIGNED_TO_BUILD)

        self.assertEqual(StockItem.objects.get(pk=5).quantity, 50)
        self.assertEqual(StockItem.objects.get(pk=5).build_order, self.build)
        self.assertEqual(StockItem.objects.get(pk=5).status, status.StockStatus.ASSIGNED_TO_BUILD)

        self.assertEqual(StockItem.objects.get(pk=6).quantity, 250)
        self.assertEqual(StockItem.objects.get(pk=6).build_order, self.build)
        self.assertEqual(StockItem.objects.get(pk=6).status, status.StockStatus.ASSIGNED_TO_BUILD)
        
        # And a new stock item created for the build output
        self.assertEqual(StockItem.objects.get(pk=7).quantity, 1)
        self.assertEqual(StockItem.objects.get(pk=7).serial, 1)
        self.assertEqual(StockItem.objects.get(pk=7).build, self.build)
Beispiel #4
0
    def post(self, request, *args, **kwargs):
        """ Handle POST of StockItemCreate form.

        - Manage serial-number valdiation for tracked parts
        """

        part = None

        form = self.get_form()

        data = {}

        valid = form.is_valid()

        if valid:
            part_id = form['part'].value()
            try:
                part = Part.objects.get(id=part_id)
                quantity = Decimal(form['quantity'].value())

            except (Part.DoesNotExist, ValueError, InvalidOperation):
                part = None
                quantity = 1
                valid = False
                form.errors['quantity'] = [_('Invalid quantity')]

            if quantity < 0:
                form.errors['quantity'] = [
                    _('Quantity cannot be less than zero')
                ]
                valid = False

            if part is None:
                form.errors['part'] = [_('Invalid part selection')]
            else:
                # A trackable part must provide serial numbesr
                if part.trackable:
                    sn = request.POST.get('serial_numbers', '')

                    sn = str(sn).strip()

                    # If user has specified a range of serial numbers
                    if len(sn) > 0:
                        try:
                            serials = ExtractSerialNumbers(sn, quantity)

                            existing = []

                            for serial in serials:
                                if part.checkIfSerialNumberExists(serial):
                                    existing.append(serial)

                            if len(existing) > 0:
                                exists = ",".join([str(x) for x in existing])
                                form.errors['serial_numbers'] = [
                                    _('The following serial numbers already exist: ({sn})'
                                      .format(sn=exists))
                                ]
                                valid = False

                            else:
                                # At this point we have a list of serial numbers which we know are valid,
                                # and do not currently exist
                                form.clean()

                                form_data = form.cleaned_data

                                if form.is_valid():

                                    for serial in serials:
                                        # Create a new stock item for each serial number
                                        item = StockItem(
                                            part=part,
                                            quantity=1,
                                            serial=serial,
                                            supplier_part=form_data.get(
                                                'supplier_part'),
                                            location=form_data.get('location'),
                                            batch=form_data.get('batch'),
                                            delete_on_deplete=False,
                                            status=form_data.get('status'),
                                            link=form_data.get('link'),
                                        )

                                        item.save(user=request.user)

                                    data['success'] = _(
                                        'Created {n} new stock items'.format(
                                            n=len(serials)))
                                    valid = True

                        except ValidationError as e:
                            form.errors['serial_numbers'] = e.messages
                            valid = False

                    else:
                        # We have a serialized part, but no serial numbers specified...
                        form.clean()
                        form._post_clean()

                        if form.is_valid():

                            item = form.save(commit=False)
                            item.save(user=request.user)

                            data['pk'] = item.pk
                            data['url'] = item.get_absolute_url()
                            data['success'] = _("Created new stock item")

                            valid = True

                else:  # Referenced Part object is not marked as "trackable"
                    # For non-serialized items, simply save the form.
                    # We need to call _post_clean() here because it is prevented in the form implementation
                    form.clean()
                    form._post_clean()

                    if form.is_valid:
                        item = form.save(commit=False)
                        item.save(user=request.user)

                        data['pk'] = item.pk
                        data['url'] = item.get_absolute_url()
                        data['success'] = _("Created new stock item")

                        valid = True

        data['form_valid'] = valid and form.is_valid()

        return self.renderJsonResponse(request, form, data=data)
Beispiel #5
0
    def post(self, request, *args, **kwargs):
        """ Handle POST request. Mark the build as COMPLETE
        
        - If the form validation passes, the Build objects completeBuild() method is called
        - Otherwise, the form is passed back to the client
        """

        build = self.get_object()

        form = self.get_form()

        confirm = str2bool(request.POST.get('confirm', False))

        loc_id = request.POST.get('location', None)

        valid = False

        if confirm is False:
            form.errors['confirm'] = [
                _('Confirm completion of build'),
            ]
        else:
            try:
                location = StockLocation.objects.get(id=loc_id)
                valid = True
            except (ValueError, StockLocation.DoesNotExist):
                form.errors['location'] = [_('Invalid location selected')]

            serials = []

            if build.part.trackable:
                # A build for a trackable part may optionally specify serial numbers.

                sn = request.POST.get('serial_numbers', '')

                sn = str(sn).strip()

                # If the user has specified serial numbers, check they are valid
                if len(sn) > 0:
                    try:
                        # Exctract a list of provided serial numbers
                        serials = ExtractSerialNumbers(sn, build.quantity)

                        existing = []

                        for serial in serials:
                            if build.part.checkIfSerialNumberExists(serial):
                                existing.append(serial)

                        if len(existing) > 0:
                            exists = ",".join([str(x) for x in existing])
                            form.errors['serial_numbers'] = [
                                _('The following serial numbers already exist: ({sn})'
                                  .format(sn=exists))
                            ]
                            valid = False

                    except ValidationError as e:
                        form.errors['serial_numbers'] = e.messages
                        valid = False

            if valid:
                if not build.completeBuild(location, serials, request.user):
                    form.non_field_errors = [('Build could not be completed')]
                    valid = False

        data = {
            'form_valid': valid,
        }

        return self.renderJsonResponse(request,
                                       form,
                                       data,
                                       context=self.get_context_data())
Beispiel #6
0
    def post(self, request, *args, **kwargs):
        """ Handle POST of StockItemCreate form.

        - Manage serial-number valdiation for tracked parts
        """

        form = self.get_form()

        valid = form.is_valid()

        if valid:
            part_id = form['part'].value()
            try:
                part = Part.objects.get(id=part_id)
                quantity = int(form['quantity'].value())
            except (Part.DoesNotExist, ValueError):
                part = None
                quantity = 1
                valid = False

            if part is None:
                form.errors['part'] = [_('Invalid part selection')]
            else:
                # A trackable part must provide serial numbesr
                if part.trackable:
                    sn = request.POST.get('serial_numbers', '')

                    try:
                        serials = ExtractSerialNumbers(sn, quantity)

                        existing = []

                        for serial in serials:
                            if not StockItem.check_serial_number(part, serial):
                                existing.append(serial)

                        if len(existing) > 0:
                            exists = ",".join([str(x) for x in existing])
                            form.errors['serial_numbers'] = [
                                _('The following serial numbers already exist: ({sn})'
                                  .format(sn=exists))
                            ]
                            valid = False

                        # At this point we have a list of serial numbers which we know are valid,
                        # and do not currently exist
                        form.clean()

                        data = form.cleaned_data

                        for serial in serials:
                            # Create a new stock item for each serial number
                            item = StockItem(
                                part=part,
                                quantity=1,
                                serial=serial,
                                supplier_part=data.get('supplier_part'),
                                location=data.get('location'),
                                batch=data.get('batch'),
                                delete_on_deplete=False,
                                status=data.get('status'),
                                notes=data.get('notes'),
                                URL=data.get('URL'),
                            )

                            item.save()

                    except ValidationError as e:
                        form.errors['serial_numbers'] = e.messages
                        valid = False

                else:
                    # For non-serialized items, simply save the form.
                    # We need to call _post_clean() here because it is prevented in the form implementation
                    form.clean()
                    form._post_clean()
                    form.save()

        data = {
            'form_valid': valid,
        }

        return self.renderJsonResponse(request, form, data=data)