How to completely delete recurring event instance? - google-calendar-api

If you create a recurring event in google calendar, you actually create one single event (parent) with recurrence rule, others are just virtually added. Once you move any of those virtuals, it gets saved as instance and you can edit it in any way you like without affecting the parent event itself.
If you edit that instance to match its parent, it gets deleted and replaced with the virtual one once again. (No need to keep instance which is no different from the parent event, right?)
I'm doing the same in my application. However, when I'm trying to do so using google-php-api-client, the only option to delete something, is to set the event status as 'cancelled' which will make the instance deleted.
My question is:
How to delete (or reset) the instances without the need of updating them one by one to match its parent?
EDIT: Forgot to mention why do I need this and what am I trying to achieve.
Basically, if you edit an instance, Google will ask you whether you want to edit "Only this", "Following", or "All" of the recurring events. If you select "Following", google will throw away everything related to the parent event from this date (where original_start > date), modify its rule to set UNTIL rule with the date of instance being edited and pass its old rule to newly created event with starting time same as the date of this particular instance.
Since I know of no method, how to delete multiple events matching some condition. The only way I could figure this out, is to select all of those, and update them one by one, which could be a bit of problem since you can:
Create recurring event with recurrence-end unspecified
Decide to modify all following events

Related

How to programmatically link newly created records to a record from another table

Thanks in advance for your advice!
Background
I’m creating a database to track orders placed by customers.
An ‘Orders’ table stores general details about an order like the customer’s name, order date, and delivery-required date.
A separate ‘Order_Items’ table stores the specific items that the customer has ordered.
The is a one-to-many relationship between the ‘Orders’ table and ‘Order_Items’ table, i.e. one ‘Order’ can have many ‘Order_Items’, but each ‘Order_Item’ must be associated with only one ‘Order’.
Current State
Currently, I have a page where the user creates a new ‘Order’ record. The user is then taken to another page where they can create as many ‘Order_Item’ records as are needed for the order.
Desired State
What I would like to achieve is: When a user creates new ‘Order_Item’ records, it automatically allocates the current ‘Order’ record as the foreign key for the new ‘Order_Item’ record.
What I've Tried So Far
Manual Action By The User: One way of establishing the link between an 'Order' and all of its 'Order_Items' would be to add a drop-down widget which which effectively asks the user something like "Which order number do all of these items belong to"? The user's action would then establish the link between the two tables and associate one 'Order' with many 'Order_Items'. However, my goal is for this step to be handled programatically instead.
Official Documentation: I’ve referred to the offical documentation which was useful, but as I'm still learning I don’t really know exactly what to search for. The prefetch feature appeared promising but does not actually establish a link; it just loads associated records more efficiently.
App Maker Tutorials: I found an App Maker tutorial which creates an HR App where a user can create a list of ‘Departments’, then create a list of ‘Employees’, and then link an ‘Employee’ to a ‘Department’. However, in the example app this connection is established manually by the user. In my desired state I would like the link to be established programatically.
Manual Save Mode:
I’ve also tried switching to manual save mode so that the user has to create a draft ‘Orders’ record and then several draft ‘Order Items’ records and then save them all at once. However, I haven’t managed to make this work. I’m not sure whether the failure of this approach is because 1) I’m try to create draft records on more than one table, 2) I’m just not doing it correctly, or 3) I thought I read somewhere that draft records are deprecated.
Other Ideas
I'm very new to this field and am may be wrong, but I have a feeling I may need to use some scripting to establish the link. For example, maybe I could use a global variable to remember which 'Order' the user creates. Then, for each 'Order_Item' I could use the onBeforeCreate event to trigger a script that establishes the link between the 'Order_Item' and the 'Order' that was remembered from the previously established global variable.
Updated Question
Thanks Markus and Morfinismo for your answers. I have been using both answers with some success.
Morfinismo: I've successfully used the code you directed me to on existing records but cannot seem to get it to work for newly created records.
For example:
widget.datasource.createItem(); // This creates a new record
var managerRecord = app.datasources.Manager.item; // This sets the Manager of the currently selected parent record as a variable successfully.
var teamRecord = app.datasources.Teams.item; // This attempts to set the Manager of the currently selected record as a variable. However, the record that was created in line 1 is not selected. Therefore, App Maker does not seem to know which record this line of code relates to and returns the error Cannot set property ‘Manager’ of null.
// Assign the manager to the team.
teamRecord.Manager = managerRecord; // This successfully assigns the manager but only in cases where the previous line of code was successful (i.e. existing records and not newly created ones).
Do you have any suggestions or comments on how to apply this code to records that are created by the initial line of code in line 1?
I have found the easiest way to create related items for situations such as yours is to actually import a form with the datasource set to Parent: Child (relation) or Parent: Child (relation) (create). So in your case the datasource would need to be set to Order: Order_Items (relation).
You can get this accomplished in two different ways using the form widget wizard:
Option 1:
If your page datasource is set to Order_Items, drag your form on your page.
In the datasource selection section, your datasource in the form widget should default to `Inherited: Order_Items'. Click the 'Advanced' button in the bottom left corner, then from the datasources category find Order as your datasource, then select relations in the next field, and then Order_Items in the next field, choose 'Insert only' or 'Edit' form and then the appropriate fields you want in the form.
Now every item that gets created in that form will automatically be a child record of the currently selected record in your Order datasource.
Option 2:
If your page datasource is set to Order, drag your form on your page.
In the datasource selection section, your datasource in the form widget should default to Inherited: Order. Scroll down in your datasource selection section until you find Order: Order_Items (relation), then choose 'Insert only' or 'Edit' form and then the appropriate fields you want in the form.
Now every item that gets created in that form will automatically be a child record of the currently selected record in your Order datasource.
In your Order model, make sure that the security setting is set appropriately that a user is allowed to create relations of Order_Items in Order. That is the simplest approach in my opinion since you don't have to hard code the parent into your form or client/server scripts. It is automatically based on the currently selected parent, and is essentially doing the same thing that #Morfinismo explained in the client script section.
The comment I placed under your question included a link to the official documentation that explains what you need. Anyways, your question is not clear enough to determine whether you are creating the records via client script or server script, hence this is a very general answer.
To manage relations via client script:
var managerRecord = app.datasources.Manager.item;
var teamRecord = app.datasources.Teams.item;
// Assign the manager to the team.
teamRecord.Manager = managerRecord;
// Changes are saved automatically if the datasource in auto-save mode
// Add a team member to a Manager's team.
// Note: Retrieve Members on the client before proceeding, such as by using prefetch option in datasource - datasources Team -> Members)
var engineerRecord = app.datasources.TeamMember.item;
teamRecord.Members.push(engineerRecord);
To manage relations via server script:
// Get the record for the Team to modify.
var teamRecord = app.models.Teams.getRecord("team1");
// Assign a manager to the Team.
var managerRecord = app.models.EmployeeDB.getRecord("manager1");
teamRecord.Manager = managerRecord;
// Note: The new association is not saved yet
// Assign a team member to the Team.
var engineerRecord = app.models.EmployeeDB.getRecord("engineer1");
teamRecord.Members.push(engineerRecord);
// Save both changes to the database.
app.saveRecords([teamRecord]);
The above information is taken directly from the official documentation, which like I said, I referred to in the comment I placed under your question.

combine multiple google tag manager triggers

I'm trying to achieve the following:
One GTM container for multiple websites/domains (within the same platform)
Only fire tags that are active for the current website (by checking configured analytics / criteo / adwords / other vendor account id in data layer)
Configure triggers like 'booking page reached' and 'booking created' once (by custom event and using data layer)
My problem is combining the condition 'active tag' (checking for account id) with a 'booking created' event without duplicating logic.
Because every trigger is an OR condition, not an AND condition.
Currently, this results in creating exceptions that are very specific, and contain most of the triggers like 'Booking created', specific for a tag (Analytics / Criteo / Adwords).
Resulting in having to still make very specific (duplicate) triggers, instead of re-using them.
Main issue is exceptions have to match the event type of the trigger. And triggers cannot be combined nor extended.
My tags / triggers configuration looks like this now:
My questions:
Is there a way to combine multiple triggers (AND instead of OR)
Can I create an exception for tag that is not depended on the same event as the original trigger?
Am I looking for a solution in the wrong direction? How do I prevent triggering a tag that is disabled (by dataLayer), without duplicating 'custom events' logic for every different tag / vendor.
If your main problem is that "exceptions have to match the event type of the trigger", the common workaround is to use a trigger of the type "custom event", check "use regex" and enter ".*" (without the quotes), which matches all events, including the built-in pageview (gtm.js), DOM ready (gtm.dom) and Window loaded (gtm.load). Then add conditions as needed.
There is a more powerful and easiest way to combine triggers in multiple AND and OR.
First of all: if you need to combine triggers with just OR condition, you can simply add a list of triggers when you are configuring a tag.
I am no talking about exceptions, just triggers. You can click on the (+) symbol and every trigger you add is managed with OR condition.
But, if you need, for instance, to add two triggers in AND? There is a very simple way that does not imply the regex.
Is the trigger group feature.
Here are the steps.
Create all the triggers you need to compose (in this phase you don't need to combine them, just one trigger at a time)
Then create a new trigger, but in this case, choose the last type in the list, that is "trigger group". Et voilà... you can combine in the group any of the existing triggers and define if you wnat combine them with AND or OR!!!! :)
Finally, go to your tag and use the GROUP instead of the single trigger.
That's all

Doctrine innerOrder[int] column implementation for manual sort order control

I have two tables in my app's schema: Event and Game (one-to-many). Games are ordered by datetime field. But sometimes there can be games played in parallel (same datetime), but the user should be able to set their relative order.
I've added innerOrder (int) field with simple idea: it should have autogenerated value that can be changed on reorder (exchange with neighbor record). But I can't achieve this behavior with Doctrine: GeneratedValue can't be used twice / with separate field (just don't work this way).
On the next attempt I've tried to do it without autogeneration. But I need some initial value on insert, for example: MAX(innerOrder) (better - to set it automatically of course).
I can't do it in prePersist or similar methods - don't have access to repository class. And don't want to do it with additional query in controller - not only because of additional code I should insert each time (get max value from table, set inner order), but I'm afraid of possible conflicts (when two users are adding Games in parallel).
How should I achieve expected behavior (maybe, I'm totally wrong here)?
There is no need in achieving this behavior with Doctrine, you can manage this value from aggregate root. I.e when you attach the Game to the Event you can update it innerOrder value according to maximum of currently attached games + 1. Conflicts could be easily avoided with different kind of locks on Event you edit (i.e fetcing it with doctrine write lock or some kind of shared locks or mutex (see symfony/lock))
After it you can specify your relation confiration to fetch it with given order using this documentation
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/ordered-associations.html
My two cents: when creating/modifying an event, you can check if there's one already at the same time (default innerOrder is 0, or even count(*) of the events at the same time). You can issue a warning when there's another event, ask for the order, or take to a form where you can manually reassign the order of the events.

How do I create a Firebase collection?

So I am writing a chat application that I want to have multiple rooms, however, I can't find a button on the Firebase console that I can add child collections.
I've tried exporting, editing, then importing but that doesn't seem to do much. I have looked at some Firebase tutorial's but I can't find one that explains this.
Anything you enter in the console has to have a value itself, or at least one child (with a value). This is because Firebase does not explicitly store "null" or empty values in the database. You can enter the name of the collection and then rather than a value use the + button at the right to start adding children to it and so on until you reach a node with a value:
You cannot however simply create a placeholder for a collection that has no values. If you need a collection but can't initialize any of its data, just use your security rules to define what's allowed and write your client code knowing it may or may not exist. Firebase allows you to attach listeners to nodes that don't exist yet.

how not to trigger event child_added for initial children

I have rather big data-set, possibly millions of objects and I need to trigger the child_added event and get the last added child. However whenever I start the service it triggers the event once for each initial child in the data-set.
How Can I avoid this behavior?
edit:
The suggested solution does not solve the problem - it is just ignoring it in my opinion. In my specific case I store the unique reference to other object as a name and it's value is other important data. The Priority on the record is set to the specific number in my case time stamp. I use this to retrieve the record to build a timeline so I need the option to save a new object with custom timestamp - not only current. Listener .on() on event child_added fits the need perfectly except fetching all the children upon the start. This in my opinion renders this feature absolutely pointless on any large collection.
You could use limit(1). Then the listener will fire once at the beginning, and then again each time a new child is added.
fireRef.limit(1).on('child_added', function() { /*code*/ });

Resources