Association blueprint

Rational

Associations need to keep track of their members, and generate the “book of members” (a list of active members with their unique code). This is similar to the company.employee model.
Usually a members need to be approved by the board, and the request date need to be registered.

Theory of operation

  • A member is defined by a party, a unique code and a starting/end date (where the member began and cease to be part of the association).
  • The user can be enrolled in one or more memberships.
  • In the membership model there is a list of periods (defined by start/end date).
  • A wizard (or/and some automatic mechanism) will generate the membership.fee lines and add it to the member. The wizard will have only the date as user input.
  • the membership.fee will be considered paid if the move associated to the fee is reconciled.
  • A wizard will generate a report of all the active member of the association
  • Another wizard will generate a report of all the periodand the state of each membership.fee line associate to each member (if paid or not)
  • An action will generate a receipt/report based on the membership.fee line selected

Proposal

model

  • association.member

    • state
      • Selection
    • code
      • Char
      • “The internal identifier for the associate.”
    • code_readonly
      • Function
    • company
      • Many2One(company.company)
      • “The association this member belongs to.”
    • party
      • Many2One(party.party)
      • “The party that represents the member.”
    • join_date
      • Date
      • “The date the member joined the association.”
    • leave_date
      • Date
      • “The date the member left the association.”
    • memberships
      • One2Many(association.membership)
  • association.membership.type

    • name
    • Char
    • periods
      • One2Many(association.membership.period)
      • “The periods that form the basis of the membership type.”
    • journal
      • Many2One(account.journal)
      • “The accounting journal that is used for the fee.”
    • account_revenue
      • Many2One(account.account)
      • “The revenue account that is used for the fee.”
    • company
      • Many2One(company.company)
      • “The association that the membership type belongs to.”
  • association.membership

    • member
      • Many2One(association.member)
    • membership
      • Many2One(association.membership.type)
    • start_date
      • Date
      • “The date when the membership starts.”
    • end_date
      • Date
      • “The date when the membership ends.”
    • member_state
      • Function
    • member_join_date
      • Function
    • member_leave_date
      • Function
  • association.membership.period

    • membership
      • Many2One(association.membership.type)
    • company
      • Many2One(company.company)
    • name
      • Char
    • start_date
      • Date
    • end_date
      • Date
    • amount
      • Numeric
      • “The fee amount.”
  • association.membership.fee

    • member
      • Many2One(association.member)
    • period
      • Many2One(association.membership.period)
      • “The period associated to this fee.”
    • move
      • Many2One(account.move)
      • “The accounting move associated to this fee.”
    • company
      • Many2One(company.company)
    • move_state
      • Function
    • paid
      • Function
    • amount
      • Function

workflow(association.member)

There will be 3 states:

  • draft
  • running
  • stopped

form draft can go only to running (the join_date is required to change state);
from runningcan go to stopped (the leave_date is required to change state);
from stopped is final (in case someone want to re-join, they need to create a new member).

Wizards

  • PostFee
  • GenerateFee
  • MembersBook

Relate

  • association.member
    • Fees

Implementation

Codereview: https://codereview.tryton.org/277491002/

or you can check here: https://git.mittelab.org/infra/tryton/mittelab_association

2 Likes

Some context:

I’m the accountant/treasurer of an association/hacker-space. Here in Italy, by law, need to create a list of member and collect the annual membership fee (from TUIR(a collection of fiscal laws)) need to be not less that 5 euro and mandatory for all members). Until this day, we did it by hand, and it was a huge pain in the back. We heard from other hacker-space that there is a need for a software specifically for association, so I hope this can be a start point for that.

Why this exist

I wanted to automate the creation of the book of members.
In Italy the book of members need have a list of names (and Fiscal code of the individual) with the request/join/leave date and a sequential code.
(this will be implemented in the future) I wanted to create/link subscription when a member is approved by the board.

Some discussion point:

  • Should creating/link subscription be part of this module, or it should a separate one.
1 Like

Hi, we developed some time ago the cooperative_ar module to fill the implementation of a work cooperative here at Argentina. Some features that you are looking for are already implemented there.

I know that is a different kind of organism, and that’s why we created the cooperative receipt, vacations and so on. I’m wondering if i could add a new blueprint with the features implemented on cooperative_ar also.

2 Likes

First of all, thank you both for sharing your thoughts.

I think we should extract the ideas behind all of the implementations of an association an create a module to manage the states of all associations.

@lukio I see you have functionality for managing vacations of association members, I think this can be probably part of a generic module based on employee. This will be useful for all kinds of companies.

maybe a best approach is to create a way to group employee by type (and have a employee_type field in the company.employee model) and generate a report for each type. So The association/company can keep track of employee/volunteer/member ecc…
Each type should have a difference sequence table (but this is more specific to my case, I’ll leave as a point of discussion)

And association module will shift his focus:

  • add more states/column in the employee tab (if necessary)
  • create/link subscription line for each member based on a template or manually created

What do you think?

Hi @pokoli, the vacations model of cooperative_ar it’s very basic. The only thing you can do is to register the vacations, but we never developed a report. I can add a new Blueprint called company_vacations if you believe it can help.

Shouldn’it be a M2M ? As you can both be an employee of the Org and a member.

It make sense to me.
But this will clash with the different code for each employee type, but i think I’ll drop this idea because it specific to my user case.

But how to deal with the fact that you can be an employee and something else, but in different date?

I think a bit more context is needed.

  1. Should the members also use Tryton? So they need to login in to Tryton
  2. Who creates the members in Tryton? Will this happen with a website, or is there a board member who enters the details.
  3. Why need members a unique code?
  4. Are you getting the fee in Cash or by Bank?

However I would suggest to extend the company.employee module. An employee has already a party, start date and end date. It just needs to have a small workflow and some extra fields to do the job. If you link a party you have an unique code created by the party-sequence. Also bankaccounts can be put on party, so you can automate import of bankstatements etc. So I think you have to stay as close as possible to the Tryton core (use as much as possible from that) and for your book of members, just use an extended company.employee.

well, yes… I’m a member, but i don’t think each user need an account…

We thought to use a flask app to generate the party/associatite… but i think this is not important for this module. for now we do it by hand.

By law (in our country) need to be a sequential code, but we can use the one in the company.employee.
This can be a problem if you need a different sequential list for different type of employee (this is why i suggested to drop the requirement of having )

both, but i wanted to use subscription for generating all the invoices, so i don’t need to reinvent the wheel, and all the module can do the rest. The one thing missing is to generating a report of all the unpaid invoice from the members.

employee have a code, i can use that. using the party code as identifier is not the way to go… supplier are a party too.

I’m just brainstorming, I don’t have a favourite solution. I’m leading to expand the employee module and add a employee type.

I think tpf/foundation_supporter: log could be used as basis but it should remove the “foundation” stuffs for more generic naming.
I do not think it is the right way to reuse the employee model because this is not the same concept (except probably for the @lukio module but this is because members of a cooperatives are a kind of employee: payroll, vacation, expenses etc.)

I do not think you really need a report. The CSV export should be good enough and generic enough for the need.

I do not think it is the right solution. A membership fee is quite different from the subscription/consumption/service model. Usually you are a member only if you pay the fee. And the recurrence is directly linked to the membership period/renewal.

Another point, the associations often cannot deduct the taxes. So it will require Support non deductible taxes (#6911) · Issues · Tryton / Tryton · GitLab

Ok, is literally (like field by field) the same module as the one I drafted, I’m on part on reuse yours (it has more checks that my code).
Still would like to have a wizard for exporting the book of members based on the company. My reason are:

  • it’s an official document, and on demand you need to produce this document, on official letterhead paper (fancy way to say… the company data)
  • can be error prone to reformat the table to be presentable

[This is in my country, and is not in general, I write about this so we can find a common ground]
Well, you are a member for life, until the board expels you for not pay the membership fee, or you request it, or other reasons(Doing otherwise, and you risk to be categorised as a commercial entity, and you need to pay all the due taxes as such)
For now I’m abusing the subscription module, because it seamed logical for generating all the recurrent invoices, but I’m ok to create a simpler module tailored to this problem. If so, we need to discuss how to implement it.

For me it’s one consumption for each period of the membership. So the subscription model fits for associations also. The membership state can be managed manually when the service invoice it is not paid.

I think we may separate the membership invoicing in a separate but I think we should manage the following case (not sure if here or in the invoicing):

  • There are associations that manage different kinds of membership (with a different fee). So it should be possible of specify the membership kind.

I do not agree. Subscription is based on a contract which defines when and how the subscription stops.
For association with fees, you are part of it until you stop paying. So you can not take for granted the next fee (which should probably not be an invoice by the way) and the payment of it define the membership status.

Ok I see your point.

So we should probably generate payments instead of invoices but also support the case to generate an invoice for the payment. We are members of one association which issues us invoices for the membership fee

No I do not think payment is the right model. I think it should be something like a request for payment.

I’m neither sure it is correct to make invoice. It is probably more a receipt.
This is because association are not business so they do not have VAT etc.

Sorry if I’m fueling the bike-shedding but:

A membership fee is mandatory until you are a member (you are a member for life), and you CAN be expel for not paying the fee (but is not automatic). So pretending the membership fee (by generating an invoice/receipt or payment line) is correct IMHO. If the member doesn’t want to pay the fee… you can simply write it off (or leave it, some association pretend you pay in full all the past membership fee before you can reinstated as a member)

In my case this is not correct, a registered association have a fiscal code (is similar to the one any citizen have) in my country. You can request a P.IVA(vat code) if you want sell services/good and be a for-profit association(Example: you can sell a magazine outside your association (and you pay the taxes on tha)t, but you will not pay the taxes on the membership fee you collect). In Italy an association are a special case of a commercial entity/company.

What is an invoice other than a more formal receipt :stuck_out_tongue:
But seriously, if you issue a receipt, you still need to report then, and have a sequential number on it. I think they should have the same “logic” of an invoice, but have a different sequence code (and another report template)

I think (at least is true in my user case) using invoice as a way to track the membership fee is a good enough workflow.

I think we should collect more user case from other country, and try to find a common ground. So please share your user case here.

No this is only for your weird case. The majority does not work like that.

So this is completely aligned with my comment to not use invoice for association membership fees.

It is much more. It has taxes report, unit price without taxes, tax identifier etc.

I do not see why a receipt will need such sequence. It has no tax report purpose.

I’m sorry for my witty comment. I meant that you can write a receipt as an invoice (without writing tax line ecc), but I didn’t want to imply you can write an invoice as a receipt.

Yes, for tax collecting purposes doesn’t make sense, but you still need to prove where the money com from. Usually you do it by having heap of numbered receipt… so the state can check you didn’t add/hide it somewhere. (Associations need to deposit the closing balance on the Italian association registry BTW)

Yes, Italian laws are weird (Fun fact: the only law that describe what is an association is buried in a section under the fiscal Text/law collection). But this distinction is necessary for discern a commercial entity like a gim(you pay a fee for a service), and an association (a group of people/legal entities united to execute a goal/mission). Sorry if I’m passionate about this topic, but I’m fresh from an argument around this.
Ok, I’ll end my discussion here.

Ok, now for the module.
I wanted to reuse some of the other module, but I’m fine to create a way to keep track of the membership fees without the subscription module. So, can define a structure for that?
Like:

  • membership fee receipt model
  • a recurrent fee model that will generate payment line/receipt
  • the member model, that will generate/be linked to a recurrent fee

Here you are talking about cash registration. This is something that can be done using account_statement or a cash journal with posted moves.

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).