Exemple #1
0
    def receive_line_item(self, line, location, quantity, user):
        """ Receive a line item (or partial line item) against this PO
        """

        if not self.status == OrderStatus.PLACED:
            raise ValidationError({
                "status":
                _("Lines can only be received against an order marked as 'Placed'"
                  )
            })

        try:
            quantity = int(quantity)
            if quantity <= 0:
                raise ValidationError(
                    {"quantity": _("Quantity must be greater than zero")})
        except ValueError:
            raise ValidationError({"quantity": _("Invalid quantity provided")})

        # Create a new stock item
        if line.part:
            stock = StockItem(part=line.part.part,
                              supplier_part=line.part,
                              location=location,
                              quantity=quantity,
                              purchase_order=self)

            stock.save()

            # Add a new transaction note to the newly created stock item
            stock.addTransactionNote(
                "Received items", user,
                "Received {q} items against order '{po}'".format(q=quantity,
                                                                 po=str(self)))

        # Update the number of parts received against the particular line item
        line.received += quantity
        line.save()

        # Has this order been completed?
        if len(self.pending_line_items()) == 0:

            self.received_by = user
            self.complete_order()  # This will save the model
Exemple #2
0
    def done(self, form_list, **kwargs):
        """Create items."""
        items = self.get_clean_items()

        import_done = 0
        import_error = []

        # Create Part instances
        for part_data in items.values():

            # set related parts
            optional_matches = {}
            for idx in self.file_manager.OPTIONAL_MATCH_HEADERS:
                if idx.lower() in part_data:
                    try:
                        optional_matches[idx] = self.allowed_items[idx].get(
                            pk=int(part_data[idx.lower()]))
                    except (ValueError,
                            self.allowed_items[idx].model.DoesNotExist, self.
                            allowed_items[idx].model.MultipleObjectsReturned):
                        optional_matches[idx] = None
                else:
                    optional_matches[idx] = None

            # add part
            new_part = Part(
                name=part_data.get('name', ''),
                description=part_data.get('description', ''),
                keywords=part_data.get('keywords', None),
                IPN=part_data.get('ipn', None),
                revision=part_data.get('revision', None),
                link=part_data.get('link', None),
                default_expiry=part_data.get('default_expiry', 0),
                minimum_stock=part_data.get('minimum_stock', 0),
                units=part_data.get('units', None),
                notes=part_data.get('notes', None),
                category=optional_matches['Category'],
                default_location=optional_matches['default_location'],
                default_supplier=optional_matches['default_supplier'],
                variant_of=optional_matches['variant_of'],
                active=str2bool(part_data.get('active', True)),
                base_cost=part_data.get('base_cost', 0),
                multiple=part_data.get('multiple', 1),
                assembly=str2bool(
                    part_data.get('assembly',
                                  part_settings.part_assembly_default())),
                component=str2bool(
                    part_data.get('component',
                                  part_settings.part_component_default())),
                is_template=str2bool(
                    part_data.get('is_template',
                                  part_settings.part_template_default())),
                purchaseable=str2bool(
                    part_data.get('purchaseable',
                                  part_settings.part_purchaseable_default())),
                salable=str2bool(
                    part_data.get('salable',
                                  part_settings.part_salable_default())),
                trackable=str2bool(
                    part_data.get('trackable',
                                  part_settings.part_trackable_default())),
                virtual=str2bool(
                    part_data.get('virtual',
                                  part_settings.part_virtual_default())),
            )
            try:
                new_part.save()

                # add stock item if set
                if part_data.get('stock', None):
                    stock = StockItem(
                        part=new_part,
                        location=new_part.default_location,
                        quantity=int(part_data.get('stock', 1)),
                    )
                    stock.save()
                import_done += 1
            except ValidationError as _e:
                import_error.append(', '.join(set(_e.messages)))

        # Set alerts
        if import_done:
            alert = f"<strong>{_('Part-Import')}</strong><br>{_('Imported {n} parts').format(n=import_done)}"
            messages.success(self.request, alert)
        if import_error:
            error_text = '\n'.join([
                f'<li><strong>x{import_error.count(a)}</strong>: {a}</li>'
                for a in set(import_error)
            ])
            messages.error(
                self.request,
                f"<strong>{_('Some errors occured:')}</strong><br><ul>{error_text}</ul>"
            )

        return HttpResponseRedirect(reverse('part-index'))