Exemplo n.º 1
0
def createProduct():
    Product(
        name=makeString(),
        price=makePrice(),
        productgroup=random.choice(ProductGroup.objects.all()),
        availability=True,
        position=makeInteger(),
        color=makeColor(),
        note=makeText(),
    ).save()
Exemplo n.º 2
0
def create_product_(request, c, android=False):
    # sellers can add product
    if not has_permission(request.user, c, 'product', 'edit'):
        return JsonError(_("You have no permission to add products"))

    data = JsonParse(request.POST['data'])
    
    # validate data
    valid = validate_product(request.user, c, data)
    if not valid['status']:
        return JsonError(valid['message'])
    data = valid['data']
    
    # save product:
    product = Product(
        company=c,
        created_by=request.user,
        category=data.get('category'),
        name=data.get('name'),
        code=data.get('code'),
        shortcut=data.get('shortcut'),
        description=data.get('description'),
        private_notes=data.get('private_notes'),
        stock=data.get('stock'),
        tax=data.get('tax'),
    )
    product.save()
    
    # update discounts
    product.update_discounts(request.user, data['discount_ids'])
    
    # prices have to be updated separately
    price = product.update_price(Price, request.user, data['price']) # purchase price
    if not price:
        product.delete()
        return JsonError(_("Error while setting purchase price"))


    #if data.get('purchase_price'):
    #    price = product.update_price(PurchasePrice, request.user, data['purchase_price'])
    #    if not price:
    #        product.delete()
    #        return JsonError(_("Error while setting sell price"))
    
    # add image, if it's there
    if data['change_image']:
        if 'image' in data:
            f = create_file_from_image(data['image'])
            product.image = f['file']
            product.save()
    
    return JsonOk(extra=product_to_dict(request.user, c, product, android))
Exemplo n.º 3
0
def xls_import(filename, company, user):
    status = {
        'success': True,
        'error_messages': [],
        'info_messages': [],
    }

    def err(message, product_name=None, row=None, column=None):
        status['success'] = False
        status['error_messages'].append({'name': product_name, 'message': message, 'row': row, 'column': column})

    def info(message, product_name=None, row=None, column=None):
        status['info_messages'].append({'name': product_name, 'message': message, 'row': row, 'column': column})

    try:
        data = xlrd.open_workbook(filename)
        book = data.sheet_by_index(0)
    except:
        err(_("Opening the file failed"))
        raise XlsImportError(status)

    def value(ir, ic, product_name=None, check_col_len=None):
        # returns cell value at specified row/column, formatted as text
        #if book.cell_type(ir, ic) != xlrd.XL_CELL_TEXT:
        # this is obviously not working since nothing is formatted as text at all
        #    info(_("Cell value is not formatted as text"), product_name, ir, ic)

        v = unicode(book.cell_value(ir, ic)).strip()

        if check_col_len: # if there's a maximum length of field
            l = max_field_length(Product, check_col_len) - 1
            if l:
                return v[-l:]

        return v  # or don't truncate it at all

    nrows = book.nrows
    ncols = book.ncols

    # exact number of columns required: 12
    if ncols < 12:
        err(_("Invalid number of columns, 12 required") + " (this file: " + str(ncols) + ")", None, None)
        raise XlsImportError(status)

    # a collection of all valid data;
    # if everything validates successfully, this will be inserted into database
    valid_products = []

    for irow in range(1, nrows):  # the first row contains titles, start with the second
        # Name
        # check if a product with that name exists already
        icol = 0
        cell = value(irow, icol, check_col_len='name')

        name = cell

        # Description
        # doesn't need checking
        icol = 1
        cell = value(irow, icol, product_name=name)

        description = cell

        # Code
        icol = 2
        cell = value(irow, icol, product_name=name, check_col_len='code')

        code = cell
        if Product.objects.filter(company=company, code=code).exists():
            err(_("A product with this name exists already"), name, irow, icol)

        # Tax (number only, check if tax exists in database)
        icol = 3
        cell = value(irow, icol, product_name=name)

        tax = None
        tax_amount = decimal.Decimal(1)
        try:
            tax_amount = decimal.Decimal(cell)
            tax = Tax.objects.get(company=company, amount=tax_amount)
        except Tax.DoesNotExist:
            err(_("Tax with this amount does not exist"), name, irow, icol)
        except (decimal.InvalidOperation, TypeError):
            err(_("Wrong number format for tax"), name)

        # Category (match by name or set no category to a product)
        icol = 4
        cell = value(irow, icol, product_name=name)

        if Category.objects.filter(company=company, name=cell).count() > 0:
            # if there are multiple categories with the same name, take the first by id
            # this should be the parent
            category = Category.objects.filter(company=company, name=cell).order_by('id')[0]
        else:
            category = None
            info(_("Category not found, none assigned"), name, irow, icol)

        # Stock
        icol = 5
        cell = value(irow, icol, product_name=name)

        stock = None
        try:
            stock = decimal.Decimal(cell)
        except (decimal.InvalidOperation, TypeError):
            err(_("Invalid number format for stock"), name, irow, icol)

        # Unit (anything that doesn't match the unit types list defaults to 'Piece')
        icol = 6
        cell = value(irow, icol, product_name=name)

        if cell not in g.UNIT_CODES:
            unit_type = g.UNIT_CODES[0]  # take a default
            info(_("No unit type matched, default taken"), name, irow, icol)
        else:
            unit_type = cell

        # Purchase price
        icol = 7
        cell = value(irow, icol, product_name=name)

        purchase_price = None
        try:
            purchase_price = decimal.Decimal(cell)
        except (decimal.InvalidOperation, TypeError):
            err(_("Invalid number format for purchase price"), name, irow, icol)

        # Sell price without tax
        icol = 8
        cell = value(irow, icol, product_name=name)

        try:
            price_without_tax = decimal.Decimal(cell)
        except (decimal.InvalidOperation, TypeError):
            price_without_tax = None
            # checking of this after parsing price with tax

        # Sell price with tax
        icol = 9
        cell = value(irow, icol, product_name=name)

        try:
            price_with_tax = decimal.Decimal(cell)
        except (decimal.InvalidOperation, TypeError):
            price_with_tax = None

        if price_without_tax is None and price_with_tax is None:
            err(_("No prices set or their number format is not valid"), name, irow, icol)

        # calculate prices
        if price_with_tax and price_without_tax is None:
            price_without_tax = price_with_tax / (decimal.Decimal(1) + (tax_amount / decimal.Decimal(100)))

        # Shortcut
        icol = 10
        cell = value(irow, icol, product_name=name, check_col_len='shortcut')

        shortcut = cell

        # Private notes
        icol = 11
        cell = value(irow, icol, product_name=name)

        notes = cell

        # if there was no error, save all data for later use
        # if there was an error, don't even bother, the data won't be used anyway
        if status['success']:
            valid_products.append({
                'company': company,  # these are required for Product.save()
                'created_by': user,

                'name': name,
                'description': description,
                'code': code,
                'tax': tax,
                'category': category,
                'stock': stock,
                'unit_type': unit_type,
                'shortcut': shortcut,
                'private_notes': notes,

                'purchase_price': purchase_price,  # these must not be in **kwargs for Product.save()
                'price_without_tax': price_without_tax,
            })

    # all products have been validated;
    # if there was no error, start inserting stuff into database;
    # keep all in the same transaction
    if not status['success']:
        raise XlsImportError(status)

    try:
        with transaction.atomic():
            for p in valid_products:
                # save product: take prices out, then use **kwargs
                price_without_tax = p['price_without_tax']
                del p['price_without_tax']

                purchase_price = p['purchase_price']
                del p['purchase_price']

                product = Product(**p)
                product.save()

                # save prices
                if not product.update_price(Price, user, price_without_tax):
                    err(_("Updating price failed"), product_name=p['name'])
                    raise Exception("Updating price failed")

                #
                # if not product.update_price(PurchasePrice, user, purchase_price):
                #    err(_("Updating purchase price failed"), product_name=p['name'])
                #    raise Exception("Updating purchase price failed")

            # that's it
            return status
    except IntegrityError as ie:
        err(_("Error while saving to database"), ie.message, None, None)
        raise XlsImportError(status)