Example #1
0
    def test_discounts(self):
        user = self.login()

        invoice = self.create_invoice_n_orgas('Invoice0001', discount=10)[0]

        kwargs = {'user': user, 'related_document': invoice}
        product_line = ProductLine.objects.create(
            on_the_fly_item='Flyyy product',
            unit_price=Decimal('1000.00'),
            quantity=2,
            discount=Decimal('10.00'),
            # discount_unit=DISCOUNT_PERCENT,
            discount_unit=Line.Discount.PERCENT,
            vat_value=Vat.get_default_vat(),
            **kwargs)
        self.assertEqual(1620, product_line.get_price_exclusive_of_tax())

        invoice = self.refresh(invoice)
        self.assertEqual(1620, invoice._get_total())
        self.assertEqual(1620, invoice.total_no_vat)

        service_line = ServiceLine.objects.create(
            on_the_fly_item='Flyyy service',
            unit_price=Decimal('20.00'),
            quantity=10,
            discount=Decimal('100.00'),
            # discount_unit=DISCOUNT_LINE_AMOUNT,
            discount_unit=Line.Discount.LINE_AMOUNT,
            vat_value=Vat.get_default_vat(),
            **kwargs)
        self.assertEqual(90, service_line.get_price_exclusive_of_tax())

        invoice = self.refresh(invoice)
        self.assertEqual(1710, invoice._get_total())  # total_exclusive_of_tax
        self.assertEqual(1710, invoice.total_no_vat)
Example #2
0
    def test_inneredit(self):
        user = self.login()

        invoice = self.create_invoice_n_orgas('Invoice001', discount=0)[0]
        pline = ProductLine.objects.create(user=user, unit_price=Decimal('10'),
                                           vat_value=Vat.get_default_vat(),
                                           related_document=invoice,
                                           on_the_fly_item='Flyyyyy',
                                           comment='I believe',
                                          )

        build_url = self.build_inneredit_url
        url = build_url(pline, 'comment')
        self.assertGET200(url)

        comment = pline.comment + ' I can flyyy'
        response = self.client.post(url, data={'entities_lbl': [str(pline)],
                                               'field_value':  comment,
                                              }
                                   )
        self.assertNoFormError(response)
        self.assertEqual(comment, self.refresh(pline).comment)

        self.assertGET(400, build_url(pline, 'on_the_fly_item'))
        self.assertGET(400, build_url(pline, 'total_discount'))
        self.assertGET(400, build_url(pline, 'discount_unit'))
Example #3
0
    def get_total_with_tax(self):
        tax = 1 + Vat.get_default_vat().value / 100

        if self.made_sales:
            return self.made_sales * tax
        else:
            return (self.estimated_sales or 0) * tax
Example #4
0
    def __init__(self, user, related_document=None, *args, **kwargs):
        super().__init__(user=user, *args, **kwargs)
        self.related_document = related_document
        fields = self.fields

        if self.instance.related_item:
            del fields['on_the_fly_item']

        currency_str = related_document.currency.local_symbol
        discount_units = [
            (constants.DISCOUNT_PERCENT, '%'),
            (constants.DISCOUNT_LINE_AMOUNT,
             gettext('{currency} per line').format(currency=currency_str)),
            (constants.DISCOUNT_ITEM_AMOUNT,
             gettext('{currency} per unit').format(currency=currency_str)),
        ]

        line = self.instance
        fields['discount_unit'] = discount_unit_f = TypedChoiceField(
            choices=discount_units, coerce=int)
        discount_unit_f.initial = constants.DISCOUNT_PERCENT if line.discount_unit == constants.DISCOUNT_PERCENT else \
                                  (constants.DISCOUNT_LINE_AMOUNT if line.total_discount else constants.DISCOUNT_ITEM_AMOUNT) #HACK: see below
        discount_unit_f.widget.attrs = {'class': 'bound'}

        fields['vat_value'].initial = Vat.get_default_vat()
Example #5
0
    def __init__(self, user, related_document=None, *args, **kwargs):
        super().__init__(user=user, *args, **kwargs)
        self.related_document = related_document
        fields = self.fields

        if self.instance.related_item:
            del fields['on_the_fly_item']

        Discount = self._meta.model.Discount

        currency_str = related_document.currency.local_symbol
        discount_units = [
            # (constants.DISCOUNT_PERCENT, '%'),
            (Discount.PERCENT, '%'),
            (
                # constants.DISCOUNT_LINE_AMOUNT,
                Discount.LINE_AMOUNT,
                gettext('{currency} per line').format(currency=currency_str),
            ),
            (
                # constants.DISCOUNT_ITEM_AMOUNT,
                Discount.ITEM_AMOUNT,
                gettext('{currency} per unit').format(currency=currency_str),
            ),
        ]

        discount_unit_f = fields['discount_unit']
        discount_unit_f.choices = discount_units
        discount_unit_f.widget.attrs = {'class': 'bound'}

        fields['vat_value'].initial = Vat.get_default_vat()
Example #6
0
 def test_create03(self):
     create_vat = partial(Vat.objects.create,
                          is_default=True,
                          is_custom=False)
     vat01 = create_vat(value=Decimal('5.0'))
     vat02 = create_vat(value=Decimal('7.0'))
     self.assertFalse(self.refresh(vat01).is_default)
     self.assertTrue(self.refresh(vat02).is_default)
     self.assertEqual(vat02, Vat.get_default_vat())
Example #7
0
    def __init__(self, user, related_document=None, *args, **kwargs):
        # super(LineEditForm, self).__init__(user=user, *args, **kwargs)
        super().__init__(user=user, *args, **kwargs)
        self.related_document = related_document
        fields = self.fields

        if self.instance.related_item:
            del fields['on_the_fly_item']
        else:
            fields['on_the_fly_item'].widget = TextInput(attrs={
                'class': 'line-on_the_fly',
                'validator': 'Value'
            })

        fields['unit_price'].widget = TextInput(attrs={
            'class': 'line-unit_price bound',
            'validator': 'Decimal'
        })
        fields['quantity'].widget = TextInput(attrs={
            'class': 'line-quantity bound',
            'validator': 'PositiveDecimal'
        })
        fields['unit'].widget = TextInput(attrs={'class': 'line-unit'})
        fields['discount'].widget = TextInput(
            attrs={'class': 'line-quantity_discount bound'})

        currency_str = related_document.currency.local_symbol
        discount_units = [
            (constants.DISCOUNT_PERCENT, '%'),
            (constants.DISCOUNT_LINE_AMOUNT,
             _('{currency} per line').format(currency=currency_str)),
            (constants.DISCOUNT_ITEM_AMOUNT,
             _('{currency} per unit').format(currency=currency_str)),
        ]

        line = self.instance
        fields['discount_unit'] = discount_unit_f = TypedChoiceField(
            choices=discount_units, coerce=int)
        discount_unit_f.initial = constants.DISCOUNT_PERCENT if line.discount_unit == constants.DISCOUNT_PERCENT else \
                                  (constants.DISCOUNT_LINE_AMOUNT if line.total_discount else constants.DISCOUNT_ITEM_AMOUNT) #HACK: see below
        discount_unit_f.required = True
        discount_unit_f.widget.attrs = {'class': 'bound'}

        fields['comment'].widget = Textarea(attrs={
            'class': 'line-comment',
            'rows': 2
        })
        fields['vat_value'].initial = Vat.get_default_vat()
Example #8
0
    def test_create01(self):
        create_vat = Vat.objects.create
        vat01 = create_vat(value=Decimal('5.0'),
                           is_default=True,
                           is_custom=False)

        vat01 = self.refresh(vat01)
        self.assertEqual(Decimal('5.0'), vat01.value)
        self.assertTrue(vat01.is_default)
        self.assertFalse(vat01.is_custom)

        vat02 = create_vat(value=Decimal('6.0'),
                           is_default=False,
                           is_custom=True)
        vat02 = self.refresh(vat02)
        self.assertEqual(Decimal('6.0'), vat02.value)
        self.assertFalse(vat02.is_default)
        self.assertTrue(vat02.is_custom)

        self.assertEqual(vat01, Vat.get_default_vat())
Example #9
0
    def test_global_discount_change(self):
        user = self.login()

        invoice = self.create_invoice_n_orgas('Invoice001', discount=0)[0]

        ProductLine.objects.create(user=user, unit_price=Decimal('10'),
                                   vat_value=Vat.get_default_vat(),
                                   related_document=invoice,
                                   on_the_fly_item='Flyyyyy',
                                  )

        discount_zero = Decimal('0.0')
        full_discount = Decimal('100.0')

        self.assertEqual(invoice.discount, discount_zero)

        invoice.discount = full_discount
        invoice.save()

        invoice = self.refresh(invoice)

        self.assertEqual(invoice.discount, full_discount)
        self.assertEqual(invoice.total_no_vat, discount_zero)
        self.assertEqual(invoice.total_vat, discount_zero)
Example #10
0
    def post(self, request, *args, **kwargs):
        klass = self.get_ctype().model_class()

        try:
            rtype_id, set_as_current, workflow_action = self.behaviours[klass]
        except KeyError as e:
            raise Http404('Bad billing document type') from e

        user = request.user
        user.has_perm_to_create_or_die(klass)
        # TODO: check in template too (must upgrade 'has_perm' to use owner!=None)
        user.has_perm_to_link_or_die(klass, owner=user)

        opp = self.get_related_entity()

        b_document = klass.objects.create(
            user=user,
            issuing_date=now(),
            status_id=1,
            currency=opp.currency,
            source=opp.emitter,
            target=opp.target,
        )

        create_relation = partial(
            Relation.objects.create,
            subject_entity=b_document,
            user=user,
        )
        create_relation(type_id=rtype_id, object_entity=opp)

        b_document.generate_number(
        )  # Need the relationship with emitter organisation
        b_document.name = self.generated_name.format(document=b_document,
                                                     opportunity=opp)
        b_document.save()

        relations = Relation.objects.filter(
            subject_entity=opp.id,
            type__in=[
                constants.REL_OBJ_LINKED_PRODUCT,
                constants.REL_OBJ_LINKED_SERVICE,
            ],
        ).select_related('object_entity')

        # TODO: Missing test case
        if relations:
            Relation.populate_real_object_entities(relations)
            vat_value = Vat.get_default_vat()
            Product = get_product_model()

            for relation in relations:
                item = relation.object_entity.get_real_entity()
                line_klass = ProductLine if isinstance(
                    item, Product) else ServiceLine
                line_klass.objects.create(
                    related_item=item,
                    related_document=b_document,
                    unit_price=item.unit_price,
                    unit=item.unit,
                    vat_value=vat_value,
                )

        if set_as_current:
            create_relation(type_id=constants.REL_SUB_CURRENT_DOC,
                            object_entity=opp)

        if workflow_action:
            workflow_action(opp.emitter, opp.target, user)

        # if request.is_ajax():
        if is_ajax(request):
            return HttpResponse()

        return redirect(opp)
Example #11
0
 def __init__(self, entity, *args, **kwargs):
     # super(_LineMultipleAddForm, self).__init__(*args, **kwargs)
     super().__init__(*args, **kwargs)
     self.billing_document = entity
     self.fields['vat'].initial = Vat.get_default_vat(
     )  # Not in field declaration because default value can change
Example #12
0
 def __init__(self, entity, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.billing_document = entity
     # Not in field declaration because default value can change
     self.fields['vat'].initial = Vat.get_default_vat()