예제 #1
0
def product_pre_save(sender, **kwargs):
    getcontext().rounding = ROUND_HALF_UP
    product = kwargs["instance"]
    producer = product.producer
    if not product.is_active:
        product.is_into_offer = False
    if product.order_unit not in [PRODUCT_ORDER_UNIT_PC, PRODUCT_ORDER_UNIT_PC_PRICE_KG,
                                  PRODUCT_ORDER_UNIT_PC_PRICE_LT, PRODUCT_ORDER_UNIT_PC_PRICE_PC]:
        product.unit_deposit = DECIMAL_ZERO
    if product.order_unit == PRODUCT_ORDER_UNIT_PC:
        product.order_average_weight = 1
    elif product.order_unit not in [PRODUCT_ORDER_UNIT_PC_KG, PRODUCT_ORDER_UNIT_PC_PRICE_KG,
                                    PRODUCT_ORDER_UNIT_PC_PRICE_LT, PRODUCT_ORDER_UNIT_PC_PRICE_PC]:
        product.order_average_weight = DECIMAL_ZERO
    if product.order_unit in [PRODUCT_ORDER_UNIT_DEPOSIT, PRODUCT_ORDER_UNIT_SUBSCRIPTION]:
        # No VAT on those products
        product.vat_level = VAT_100

    recalculate_prices(product, producer.producer_price_are_wo_vat, producer.is_resale_price_fixed,
                       producer.price_list_multiplier)

    if producer.producer_pre_opening or producer.manage_production:
        product.producer_order_by_quantity = DECIMAL_ZERO
        product.limit_order_quantity_to_stock = True
        if not product.is_box:
            # IMPORTANT : Deactivate offeritem whose stock is not > 0
            product.is_into_offer = product.stock > DECIMAL_ZERO
    elif not producer.manage_replenishment:
        product.limit_order_quantity_to_stock = False
    if product.is_box:
        product.limit_order_quantity_to_stock = False
    if product.limit_order_quantity_to_stock:
        product.customer_alert_order_quantity = min(999, product.stock)

    if product.customer_increment_order_quantity <= DECIMAL_ZERO:
        product.customer_increment_order_quantity = DECIMAL_ONE
    if product.customer_minimum_order_quantity <= DECIMAL_ZERO:
        product.customer_minimum_order_quantity = product.customer_increment_order_quantity
    if product.order_average_weight <= DECIMAL_ZERO:
        product.order_average_weight = DECIMAL_ONE
    if not product.reference:
        product.reference = uuid.uuid4()
    # Update stock of boxes containing this product
    for box_content in product.box_content.all():
        if box_content.box is not None:
            box_content.box.save_update_stock()
예제 #2
0
def import_purchase_sheet(worksheet, permanence=None,
                          customer_2_id_dict=None,
                          producer_2_id_dict=None
                          ):
    error = False
    error_msg = None
    import_counter = 0
    header = get_header(worksheet)
    if header:
        row_num = 1
        array_purchase = []
        rule_of_3_source = DECIMAL_ZERO
        row = get_row(worksheet, header, row_num)
        while row and not error:
            try:
                row_format = row[_('Format')]
                if row_format in ["A", "B"]:
                    import_counter += 1
                    if row[_('Id')] is None:
                        error = True
                        error_msg = _("Row %(row_num)d : No purchase id given.") % {'row_num': row_num + 1}
                        break
                    row_id = Decimal(row[_('Id')])
                    purchase = Purchase.objects.filter(id=row_id).order_by('?').first()
                    if purchase is None:
                        error = True
                        error_msg = _("Row %(row_num)d : No purchase corresponding to the given purchase id.") % {
                            'row_num': row_num + 1}
                        break
                    if purchase.permanence_id != permanence.id:
                        error = True
                        error_msg = _("Row %(row_num)d : The given permanence doesn't own the given purchase id.") % {
                            'row_num': row_num + 1}
                        break
                    producer_id = None
                    if row[_('producer')] in producer_2_id_dict:
                        producer_id = producer_2_id_dict[row[_('producer')]]
                    if producer_id != purchase.producer_id:
                        error = True
                        error_msg = _("Row %(row_num)d : No valid producer.") % {'row_num': row_num + 1}
                        break
                    customer_name = "%s" % row[_('customer')]
                    if customer_name in customer_2_id_dict:
                        customer_id = customer_2_id_dict[customer_name]
                        if customer_id != purchase.customer_id:
                            error = True
                            error_msg = _("Row %(row_num)d : No valid customer") % {'row_num': row_num + 1}
                            break
                    comment = cap(row[_('comment')], 100)
                    quantity_invoiced = DECIMAL_ZERO if row[_('quantity invoiced')] is None \
                        else Decimal(row[_('quantity invoiced')]).quantize(FOUR_DECIMALS)
                    producer_row_price = row[_('purchase price')]
                    if producer_row_price is not None:
                        producer_row_price = Decimal(producer_row_price).quantize(TWO_DECIMALS)
                        if purchase.purchase_price.amount != producer_row_price:
                            purchase_price_modified = True
                            if purchase.offer_item.order_unit in [
                                PRODUCT_ORDER_UNIT_KG, PRODUCT_ORDER_UNIT_PC_KG,
                                PRODUCT_ORDER_UNIT_LT
                            ]:
                                producer_unit_price = (purchase.offer_item.producer_unit_price.amount +
                                                       purchase.offer_item.unit_deposit.amount).quantize(TWO_DECIMALS)
                                if producer_unit_price != DECIMAL_ZERO:
                                    purchase.quantity_invoiced = (producer_row_price /
                                                                  producer_unit_price).quantize(FOUR_DECIMALS)
                                else:
                                    purchase.quantity_invoiced = DECIMAL_ZERO
                        else:
                            purchase_price_modified = False
                    elif purchase.quantity_invoiced != quantity_invoiced:
                        purchase.quantity_invoiced = quantity_invoiced
                        purchase_price_modified = False
                    else:
                        purchase_price_modified = False
                    if row_format == "A":
                        array_purchase = []
                        rule_of_3_source = DECIMAL_ZERO
                        if not purchase_price_modified:
                            producer_unit_price = Decimal(row[_('producer unit price')]).quantize(TWO_DECIMALS)
                            previous_producer_unit_price = purchase.get_producer_unit_price()
                            if producer_unit_price != previous_producer_unit_price:
                                offer_item = OfferItem.objects.filter(id=purchase.offer_item_id).order_by('?').first()
                                offer_item.producer_unit_price = producer_unit_price
                                recalculate_prices(offer_item, offer_item.producer_price_are_wo_vat,
                                                   offer_item.is_resale_price_fixed,
                                                   offer_item.price_list_multiplier)
                                offer_item.save()
                                recalculate_order_amount(
                                    permanence_id=offer_item.permanence_id,
                                    offer_item_queryset=OfferItem.objects.filter(id=offer_item.id).order_by('?'),
                                    send_to_producer=False
                                )
                    purchase.comment = comment
                    purchase.save()
                    rule_of_3_source += purchase.purchase_price.amount
                    array_purchase.append(purchase)
                elif row_format in ["C", "D"]:
                    rule_of_3_target = row[_('rule of 3')]
                    if rule_of_3_target is not None:
                        rule_of_3_target = Decimal(rule_of_3_target).quantize(TWO_DECIMALS)
                        if rule_of_3_target != rule_of_3_source:
                            max_purchase_counter = len(array_purchase)
                            if max_purchase_counter <= 1:
                                error = True
                                error_msg = _("Row %(row_num)d : Rule of 3 target in wrong context.") % {
                                    'row_num': row_num + 1}
                                return error, error_msg
                            else:
                                if rule_of_3_source != DECIMAL_ZERO:
                                    ratio = rule_of_3_target / rule_of_3_source
                                else:
                                    if rule_of_3_target == DECIMAL_ZERO:
                                        ratio = DECIMAL_ZERO
                                    else:
                                        ratio = DECIMAL_ONE
                                # Rule of 3
                                if ratio != DECIMAL_ONE:
                                    adjusted_invoice = DECIMAL_ZERO
                                    for i, purchase in enumerate(array_purchase, start=1):
                                        producer_unit_price = (purchase.offer_item.producer_unit_price.amount +
                                                               purchase.offer_item.unit_deposit.amount
                                                               ).quantize(TWO_DECIMALS)
                                        if i == max_purchase_counter:
                                            delta = rule_of_3_target - adjusted_invoice
                                            if producer_unit_price != DECIMAL_ZERO:
                                                purchase.quantity_invoiced = (delta / producer_unit_price).quantize(
                                                    FOUR_DECIMALS)
                                            else:
                                                purchase.quantity_invoiced = DECIMAL_ZERO
                                        else:
                                            purchase.quantity_invoiced = (purchase.quantity_invoiced * ratio).quantize(
                                                FOUR_DECIMALS)
                                            adjusted_invoice += purchase.quantity_invoiced * producer_unit_price
                                        purchase.save()

                row_num += 1
                row = get_row(worksheet, header, row_num)

            except KeyError, e:
                # Missing field
                error = True
                error_msg = _("Row %(row_num)d : A required column is missing %(error_msg)s.") % {
                    'row_num': row_num + 1, 'error_msg': str(e)}
            except Exception, e:
                error = True
                error_msg = _("Row %(row_num)d : %(error_msg)s.") % {'row_num': row_num + 1, 'error_msg': str(e)}