mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-12 21:48:25 +03:00
refactor(tests): udpates tests based on the english lexer
This commit is contained in:
parent
304f6a27ae
commit
a42d0c7728
@ -1,8 +1,8 @@
|
||||
@@Include: ../tutorial_en.catala_en@@
|
||||
> Include: ../tutorial_en.catala_en
|
||||
|
||||
@Test@
|
||||
## [Test]
|
||||
|
||||
/*
|
||||
```catala
|
||||
declaration scope UnitTest1:
|
||||
context tax_computation scope NewIncomeTaxComputation
|
||||
|
||||
@ -26,4 +26,4 @@ scope UnitTest2:
|
||||
}
|
||||
|
||||
assertion tax_computation.income_tax = $0.00
|
||||
*/
|
||||
```
|
||||
|
@ -1,4 +1,4 @@
|
||||
@@The Catala language tutorial@@
|
||||
## The Catala language tutorial
|
||||
|
||||
Welcome to this tutorial, whose objective is to guide you through the features
|
||||
of the Catala language and teach you how to annotate a legislative text using
|
||||
@ -6,7 +6,7 @@ the language. This document is addressed primarily to developers or people that
|
||||
have a programming background, though tech-savvy lawyers will probably figure
|
||||
things out.
|
||||
|
||||
@@Literate programming@@+
|
||||
### Literate programming
|
||||
|
||||
To begin writing a Catala program, you must start from the text of the
|
||||
legislative source that will justify the code that you will write. Concretely,
|
||||
@ -27,16 +27,17 @@ importance by adding increasing numbers of "+" after the title of the heading.
|
||||
The fundamental division unit is the article, introduced by a single "at".
|
||||
Let's analyse a fictional example that defines an income tax.
|
||||
|
||||
@Article 1@
|
||||
#### [Article 1]
|
||||
|
||||
The income tax for an individual is defined as a fixed percentage of the
|
||||
individual's income over a year.
|
||||
|
||||
/*
|
||||
```catala
|
||||
# Welcome to the code mode of Catala. This is a comment, because the line is
|
||||
# prefixed by #.
|
||||
# We will soon learn what to write here in order to translate the meaning
|
||||
# of the article into Catala code.
|
||||
*/
|
||||
```
|
||||
|
||||
To do that, we will intertwine short snippets of code between the sentences of
|
||||
the legislative text. Each snippet of code should be as short as possible and
|
||||
@ -44,7 +45,7 @@ as close as possible to the actual sentence that justifies the code. This style
|
||||
is called literate programming, a programming paradigm invented by the famous
|
||||
computer scientist Donald Knuth in the 70s.
|
||||
|
||||
@@Defining a fictional income tax@@+
|
||||
### Defining a fictional income tax
|
||||
|
||||
The content of article 1 uses a lot of implicit context: there exists an
|
||||
individual with an income, as well as an income tax that the individual has
|
||||
@ -56,8 +57,9 @@ inside the law.
|
||||
Let's start our metadata section by declaring the type information for the
|
||||
individual:
|
||||
|
||||
@@Begin metadata@@
|
||||
/*
|
||||
> Begin metadata
|
||||
|
||||
```catala
|
||||
declaration structure Individual:
|
||||
# The name of the structure "Individual", must start with an
|
||||
# uppercase letter: this is the CamelCase convention.
|
||||
@ -69,8 +71,9 @@ declaration structure Individual:
|
||||
data number_of_children content integer
|
||||
# "income" and "number_of_children" start by a lowercase letter,
|
||||
# they follow the snake_case convention
|
||||
*/
|
||||
@@End metadata@@
|
||||
```
|
||||
|
||||
> End metadata
|
||||
|
||||
This structure contains two data fields, "income" and "number_of_children". Structures are
|
||||
useful to group together data that goes together. Usually, you
|
||||
@ -80,8 +83,10 @@ but you should aim to optimize code readability.
|
||||
|
||||
Sometimes, the law gives an enumeration of different situations. These
|
||||
enumerations are modeled in Catala using an enumeration type, like:
|
||||
@@Begin metadata@@
|
||||
/*
|
||||
|
||||
> Begin metadata
|
||||
|
||||
```catala
|
||||
declaration enumeration TaxCredit:
|
||||
# The name "TaxCredit" is also written in CamelCase
|
||||
-- NoTaxCredit
|
||||
@ -92,8 +97,9 @@ declaration enumeration TaxCredit:
|
||||
# of type integer corresponding to the number of children concerned
|
||||
# by the tax credit. This means that if you're in the "ChildrenTaxCredit"
|
||||
# situation, you will also have access to this number of children
|
||||
*/
|
||||
@@End metadata@@
|
||||
```
|
||||
|
||||
> End metadata
|
||||
|
||||
In computer science terms, such an enumeration is called a "sum type" or simply
|
||||
an enum. The combination of structures and enumerations allow the Catala
|
||||
@ -105,8 +111,9 @@ to define the logical context in which these data will evolve. This is done in
|
||||
Catala using "scopes". Scopes are close to functions in terms of traditional
|
||||
programming. Scopes also have to be declared in metadata, so here we go:
|
||||
|
||||
@@Begin metadata@@
|
||||
/*
|
||||
> Begin metadata
|
||||
|
||||
```catala
|
||||
declaration scope IncomeTaxComputation:
|
||||
# Scope names use CamelCase
|
||||
context individual content Individual
|
||||
@ -115,20 +122,23 @@ declaration scope IncomeTaxComputation:
|
||||
# data on which the scope will operate
|
||||
context fixed_percentage content decimal
|
||||
context income_tax content money
|
||||
*/
|
||||
@@End metadata@@
|
||||
```
|
||||
|
||||
> End metadata
|
||||
|
||||
We now have everything to annotate the contents of article 1, which is copied
|
||||
over below.
|
||||
|
||||
@Article 1@
|
||||
#### [Article 1]
|
||||
|
||||
The income tax for an individual is defined as a fixed percentage of the
|
||||
individual's income over a year.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope IncomeTaxComputation:
|
||||
definition income_tax equals
|
||||
individual.income *$ fixed_percentage
|
||||
*/
|
||||
```
|
||||
|
||||
In the code, we are defining inside our scope the amount of the income tax
|
||||
according to the formula described in the article. When defining formulae,
|
||||
@ -151,41 +161,46 @@ But inside article 1, one question remains unknown: what is the value of
|
||||
of the fixed percentage? Often, precise values are defined elsewhere in the
|
||||
legislative source. Here, let's suppose we have:
|
||||
|
||||
@Article 2@
|
||||
#### [Article 2]
|
||||
|
||||
The fixed percentage mentionned at article 1 is equal to 20 %.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope IncomeTaxComputation:
|
||||
definition fixed_percentage equals 20 %
|
||||
# Writing 20% is just an abbreviation for 0.20
|
||||
*/
|
||||
```
|
||||
|
||||
You can see here that Catala allows definitions to be scattered throughout
|
||||
the annotation of the legislative text, so that each
|
||||
definition is as close as possible to its location in the text.
|
||||
|
||||
@@Conditional definitions@@+
|
||||
### Conditional definitions
|
||||
|
||||
So far so good, but now the legislative text introduces some trickiness. Let us
|
||||
suppose the third article says:
|
||||
|
||||
@Article 3@ If the individual is in charge of 2 or more children, then the fixed
|
||||
#### [Article 3]
|
||||
|
||||
If the individual is in charge of 2 or more children, then the fixed
|
||||
percentage mentionned at article 1 is equal to 15 %.
|
||||
/*
|
||||
|
||||
```catala
|
||||
# How to redefine fixed_percentage?
|
||||
*/
|
||||
```
|
||||
|
||||
This article actually gives another definition for the fixed percentage, which
|
||||
was already defined in article 2. However, article 3 defines the percentage
|
||||
conditionnally to the individual having more than 2 children. Catala allows
|
||||
you precisely to redefine a variable under a condition:
|
||||
|
||||
/*
|
||||
```catala
|
||||
scope IncomeTaxComputation:
|
||||
definition fixed_percentage under condition
|
||||
individual.number_of_children >= 2
|
||||
consequence equals 15 %
|
||||
# Writing 15% is just an abbreviation for 0.15
|
||||
*/
|
||||
```
|
||||
|
||||
When the Catala program will execute, the right definition will be dynamically
|
||||
chosen by looking at which condition is true. A correctly drafted legislative
|
||||
@ -193,14 +208,15 @@ source should always ensure that at most one condition is true at all times.
|
||||
However, if it is not the case, Catala will let you define a precedence on the
|
||||
conditions, which has to be justified by the law.
|
||||
|
||||
|
||||
@@Functions@@+
|
||||
### Functions
|
||||
|
||||
Catala lets you define functions anywhere in your data. Here's what it looks
|
||||
like in the metadata definition when we want to define a two-brackets tax
|
||||
computation:
|
||||
@@Begin metadata@@
|
||||
/*
|
||||
|
||||
> Begin metadata
|
||||
|
||||
```catala
|
||||
declaration structure TwoBrackets:
|
||||
data breakpoint content money
|
||||
data rate1 content decimal
|
||||
@ -209,15 +225,18 @@ declaration structure TwoBrackets:
|
||||
declaration scope TwoBracketsTaxComputation :
|
||||
context brackets content TwoBrackets
|
||||
context tax_formula content money depends on money
|
||||
*/
|
||||
@@End metadata@@
|
||||
```
|
||||
|
||||
> End metadata
|
||||
|
||||
And in the code:
|
||||
|
||||
@Article4@ The tax amount for a two-brackets computation is equal to the amount
|
||||
#### [Article4]
|
||||
|
||||
The tax amount for a two-brackets computation is equal to the amount
|
||||
of income in each bracket multiplied by the rate of each bracket.
|
||||
|
||||
/*
|
||||
```catala
|
||||
scope TwoBracketsTaxComputation :
|
||||
definition tax_formula of income equals
|
||||
if income <=$ brackets.breakpoint then
|
||||
@ -226,17 +245,20 @@ scope TwoBracketsTaxComputation :
|
||||
brackets.breakpoint *$ brackets.rate1 +$
|
||||
(income -$ brackets.breakpoint) *$ brackets.rate2
|
||||
)
|
||||
*/
|
||||
```
|
||||
|
||||
@@Scope inclusion@@+
|
||||
### Scope inclusion
|
||||
|
||||
Now that we've defined our helper scope for computing a two-brackets tax, we
|
||||
want to use it in our main tax computation scope.
|
||||
|
||||
@Article 5@ For individuals whose income is greater than $100,000, the income
|
||||
#### [Article 5]
|
||||
|
||||
For individuals whose income is greater than $100,000, the income
|
||||
tax of article 1 is 40% of the income above $100,000. Below $100,000, the
|
||||
income tax is 20% of the income.
|
||||
/*
|
||||
|
||||
```catala
|
||||
declaration scope NewIncomeTaxComputation:
|
||||
context two_brackets scope TwoBracketsTaxComputation
|
||||
# This line says that we add the item two_brackets to the context.
|
||||
@ -252,17 +274,19 @@ scope NewIncomeTaxComputation :
|
||||
-- rate2: 40%
|
||||
}
|
||||
definition income_tax equals two_brackets.tax_formula of individual.income
|
||||
*/
|
||||
```
|
||||
|
||||
#### [Article 6]
|
||||
|
||||
@Article 6@
|
||||
Individuals earning less than $10,000 are exempted of the income tax mentionned
|
||||
at article 1.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope NewIncomeTaxComputation:
|
||||
definition income_tax under condition
|
||||
individual.income <=$ $10,000
|
||||
consequence equals $0
|
||||
*/
|
||||
```
|
||||
|
||||
That's it! We've defined a two-brackets tax computation simply by annotating
|
||||
legislative article by snippets of Catala code. However, attentive readers
|
||||
@ -273,15 +297,16 @@ The law leaves it unspecified ; our dummy articles are clearly badly drafted.
|
||||
But Catala can help you find this sort of errors via simple testing or
|
||||
even formal verification. Let's start with the testing.
|
||||
|
||||
@@Testing Catala programs@@+
|
||||
### Testing Catala programs
|
||||
|
||||
Testing Catala programs can be done directly into Catala. Indeed, writing test
|
||||
cases for each Catala scope that you define is a good practice called
|
||||
"unit testing" in the software engineering community. A test case is defined
|
||||
as another scope:
|
||||
|
||||
@Testing NewIncomeTaxComputation@
|
||||
/*
|
||||
#### [Testing NewIncomeTaxComputation]
|
||||
|
||||
```catala
|
||||
declaration scope Test1:
|
||||
context tax_computation scope NewIncomeTaxComputation
|
||||
context income_tax content money
|
||||
@ -303,10 +328,11 @@ scope Test1:
|
||||
# assert that it is equal to the expected value :
|
||||
# ($230,000-$100,00)*40%+$100,000*20% = $72,000
|
||||
assertion income_tax = $72,000
|
||||
*/
|
||||
```
|
||||
|
||||
This test should pass. Let us now consider a failing test case:
|
||||
/*
|
||||
|
||||
```catala
|
||||
declaration scope Test2:
|
||||
context tax_computation scope NewIncomeTaxComputation
|
||||
context income_tax content money
|
||||
@ -319,24 +345,24 @@ scope Test2:
|
||||
|
||||
definition income_tax equals tax_computation.income_tax
|
||||
assertion income_tax = $0
|
||||
*/
|
||||
```
|
||||
|
||||
This test case should compute a $0 income tax because of Article 6. But instead,
|
||||
execution will yield an error saying that there is a conflict between rules.
|
||||
|
||||
@@Defining exceptions to rules@@+
|
||||
### Defining exceptions to rules
|
||||
|
||||
Indeed, the definition of the income tax in article 6 conflicts with the
|
||||
definition of income tax in article 5. But actually, article 6 is just an
|
||||
exception of article 5. In the law, it is implicit that if article 6 is
|
||||
applicable, then it takes precedence over article 5.
|
||||
|
||||
@Fixing the computation@
|
||||
#### [Fixing the computation]
|
||||
|
||||
This implicit precedence has to be explicitely declared in Catala. Here is a
|
||||
fixed version of the NewIncomeTaxComputation scope:
|
||||
|
||||
/*
|
||||
```catala
|
||||
declaration scope NewIncomeTaxComputationFixed:
|
||||
context two_brackets scope TwoBracketsTaxComputation
|
||||
context individual content Individual
|
||||
@ -360,11 +386,11 @@ scope NewIncomeTaxComputationFixed :
|
||||
definition income_tax under condition
|
||||
individual.income <=$ $10,000
|
||||
consequence equals $0
|
||||
*/
|
||||
```
|
||||
|
||||
And the test that should now work:
|
||||
|
||||
/*
|
||||
```catala
|
||||
declaration scope Test3:
|
||||
context tax_computation scope NewIncomeTaxComputationFixed
|
||||
context income_tax content money
|
||||
@ -376,9 +402,9 @@ scope Test3:
|
||||
}
|
||||
definition income_tax equals tax_computation.income_tax
|
||||
assertion income_tax = $0
|
||||
*/
|
||||
```
|
||||
|
||||
@@Conclusion@@+
|
||||
### Conclusion
|
||||
|
||||
This tutorial presents the basic concepts and syntax of the Catala language
|
||||
features. It is then up to you use them to annotate legislative texts
|
||||
|
@ -1,7 +1,8 @@
|
||||
@@Section 121@@
|
||||
## Section 121
|
||||
|
||||
@@Begin metadata@@
|
||||
/*
|
||||
> Begin metadata
|
||||
|
||||
```catala
|
||||
declaration structure Period:
|
||||
data begin content date
|
||||
data end content date
|
||||
@ -156,16 +157,17 @@ scope Section121TwoPasses:
|
||||
|
||||
definition income_excluded_from_gross_income equals
|
||||
second_pass.income_excluded_from_gross_income
|
||||
*/
|
||||
@@End metadata@@
|
||||
```
|
||||
> End metadata
|
||||
|
||||
@(a) Exclusion@
|
||||
## [(a) Exclusion]
|
||||
|
||||
Gross income shall not include gain from the sale or exchange of property if,
|
||||
during the 5-year period ending on the date of the sale or exchange, such
|
||||
property has been owned and used by the taxpayer as the taxpayer’s principal
|
||||
residence for periods aggregating 2 years or more.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope Section121SinglePerson:
|
||||
# Here we aggregate over all the periods of the collection. For
|
||||
# each period, three cases:
|
||||
@ -210,15 +212,16 @@ scope Section121TwoPersons:
|
||||
definition income_excluded_from_gross_income_uncapped equals
|
||||
section121Person1.income_excluded_from_gross_income_uncapped
|
||||
|
||||
*/
|
||||
```
|
||||
|
||||
@@(b) Limitations@@+
|
||||
### (b) Limitations
|
||||
|
||||
@(1) In general@
|
||||
#### [(1) In general]
|
||||
|
||||
The amount of gain excluded from gross income under subsection (a) with
|
||||
respect to any sale or exchange shall not exceed $250,000.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope Section121SinglePerson:
|
||||
definition gain_cap equals $250,000
|
||||
|
||||
@ -239,21 +242,21 @@ scope Section121TwoPersons:
|
||||
gain_cap
|
||||
else
|
||||
income_excluded_from_gross_income_uncapped
|
||||
*/
|
||||
```
|
||||
|
||||
@(2) Special rules for joint returns@
|
||||
#### [(2) Special rules for joint returns]
|
||||
|
||||
In the case of a husband and wife who make a joint return for the taxable year
|
||||
of the sale or exchange of the property—
|
||||
|
||||
/*
|
||||
```catala
|
||||
# Taxable year of the sale or exchange ?=? year when the income is taxed
|
||||
# Imagine a couple selling the house in 2020 and getting the payment in
|
||||
# 2021 where they file a joint return. Does (A) apply or not ?
|
||||
# Reasonably it should.
|
||||
*/
|
||||
```
|
||||
|
||||
@(A) $500,000 Limitation for certain joint returns@
|
||||
#### [(A) $500,000 Limitation for certain joint returns]
|
||||
|
||||
Paragraph (1) shall be applied by substituting “$500,000” for “$250,000” if—
|
||||
|
||||
@ -266,7 +269,7 @@ such property; and
|
||||
(iii) neither spouse is ineligible for the benefits of subsection (a) with
|
||||
respect to such property by reason of paragraph (3).
|
||||
|
||||
/*
|
||||
```catala
|
||||
scope Section121TwoPersons:
|
||||
rule section_121_b_2_A_condition under condition
|
||||
(return_type with pattern JointReturn of data_couple)
|
||||
@ -294,15 +297,17 @@ scope Section121TwoPersons:
|
||||
definition gain_cap under condition
|
||||
section_121_b_2_A_condition
|
||||
consequence equals $500,000
|
||||
*/
|
||||
```
|
||||
|
||||
#### [(B) Other joint returns]
|
||||
|
||||
@(B) Other joint returns@
|
||||
If such spouses do not meet the requirements of subparagraph (A), the limitation
|
||||
under paragraph (1) shall be the sum of the limitations under paragraph (1) to
|
||||
which each spouse would be entitled if such spouses had not been married. For
|
||||
purposes of the preceding sentence, each spouse shall be treated as owning the
|
||||
property during the period that either spouse owned the property.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope Section121TwoPasses under condition
|
||||
(return_type with pattern JointReturn) and
|
||||
not (first_pass.section_121_b_2_A_condition):
|
||||
@ -332,14 +337,16 @@ scope Section121TwoPasses under condition
|
||||
first_pass.person2.property_usage_as_principal_residence
|
||||
-- other_section_121a_sale: first_pass.person2.other_section_121a_sale
|
||||
}
|
||||
*/
|
||||
@(3) Application to only 1 sale or exchange every 2 years@
|
||||
```
|
||||
|
||||
#### [(3) Application to only 1 sale or exchange every 2 years]
|
||||
|
||||
|
||||
Subsection (a) shall not apply to any sale or exchange by the taxpayer if,
|
||||
during the 2-year period ending on the date of such sale or exchange, there
|
||||
was any other sale or exchange by the taxpayer to which subsection (a) applied.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope Section121SinglePerson:
|
||||
rule section_121_b_3_applies under condition
|
||||
(other_section_121a_sale with pattern
|
||||
@ -351,20 +358,21 @@ scope Section121SinglePerson:
|
||||
definition income_excluded_from_gross_income_uncapped under condition
|
||||
section_121_b_3_applies
|
||||
consequence equals $0
|
||||
*/
|
||||
```
|
||||
|
||||
@(4) Special rule for certain sales by surviving spouses@
|
||||
#### [(4) Special rule for certain sales by surviving spouses]
|
||||
|
||||
/*
|
||||
```catala
|
||||
# Sarah: the year when your spouse dies, do you file a joint return or
|
||||
# separate returns?
|
||||
*/
|
||||
```
|
||||
In the case of a sale or exchange of property by an unmarried individual whose
|
||||
spouse is deceased on the date of such sale, paragraph (1) shall be applied by
|
||||
substituting “$500,000” for “$250,000” if such sale occurs not later than 2
|
||||
years after the date of death of such spouse and the requirements of paragraph
|
||||
(2)(A) were met immediately before such date of death.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope Section121TwoPasses under condition
|
||||
return_type with pattern SingleReturnSurvivingSpouse of single_data and
|
||||
single_data.date_of_spouse_death <@ date_of_sale_or_exchange and
|
||||
@ -390,16 +398,16 @@ scope Section121TwoPasses under condition
|
||||
definition second_pass.gain_cap under condition
|
||||
first_pass.section_121_b_2_A_condition
|
||||
consequence equals $500,000
|
||||
*/
|
||||
```
|
||||
|
||||
@@(5) Exclusion of gain allocated to nonqualified use@@++
|
||||
#### (5) Exclusion of gain allocated to nonqualified use
|
||||
|
||||
@(A) In general@
|
||||
##### [(A) In general]
|
||||
|
||||
Subsection (a) shall not apply to so much of the gain from the sale or exchange
|
||||
of property as is allocated to periods of nonqualified use.
|
||||
|
||||
@(B) Gain allocated to periods of nonqualified use@
|
||||
##### [(B) Gain allocated to periods of nonqualified use]
|
||||
|
||||
For purposes of subparagraph (A), gain shall be allocated to periods of
|
||||
nonqualified use based on the ratio which—
|
||||
@ -409,18 +417,18 @@ was owned by the taxpayer, bears to
|
||||
|
||||
(ii) the period such property was owned by the taxpayer.
|
||||
|
||||
@@(C) Period of nonqualified use@@+++
|
||||
##### (C) Period of nonqualified use
|
||||
|
||||
For purposes of this paragraph—
|
||||
|
||||
@(i) In general@
|
||||
###### [(i) In general]
|
||||
|
||||
The term “period of nonqualified use” means any period (other than the portion
|
||||
of any period preceding January 1, 2009) during which the property is not used
|
||||
as the principal residence of the taxpayer or the taxpayer’s spouse or former
|
||||
spouse.
|
||||
|
||||
@(ii) Exceptions@
|
||||
###### [(ii) Exceptions]
|
||||
|
||||
The term “period of nonqualified use” does not include—
|
||||
|
||||
@ -436,7 +444,8 @@ subsection (d)(9)(A), and
|
||||
(III) any other period of temporary absence (not to exceed an aggregate period
|
||||
of 2 years) due to change of employment, health conditions, or such other
|
||||
unforeseen circumstances as may be specified by the Secretary.
|
||||
@(D) Coordination with recognition of gain attributable to depreciation@
|
||||
|
||||
###### [(D) Coordination with recognition of gain attributable to depreciation]
|
||||
|
||||
For purposes of this paragraph—
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
@@Section 132@@
|
||||
## Section 132
|
||||
|
||||
@@Begin metadata@@
|
||||
/*
|
||||
> Begin metadata
|
||||
```catala
|
||||
# We only formalize part (c) here
|
||||
declaration enumeration DiscountType:
|
||||
-- Property
|
||||
@ -25,19 +25,21 @@ scope QualifiedEmployeeDiscount:
|
||||
definition is_services equals match discount_type with pattern
|
||||
-- Property: false
|
||||
-- Services: true
|
||||
*/
|
||||
@@End metadata@@
|
||||
```
|
||||
> End metadata
|
||||
|
||||
|
||||
@@(c) Qualified employee discount defined@@+
|
||||
### (c) Qualified employee discount defined
|
||||
For purposes of this section—
|
||||
|
||||
@(1) Qualified employee discount@
|
||||
#### [(1) Qualified employee discount]
|
||||
|
||||
The term “qualified employee discount” means any employee discount with respect
|
||||
to qualified property or services to the extent such discount does not exceed—
|
||||
(A) in the case of property, the gross profit percentage of the price at which
|
||||
the property is being offered by the employer to customers, or
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope QualifiedEmployeeDiscount :
|
||||
definition qualified_employee_discount
|
||||
under condition is_property consequence
|
||||
@ -46,10 +48,12 @@ scope QualifiedEmployeeDiscount :
|
||||
customer_price *$ gross_profit_percentage
|
||||
then customer_price *$ gross_profit_percentage
|
||||
else employee_discount
|
||||
*/
|
||||
```
|
||||
|
||||
(B) in the case of services, 20 percent of the price at which the services are
|
||||
being offered by the employer to customers.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope QualifiedEmployeeDiscount :
|
||||
definition qualified_employee_discount
|
||||
under condition is_services consequence
|
||||
@ -64,24 +68,29 @@ scope QualifiedEmployeeDiscount under condition is_services:
|
||||
# We provide a default value here so that the computations run smooth.
|
||||
definition aggregate_cost equals $0
|
||||
definition gross_profit_percentage equals 0%
|
||||
*/
|
||||
@@(2) Gross profit percentage@@++
|
||||
```
|
||||
|
||||
#### (2) Gross profit percentage
|
||||
|
||||
##### [(A) In general]
|
||||
|
||||
@(A) In general@
|
||||
The term “gross profit percentage” means the percent which—
|
||||
|
||||
(i) the excess of the aggregate sales price of property sold by the employer
|
||||
to customers over the aggregate cost of such property to the employer, is of
|
||||
|
||||
(ii) the aggregate sale price of such property.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope QualifiedEmployeeDiscount under condition is_property:
|
||||
assertion customer_price >=$ aggregate_cost
|
||||
|
||||
definition gross_profit_percentage equals
|
||||
(customer_price -$ aggregate_cost) /$ customer_price
|
||||
*/
|
||||
@(B) Determination of gross profit percentage@
|
||||
```
|
||||
|
||||
##### [(B) Determination of gross profit percentage]
|
||||
|
||||
Gross profit percentage shall be determined on the basis of—
|
||||
|
||||
(i) all property offered to customers in the ordinary course of the line of
|
||||
@ -89,11 +98,14 @@ business of the employer in which the employee is performing services (or a
|
||||
reasonable classification of property selected by the employer), and
|
||||
|
||||
(ii) the employer’s experience during a representative period.
|
||||
/*
|
||||
|
||||
```catala
|
||||
# (i) and (ii) are subjective criteria for determining the gross profit
|
||||
# percentage ; we do not formalize them
|
||||
*/
|
||||
@(3) Employee discount defined@
|
||||
```
|
||||
|
||||
##### [(3) Employee discount defined]
|
||||
|
||||
The term “employee discount” means the amount by which—
|
||||
|
||||
(A) the price at which the property or services are provided by the employer to
|
||||
@ -101,20 +113,24 @@ an employee for use by such employee, is less than
|
||||
|
||||
(B) the price at which such property or services are being offered by the
|
||||
employer to customers.
|
||||
/*
|
||||
|
||||
```catala
|
||||
scope QualifiedEmployeeDiscount:
|
||||
assertion customer_price >=$ employee_price
|
||||
|
||||
definition employee_discount equals
|
||||
customer_price -$ employee_price
|
||||
*/
|
||||
@(4) Qualified property or services@
|
||||
```
|
||||
|
||||
##### [(4) Qualified property or services]
|
||||
|
||||
The term “qualified property or services” means any property (other than real
|
||||
property and other than personal property of a kind held for investment) or
|
||||
services which are offered for sale to customers in the ordinary course of
|
||||
the line of business of the employer in which the employee is performing
|
||||
services.
|
||||
/*
|
||||
|
||||
```catala
|
||||
# Again, this is for subjectively determining what item qualifies for a
|
||||
# discount, not formalizing
|
||||
*/
|
||||
```
|
||||
|
@ -1,8 +1,8 @@
|
||||
@@Include: ../section_121.catala_en@@
|
||||
> Include: ../section_121.catala_en
|
||||
|
||||
@Testing paragraph (a)@
|
||||
## [Testing paragraph (a)]
|
||||
|
||||
/*
|
||||
```catala
|
||||
declaration scope Data:
|
||||
context period_four_years_recent content Period
|
||||
context period_one_year_recent content Period
|
||||
@ -143,4 +143,4 @@ scope Test6:
|
||||
-- person2: data_.person_ok_2
|
||||
})
|
||||
assertion scope121.income_excluded_from_gross_income = $350,000
|
||||
*/
|
||||
```
|
||||
|
@ -1,7 +1,8 @@
|
||||
@@Include: ../section_132.catala_en@@
|
||||
> Include: ../section_132.catala_en
|
||||
|
||||
@Test@
|
||||
/*
|
||||
### [Test]
|
||||
|
||||
```catala
|
||||
declaration scope TestSection132_1:
|
||||
context section_132 scope QualifiedEmployeeDiscount
|
||||
|
||||
@ -13,9 +14,9 @@ scope TestSection132_1:
|
||||
assertion section_132.employee_discount = $500
|
||||
assertion section_132.gross_profit_percentage = 0.4
|
||||
assertion section_132.qualified_employee_discount = $500
|
||||
*/
|
||||
```
|
||||
|
||||
/*
|
||||
```catala
|
||||
declaration scope TestSection132_2:
|
||||
context section_132 scope QualifiedEmployeeDiscount
|
||||
|
||||
@ -27,9 +28,9 @@ scope TestSection132_2:
|
||||
assertion section_132.employee_discount = $500
|
||||
assertion section_132.gross_profit_percentage = 0.2
|
||||
assertion section_132.qualified_employee_discount = $300.00
|
||||
*/
|
||||
```
|
||||
|
||||
/*
|
||||
```catala
|
||||
declaration scope TestSection132_3:
|
||||
context section_132 scope QualifiedEmployeeDiscount
|
||||
|
||||
@ -39,4 +40,4 @@ scope TestSection132_3:
|
||||
definition section_132.discount_type equals Services
|
||||
assertion section_132.employee_discount = $500
|
||||
assertion section_132.qualified_employee_discount = $300
|
||||
*/
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user