# Association blueprint

**URL:** https://discuss.tryton.org/t/association-blueprint/1282
**Category:** Ideas
**Created:** [March 31, 2019, 8:46pm UTC](https://discuss.tryton.org/t/association-blueprint/1282 "2019-03-31T20:46:36Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![albert](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/albert/32/21_2.png) [@albert](https://discuss.tryton.org/u/albert)
#### Post date: [April 4, 2019, 10:15am UTC](https://discuss.tryton.org/t/association-blueprint/1282/21 "2019-04-04T10:15:29Z")

</div>

> [@ced](#):
>
> For me, it should be based on a fee request model for a period. This requests will be created by a wizard using all active member and for the next membership period (I’m guessing all association used a fixed period for membership which is what I always saw).  
> The status of a member at a date is computed from the status of the request if it is paid or not.  
> The status of the request is linked to linkes move lines with a total equals to the fee (probably with a domain on account). (account\_statement could be extended to allow to link a line to a request).  
> The fee amount of a request should be based on the membership type where price is defined (I do not think it is needed to historize it).

I think it should be noted that many associations have some kind of “honour” members who do not pay for their membership.

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 4, 2019, 10:17am UTC](https://discuss.tryton.org/t/association-blueprint/1282/22 "2019-04-04T10:17:12Z")

</div>

> [@albert](#):
>
> I think it should be noted that many associations have some kind of “honour” members who do not pay for their membership.

I think this can work with a request of amount 0 which will be considered as paid.

---

<div class="post-metadata">

### Author: ![pokoli](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/pokoli/32/22_2.png) [@pokoli](https://discuss.tryton.org/u/pokoli)
#### Post date: [April 4, 2019, 10:20am UTC](https://discuss.tryton.org/t/association-blueprint/1282/23 "2019-04-04T10:20:37Z")

</div>

> [@ced](#):
>
> For me, it should be based on a fee request model for a period.

IIUC the period should be configurable as some associations manage their membership on a yearly period and others on monthly, trimester, etc.

How should this period be defined?

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 4, 2019, 10:28am UTC](https://discuss.tryton.org/t/association-blueprint/1282/24 "2019-04-04T10:28:27Z")

</div>

> [@pokoli](#):
>
> How should this period be defined?

Why not let the user choose the dates?

Indeed there could be a model that store each period (from-to) and on it for each membership type, there will be the price. So instead of a wizard, it will be a button on this model that create the request.

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 4, 2019, 10:28am UTC](https://discuss.tryton.org/t/association-blueprint/1282/25 "2019-04-04T10:28:35Z")

</div>

> [@ced](#):
>
> For me, it should be based on a fee request model for a period. This requests will be created by a wizard using all active member and for the next membership period (I’m guessing all association used a fixed period for membership which is what I always saw).

I think this will fit most user cases (or at lest it fits mine)

> [@ced](#):
>
> The status of a member at a date is computed from the status of the request if it is paid or not.

Ok, what state a membercan be? i propose:

- draft
- pending (for approval)
- unpaid
- payed
- expelled (this should be manual i think)

> [@ced](#):
>
> The fee amount of a request should be based on the membership type where price is defined (I do not think it is needed to historize it).

I like this solution, yes i think we don’t need to have a history of all the membership fee amount. Should we use the product category for this (maybe add a new type)

> [@pokoli](#):
>
> IIUC the period should be configurable as some associations manage their membership on a yearly period and others on monthly, trimester, etc.

I’m prone to reuse the rrule of the subscription module (or create something similar specific to this module). The problem of the rrule is that will not trigger for the first instance, but i think the module can create a move, and then use the rrule.

I feel confident enough this will be the final solution, so I’ll try to draft (very roughly) something this weekend

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 4, 2019, 10:33am UTC](https://discuss.tryton.org/t/association-blueprint/1282/26 "2019-04-04T10:33:26Z")

</div>

> [@wifasoi](#):
>
> - draft
> - pending (for approval)

I do not see the point of having two states. A draft membership is the same as pending.

> [@wifasoi](#):
>
> - unpaid
> - payed

I think the payment status should be different from the state. So I would have a running state and another field which provides paid Boolean for the current date.

> [@wifasoi](#):
>
> - expelled (this should be manual i think)

I would named it stopped.

---

<div class="post-metadata">

### Author: ![albert](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/albert/32/21_2.png) [@albert](https://discuss.tryton.org/u/albert)
#### Post date: [April 4, 2019, 10:54am UTC](https://discuss.tryton.org/t/association-blueprint/1282/27 "2019-04-04T10:54:42Z")

</div>

> [@ced](#):
>
> > - draft
> > - pending (for approval)
> 
> I do not see the point of having two states. A draft membership is the same as pending.

I would agree with distinguishing between draft and pending for approval. The cases I know, candidates must provide certain information before they’re considered for approval. So having a draft state seems convenient waiting for all the information to be provided.

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 4, 2019, 10:57am UTC](https://discuss.tryton.org/t/association-blueprint/1282/28 "2019-04-04T10:57:03Z")

</div>

> [@albert](#):
>
> I would agree with distinguishing between draft and pending for approval. The cases I know, candidates must provide certain information before they’re considered for approval. So having a draft state seems convenient waiting for all the information to be provided.

No it is not necessary and create extra burden. If there are some requirements to met to be running, then it should be managed with a condition on the transition (and there could be a domain to find those).

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 4, 2019, 12:19pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/29 "2019-04-04T12:19:00Z")

</div>

The only motivation i can think of to have an intermediate state is:  
If someone goes from stopped/expelled to edit(or pending) they should maintain the same code(and same record)

#### user case

A member have some unpaid membership fee, and you want to force him to pay all the past dept before being accepted.  
I think the norm(and please correct me if i’m wrong) is overwrite the past code of the record when you go to the next state.

This i think can be the only reason (if assumption above is correct) to have a separate state from edit.

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 4, 2019, 1:13pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/30 "2019-04-04T13:13:57Z")

</div>

> [@wifasoi](#):
>
> If someone goes from stopped/expelled to edit(or pending) they should maintain the same code(and same record)

I think the stopped state should be finale. Re-introduce back a member should be done using a new membership.

> [@wifasoi](#):
>
> A member have some unpaid membership fee, and you want to force him to pay all the past dept before being accepted.

He can not have dunning if he is not yet running.

> [@wifasoi](#):
>
> I think the norm(and please correct me if i’m wrong) is overwrite the past code of the record when you go to the next state.

I do not understand.

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 5, 2019, 5:01pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/31 "2019-04-05T17:01:22Z")

</div>

> [@ced](#):
>
> I think the stopped state should be finale. Re-introduce back a member should be done using a new membership.

I’m fine with this. So i think we can reduce all the state to:

- draft
- running
- stopped

* * *

Now lets discuss how to organize the membership part:  
I’m proposing to re-use the product model, and adding a “membership” type.  
This is the structure i have in mind:

- association.membership.line:
  - member (many2one of association.member)
  - description
  - membership (a product of type membership)
  - uom
  - quantity
  - unit\_price
  - from\_date (default to\_date from the last membership line)
  - to\_date
  - payment\_lines (all the payments line associated to this one)
  - membership\_move (the move to pay)
  - state (function field: Boolean for paid/unpaid)

- association.member
  - …
  - membership (many2many of association.membership.line)

What do you think?

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 5, 2019, 10:30pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/32 "2019-04-05T22:30:50Z")

</div>

> [@wifasoi](#):
>
> - association.membership.line:

I would name it `association.membership.fee`.

> [@wifasoi](#):
>
> description

I do not think it is needed.

> [@wifasoi](#):
>
> \*membership (a product of type membership)

I do not think it needs to be a product because we do not need any of the accounting stuffs (account, taxes etc.)  
I think we need to have a membership fee type which can be used to define the price per period and for how much members.

> [@wifasoi](#):
>
> - member (many2one of association.member)

I think a fee could be linked to multiple members. E.g. there is often family pack.

> [@wifasoi](#):
>
> - from\_date (default to\_date from the last membership line)
> - to\_date

I think we should consider that the periods are common to all members (or at least some part). So we would need a `association.membership.period`.  
But maybe there could be different kind of period (e.g. per month and per year). So a member should be subscribe to one kind. But this may be too complex for simple association and so I think the multiple period should be managed by a second module (but initial module should take care to leave room for that).

> [@wifasoi](#):
>
> - payment\_lines (all the payments line associated to this one)

It should be `account.move.line` and it will be used only for technical usage. A relate should open them for the accountant (like paybale/receivable on party).

> [@wifasoi](#):
>
> - membership\_move (the move to pay)

There should be no move to pay. Because it is not a debt, it is just a request to renew the membership.

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 5, 2019, 11:12pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/33 "2019-04-05T23:12:49Z")

</div>

> [@ced](#):
>
> > description
> 
> I do not think it is needed.

Fair enough.

> [@ced](#):
>
> > - member (many2one of association.member)
> 
> I think a fee could be linked to multiple members. E.g. there is often family pack

In my user case this is frowned upon, but I think this should be fine to implement (and I like the idea)

> [@ced](#):
>
> > \*membership (a product of type membership)
> 
> I do not think it needs to be a product because we do not need any of the accounting stuffs (account, taxes etc.)

well, I still need to define an account receivable and an account for revenue (see last paragraph TL;DR: fees due are debt). The product model gives me that. If i can reuse it, i will.

> [@ced](#):
>
> think we need to have a membership fee type which can be used to define the price per period and for how much members.

I don’t understand, you mean crate a model for membership type, or add a type to the product model (i think is the former.. but I’m not sure)

> [@ced](#):
>
> > - membership\_move (the move to pay)
> 
> There should be no move to pay. Because it is not a debt, it is just a request to renew the membership.

Mmmm, the module main goal (or it was initially) is to keep track of membership fee they are due (so they are a debt in my view). I need to register it as such, in Italy the fee is mandatory.  
How the dunning module will work without a receivable move? (maybe this is not the correct phrasing, but i hope the message is clear) Is not a rhetorical question because i didn’t use this module much.

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 6, 2019, 7:53am UTC](https://discuss.tryton.org/t/association-blueprint/1282/34 "2019-04-06T07:53:57Z")

</div>

> [@wifasoi](#):
>
> In my user case this is frowned upon, but I think this should be fine to implement (and I like the idea)

On a second though, I think it is better to keep a Many2One.  
So the family case could be solved by having a single member link to a main party but with extra parties for the family members.

> [@wifasoi](#):
>
> need to define an account receivable

The receivable is given on the party.

> [@wifasoi](#):
>
> an account for revenue

Well in my initial thoughts, it would have been filled on the statement.

But now, I think it may be useful that the membership.fee creates a **draft** move that will be posed when the statement tries to reconcile it (a little bit like `account_payment_clearing`).

> [@wifasoi](#):
>
> I don’t understand, you mean crate a model for membership type, or add a type to the product model (i think is the former… but I’m not sure)

I mean create a new model `association.membership.type` which will hold:

- prices per period (multivalue)
- revenue account (multivalue)
- number of linked member allowed etc.

---

<div class="post-metadata">

### Author: ![jcm](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/jcm/32/344_2.png) [@jcm](https://discuss.tryton.org/u/jcm)
#### Post date: [April 6, 2019, 10:36am UTC](https://discuss.tryton.org/t/association-blueprint/1282/35 "2019-04-06T10:36:01Z")

</div>

> [@wifasoi](#):
>
> > > \*membership (a product of type membership)
> > 
> > I do not think it needs to be a product because we do not need any of the accounting stuffs (account, taxes etc.)
> 
> well, I still need to define an account receivable and an account for revenue (see last paragraph TL;DR: fees due are debt). The product model gives me that. If i can reuse it, i will.

In many associations I know, there can be two kinds of members with different amounts paid. Having a product would be a simple way to store these amounts.

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 9, 2019, 1:18pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/36 "2019-04-09T13:18:10Z")

</div>

> [@ced](#):
>
> number of linked member allowed etc.

mmm, I don’t think this is necessary.. or at least i think it should be a separate module.

I modified the top post with all the feedback gathered so far (I hope is correct, if not please edit or discuss it here).

I drafted the structure the association.membership.type as so:

- association.membership.type
  - name
  - period
  - fee\_amount
  - revenue (the revenue account, if not specified use the one indicated int he parent type)
  - receivable (default to the party receivable if not specified, or use the parent account)
  - parent
  - children

My only doubt is the receivable account: should i use the party default one alone, or have the ability to define it in the type?

* * *

now i want to discuss how to create the `association.membership.period`:  
The easiest way is to have this (or at least i think is the simplest way):

- name
- from\_date
- to\_date

and the have a wizard that generate new periods based on user input (like +1Year, +1Month, a end date ecc..).  
The wizard will take the record with the latest to\_date and copy it with the from/to date changed accordingly. For this to wort the should not be any overlap, so this will limit to only one period per association.  
We can have a period type and have multiple period that can overlap (like @ced suggested), I’m not thinking to implement it in this module unless there is a strong reason/user case that will benefit from such feature.

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 9, 2019, 9:22pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/37 "2019-04-09T21:22:24Z")

</div>

> [@wifasoi](#):
>
> - period
> - fee\_amount

I think the fee amount should be defined by a list with a from date. So to compute it will take the last amount with a from date before the period date. (Similar to the cost price of employee).

> [@wifasoi](#):
>
> - parent
> - children

I do not see the point to make a tree structure.

> [@wifasoi](#):
>
> My only doubt is the receivable account: should i use the party default one alone, or have the ability to define it in the type?

Receivable should always be taken from party.

> [@wifasoi](#):
>
> The wizard will take the record with the latest to\_date and copy it with the from/to date changed accordingly. For this to wort the should not be any overlap, so this will limit to only one period per association.

Yes it should be similar to the fiscal year.  
But I think we should allow different kind of period (e.g. monthly, quaterly, yearly etc.). But it should just be a name. It does not require to have any frequency defined.  
I do not know how we can call that. But it will be set on period and on membership.type

> [@wifasoi](#):
>
> We can have a period type and have multiple period that can overlap (like @ced suggested), I’m not thinking to implement it in this module unless there is a strong reason/user case that will benefit from such feature.

If it is not implemented in base, it will not be possible to extend the module to add it.

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 10, 2019, 3:59pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/38 "2019-04-10T15:59:53Z")

</div>

> [@ced](#):
>
> I do not know how we can call that. But it will be set on period and on membership.type

If I structure it more like the Fiscal year periods the “type”(like a product type) is not necessary: so we have something like:

- membership.TBD

- memership.period.line (TBD name)

and like the fiscal year, two wizard:

- For generating contiguous periods (like Monty, weekly ecc..)
- For creating a new “membership.TBD”(the one that collect all the period line) based from the one you select, but will add a year to all the period date.

then a wizard can generate all the fee lines (association.membership.fee) based on the “membership.TBD” the join\_date and the leave\_date (association.member ). (need to add “membership.TBD” filed to the “association.member” for this to work")

> [@wifasoi](#):
>
> > number of linked member allowed etc.
> 
> mmm, I don’t think this is necessary… or at least i think it should be a separate module.

Sorry, but i think i misunderstood you. Can you elaborate more on this?

Thank you for all the feedback (specially @ced)

---

<div class="post-metadata">

### Author: ![wifasoi](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/w/ed655f/32.png) [@wifasoi](https://discuss.tryton.org/u/wifasoi)
#### Post date: [April 12, 2019, 2:46pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/39 "2019-04-12T14:46:28Z")

</div>

Ok, I’m proposing this structure:

- association.membership
  - name
  - periods
  - account\_revenue
  - company (from CompanyMultiValueMixin)

- association.membership.period
  - name
  - start\_date
  - end\_date
  - fee\_amount
  - membership (many2One)
  - company (function)

- association.membership.fee
  - sequence (from sequence\_ordered)
  - member (many2one of association.member)
  - fee\_amount (multivalue)
  - period (the association.membership.period associated to this line)
  - payment\_lines (a function field, like the one in the invoice model)
  - membership\_move (the account.move.line associate with this fee line)
  - state (a function field with selector field, so you can check if the line is payed or not)
  - company (from CompanyMultiValueMixin)

and for the member:

- association.member
  - state
  - code (read-only, set by member\_sequence)
  - company (taken from context)
  - request\_date (maybe this is not necessary)
  - join\_date
  - leave\_date
  - memberships (Many2Many to association.membership)
  - membership\_fees (many2one field with all the association.membership.fee lines)

The new idea is that a member can have multiple “membership”(association.membership). with `association.membership` model is now possible to do so.

the `association.membership` in short:

- there is no state to a membership (not like a fiscal year, and there is no need)
- the `association.membership` defines the account revenue.
- you need to add a ‘association.membership.period’, and the the wizard/cron job will generate all the `association.membership.fee` for each member based on a given date.

the `association.membership.fee` in short:

- defined by a start-end date
- the price can vary between periods

If there are no other comment/necessary feature to implement, I’ll start to program the module with this structure/feature

---

<div class="post-metadata">

### Author: ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)
#### Post date: [April 13, 2019, 12:10pm UTC](https://discuss.tryton.org/t/association-blueprint/1282/40 "2019-04-13T12:10:06Z")

</div>

> [@wifasoi](#):
>
> - sequence (from sequence\_ordered)

I do not see the point. For me, the order should be based on start\_date of the linked period.

> [@wifasoi](#):
>
> - fee\_amount (multivalue)

I would name it simply `amount`.  
I do not think it should be a multivalue, it should be the value for the linked company.

> [@wifasoi](#):
>
> - membership\_move

Just name it `move`.

> [@wifasoi](#):
>
> - state (a function field with selector field, so you can check if the line is payed or not)

I think it is better to name it `paid` and store the reconciliation date (behave like the `reconciled` of invoice).

> [@wifasoi](#):
>
> - request\_date (maybe this is not necessary)

I think the `create_date` could be enough (or it could be delegated to customization)

> [@wifasoi](#):
>
> - memberships (Many2Many to association.membership)

I think it should be a `One2Many` with a `Many2One` to `association.membership`. The relation model should have a start and end date (so the `join_date` and `leave_date` move to this relation model).  
It could still have a `join_date` and `leave_date` but they will be Function field computed out of the `memberships`.

[Previous page](https://discuss.tryton.org/t/association-blueprint/1282.md?page=1)

[Next page](https://discuss.tryton.org/t/association-blueprint/1282.md?page=3)
