=== Plugixa CRM ===
Contributors: plugixa, freemius
Tags: crm, contacts, leads, sales, pipeline
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.2
Stable tag: 1.0.0
License: GPLv2
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A CRM for WordPress: contacts, leads, deals, email, cases, a knowledge base, roles, reports and PDF templates, in a fast React admin.

== Description ==

Plugixa CRM turns WordPress into a working sales CRM. It stores records in its own
normalized database tables rather than as posts, so lists, filters and pipeline
reporting stay fast as your data grows.

Everything is built as modules, so the CRM grows without the core changing.

**Records**

* Accounts: companies, with hierarchy and customer/supplier/partner types
* Contacts: people, with multiple emails and phone numbers
* Leads: capture, qualify, and convert into an account, contact and opportunity
* Opportunities: customisable pipelines, stages and a kanban board

**Working the day**

* Activities: tasks, meetings and calls, with a shared timeline
* Email: write and send from any record, with templates and placeholders
* Calendar: month, week and day views
* Stream: every record keeps a feed of what changed and who said what
* Follow a record, @mention a colleague, and get told in the notification bell
* Reminders and in-app notifications

**Support**

* Cases: a support queue with statuses, priorities and types
* Email-to-Case: turn an inbox into cases, assigned round-robin or to whoever is least busy
* Knowledge base: articles in a category tree, linked to the cases they answer

**Organising the team**

* Teams: groups of users
* Roles: per record type and per action, one of everything / your team's / your own / none
* Field-level permissions: hide a field, or make it read-only, for the people who should not edit it
* Per-record sharing: put one record in front of a team, or of named people
* Reports: a report builder over deals, leads, meetings, calls and tasks
* Forecasting: weighted pipeline, win rate, and expected close by month

**Getting data in and out**

* CSV import: map your columns, create or update, and undo the whole run if it goes wrong
* CSV export: from any list, honouring the filter you are looking at
* PDF templates: design a document per record type and print one record or a whole selection

**Making it yours**

* Tags, with usage counts
* Attachments on records, plus a shared document library
* Dashboard with pipeline reporting, and global search across every record
* Trash: deleting a record is reversible

**Shortcodes - the CRM on your own site**

* `[plugixa_crm_app]`: the whole CRM on a page of your site, for your staff: inside your theme,
  with your header and footer where they always are, and a full-screen button for when someone
  needs the room. Anyone without permission to use the CRM sees a sign-in link and nothing else.
* `[plugixa_crm_portal]`: a customer portal: your customers sign in and see their own support
  requests, the documents you share with them, the meetings and calls they took part in, their
  own contact details, and the help articles you publish to them. Every one of those is a
  separate switch, and all but support requests start switched off.
* `[plugixa_crm_kb]`: a public help centre: your knowledge base articles, readable by anyone
  and indexable by search engines. An article appears only if you tick "Anyone can read this"
  on it - being readable in the customer portal is a separate, narrower permission.
* `[plugixa_crm_lead_form id="1"]`: a web-to-lead form. Submissions arrive as leads.

Every one of them loads its CSS and JavaScript only on the pages where you place it. Every other
page on your site loads none of it.

**Nothing above is locked, and nothing expires**

Every feature listed above is in this download and works, for as long as you keep the
plugin installed. Nothing is time-limited, nothing is disabled pending payment, and there
is no licence key to enter to make any of it run.

There is a paid version, and what it adds is integrations with other services - the
connectors that link the CRM to the rest of your stack. That is additional code which is
simply not part of this download, rather than code that is here but switched off. Removing
a feature from this list to sell it back is not something we will do.

For a period this plugin acted as a host for six separate paid add-on plugins. That
model has been dropped - see the 3.2.0 changelog below if you were using any of them.

== Installation ==

1. Upload the plugin to `/wp-content/plugins/plugixa-crm`, or install it through the Plugins screen.
2. Activate it.
3. Open **Plugixa CRM** in the admin menu.

== External services ==

This plugin does not connect to any third-party service on its own, and it has no service of its own
to connect to. Every connection below is one **you** set up, to an address or an account **you**
name. Nothing is ever sent to Plugixa.

Only the first two - reading your mail over IMAP, and webhooks - are part of the free download, and
neither of them contacts a vendor: both go to an address you enter yourself. **The free download
contains no third-party connector code at all**, so it cannot make a request to Twilio, Microsoft or
Google even if you wanted it to. Those three are paid add-ons whose code is simply not present in
this plugin. They are described below so you can see what each would do before deciding to buy one,
and none of them connects to anything until you enter your own credentials for it.

**1. Reading your mail (IMAP)**

Set up under Plugixa CRM → Settings → Mail accounts.

**What it connects to:** the IMAP server you enter - your own mail provider. The plugin ships no
default and has no service of its own.

**When:** every five minutes on WP-Cron once an account is active, and immediately when you press
Test connection or Fetch now. If you configure no account, it never connects.

**What is sent:** the username and password you entered, to authenticate, over the encrypted
connection you chose (SSL or TLS).

**What is received:** the messages in the folder you asked it to monitor - sender, recipients,
subject, date and body - which are stored in your own database as CRM records.

**Your provider's terms:** because the server is one you already use, its own terms of service and
privacy policy apply. The plugin sends nothing to Plugixa or to anyone else.

Passwords are encrypted before being stored, using a key derived from your site's own security keys
in `wp-config.php`. That protects them if your database is exposed; it cannot protect them from
someone who can already read your site's files.

**2. Webhooks**

Set up under Plugixa CRM → Webhooks. If you create none, the plugin never makes an outbound request.

**What it connects to:** the address you type into the webhook. It must be a public `http://` or
`https://` address; addresses inside your own server's network are refused.

**When:** within a few minutes of a record being created, changed or deleted, for the events you
subscribed to, and immediately when you press Send test. Refused messages are retried up to five
times with a growing delay.

**What is sent:** a small JSON message naming the event (for example `contact.created`), the kind of
record, its numeric id, the time it happened and your site's address - plus a signature header proving
the message came from your site. **No field data is included**, so names, addresses and any other
record content stay on your server unless your own code adds them.

**What is received:** only the receiving system's HTTP status, which is stored in the delivery log so
you can see whether it arrived.

**Whose terms apply:** the receiving system is one you chose, so its terms of service and privacy
policy apply. Again, nothing is sent to Plugixa.

Signing secrets are encrypted before being stored, the same way mail passwords are.

**3. Twilio (text messages)**

Set up under Plugixa CRM → Integrations → Twilio. If you do not enter Twilio credentials, the plugin
never contacts Twilio.

**What it connects to:** `api.twilio.com`, using the account SID, auth token and sending number from
your own Twilio account. Plugixa ships no keys and operates no messaging service.

**When:** when somebody presses Send on a record, and - while replies are switched on - every five
minutes on WP-Cron to ask whether anything new has arrived and what became of messages already sent.
Twilio never contacts your site; your site always does the asking.

**What is sent:** the recipient's phone number and the text of the message you typed. Nothing else
about the record leaves your site - no name, no email address, no other field - unless you type it
into the message yourself.

**What is received:** messages sent to your Twilio number (sender, recipient, text and time), and the
delivery status of messages you sent.

**Their terms:** [Twilio's terms of service](https://www.twilio.com/legal/tos) and
[privacy policy](https://www.twilio.com/legal/privacy). Twilio is a communications provider and will
hold the messages you send through it, under its own retention rules.

Your auth token is encrypted before being stored, the same way mail passwords are.

**4. Microsoft 365 (Outlook calendar)**

Set up under Plugixa CRM → Integrations → Microsoft 365, and then connected per person.

**What it connects to:** `login.microsoftonline.com` and `graph.microsoft.com`, using an Azure app
registration **you** create and whose application ID and secret you enter. Plugixa ships no Microsoft
keys and runs no middleman, so your data travels between your site and Microsoft only.

**When:** when somebody signs in to connect their calendar, whenever a CRM meeting is created,
changed or cancelled, and hourly to ask what has changed. Microsoft never contacts your site.

**What is sent:** the meeting's subject, description, start and end time, and time zone. **No
attendee is ever sent**, deliberately, so Microsoft cannot email your customers on your behalf.

**What is received:** changes to events the CRM itself created - that they moved, or were cancelled.
Nothing else in your calendar is read into the CRM.

**If you also set up a Microsoft mailbox**, the CRM additionally reads messages from the folder you
choose on that account - sender, recipients, subject, date and body - and stores them as CRM records,
exactly as it does for an IMAP mailbox. It never marks a message read, moves it or deletes it.

**Their terms:** [Microsoft's terms of use](https://www.microsoft.com/legal/terms-of-use) and
[privacy statement](https://privacy.microsoft.com/privacystatement).

Microsoft sign-in tokens are encrypted before being stored, the same way mail passwords are.

**5. Google Calendar**

Set up under Plugixa CRM → Integrations → Google Calendar, and then connected per person.

**What it connects to:** `accounts.google.com` and `www.googleapis.com`, using a Google Cloud project
**you** create and whose client ID and secret you enter. Plugixa ships no Google keys and runs no
middleman, so your calendar data travels between your site and Google only.

**When:** when somebody signs in to connect their calendar, whenever a CRM meeting is created,
changed or cancelled, and hourly to ask Google what has changed.

**What is sent:** the meeting's title, description, start and end time, and time zone. **No attendee
is ever sent**, deliberately, so Google cannot email your customers on your behalf.

**What is received:** changes to events the CRM itself created - that they moved, or were cancelled.
Nothing else in your calendar is read into the CRM.

**Their terms:** [Google's terms of service](https://policies.google.com/terms) and
[privacy policy](https://policies.google.com/privacy).

Google sign-in tokens are encrypted before being stored, the same way mail passwords are.

== Source Code ==

The complete human-readable source for the compiled JavaScript and CSS ships inside
this plugin, with pinned dependencies (package.json + package-lock.json):

* Admin app: assets/backend/app/ (React 19, Material UI 9, TanStack Query 5,
  React Router 6, React Hook Form, Recharts; TypeScript 5, Vite 8)
  builds to assets/backend/build/

* Public app: assets/frontend/app/ (React 19, Material UI 9, Emotion; TypeScript 5, Vite 8)
  builds to assets/frontend/build/
  Two entries, lead-form and portal, sharing one vendor chunk.

Build with Node.js 20+: in each of those directories run `npm install` then `npm run build`.
Both builds run `tsc --noEmit` before Vite, so they type-check as well as compile.

They are separate projects on purpose. The admin app carries the data grid, the scheduler and
the charting library and comes to about 1.5 MB; the public app has none of them, so a page
carrying a contact form downloads about 135 KB gzipped rather than the CRM.

Some front-end assets are still not compiled at all: assets/frontend/*.css and the small
plain-JavaScript files beside them, plus the Gutenberg blocks that place the shortcodes
(assets/frontend/block/, assets/frontend/portal-block/), which are written against
WordPress's own editor APIs with no build step.

The `[plugixa_crm_app]` shortcode mounts the compiled ADMIN app, because it is the admin
app on a different page. It loads nothing at all for a visitor who does not hold the CRM
capability.

Bundled PHP libraries, all shipped as readable source under vendor/:

* mPDF 8.3 (GPL-2.0-only): generates the PDFs produced by PDF templates.
  https://mpdf.github.io/  Its font collection is trimmed to the four families the
  plugin offers (Latin, Cyrillic, Greek, Hebrew and Arabic coverage); the full set is
  restored by `composer install`.
* setasign/FPDI, myclabs/deep-copy, paragonie/random_compat, psr/log,
  psr/http-message (MIT) - dependencies of mPDF.
* psr/container (MIT): the service container interface.

PDF generation needs PHP's mbstring and gd extensions. Where they are missing the
plugin says so on the PDF templates screen rather than failing when you press Print.

== Frequently Asked Questions ==

= Does this store CRM records as WordPress posts? =

No. Records live in dedicated tables, which keeps CRM data out of your posts table and
keeps list and reporting queries fast.

= Will it slow my site down? =

Almost certainly not. The CRM is an admin application, and the only thing it adds to a
visitor-facing page is a web-to-lead form - on the pages where you have put one. A page
with no form loads none of this plugin's CSS or JavaScript, and a page with one loads
about two kilobytes of script and a stylesheet that sets layout only, so your theme keeps
control of how the form looks.

= Can my staff use the CRM without going into wp-admin? =

Yes. Add `[plugixa_crm_app]` to any page and the whole CRM appears on it, inside your theme, with
your header and footer where they always are. There is a full-screen button in the CRM's toolbar
for when someone needs the room.

It is the same application the admin screen loads and it talks to the same API, so permissions are
identical - there is no second set of rules to keep in step. Anyone without access sees a short
"sign in" notice instead, and the application is never loaded for them.

= What options does the staff CRM shortcode take? =

These apply to `[plugixa_crm_app]`:

* `width`: `wide` (default), `full` or `content`. `wide` and `full` use your theme's own wide and
  full alignments. `content` keeps the CRM in the normal text column, which is usually too narrow
  to be comfortable.
* `height`: a number of pixels. Left out, the CRM sizes itself to the window.
* `mode`: `embed` (default), or `full` to give the CRM the whole page with no theme around it.

For example: `[plugixa_crm_app width="full" height="800"]`

= Why does the CRM appear in a frame rather than directly in the page? =

Because it is the only way it can keep working on any theme. The application is built with Material
UI, whose styling is deliberately low-specificity so that it is easy to override - and a theme's own
form styling beats it by construction. Any reset strong enough to protect the CRM would also flatten
the theme around it, and the CRM's own baseline styles would restyle your header and footer links
and repaint the page background.

A frame keeps the two apart completely, so your theme stays exactly as you designed it and the CRM
looks the same on every site.

= What happens to my data if I deactivate the plugin? =

Nothing. Deactivating leaves every table intact. Data is removed only if you delete the
plugin, which runs the uninstaller.

= Does the free version expire or stop working? =

No. Every feature listed above works for as long as you keep the plugin installed. There
is no trial, no expiry and no licence check anywhere in this plugin.

= What is in the paid version? =

Custom fields, and the integration connectors that link the CRM to other services and
plugins. Both are extra code that is not part of this download at all, so nothing you can
see here is being held back. Everything the feature list above describes is in front of you
and working.

= What are custom fields, and what happens if I stop paying? =

A custom field is one you define yourself - "Contract renews", "Company size" - on
contacts, accounts, leads and deals. It is stored in a typed column, so a number sorts as a
number and a date can be filtered as a date, and it appears on the record, in the filter
drawer, in search and in every export.

If a subscription lapses, nothing is deleted. The answers stay in their tables exactly as
they were and reappear the moment the paid build is installed again; what goes is the
screen that reads them. Uninstalling the plugin removes them along with everything else,
because uninstall drops every table this plugin created.

= Does it send email through its own server? =

No. Sending goes through WordPress's own mail, so any SMTP plugin you already use applies to CRM
email too. The CRM configures only the from address, from name and reply-to it should use.

= Do I have to set up roles? =

No. Roles are opt-in: until you create one, everybody keeps the access they had before. Create a role
only when you need to narrow what somebody can see or change.

= Where are attached files stored? =

In a protected folder inside your uploads directory, not in the media library. The plugin
writes deny rules for it and checks on activation whether your web server actually honours
them, warning you in the admin if it does not.

== Screenshots ==

1. Dashboard: open pipeline, won this month, overdue activities and the leads worth working
2. Opportunities: a drag-and-drop board where every stage carries its own probability
3. An account: its contacts and their roles, plus the notes, files, tags and stream every record carries
4. Calendar: tasks, calls and meetings on one view, with working hours behind free/busy
5. Cases: six statuses, three types, and a case number that survives an export
6. Campaigns: target lists, batched sending, and tracking served from your own domain
7. Reports: a report builder with charts and a weighted pipeline forecast
8. The customer portal, as a customer sees it
9. Integrations: the framework is free and every connector is paid

== Changelog ==

= 1.0.0 =
First public release.

* **Records.** Accounts, contacts, leads, opportunities, tasks, calls, meetings and cases, stored in
  the CRM's own database tables rather than as posts, so lists, filters and reporting stay fast as
  the data grows.
* **Pipelines and a kanban board.** Drag an opportunity between stages, with per-stage probability
  and a weighted forecast.
* **A calendar and scheduler.** Meetings, calls and tasks on one view, with working hours and
  free/busy so you can see when somebody is actually available.
* **Email.** Send from a record and receive over IMAP, turning incoming mail into cases
  automatically. Messages are matched on Message-ID, so a message read twice is stored once.
* **Campaigns and mass email.** Target lists, an unsubscribe link that cannot be switched off, and
  optional open and click tracking that runs entirely on your own site.
* **Cases and a knowledge base**, with a category tree and articles you can optionally show to
  customers.
* **A customer portal.** Nothing is exposed until you set it up: case notes are private by default
  and articles need a separate "show to customers" setting.
* **Web-to-lead forms**, as a shortcode or a block, plus a REST endpoint for your own forms.
* **Roles and per-record sharing.** An all/team/own/none matrix with field-level permissions. A user
  holding no role keeps exactly the access they had before you created one.
* **Reports and arrangeable dashboards**, with multiple tabs.
* **PDF templates and Print to PDF**, rendered on your own server.
* **Import and export**, as CSV or Excel.
* **Webhooks.** Signed, queued and retried, carrying no record data - nothing connects out until you
  create one and name the address yourself.
* **Duplicate detection and record merging**, with an audit log and GDPR erasure support.
* **A React admin application** that also runs on the front end through a shortcode.
