Duplicated/Triplicated contacts in Mautic-Pipedrive - duplicates

I have my Mautic account that imports the Pipedrive persons. The major part of my contacts appear duplicated. The first is only created. The second one is created and updated. The two contacts are created at the same time.
Also, if I actualize a contact in Pipedrive, it only updates in one contact in Mautic (in the second one).
I tried with only the unique key of email, also with unique keys as Phone, email, IDPipedrive. All my contacts have email and Phone.
I also tried with Updatable contacts and still does not work!
Also sometimes there are contacts that are created 3 times, and some that are only one 1.
What can I do?

This should be fixed in Mautic 2.15.0. (beta version was released yesterday). The reason for duplication is when you configure both create and update webhooks for contacts. Pipedrive for some reason sends both webhooks at the same time when the contact is created in Pipedrive. This leads to a race condition and Mautic creates both. The documentation is updated to lead you to create only webhooks for updates.
https://www.mautic.org/docs/en/plugins/pipedrive.html
Select updated to send to Mautic updated events for the given object. Do not select * as Pipedrive will send the updated events on create event too. If you select * the contacts/companies/users will be duplicated.
Mautic 2.15.0 will ignore the create webhooks and so the badly configured webhooks won't cause duplications.

Related

Should I create a separate table for this use case?

I need to onboard some of my merchants on a third party platform, for which I need to send merchant details along with a request ref no.(rrn) (unique for every onboarding request). After onboarding, whether the merchant actually got onboarded or not will be done by a seperate verify api, which will require me to send request ref no.
The question is whether I should add a new column in my already existing merchants table or should I create a separate table for mapping merchant_id with request rrn, given that only 5% of merchants will be onboarded on this third-party?
As long as the merchants table is small (less than 1 million), you can just add a column to the table and index it
I would suggest that you store this information in a separate table. You have described a simple scenario, but the actual scenario might be more complicated:
There is a timelag between starting the on-boarding and it being successful.
Perhaps the onboarding is not successful.
If a merchant can be "onboarded", they can be "offboarded".
And then onboarded again.
In other words, if you are managing the process, you should keep track of each of the possibilities.
If you are not managing the process and the merchant simply tells you that they are onboarded, then storing the information as a flag is fine.

MySql DB structure with Overriting group settings and allowing settings

how are you?
I'm working on a project that contains accounts with mailing list.
The account has 3 packages he can buy. Each package has it's own settings. e.g.: first package the user gets 1 email per day, and in second package he gets 5 emails per day.
Another feature that I want is the opertunity to override some of the package settings. Which means, for one account I'll set daily email limit as 7.
One more feature I need in this system is email providers. I want the first package to get emails only from first provider, second package from 2 providers and so on.
So I have a problem designing my DB.
I created table emailSubscriptions which has EmailID and name.
I created table accountsGroup which only contains GroupId and name.
I created table accounts which has AccountID, GroupID (foreign key), Email, password and investment. (According to his investment he gets his package).
I've created table accountsSubscriptions which has SUBSCRIPTION ID, AccountID, EmailID and IsActive.
I created table packages which contains PackageID, GroupID, from investment and to investment, and all other package settings e.g. maxEmailsPerDay ....
Of course the end user has. GUI that he can see his settings and edit what he can according to his current package. The admin of the users has GUI too.
Any way, now I got stuck.
I thought about adding to accounts all package columns and then when I want to send emails, I'll take the settings from the group and where ever it's not 0 / empty just override, but the problem is when some settings are 0 / 1, then the column is default 0 and if the groupSettings is 1 for something and I want to turn it off I can't. So this is the first problem
The second problem is with allowed emails subscriptions ... Same problem actually.
I thought about adding to package the allowedEmails, but then it means when ever I send the emails I need to use LIKE operator - and this is not good for runtime.
So I really need you help... Hope you can help me.
Thanks !!
The requirements part lacks clarity, I'd say.
But let's go for it anyway.
Let's extract entities from this messy field of things.
Each entity would generally means one table.
Start from Account.
Account has Subscriptions. It is not clear what's the relation here: if it is 1:1 ("account can have only one subscription") - then reference to it is a part of the Account entity, if it is 1:n - then you'll need a special Account-Subscriptions relation table.
Now Subscription - it is defined by SubscriptionType, or Package, so there must be a table that contains these records (these limits and whatever else you want). Account or Account-Subscription table would refer to it to define what subscription(s) the Account have.
Then Providers - they're referred by SubscriptionType/Packages. If there could be more than 1 Provider per Package/SubscriptionType - then you need additional Package-Provider realtion table.
And finally, the Overrides. That's a trickier part because of the weak requirements on it, but as soon as they're overriding the Package paremeters, I suggest to keep the entity structure same to the package.
You may even place it into the same Package table, sorting 'em out by date, or assign them weights, always keeping the default Package record with the lowest weight.
Then, when you create an override, you copy the whole default record except for the overridden fields, and assign it next weight (or current date), and when you query it - group it and get the MAX().
There's no Email entity itself - but you didn't mention it in your requirements sections whatsoever.
So, that's pretty much it: Accounts, Subscriptions, (optional) Account-Subscription, Packages, Providers, (optional) Package-Provider, (optional, may be incorporated into Packages) Overrrides.
Works for you?

GCM speed and DB design conflict

I'm puzzled and looking for a way out here. I will appreciate any help:
I am sending notifications from a server to Android devices using GCM. In Mysql, I have a User Table (UT) with user ID, user data and GCM registration ID. I also have a User Notifications Table (UNT) in which I store the notification types that each user is registered to. This table includes the user ID and the notification type ID.
When Sending the notification, I need to go through UNT and build an array of all user IDs that are registered to this type of notification. Then I need to go through the UT and get the GCM Registration ID for each user and send the notification.
DB design-wise, I believe that this is the right way to do it. However, in notification sending, speed is a major issue if I want a million users to get the notification a few seconds after sending it. Going through 2 tables significantly increases the processing time (I measured 47 seconds for 1 million users when going through both tables compared to 17 seconds when going through 1 table).
The question is will it be right to store the GCM registration ID also in the UNT so I won't have to go through the UT? Again... DB design wise it is incorrect but GCM wise, it might be the best solution.
If you know of additional methods to solve this issue, I'll be happy to hear about it.
Thank you
You can always decide to hold data redundantly. Yes, this means de-normalizing data, but is something that is often done when you need quick access to many data - in data warehouses for instance.
The dbms even supports this by ON UPDATE CASCADE. But GCM registration ID must be unique in the table.
So either it is unique in UT, then just add the field in UNT, fill it, and create the foreign key with the cascade option.
Or it is not unique in UT, then you need a GCM table (which you should have then anyhow) and have this foreign key from UNT to GCM then. (But in this case you would have to think about if it is really a user notification table you need or a a GCM notification table or both.)

database design issue...for booking app

I have 4 tables,one is credentials(it holds an id, email and password), the other 2 are for business users and regular users of the app.
The business users table holds crID(foreign key)name,lastname,address etc...
The regular users table holds crID(foreign key),name,lastname etc...
The 4th is the booking table, it holds a bookingID, bookedfrom,bookedfor(the last 2 being foreign keys that point to the credentials table).
If a regular user registers in the site he closes a bookingslot and that is stored in the booking table, his name,last name are stored in the regular users table and his credentials in the credentials table.
The business user table just holds the business user for which a booking is made by the regular users.
Here is a graph:
db image
The question is what to do if a regular user does not choose the web to make the booking but makes a call. The business users are given the option to make the booking "manually" also. I am just having difficulty how to integrate that in the db.
As I see it I need to make the following:
Create a booking slot in the bookings table
Create a new regular user entry in the regular users table and at the same time create another column that would indicate if the user is registered or not.
create an entry in the credentials table but without password/email since this he will not be a registered user...he just made a booking using the phone.
WHat is your opinion.If you want I will post some show create statements. I think I made my point.
I would personally merge business users, normal users and optionally credentials in one single userstable.
Since I don't see the need of two seperate tables for your users, it would simplify drastically your data model. You just need a flag to determine if the user is a business user or a normal user.
For the rest, I think that having a null password is enough to determine if the user hasn't registered yet.

MySQL Database Schema for role based system

We are developing a platform for NGOs (N) to get their work done via Individual Volunteers (V) or Volunteers via a Company (C)
NGO
An NGO can come signup for an account and create a profile.
It creates Activities (jobs it needs help from volunteers) to which Individual Volunteers or a Company (Sub set of their Employees who are registered as Volunteers in the system) can apply.
An NGO can check the Applicants Profile and previous Work History
and accept the application. On Acceptance they become members of an
Activity.
Here While they work after regular intervals say 2weeks they need to
enter the amount of hours they have contributed towards that
particular activity.
NGO has to validate this time so that it can reflect in a Volunteers profile as credit
Company
A Company signup for a profile.
It uploads the list of all its employees in a particular formatted CSV file to add Volunteers against itself or send an invite link to to ask their employees to signup. If an Employees already exists in the system we send an email asking him to validate the company's claims
Company can search for a particular Task and apply to it by selecting all its employes or a subset of it.
While Validating time for the work done it can be done it two ways. 1 Company can centrally say V1 V2 V3 have completed 2hrs 3hrs and 2hrs and submit for validation from the NGO or allow each of its Employees handle this manually and allow them to submit it.
Where i need help?
I have created the NGO and single Volunteer relationships. I am confused as to how use the same tables but allow a new entity like Company come in between the NGO and Volunteer and manage the time validation and activity management.
The Time Validated is very important as it will be used to be shown that in the Social Equity Balance of the NGO, Company as well as Volunteers (Individual Work and also Worked for a cause through a company)
I have created the ER diagram below for the NGO and Volunteer and need to create the Company part of it.
Link: http://i.stack.imgur.com/OMY21.png
I'm not sure you need to change your schema much, or even at all. Your schema requires an application to go with it to make it do anything - you can't implement all the logic here - some/most of it will be in your application.
As I understand it, your spec says that all actual volunteer work is performed by individuals, some of whom may be associated with a Company and some aren't. Your schema captures this already.
That's pretty much all you need, I think. When you say:
While Validating time for the work done it can be done it two ways. 1 Company can centrally say V1 V2 V3 have completed 2hrs 3hrs and 2hrs and submit for validation from the NGO or allow each of its Employees handle this manually and allow them to submit it.
This is already covered - either each individual inputs their own work records or the application allows the company to do it for them - and then the NGO validates these records in the same way, regardless of who entered them.
I have created the NGO and single Volunteer relationships. I am confused as to how use the same tables but allow a new entity like Company come in between the NGO and Volunteer and manage the time validation and activity management.
Lets go through a worked example to illustrate both use cases, to make sure we've got everything covered:
Worked Examples
Individual, no company
An individual signs up, creating a row in the volunteers table. They sign-up for an activity, creating a row in the ngo_activity_applications table.
The NGO approves them, creating a row in the ngo_activity_members table - and either removing the row in the ngo_activity_applications table, or changing it's status - the spec. is unclear.
The individual does some work and logs the time in the app, creating rows in the ngo_activity_time_validations table.
The NGO validates the work done somehow, then tells the app this. This presumably changes the status of the rows in the ngo_activity_time_validations table and creates either one summary row or matching rows in the volunteer_validated_times table. Spec unclear where cost_per_hour comes from?
Company
A company signs up and uploads a CSV file with 3 volunteers in. This creates a row in the companies table, plus three rows in the volunteers table, and 3 rows in the company_volunteers linking table.
Company Volunteer 1 signs up to an activity individually and everything proceeds as above.
The Company signs up for a different activity and volunteers all 3 of it's people to work on it. This creates 3 rows in the ngo_activity_applications table.
The NGO approves all three, creating three new rows in the ngo_activity_members table - and either removing the rows in the ngo_activity_applications table, or changing their status - the spec. is unclear.
The volunteers do some work and the company logs time in the app on behalf of Company Volunteers 1 and 2 - and Company Volunteer 3 logs her own time:
Company Volunteers 1 and 2
The company uses the application to log the time on their behalf - creating 2 rows in the ngo_activity_time_validations table.
Company Volunteer 3
Company Volunteer 3 uses the application to log their own time - creating a row in the ngo_activity_time_validations table.
The NGO validates the work done somehow, then tells the app this. This presumably changes the status of the rows in the ngo_activity_time_validations table and creates either one summary row or matching rows in the volunteer_validated_times table. Spec unclear where cost_per_hour comes from?
Summary
You can see how much validated time any individual has logged by querying the volunteer_validated_times table JOINed to the volunteers table. You can also see how much validated time any Company has logged, by doing the same query but also joining on the company_volunteers table.
Possible changes & Questions:
You might want to add a company_entered flag to the ngp_activity_time_validations table, so that you can distinguish between records entered by individuals and ones entered by the company on an individuals behalf. You might also want to add the ID of the person who makes the entry in this table, if logging that is relevant to your application.
Might want to add an hourly_rate column to the volunteers table, to use as a default cost_per_hour when creating rows in the volunteer_validated_times table.