Discover powerful Dolibarr extensions designed to automate your business processes

Blood Donation Center Management is a Dolibarr add-on module, published by DoliResources, that manages the complete administrative and logistical life cycle of a blood collection organisation: the donor file, appointment booking, reception and the waiting queue, the pre-donation paperwork, the recording of the donation itself, the identification of bags and sample tubes, post-donation recovery, fixed and mobile collection campaigns, consumable stock, equipment, quality management, partner billing and cost control. It is delivered in version 1.0.0 under the GNU GPL v3 or later licence and runs on Dolibarr 16 to 23 with PHP 8.0 or above.
The module contributes 51 business objects, each with its own list, record card, document tab, note tab and agenda tab, backed by 51 dedicated database tables prefixed llx_bdc_. Coded columns are governed by 119 controlled vocabularies so that statuses, types and reasons are stored as stable codes and displayed as translated badges. Access is governed by 28 permission groups totalling 96 individual permissions, and the whole data model is exposed through a REST API of 255 routes. Five language packs are shipped: French, English, Spanish, Italian and German, each with approximately 1,700 keys.
Eight bespoke pages complete the standard Dolibarr screens: a command centre dashboard, a twelve-report reporting console with CSV export, a live waiting-queue board, an end-to-end traceability search, a weekly appointment planning grid, a donor portal back office, and the two administration pages for parameters and version information.
This module is a management tool. It never substitutes for the medical assessment of a donor, for the decision to accept or defer that donor, for the interpretation of measured parameters or of any biological result, or for the handling of a donation reaction. It records what an authorised health professional has decided; it does not decide. Every sensitive medical decision remains under the control of an authorised health professional, who remains solely responsible for it.
The module is likewise not a replacement for the specialised software used for biological qualification of donations, for component preparation, or for transfusion delivery to patients. It stops at the traceable hand-over of bags and sample tubes to an external destination, and records the reference and date of that hand-over. No regulatory certification, accreditation or compliance approval is claimed for the module; conformity with the rules applicable to the operator remains the responsibility of the operator and of its medical management.
The module answers a small number of operational problems that recur in every collection organisation, whether it runs a single fixed site or a network of centres and mobile teams.
· Keep one reliable donor file. llx_bdc_donor carries 36 fields, from the donor number and civil identity to the declared blood group, the communication preferences, the segment and the counters nb_donations, first_donation_date and last_donation_date, so that the same person is never created twice.
· Shorten the donor's visit. Appointments, admissions and the waiting queue are separate objects sharing the same references, which makes the actual waiting time (wait_minutes) measurable rather than estimated.
· Make the pre-donation file complete and auditable before the collection starts: questionnaire response, consents, interview, measurements and an explicit eligibility decision, each with its own status.
· Guarantee the identification chain. Every bag and every sample tube carries a number, a barcode and a QR payload, is attached to a donation, and is traceable to its external destination.
· Plan and cost campaigns. Registered, present, donations and deferrals are counted against a target and a budget, and the cost per donation is computed from the recorded costs.
· Protect stock continuity. Consumables, lots, reservations, supplier orders, inventories and losses are managed together, with expiry and minimum-threshold alerts.
· Retain donors. Loyalty levels, engagement and satisfaction scores, segmented communications and appointment reminders address the attrition that most organisations measure only after the fact.
The commercial objective for the buyer is a single system of record inside an ERP they already operate, rather than a set of spreadsheets and isolated tools whose figures never reconcile.
The functional scope is expressed by 51 business objects grouped in 13 menu sections: donors, schedule, reception, pre-donation, collection, campaigns, mobile, loyalty, stock, equipment, quality, finance and network administration. Four objects act as hubs because most other records point at them: the donor, the appointment, the donation and the campaign. Five objects are line objects, edited inside their parent record rather than as free-standing lists: questions inside a questionnaire, answers inside a response, measurements inside an interview, and messages inside a communication.
Each object provides the standard Dolibarr behaviour: a filterable and sortable list, a record card with tabs, attached documents, free-text notes, an agenda of events, extra-field support, and mass actions. The table below lists the complete inventory delivered in version 1.0.0.
|
Object |
Table |
Menu entry |
Fields |
|
bdccenter |
llx_bdc_center |
Centres |
17 |
|
bdcstaff |
llx_bdc_staff |
Staff |
17 |
|
bdcpartner |
llx_bdc_partner |
Partners |
16 |
|
bdcagreement |
llx_bdc_agreement |
Agreements |
17 |
|
bdcdonor |
llx_bdc_donor |
Donors (hub) |
36 |
|
bdcdonorcard |
llx_bdc_donor_card |
Donor cards |
13 |
|
bdcappointment |
llx_bdc_appointment |
Appointments (hub) |
18 |
|
bdcadmission |
llx_bdc_admission |
Admissions |
17 |
|
bdcqueue |
llx_bdc_queue |
Waiting queue |
17 |
|
bdcquestionnaire |
llx_bdc_questionnaire |
Questionnaires |
17 |
|
bdcquestion |
llx_bdc_question |
Questions (lines) |
13 |
|
bdcresponse |
llx_bdc_response |
Responses |
16 |
|
bdcanswer |
llx_bdc_answer |
Answers (lines) |
10 |
|
bdcconsent |
llx_bdc_consent |
Consents |
16 |
|
bdcinterview |
llx_bdc_interview |
Interviews |
22 |
|
bdcmeasure |
llx_bdc_measure |
Measurements (lines) |
12 |
|
bdcdeferralreason |
llx_bdc_deferral_reason |
Deferral reasons |
12 |
|
bdcdeferral |
llx_bdc_deferral |
Deferrals |
16 |
|
bdcdonation |
llx_bdc_donation |
Donations (hub) |
26 |
|
bdcbag |
llx_bdc_bag |
Collection bags |
20 |
|
bdcsample |
llx_bdc_sample |
Tubes and samples |
18 |
|
bdclabel |
llx_bdc_label_print |
Label printing |
16 |
|
bdcreaction |
llx_bdc_reaction |
Donation reactions |
18 |
|
bdcrecovery |
llx_bdc_recovery |
Recovery |
17 |
|
bdcrefreshment |
llx_bdc_refreshment |
Refreshments |
15 |
|
bdccampaign |
llx_bdc_campaign |
Campaigns (hub) |
26 |
|
bdcstation |
llx_bdc_station |
Stations |
11 |
|
bdcmobileteam |
llx_bdc_mobile_team |
Mobile teams |
13 |
|
bdcmission |
llx_bdc_mission |
Missions |
20 |
|
bdcvehicle |
llx_bdc_vehicle |
Vehicles |
15 |
|
bdcsync |
llx_bdc_sync_log |
Synchronisation logs |
16 |
|
bdcloyalty |
llx_bdc_loyalty |
Loyalty |
17 |
|
bdccommunication |
llx_bdc_communication |
Communications |
20 |
|
bdcmessage |
llx_bdc_message |
Messages (lines) |
11 |
|
bdcreminder |
llx_bdc_reminder |
Reminders |
14 |
|
bdcsurvey |
llx_bdc_survey |
Satisfaction surveys |
19 |
|
bdcconsumable |
llx_bdc_consumable |
Consumables |
18 |
|
bdclot |
llx_bdc_lot |
Lots |
16 |
|
bdcreservation |
llx_bdc_reservation |
Reservations |
15 |
|
bdcpurchase |
llx_bdc_purchase |
Supplier orders |
18 |
|
bdcinventory |
llx_bdc_inventory |
Inventories |
16 |
|
bdcloss |
llx_bdc_loss |
Losses |
16 |
|
bdcequipment |
llx_bdc_equipment |
Equipment |
24 |
|
bdcmaintenance |
llx_bdc_maintenance |
Maintenance |
17 |
|
bdcincident |
llx_bdc_incident |
Incidents |
21 |
|
bdcaudit |
llx_bdc_audit |
Audits |
16 |
|
bdcaction |
llx_bdc_capa |
Corrective actions |
15 |
|
bdccontinuity |
llx_bdc_continuity |
Continuity plans |
14 |
|
bdcbilling |
llx_bdc_billing |
Billing |
23 |
|
bdccost |
llx_bdc_cost |
Costs |
17 |
|
bdcdocument |
llx_bdc_document |
Donor documents |
18 |
Table 1 - The 51 business objects delivered by the module
Permissions follow the native Dolibarr model: they are granted to users or to user groups, and they are checked both by the user interface and by the REST API. The module declares 28 permission groups, each offering read, write and delete, plus a small number of sensitive sub-permissions. In total 96 permissions are declared. Read and write are enabled by default when the module is activated; delete, the sensitive sub-permissions and the administration permission are disabled by default and must be granted deliberately.
Four sensitive sub-permissions deserve particular attention when roles are designed: questionnaire/validate, which locks a questionnaire version; interview/decide, which records the eligibility decision; donation/identify, which performs the second identity check before the puncture; and label/reprint, which reprints an identification label. Restricting those four to qualified staff is the practical way to keep the audit trail meaningful.
|
Permission group |
Covers |
Sensitive sub-permission |
|
center |
Collection centres and sites |
- |
|
staff |
Staff members |
- |
|
donor |
Donors and donor cards |
- |
|
loyalty |
Donor loyalty records |
- |
|
appointment |
Appointments and slots |
- |
|
admission |
Admissions and the waiting queue |
- |
|
questionnaire |
Pre-donation questionnaires |
validate |
|
consent |
Donor consents |
- |
|
interview |
Pre-donation interviews |
decide |
|
deferral |
Deferrals and deferral reasons |
- |
|
donation |
Donations and collection |
identify |
|
bag |
Collection bags |
- |
|
sample |
Tubes and samples |
- |
|
label |
Label printing |
reprint |
|
reaction |
Donation reactions |
- |
|
recovery |
Post-donation recovery and refreshments |
- |
|
campaign |
Collection campaigns |
- |
|
partner |
Partners and agreements |
- |
|
mobile |
Mobile teams, missions and vehicles |
- |
|
communication |
Communication campaigns and reminders |
- |
|
survey |
Satisfaction surveys |
- |
|
stock |
Consumables, lots and reservations |
- |
|
purchase |
Supplier orders, inventories and losses |
- |
|
equipment |
Equipment |
- |
|
maintenance |
Maintenance operations |
- |
|
quality |
Audits, incidents and corrective actions |
- |
|
billing |
Billing and payments |
- |
|
document |
Donor documents and certificates |
issue |
Table 2 - The 28 permission groups
Seven cross-cutting permissions complete the set: reporting, traceability, costs, portal, export, demo and admin. They gate the bespoke pages rather than a single object, so a reception agent may be given the waiting-queue screens without any access to the reporting console, the cost figures or the module configuration.
The role_code vocabulary carried by llx_bdc_staff describes the staffing structure independently of the technical permissions: director, medical director, physician, nurse, technician, centre manager, campaign coordinator, team leader, reception, secretary, logistics, stock manager, quality, biomedical engineer, billing, cashier, accountant and auditor. Two boolean flags, can_interview and can_collect, together with mobile_ready, indicate which activities a staff member may be assigned to.
dashboard.php is the entry point of the module and is titled the Blood Donation Engagement and Collection Command Center. It opens on an SVG blood-drop illustration and an eight-step representation of the donor journey, from booking through reception, questionnaire, consent, interview, collection, recovery and exit, so that a newcomer understands the process before reading a single figure.
Below the journey, six key-performance-indicator zones present 42 tiles. They cover donor population and segments, the appointment book and its confirmation rate, the current day's collection, campaign progress against target, stock and equipment alerts, and financial indicators. Every tile is computed live from the module tables; none is stored as a denormalised figure that could drift.
Four twelve-month charts close the page, giving the seasonal view that single-period tiles cannot show: donations over the rolling year, appointments and attendance, campaign output, and the evolution of deferrals. The rolling twelve-month window means the charts are populated from the first activation when the demo dataset is loaded.
A complementary dashboard widget, core/boxes/box_blooddonationcenter.php, can be placed on the Dolibarr home page for users who do not need the full command centre. It shows six live counters drawn from the same queries.
The donor is the central object of the module. llx_bdc_donor carries 36 fields and is referenced by appointments, admissions, questionnaire responses, consents, interviews, deferrals, donations, bags, samples, reactions, recoveries, loyalty records, communications, reminders, surveys and documents.
Identity and contact data include ref, donor_number, civility, lastname, firstname, birthdate, gender, national_id, the postal address, phone, email, pref_language and profession. Attachment fields connect the donor to the organisation: fk_center for the usual collection centre, fk_partner when the donor is reached through a company, school or association, and fk_soc for the Dolibarr third party when one exists. Safety fields cover emergency_contact, emergency_phone and gp_name.
Three fields deserve explicit mention because they are frequently misread. blood_group_declared is a declared value only, taken from the vocabulary unknown, A+, A-, B+, B-, AB+, AB-, O+ and O-; it is never a laboratory result and must not be used as one. is_minor together with legal_guardian records the situation of a donor below the legal age, where local rules apply. consent_data and consent_contact are the two consent flags, complemented by the full consent object described later in this document.
Relationship management uses contact_channel and contact_frequency, donor_segment, the counters nb_donations, first_donation_date, last_donation_date and next_contact_date, and portal_enabled. donor_status follows the life cycle candidate, active, regular, occasional, temporarily deferred, permanently deferred, inactive and archived, so a deferral is visible directly in the donor list without opening the deferral record.
llx_bdc_donor_card issues and tracks the physical or digital card that identifies the donor at reception. Each card holds card_number, barcode and qr_payload, is attached to a donor through fk_donor and to an issuing centre through fk_center, and carries issue_date and expiry_date.
card_format offers four options: pdf, print, digital and wallet, so an organisation can move progressively from printed cards to a card held on the donor's telephone without changing process. card_status follows requested, issued, active, reissued, revoked and expired.
Reissues are tracked rather than hidden: reissue_count and reissue_reason record how often a card has been replaced and why. A card that has been revoked stays in the file with its history, which matters when an identification incident has to be investigated.
The donor portal is delivered as a back office, portal.php, controlled by the BDC_PORTAL_ENABLED constant and by the portal cross-cutting permission. It gives the staff a per-donor view of what the donor sees and does: booked and past appointments, issued documents, questionnaire responses submitted through the portal channel, and returned satisfaction surveys.
Adoption is measured on the same page. The portal_enabled flag on the donor record makes it possible to report how much of the donor base has activated the service, and the appt_channel and filled_channel vocabularies show how many appointments and questionnaires actually arrived through the portal rather than by telephone, at reception, through a partner or as walk-ins.
Portal-signed consents are recognised: signature_mode accepts portal alongside handwritten, tablet and verbal, and document delivery records sent_channel including the portal value. Digital document delivery is itself subject to a dedicated consent type, digitaldocs.
llx_bdc_appointment is the second hub of the module. An appointment links a donor to a date, a centre or a campaign, and optionally to a station and a member of staff, through fk_donor, fk_campaign, fk_center, fk_station and fk_staff. appt_date and duration_min define the slot; the default duration is taken from the BDC_DEFAULT_SLOT_MINUTES constant, delivered at 15 minutes.
appt_channel records how the appointment was obtained: portal, phone, reception, partner, walkin or import. donation_type states what is planned, from whole blood to plasma, platelets, double red cells, first donation, autologous or specific donation. slot_capacity, is_group and waiting_list support collective bookings, typically a company slot where a group of employees is expected together.
The status vocabulary is deliberately detailed, with fifteen values: requested, to confirm, confirmed, reminded, arrived, in admission, waiting, in interview, authorised, in collection, in recovery, done, absent, cancelled and postponed. This is what allows a supervisor to see, at any moment of the day, where each expected donor actually is. reminder_sent and confirmed_at close the loop with the reminder engine, and cancel_reason documents cancellations for later analysis of no-shows.
agenda.php presents the appointment book as a weekly planning grid, filtered by centre and by campaign, and displays the daily capacity load so that over-booking is visible before the day starts rather than at the reception desk.
The admission is the reception step. llx_bdc_admission records the arrival of a donor, whether or not an appointment exists, through fk_donor, fk_appointment, fk_campaign, fk_center and fk_staff, and compares planned_time with arrival_time.
Six boolean checks structure the desk's work and make the file measurably complete before the donor moves on: identity_checked, contact_checked, card_presented, questionnaire_ready, consent_ready and docs_complete. planned_donation_type carries forward what was booked, which may still change after the interview.
admission_status follows registered, checking, questionnaire, waiting, routed, done and left. The value left is important operationally: a donor who gives up during the wait is recorded as such instead of disappearing from the statistics, and the loss becomes visible in the appointment and campaign reports.
llx_bdc_queue turns the reception hall into measurable data. Each waiting donor receives a ticket_number and a display_name, is attached to the admission, the campaign, the centre, a station and a member of staff, and is positioned in the process by stage_code: reception, questionnaire, interview, collection, recovery or exit.
planned_time, arrival_time, called_time and wait_minutes give the actual waiting time rather than an estimate. The BDC_WAIT_ALERT_MINUTES constant, delivered at 30 minutes, defines the threshold above which a wait is flagged. priority accepts normal, priority and urgent, which supports the local rules an organisation applies to particular donors.
queue.php is a live board designed to be displayed on a screen in the waiting area. It shows one column per stage and offers an anonymised public mode, in which ticket numbers and display names replace donor identities so the board can be shown to the public without exposing personal data. queue_status follows waiting, called, in progress, paused, done and left.
The questionnaire is versioned as a document, not hard-coded. llx_bdc_questionnaire holds label, questionnaire_type, version, date_effective and date_obsolete, together with the targeting fields target_donation_type, target_audience, min_age, max_age and country_scope, and a regulation_ref field for the organisation's own reference to the text it applies.
Eight questionnaire types are provided: standard, first donation, regular donor, plasma, platelets, mobile collection, minor and follow-up. questionnaire_status follows draft, review, active, superseded and archived, and the is_locked flag, set through the questionnaire/validate permission, prevents a form from being altered once it is in use. Superseded versions remain readable, which is what makes an old response interpretable years later.
Questions are lines of the questionnaire, stored in llx_bdc_question with question_code, label, section_label, rank_order and is_required. field_type supports yes/no, single choice, multiple choice, free text, number, date, attachment, signature, comment and section separators, with the available options held in choices_txt. Conditional display is available through show_if_code and show_if_value, so that follow-up questions appear only when they are relevant.
The vigilance_value field marks the answer that requires the attention of the interviewer. It is a flag for a human being to examine, not an automatic exclusion: the module never derives an eligibility conclusion from a questionnaire answer.
llx_bdc_consent records consent as a first-class object with its own history rather than as a checkbox on the donor record. Seven consent types are distinguished: donation, data processing, communication, reminders, campaign, digital documents and research.
Each consent carries template_ref and version, so the exact wording the donor agreed to can be identified later; fk_appointment and fk_campaign for the context; signed_at, signature_mode (handwritten, tablet, portal or verbal), collected_by and fk_staff for the circumstances; and document_path for the stored evidence.
Withdrawal is explicitly supported through withdrawn_at and withdraw_reason, and consent_status follows pending, granted, refused, withdrawn and expired. Because communication targeting reads these statuses, a withdrawal has an immediate operational effect rather than remaining a note in a file.
The pre-donation interview is conducted by an authorised health professional and is recorded in llx_bdc_interview, which carries 22 fields. It is attached to the donor, the appointment, the admission, the questionnaire response and the campaign through fk_donor, fk_appointment, fk_admission, fk_response and fk_campaign, and to the interviewer through fk_staff. interview_date and duration_min record when it took place and how long it lasted.
The declarative content gathered during the interview is stored in history_declared, treatments_declared, travel_declared, previous_donations and previous_incidents, with vigilance_points summarising the items flagged by the questionnaire and observations holding the free-text notes of the interviewer.
interview_status follows planned, in progress, to decide, decided, validated and cancelled. The decision itself is held in decision_code and decision_comment and is described in the Eligibility Decisions section; planned_donation_type may be revised at this point, and signed_by identifies the professional who signs the interview.
The module structures and stores this exchange. It does not conduct it, does not score it and does not propose a conclusion. The professional's clinical judgement is the only source of the decision.
Measurements are lines of the interview, stored in llx_bdc_measure with fk_interview and fk_donor. Nine measure codes are provided by the vocabulary: weight, height, temperature, systolic and diastolic blood pressure, pulse, haemoglobin, haematocrit and body mass index.
Each line holds measure_value, measure_unit and an optional measure_text, together with measured_at, fk_staff and device_ref, which identifies the instrument used. Recording the device makes it possible to review a series of measurements when a device is later found to be out of calibration; the equipment module tracks calibration due dates for the same instruments.
Corrections are traceable rather than silent: is_amended and amend_reason record that a value was modified and why. The original context remains visible in the interview.
The module stores measured values and displays them. It does not interpret them, does not compare them against thresholds to authorise a donation, and does not raise a clinical alert. Reading these parameters is a medical act performed by the authorised professional.
The outcome of the pre-donation interview is recorded in the decision_code field of llx_bdc_interview, governed by a six-value vocabulary: authorised, to review, temporarily deferred, permanently deferred, cancelled and referred. decision_comment holds the justification, and signed_by identifies the professional who takes responsibility for it.
Writing a decision requires the interview/decide sub-permission, which is disabled by default. This separates the staff who prepare and record an interview from those entitled to conclude it, and it makes the audit trail meaningful: the trigger writes the change into the Dolibarr agenda with the user who performed it.
A decision has downstream consequences that the module applies mechanically. An authorised decision allows a donation record to be prepared for the planned donation type. A deferral decision creates a deferral record and updates donor_status to deferredtemp or deferredperm, which makes the donor visible as such in every list and blocks nothing that a human has not already decided. A referral records that the donor was directed elsewhere.
The module never computes an eligibility decision. It offers no rule engine, no automatic exclusion and no suggested conclusion derived from questionnaire answers or measured parameters. The decision to accept or defer a donor is a medical act taken by an authorised health professional, and the software only stores it.
llx_bdc_deferral records that a donor may not give blood, for how long and on what grounds. It is attached to the donor and, when it originates from an interview, to that interview, through fk_donor and fk_interview. deferral_kind distinguishes three cases: temporary, permanent and same-day, the last covering a donor turned away on the day without a lasting restriction.
The period is held in date_start, date_end and duration_days, and next_review_date schedules the reassessment of a temporary deferral. deferral_status follows active, ending, expired, lifted and cancelled, so a deferral that has run its course is distinguishable from one that a professional has deliberately lifted.
The grounds come from a configurable dictionary, llx_bdc_deferral_reason, rather than from free text. Each reason carries code, label, reason_family (health, treatment, travel, procedure, lifestyle, interval, measurement, administrative or other), the is_permanent flag, default_days used to propose an end date, a version and a regulation_ref. Two separate wordings are stored: internal_message for the staff and donor_message for the donor, which lets the organisation control precisely what is said to the person concerned. reason_status allows a reason to be drafted, activated or made obsolete without deleting the historical records that used it.
Informing the donor is tracked through donor_informed and informed_channel (on site, email, SMS, telephone or post), with decided_by, fk_staff and comment_txt completing the record. A deferral notice can be issued as a PDF document through the document object.
llx_bdc_donation is the third hub and carries 26 fields. It links the donor, the appointment, the authorising interview, the campaign, the centre, the station and the collecting staff member through fk_donor, fk_appointment, fk_interview, fk_campaign, fk_center, fk_station and fk_staff.
The collection itself is described by donation_type, donation_date, start_time, end_time, duration_min and volume_ml, whose default for whole blood comes from the BDC_WHOLEBLOOD_VOLUME_ML constant, delivered at 450 millilitres. The material used is identified by fk_lot and kit_ref, which is what connects a donation to the consumable lot it consumed. puncture_arm and nb_attempts record the technical conditions of the venepuncture.
donation_status follows planned, authorised, prepared, in progress, done, interrupted, cancelled, non-conform and archived. interrupt_reason documents an interrupted collection and has_reaction flags a donation followed by a reaction, so that the two records are never separated. unit_cost carries the collection cost used by the cost management module.
A donation is expected to be created from an authorised interview. Bags, sample tubes, labels, the recovery record and, where applicable, the reaction record all hang from the donation, which makes it the natural starting point of any traceability enquiry.
Identifying the right donor immediately before the puncture is the single most sensitive step of the process. The module implements it as three fields on llx_bdc_donation: id_check_1, id_check_2 and id_check_by, recording the two independent checks and the person who performed the second one.
The behaviour is governed by the BDC_REQUIRE_DOUBLE_CHECK constant, delivered enabled, and by the donation/identify sub-permission, which is disabled by default so it must be granted explicitly to the staff entitled to perform the check. Where an organisation's procedure does not use a second check, the constant can be turned off, but the fields remain available.
Upstream, identity is verified at reception through identity_checked and card_presented on the admission, and through the donor card with its barcode and QR payload. Downstream, an identification failure is recorded as an incident of type identity, and identity is one of the fourteen audit scopes.
llx_bdc_bag identifies the collected units. Each bag carries bag_number, barcode and qr_payload, and is bound to its donation, its donor and its campaign through fk_donation, fk_donor and fk_campaign, so that a bag can never be orphaned from the collection that produced it.
bag_type distinguishes whole blood, plasma, platelets, double red cells and satellite bags. The physical description covers fk_lot and manufacturer for the bag itself, collect_date, volume_ml, weight_g and fk_staff for the collecting operator.
The hand-over to the next stage is recorded by destination, transfer_date and transfer_ref. This is the boundary of the module: it records to whom a bag was handed over, when, and under which reference. What happens afterwards, in biological qualification, component preparation or transfusion delivery, is outside its scope and belongs to specialised systems.
bag_status follows created, assigned, in collection, collected, transferred, cancelled, non-conform and destroyed, and the nonconformity field documents an anomaly. Unlabelled bags are one of the conditions checked by the daily alert job.
Sample tubes are managed separately from bags in llx_bdc_sample, because they follow a different route: they leave for a laboratory rather than for component preparation. Each sample carries sample_number and barcode and is bound to the donation, the donor and, where relevant, the bag through fk_donation, fk_donor and fk_bag.
sample_type covers serology, blood grouping, nucleic acid testing, haemogram, archive samples and an other category. tube_color reproduces the physical colour coding used at the bench: red, purple, blue, green, grey and yellow. volume_ml, collected_at and fk_staff describe the collection. The number of tubes normally created for each donation is set by the BDC_SAMPLES_PER_DONATION constant, delivered at three.
The despatch chain is tracked end to end: destination_lab, shipped_at, received_at and reception_proof, with reject_reason when the receiving laboratory refuses a tube. sample_status follows created, assigned, collected, shipped, received, accepted, rejected and destroyed.
The module records the movement and the acknowledgement of the tubes. It does not receive, store or interpret biological results; the qualification of a donation is performed by the laboratory information system of the receiving laboratory.
Identification labels are not a side effect of printing: each print job is an object, stored in llx_bdc_label_print, so that the number of labels produced for a given bag or tube is known. label_target states what is being labelled, among bag, sample, kit, file, container and donor card, with target_ref and the direct keys fk_donation, fk_bag and fk_sample.
template_code selects the layout among the seven delivered templates: standard bag, plasma bag, sample tube, kit label, file cover, container box and standard donor card. label_format offers small, medium, large and A4 sheet, and printer_name and nb_copies complete the job definition.
Reprints are controlled and traced. is_reprint and reprint_reason document why a label was produced again, and the label/reprint sub-permission, disabled by default, restricts the operation to authorised staff. printed_at and printed_by record the execution, and label_status follows queued, printed, applied, cancelled and failed, so a failed print is visible instead of being assumed successful.
An adverse reaction of a donor is recorded in llx_bdc_reaction, attached to the donor, the donation and the campaign through fk_donor, fk_donation and fk_campaign. reaction_date and stage_code situate the event in the process, since a reaction may occur at reception, during the interview, during the collection, in the recovery area or on the way out.
reaction_type covers vasovagal reaction, haematoma, pain, nausea, malaise, puncture-related events, delayed reactions and an other category. declared_signs holds what was observed, severity is graded minor, moderate, major or critical, and immediate_action records what was done at the time, by whom (fk_staff) and to whom the donor was referred (referred_to).
Follow-up is part of the record: followup_txt, followup_date, recovery_minutes and closed_at, with reaction_status following open, monitoring, referred, resolved and closed. Open reactions are one of the conditions raised by the daily alert job, so that a case is not forgotten after the collection day ends. A reaction may also be escalated into a quality incident of type reaction.
The module documents a reaction; it does not manage it. Assessing the donor, deciding on care and organising any referral are medical acts performed by an authorised health professional. No instruction, protocol or clinical guidance is produced by the software.
llx_bdc_recovery records the mandatory rest period after a donation. enter_time, exit_time and duration_min give the observed duration, and the BDC_MIN_RECOVERY_MINUTES constant, delivered at 15 minutes, sets the minimum the organisation expects.
snack_given and drink_given record what was served, declared_state captures how the donor said they felt using the vocabulary good, tired, dizzy or unwell, and has_reaction links the record to a reaction when one occurred. advice_given and observations hold the free-text content, and exit_authorized_by names the person who authorised the donor to leave.
recovery_status follows in progress, extended, done and referred. An extended recovery is therefore visible as such in the reporting, which is one of the practical indicators of collection quality that organisations rarely have in a usable form.
Refreshments served in the recovery area are managed as consumable items in llx_bdc_refreshment, attached to the recovery record, the donor and the campaign through fk_recovery, fk_donor and fk_campaign, and optionally to a Dolibarr product through fk_product.
refreshment_type distinguishes drinks, sweet items, savoury items, fruit, meals and gluten-free items. Food-safety fields are provided because they are genuinely needed on a collection site: allergens, lot_number and expiry_date. quantity, unit_cost and served_at complete the line, and refreshment_status follows planned, served, out of stock and refused.
Because refreshments carry a unit cost and a campaign key, they feed the cost management module directly through the refreshment cost category, and they are also part of the consumable catalogue, where snack and drink are two of the fifteen consumable types.
llx_bdc_document is the generic document object of the module. It produces and tracks 21 document types, including the donor card, invitations, confirmations, the questionnaire, the consent form, admission and interview documents, the deferral notice, the donation sheet, the attendance certificate, the donation certificate, recovery and reaction documents, campaign, mission, stock and inventory reports, incident and quality reports, agreements and free-form letters.
A document is attached to the donor, the donation, the campaign or the partner through fk_donor, fk_donation, fk_campaign and fk_partner, and identifies its own production through template_code, lang_code, version, issue_date and issued_by. file_path points at the generated file and qr_payload supports verification of a printed certificate.
Delivery is tracked by sent_at and sent_channel (email, portal, print, post or none), and document_status follows draft, generated, signed, sent, archived and cancelled. Issuing a document requires the document/issue sub-permission, which is disabled by default.
Generation uses the Dolibarr PDF framework through core/modules/blooddonationcenter/pdf/pdf_bdc_document.modules.php, selected by the BDC_ADDON_PDF_DOCUMENT constant. The delivered model covers the donation certificate, the attendance certificate and the deferral notice, and the five language packs allow a certificate to be produced in the donor's preferred language.
llx_bdc_campaign is the fourth hub and carries 26 fields. A campaign is a planned collection operation, held at a centre or at an external site described by site_label and a full postal address, between date_start and date_end, with open_hours, capacity and nb_stations.
Eight campaign types are supported: fixed site, mobile, corporate, school, university, association, public and emergency. A campaign may be attached to a partner and to the agreement that frames it through fk_partner and fk_agreement, and to a Dolibarr project through fk_projet.
Performance is measured against a target rather than reported in the abstract: target_donations, nb_registered, nb_present, nb_donations and nb_deferred, alongside budget_amount and real_cost. Those five counters are what the campaign report and the dashboard charts consume, and they make attendance rate, conversion rate and deferral rate comparable between operations.
campaign_status follows draft, planning, to validate, validated, open, in progress, suspended, done, closed and cancelled, which supports an approval step before a campaign is announced publicly. Stations, appointments, admissions, donations, missions, stock reservations, communications and costs all carry the campaign key, so a campaign can be closed with a complete operational and financial picture.
A corporate campaign is a campaign of type corporate, attached to a partner of type company. The partner record carries headcount, which is the natural denominator for a participation rate, together with nb_campaigns and total_donations accumulated over the relationship.
The commercial frame comes from the agreement: agreement_type sponsorship or framework, services_txt describing what the centre provides, and amount_ht where the operation is billable. The is_billable flag on the partner determines whether the campaign generates billing lines.
Operationally, corporate campaigns rely on group bookings. The appointment fields is_group and slot_capacity support a company slot in which several employees are expected together, and the appt channel partner records that the booking came through the employer rather than from the donor directly.
Donors reached this way are identified by fk_partner on the donor record and by the corporate value of donor_segment and segment_code, which makes it possible to communicate with that population separately and to measure whether corporate donors return to fixed sites afterwards.
School and university campaigns are two distinct campaign types, matched by the partner types school and university. They are treated separately from corporate operations because their population, their calendar and their constraints differ.
The main functional difference is age. The questionnaire object carries min_age and max_age and offers a dedicated minor questionnaire type, and the donor record carries is_minor and legal_guardian. Where local rules permit the donation of a minor under conditions, the module provides the fields to record the guardian and to use the appropriate form; it does not encode any age rule itself, since that rule varies by country and belongs to the operator's procedures.
These campaigns typically produce a high proportion of first donations. donation_type and target_donation_type both include firstdonation, and the firstdonation questionnaire type addresses the specific information a first-time donor needs. The new value of donor_segment identifies that population for follow-up, which is where the loyalty module earns its place: a first donation converted into a second is the practical measure of a successful campus operation.
Public campaigns cover open collections in town halls, shopping centres, sports facilities and similar venues, and are recorded with campaign_type public, or emergency where the operation responds to an urgent need. They are usually mobile operations, so they combine a campaign with a mission carried out by a mobile team.
Walk-in attendance is the norm rather than the exception. The appt_channel value walkin and the admission process, which does not require an existing appointment, allow a donor to be received and recorded in full without prior booking, while nb_registered and nb_present still distinguish booked attendance from spontaneous attendance.
Communication for a public campaign is handled by the communication object with message_type newcampaign, targeting a segment and a language, and its results are counted in nb_targets, nb_sent, nb_opened, nb_clicked, nb_replied and nb_optout. Comparing that effort with nb_present on the campaign gives the recruitment cost of an open collection, and the cost object with the communication category puts a figure on it.
llx_bdc_mobile_team describes the crews that carry out collections away from a fixed centre. A team belongs to a centre through fk_center and names its manager, its physician and its vehicle through fk_manager, fk_physician and fk_vehicle. Its capacity is expressed by nb_nurses, nb_agents and nb_stations, and equipment_txt lists what it takes with it. nb_missions accumulates its activity.
team_status follows the day of a mobile team rather than an abstract life cycle: planned, preparing, ready, travelling, installed, collecting, returning, closed and cancelled. A coordinator therefore sees where each team is without telephoning it.
Vehicles are managed as their own object in llx_bdc_vehicle, with vehicle_type bloodmobile, van, truck, car or trailer, plate_number, brand, model, nb_seats, nb_stations, mileage_km, next_service_date, insurance_ref and insurance_end. vehicle_status follows available, on mission, maintenance, breakdown and retired, and vehicles are covered by the maintenance object through fk_vehicle, including the dedicated vehicle maintenance type.
Stations are equally mobile: llx_bdc_station carries an is_mobile flag and can be attached to a campaign rather than to a room, with station_type chair, bed, interview, reception, recovery or apheresis, and capacity_hour giving the expected throughput.
A mission is one outing of one team, recorded in llx_bdc_mission and linked to the campaign it serves, the team that performs it, the partner hosting it and the vehicle used, through fk_campaign, fk_team, fk_partner and fk_vehicle. site_label, town and mission_date situate it.
The logistics of the day are recorded precisely: departure_time, return_time and distance_km, with expenses capturing the direct costs of the outing. The operational result is measured by expected_donors, received_donors, nb_donations, nb_deferred and nb_incidents, so the gap between what was planned and what happened is available immediately rather than reconstructed later.
mission_status follows planned, prepared, in progress, done, debriefed and cancelled. The debriefed value matters: it distinguishes a mission that is merely finished from one whose figures, stock returns and incidents have actually been reviewed. Stock reservations, losses, inventories and costs can all be attached to a mission, which is what allows a true cost per donation to be computed for a mobile operation.
Mobile collections often take place where network coverage is poor. The module therefore provides the server-side foundation of a disconnected mode: llx_bdc_sync_log records every synchronisation exchange between a field device and the central installation, with fk_mission, fk_team, device_name and sync_direction (download, upload or two-way).
Each exchange is measured and auditable: started_at, finished_at, nb_records, nb_conflicts, nb_duplicates, payload_kb, the is_encrypted flag, wiped_after for the erasure of the local copy after transfer, and error_txt. sync_status follows pending, running, done, conflict and failed, so a partial or conflicting exchange is visible and can be replayed rather than silently lost.
Full offline mode is NOT delivered in version 1.0. The data model, the synchronisation log and the traceability of exchanges exist and are operational, but the client layer does not: there is no packaged offline application, no local database on the device, no automatic conflict resolution and no background replication agent. In version 1.0 the synchronisation log documents exchanges performed by the organisation's own means, and provides the foundation on which a disconnected client can be built.
Buyers who require a genuinely disconnected field workflow should plan that component separately and should not treat the presence of these tables as evidence that it is included.
llx_bdc_loyalty maintains, for each donor, the relationship indicators that a donor record alone cannot express. segment_code and loyalty_level position the donor: the five levels are bronze, silver, gold, platinum and ambassador, and the segments are new, regular, occasional, loyal, to reactivate, inactive, mobile-ready, corporate and custom.
Behaviour is measured by nb_donations, nb_invitations, nb_responses, seniority_months and avg_interval_days, which is the practical indicator of donation rhythm. last_donation_date and next_contact_date drive recontact, the delay being set by the BDC_NEXT_CONTACT_DAYS constant, delivered at 56 days. preferred_channel and preferred_period record when and how the donor actually wants to be approached.
engagement_score and satisfaction_score summarise the relationship, the latter fed by the satisfaction surveys. loyalty_status follows active, watch, at risk, lost and reactivated, which turns attrition into something a coordinator can act on before it is complete rather than something a report reveals a year later.
The loyalty report of the reporting console lists levels, engagement, average interval and donors at risk, and the segments feed directly into the targeting of communications.
llx_bdc_communication manages outbound campaigns towards donors. A communication has a label, a message_type among invitation, confirmation, reminder, thanks, practical information, new campaign, data update, survey and follow-up, a channel_code among email, SMS, notification, portal, post, telephone call and webhook, and a target defined by fk_campaign, segment_code and lang_code.
Content is held in subject_txt and body_txt, and scheduling in planned_at and sent_at. Results are counted field by field: nb_targets, nb_sent, nb_opened, nb_clicked, nb_replied and nb_optout, with unit_cost giving the cost of the operation. communication_status follows draft, planned, sending, sent, partial, failed and cancelled, so a partially delivered campaign is not reported as a success.
Individual deliveries are lines of the communication, stored in llx_bdc_message with fk_donor, recipient, channel_code, sent_at, opened_at, replied_at, response_code (none, accepted, declined, later or opt-out) and error_txt. message_status follows queued, sent, delivered, opened, bounced and failed. That level of detail is what allows a bounced address to be corrected on the donor record.
Targeting respects the donor's recorded wishes: contact_channel and contact_frequency on the donor, preferred_channel on the loyalty record, and the communication and reminders consent types, whose withdrawal removes the donor from subsequent targeting.
Reminders are a separate object, llx_bdc_reminder, because they are individual and event-driven rather than campaign-based. A reminder is attached to a donor and, where relevant, to an appointment and a campaign through fk_donor, fk_appointment and fk_campaign.
reminder_type covers seven situations: several days before, the day before, the same day, after an absence, after a cancellation, on return to eligibility, and for a campaign. offset_days and planned_at define the timing, with the default lead time taken from BDC_REMINDER_DAYS_BEFORE, delivered at two days. channel_code selects the medium.
Execution is tracked by sent_at, confirmed_at, nb_attempts and error_txt, and reminder_status follows planned, sent, received, confirmed, rescheduled, cancelled and failed. The confirmed_at value feeds back into the appointment through reminder_sent and confirmed_at, which is what makes the confirmation rate reportable.
The daily alert job of the module lists appointments still awaiting confirmation, so that reminders that produced no response can be escalated by telephone before the collection day.
llx_bdc_partner holds the organisations that host or support collections. Ten partner types are distinguished: company, school, university, association, non-governmental organisation, public authority, hospital, clinic, sponsor and supplier. A partner may be bound to a Dolibarr third party through fk_soc, which avoids maintaining two customer files.
Contact and location data cover contact_name, contact_phone, contact_email, address, zip and town. headcount gives the size of the population the partner represents, and nb_campaigns and total_donations accumulate the history of the relationship, which is the argument a coordinator needs when renewing an arrangement.
is_billable indicates whether operations with this partner generate billing, and partner_status follows prospect, active, recurring and inactive, so the prospection pipeline and the active portfolio are visible in the same list.
llx_bdc_agreement formalises the relationship with a partner. agreement_type distinguishes framework agreements, annual agreements, single-campaign agreements, service agreements and sponsorships, and subject describes what is agreed. The period is defined by date_start and date_end.
Renewal is managed rather than remembered: auto_renew indicates tacit renewal and notice_days gives the notice period, while agreement_status follows draft, negotiation, signed, active, expiring, expired and terminated. The expiring value is what allows an agreement to be renegotiated before it lapses.
The commercial content is held in services_txt, amount_ht and budget_amount, and the signatories on both sides are recorded in signatory_center and signatory_partner. An agreement can be attached to a Dolibarr project through fk_projet, and campaigns reference it through fk_agreement, so each operation is traceable back to the arrangement that authorised it and to the billing it produces.
Consumable stock is managed by llx_bdc_consumable, which covers fifteen consumable types: collection kits, bags, tubes, needles, antiseptics, compresses, gloves, dressings, labels, wristbands, personal protective equipment, snacks, drinks, printing supplies and cleaning products. Each item may be linked to a Dolibarr product through fk_product and to a supplier third party through fk_soc.
Quantities are held in qty_onhand, qty_reserved, qty_min and qty_max, with unit_label, unit_cost and stock_value. The is_critical flag marks the items whose absence stops a collection, and stock_status follows ok, low, critical, out of stock and expiring, which is what the dashboard alert tiles and the daily job read.
Lots are tracked separately in llx_bdc_lot, with lot_number, manufacturer, supplier_name, manufacture_date, expiry_date, received_date, qty_received, qty_remaining and qty_used. control_done and in_quarantine record incoming inspection, and lot_status follows received, available, in use, quarantine, expiring, expired, consumed, returned and destroyed. The expiry alert window is set by BDC_EXPIRY_ALERT_DAYS, delivered at 60 days.
Because a donation records fk_lot and kit_ref, the link between a collected unit and the material used to collect it is preserved. That is the basis on which an affected lot can be traced to the donations that consumed it.
A collection away from base fails if the material does not arrive. llx_bdc_reservation allocates consumables to a campaign or to a mission before departure, through fk_campaign, fk_mission, fk_consumable and fk_lot.
Six quantity fields follow the material through the operation: qty_planned, qty_reserved, qty_prepared, qty_used, qty_returned and qty_lost, with qty_gap giving the discrepancy. reservation_status follows planned, reserved, prepared, delivered, used, returned and closed.
The reserved quantities are reflected in qty_reserved on the consumable, so that stock committed to a forthcoming campaign is not counted twice when another operation is planned. On return, the difference between prepared, used, returned and lost quantities is what feeds the loss records and the real cost of the campaign.
llx_bdc_purchase records the procurement of consumables. An order line identifies the supplier by supplier_name and fk_soc, the item by fk_consumable, and the destination by fk_center, with order_date, expected_date and received_date.
Quantities and amounts are held in qty_ordered, qty_received, unit_price and amount_ht, and the received goods are qualified by lot_number, expiry_date and control_result, whose vocabulary is conform, reserve, non-conform and pending. purchase_status follows request, ordered, partial, received, invoiced and cancelled, so a partially delivered order remains visible.
Integration with Dolibarr purchasing is provided by fk_commande_fourn, which links the record to a native supplier order. Organisations already running Dolibarr procurement therefore keep a single purchasing process, while the module retains the collection-specific information, notably the lot numbers and expiry dates that native purchasing does not carry in the same way.
llx_bdc_inventory records stock counts. inventory_type covers general, per centre, per campaign, mobile, per warehouse, per lot and rolling inventories, so both the annual count and the return of a mobile team's kit are handled by the same object.
An inventory is attached to a centre, a campaign or a team through fk_center, fk_campaign and fk_team, and dated by inventory_date. nb_lines, qty_theoretical, qty_physical, qty_gap and gap_value quantify the count and its financial impact, while gap_reason documents the explanation.
inventory_status follows planned, counting, to validate, validated, adjusted and closed, and validated_by names the person who accepted the result. The separation of validated and adjusted makes it clear whether a discrepancy has merely been accepted or has actually been posted against the stock figures.
Consumable losses are declared in llx_bdc_loss, attached to the consumable, the lot, the centre and, where applicable, the campaign or mission through fk_consumable, fk_lot, fk_center, fk_campaign and fk_mission.
loss_reason covers expiry, breakage, contamination, partial use, logistics, anomaly, non-return and other. destruction_method records how the material was disposed of, using the vocabulary clinical waste stream, incineration, external provider, return to supplier and standard waste, which matters for items subject to specific disposal rules.
Accountability is explicit: responsible_name, witness_name and document_path, together with cost_amount for the financial impact. loss_status follows declared, to validate, validated, destroyed and cancelled, so a declared loss is not deducted from stock until it has been reviewed. Losses feed the cost object through the loss and destruction categories.
llx_bdc_equipment carries 24 fields and covers the sixteen equipment types used in collection: donation chairs and beds, blood mixers, scales, blood pressure monitors, haemoglobin meters, thermometers, refrigerators, cool boxes, computers, tablets, printers, scanners, generators, radios and apheresis machines.
Identification and ownership come from manufacturer, model, serial_number, fk_center, room_label and fk_team, the last allowing a device to be assigned to a mobile team. The contractual and financial side is held in supplier_name, install_date, service_date, warranty_end, contract_ref and purchase_cost.
Two forward-looking dates drive planning: next_maintenance and next_calibration. Calibration is distinguished from maintenance because a device that measures a parameter used during an interview must have a traceable calibration date, and the measurement lines record device_ref for exactly that reason.
Reliability is quantified by nb_breakdowns, downtime_hours, mtbf_hours, mttr_hours and availability_pct, and equipment_status follows available, in use, on mission, maintenance, breakdown, calibration and retired. The equipment report of the reporting console presents those indicators together with maintenance falling due.
llx_bdc_maintenance covers both equipment and vehicles, through fk_equipment and fk_vehicle. maintenance_type distinguishes preventive maintenance, corrective repair, calibration, control, cleaning and vehicle servicing.
An operation is planned by planned_date and closed by done_date, performed by provider_name and technician_name, and described by parts_txt and result_txt. duration_hours, downtime_hours and cost_amount quantify it, and the downtime figure feeds the availability indicators of the equipment record.
The blocks_planning flag states whether the operation makes the equipment unavailable for collection, which is the piece of information a campaign coordinator needs when scheduling. maintenance_status follows planned, requested, in progress, done, late and cancelled, and the late value, together with the daily alert job, prevents an overdue calibration from being discovered on the morning of a collection.
llx_bdc_continuity holds the contingency plans of the organisation. Eleven scenarios are catalogued: power failure, network failure, equipment failure, staff shortage, team delay, stock shortage, campaign cancellation, site change, vehicle failure, information system failure and weather events.
Each plan is attached to a centre through fk_center, graded by impact_level (low, moderate, high or critical), and described by procedure_txt, with emergency_contact and emergency_phone giving the people to call. recovery_hours states the target time to resume normal operation.
A plan that is never exercised is of little value, so the object tracks last_drill_date, next_drill_date and drill_result. continuity_status follows draft, active, to drill, review and obsolete, which keeps the plan library current instead of letting it age quietly in a shared folder.
Quality management rests on three objects: audits, incidents and corrective actions. llx_bdc_audit records a planned check of one of the fourteen audit scopes shared with the incident process code vocabulary: reception, identity, questionnaire, consent, interview, collection, labelling, traceability, recovery, stock, mobile operations, equipment, data security and billing.
audit_type distinguishes internal, external, self-check, regulatory and supplier audits. The result is quantified by nb_checks, nb_conform, nb_nonconform and conformity_pct, and documented by findings_txt and procedure_ref. audit_status follows planned, in progress, done, actions and closed, the actions value marking an audit whose findings are still being addressed.
Corrective and preventive actions are held in llx_bdc_capa, attached to the incident or the audit that raised them through fk_incident and fk_audit. action_kind distinguishes corrective, preventive, improvement and immediate actions, and the record carries responsible_name, start_date, due_date, done_date, evidence_txt and cost_amount. effectiveness is graded to be assessed, effective, partial or ineffective, and action_status follows open, in progress, done, late, verified, closed and cancelled.
The distinction between done, verified and closed is deliberate: an action is not closed because it was performed, but because its effect has been checked. No regulatory certification or compliance approval is claimed for this framework; it is a management structure that an organisation populates according to its own quality system.
llx_bdc_incident carries 21 fields and is deliberately connected to everything: fk_center, fk_campaign, fk_donor, fk_donation, fk_bag, fk_sample and fk_equipment. An incident can therefore be attached to the exact object concerned rather than described in prose.
Fourteen incident types are catalogued: identity, appointment, consent, questionnaire, collection, reaction, label, bag, sample, stock-out, equipment, mobile operations, information technology and other. process_code positions the incident in the same fourteen-value process taxonomy used by audits, so incidents and audit findings aggregate on the same axis.
The record covers incident_date, description, severity (minor, moderate, major or critical), immediate_action, root_cause, responsible_name, due_date and closed_at. incident_status follows open, analysis, action, verification and closed, which mirrors the analysis-then-verification discipline of the corrective action object.
The quality report of the reporting console presents incidents by process alongside the audit conformity rate and the status of corrective actions, which is what makes a trend visible rather than a list of isolated events.
llx_bdc_survey collects the donor's view of the visit. A survey is attached to the donor, the donation, the campaign and the centre through fk_donor, fk_donation, fk_campaign and fk_center, and dated by survey_date.
Eight scores follow the donor journey step by step: welcome, booking, waiting, interview, comfort, collection, recovery and staff, plus an overall score_global and the would_recommend indicator. Scoring each step separately is what turns a satisfaction figure into an actionable one: a poor waiting score and a poor interview score call for entirely different responses.
comment_txt holds the free-text remarks, and survey_status follows sent, answered, analysed, closed and no answer, so the response rate is measurable. The satisfaction_score of the loyalty record is fed from these surveys, which connects perceived quality with donor retention.
llx_bdc_billing invoices services delivered to partners. service_code distinguishes ten billable services: campaign organisation, mobile collection, transport, equipment rental, communication, training, administrative services, supplies, reporting and other. The billing line is attached to the partner, the agreement, the campaign or the mission through fk_partner, fk_agreement, fk_campaign and fk_mission, and to the Dolibarr third party through fk_soc.
Amounts are held in quantity, unit_price, amount_ht, vat_rate, amount_ttc and amount_paid, with billing_date, due_date, payment_date and payment_method (transfer, cheque, card, cash or direct debit). billing_status follows draft, quoted, ordered, invoiced, partial, paid, unpaid, credited and cancelled.
Native Dolibarr documents are referenced directly through fk_propal, fk_commande and fk_facture, so a billing line produced in the module becomes a commercial proposal, a sales order and an invoice in the accounting chain the organisation already uses. Nothing is re-implemented: the module provides the collection-specific origin of the amount, and Dolibarr performs the invoicing.
Unpaid billing is one of the conditions reported by the daily alert job, and the finance report presents billing by partner and by service together with payments and outstanding amounts.
llx_bdc_cost records what an operation costs. Fifteen cost categories are provided: collection kits, consumables, refreshments, staff, communication, transport, vehicles, site rental, equipment, maintenance, energy, external services, losses, destruction and other.
Each cost line is attached to a campaign, a mission, a centre or a team through fk_campaign, fk_mission, fk_center and fk_team, and dated by cost_date. quantity, unit_cost and amount_ht give the amount, budget_amount the reference and gap_amount the variance.
The two fields that make this object useful are nb_donations and cost_per_donation. Because the number of donations produced by the operation is carried on the cost line itself, the cost per donation is a stored, reportable figure rather than a calculation performed once in a spreadsheet. cost_status follows estimated, committed, actual and closed, so a forecast is never confused with an actual.
Costs converge with the campaign object, which carries budget_amount and real_cost, and with the mission object, which carries expenses. The costs report of the reporting console presents cost by category, budget against actual, and cost per donation across the selected period.
reporting.php is a single console offering twelve reports, each with a period filter and CSV export. Export is governed by the export cross-cutting permission, and access to the console by the reporting permission, so figures can be opened to management without opening the underlying records.
|
Report |
Content |
|
Donors |
Population, segments, seniority, activity and archiving |
|
Appointments |
Volumes by channel and status, no-shows, cancellations, conversion |
|
Collection |
Donations by type, volumes, durations, interruptions, non-conformities |
|
Campaigns |
Registered, present, donations, deferrals versus targets and capacity |
|
Mobile |
Missions, distances, expected versus received donors, expenses |
|
Loyalty |
Levels, engagement, average interval, donors at risk |
|
Stock |
On-hand and reserved quantities, minimum thresholds, lots and expiry |
|
Equipment |
Availability, breakdowns, downtime, MTBF and MTTR, maintenance due |
|
Quality |
Audits, conformity rate, incidents by process, corrective actions |
|
Finance |
Billing by partner and service, payments, outstanding amounts |
|
Costs |
Cost per category, budget versus actual, cost per donation |
|
Traceability |
Chain completeness from donor to external destination |
Table 3 - The twelve reports of the reporting console
Every report is computed live from the module tables over the selected period. Because the coded columns are governed by controlled vocabularies, aggregation by status, type, reason or category is exact rather than dependent on how a value was typed, and the CSV export carries the same codes, which makes it usable directly in a spreadsheet or a data warehouse.
The traceability report is of a different nature from the other eleven: rather than counting activity, it measures the completeness of the identification chain, and is described in the Traceability section of this document.
Beyond the reporting console, the module is designed so that the figures a management team needs are stored rather than recomputed. Campaigns carry nb_registered, nb_present, nb_donations and nb_deferred against target_donations and capacity; missions carry expected_donors and received_donors; cost lines carry nb_donations and cost_per_donation; equipment carries mtbf_hours, mttr_hours and availability_pct; audits carry conformity_pct.
Three families of indicator follow naturally. Activity indicators compare attendance with bookings and donations with attendance. Quality indicators combine the deferral rate, the reaction rate, the non-conformity rate on bags and samples, and audit conformity. Economic indicators combine cost per donation, budget variance and the billing recovered from partners.
The dashboard presents 42 tiles across six zones and four twelve-month charts, which is the day-to-day view. For deeper analysis, the CSV exports and the 255 REST routes make every table available to an external business intelligence tool without database access, using an API key and the same permission model as the user interface.
A caution applies to every ratio produced from this data: numerator and denominator must be drawn from the same population and the same period. A conversion rate computed over a period during which a campaign is still open, for example, will understate performance until that campaign closes.
The module exposes a REST API through the class BloodDonationCenter, served at /api/index.php/blooddonationcenter/. All 51 business objects are published, each with five operations, giving 255 routes in total. The API follows the Dolibarr API conventions, so existing Dolibarr API clients and tooling work unchanged.
|
Method |
Route pattern |
Behaviour |
|
GET |
/blooddonationcenter/{object}s |
Paginated list; sortfield, sortorder, limit, page, sqlfilters |
|
GET |
/blooddonationcenter/{object}s/{id} |
Single record with all of its declared fields |
|
POST |
/blooddonationcenter/{object}s |
Create a record from a JSON payload |
|
PUT |
/blooddonationcenter/{object}s/{id} |
Update the supplied fields of an existing record |
|
DELETE |
/blooddonationcenter/{object}s/{id} |
Delete a record, subject to the delete permission |
Table 4 - The five-route pattern applied to each of the 51 objects
Authentication uses the DOLAPIKEY header. A request without a valid key is rejected with HTTP 401. Authorisation reuses exactly the same 28 permission groups as the user interface: a key belonging to a user who cannot read donations in the interface cannot read them through the API either, and the sensitive sub-permissions apply identically.
List routes accept sortfield and sortorder, a limit and page pagination pair, and sqlfilters for server-side filtering. The sortfield value is validated against the actual columns of the table, obtained through SHOW COLUMNS, rather than concatenated into the query, which closes the classic injection route through a sort parameter.
Security rests first on the Dolibarr platform: authentication, session handling, CSRF tokens, SQL escaping and the entity mechanism for multi-company installations are provided by the framework and used by the module rather than reimplemented.
On top of that, the module applies its own 96 permissions in 28 groups. Read and write are enabled by default; delete, the four sensitive sub-permissions and the administration permission are disabled by default and must be granted deliberately. The same checks are applied by the user interface and by the REST API.
Personal data receives specific handling. Consent is an object with its own status and withdrawal fields, not a checkbox; the donor record carries consent_data and consent_contact; the waiting-queue board offers an anonymised public mode so that a screen in a waiting area shows ticket numbers rather than names; and synchronisation logs record whether an exchange was encrypted and whether the local copy was wiped afterwards. Data security is one of the fourteen audit scopes and one of the fourteen incident types.
Two points must be stated plainly. First, the module records medical information but takes no medical decision: assessment, acceptance or deferral, interpretation of measured parameters and biological results, and the handling of donation reactions all remain under the control of an authorised health professional. Second, no regulatory certification, accreditation or compliance approval is claimed. Configuring roles, retention rules and the lawful basis for processing according to the regulation applicable to the operator remains the operator's responsibility.
traceability.php reconstructs the complete chain of a donation on a single screen: donor, appointment, admission, questionnaire response, consent, interview, eligibility decision, donation, bags, sample tubes and external destination. The chain is resolvable from any of four entry points: a donor number, a donation reference, a bag number or a sample number.
This works because the links are stored as foreign keys at every step rather than inferred: the interview carries fk_response and fk_admission, the donation carries fk_interview, the bag and the sample carry fk_donation, and the sample also carries fk_bag. Nothing in the chain depends on matching text or on a naming convention.
A second layer of traceability is provided by the trigger interface_99_modBloodDonationCenter_BloodDonationCenterTriggers.class.php, which writes creation, modification and deletion events for all 51 elements into the Dolibarr agenda. Combined with the identification fields id_check_1, id_check_2 and id_check_by, the reprint traceability of labels, and the amendment fields on measurements, this gives an audit trail of who did what and when.
The traceability report of the reporting console measures the completeness of the chain across a period, so that a donation lacking a bag, a bag lacking a label or a sample lacking a reception acknowledgement is identified before an auditor finds it.
The module ships a complete demonstration dataset, generated by class/blooddonationcentersampledata.class.php and loaded from the administration page. It creates approximately 107,500 rows across the 51 tables, covering centres, staff, partners, donors, appointments, admissions, questionnaires and responses, consents, interviews and measurements, deferrals, donations, bags, samples, labels, reactions, recoveries, campaigns, missions, stock, equipment, quality records, billing and costs.
The dataset is built with the reporting in mind rather than merely to fill lists. Records are spread over a rolling twelve-month window so that the four dashboard charts and the period-filtered reports are populated from the first activation, and the current month is populated so that month-to-date indicators are not empty.
Loading is protected by a versioned guard, so the dataset cannot be applied twice and produce duplicated rows. Removal is a cascade purge that enumerates every one of the 51 tables and also removes the dependent records created during a demonstration, leaving a clean installation. Both operations require the demo cross-cutting permission.
The demonstration data is fictitious. It contains no real donor, no real medical information and no real partner, and it must be purged before the installation is used in production.
The module installs like any Dolibarr add-on: the blooddonationcenter directory is copied into the custom folder of the installation and the module is enabled from Home, Setup, Modules. Table creation, permission declaration, menu entries, the trigger, the widget and the scheduled job are all registered by the module descriptor at activation. It requires Dolibarr 16 to 23, PHP 8.0 or above, and MySQL, MariaDB or PostgreSQL.
Configuration is performed on admin/setup.php, which exposes ten operational parameters plus the selection of the default PDF model, together with the demonstration data load and purge buttons. admin/about.php shows the version, the editor and a functional coverage table.
|
Constant |
Default |
Purpose |
|
BDC_DEFAULT_SLOT_MINUTES |
15 |
Default duration of an appointment slot, in minutes. |
|
BDC_MIN_RECOVERY_MINUTES |
15 |
Minimum post-donation recovery time, in minutes. |
|
BDC_WHOLEBLOOD_VOLUME_ML |
450 |
Standard volume of a whole blood donation, in millilitres. |
|
BDC_SAMPLES_PER_DONATION |
3 |
Number of sample tubes created for each donation. |
|
BDC_REMINDER_DAYS_BEFORE |
2 |
Appointment reminder lead time, in days before the slot. |
|
BDC_NEXT_CONTACT_DAYS |
56 |
Administrative recontact delay after a donation, in days. |
|
BDC_WAIT_ALERT_MINUTES |
30 |
Donor waiting-time alert threshold, in minutes. |
|
BDC_EXPIRY_ALERT_DAYS |
60 |
Lot expiry alert window, in days. |
|
BDC_REQUIRE_DOUBLE_CHECK |
1 |
Require the double identification before any collection. |
|
BDC_PORTAL_ENABLED |
1 |
Enable the donor portal back office. |
|
BDC_ADDON_PDF_DOCUMENT |
bdc_document |
Default PDF model used for donor documents. |
Table 5 - Module constants exposed by the configuration page
Upgrades are protected by the ensureSchema self-healing routine in lib/blooddonationcenter.lib.php, which issues ALTER TABLE ADD COLUMN statements for columns that Dolibarr does not add automatically when a module is updated. This prevents the classic upgrade failure in which a new field exists in the code but not in the database.
A scheduled job, runDailyAlerts in class/blooddonationcentercron.class.php, should be enabled in the Dolibarr scheduled jobs page after installation. It reports appointments awaiting confirmation, interviews without a decision, open reactions, unlabelled bags, donors due for contact, low stock, expiring lots, maintenance falling due and unpaid billing.
The delivery consists of the complete module source, ready to copy into the custom folder of a Dolibarr installation, under the GNU GPL v3 or later licence. It contains no obfuscated code and no external service dependency.
· 51 business objects with their classes, lists, record cards and 51 llx_bdc_ tables.
· 119 controlled vocabularies rendered as translated badges through lib/blooddonationcenter_vocab.php.
· 28 permission groups totalling 96 permissions, applied to both the interface and the API.
· Eight bespoke pages: dashboard.php, reporting.php, queue.php, traceability.php, agenda.php, portal.php, admin/setup.php and admin/about.php.
· A REST API of 255 routes exposed by the BloodDonationCenter class.
· An audit trigger writing agenda events for all 51 elements, a daily alert scheduled job, a home-page widget with six live counters, and a PDF model for donor documents.
· A demonstration dataset of approximately 107,500 rows with a versioned guard and a cascade purge.
· Five language packs of about 1,700 keys each, every key prefixed to avoid collisions with other modules installed on the same Dolibarr.
|
Code |
Language |
Notes |
|
fr_FR |
French |
Reference language of the module |
|
en_US |
English |
Full translation, used by this documentation |
|
es_ES |
Spanish |
Full translation |
|
it_IT |
Italian |
Full translation |
|
de_DE |
German |
Full translation |
Table 6 - The five language packs delivered
Two statements complete this documentation and should be read alongside the Executive Summary. Full offline mode is not delivered in version 1.0: the data model and the synchronisation log exist, the client layer does not. And the module is a management tool that never substitutes for the medical assessment of a donor, the decision to accept or defer, the interpretation of measured parameters or biological results, or the handling of a donation reaction; it does not replace software for biological qualification, component preparation or transfusion delivery; all sensitive medical decisions remain under the control of an authorised health professional. No regulatory certification or compliance approval is claimed.