A common issue inherited from Business NXT is that users forget to set the actualStartDate when they create a project, and when the project is concluded, they forget to set the actualEndDate.
This trigger will automatically set the actualStartDate to the current date when the project is created and the actualEndDate to the current date when the project is concluded. In addition it will set the project department to the department of the user who created the project.
TLDR
Let’s create the trigger part by part.
Setup an ISV user
First we have to create an ISV user, so that we can use GraphQL to query the Business NXT API.
- Start by following Vismas guide on how to create an ISV user here. Make sure that the name of the user starts with nbt or nt in order to not acrue any extra costs for ignored events. The user name will be isv_nt_yourclientname.
- Add the ISV user to Business NXT by following the guide here.
- Take the credentials created for the ISV user and add them to the settings in NXT Triggers. It must be stored under
VISMA_CLIENT_ID
and VISMA_CLIENT_SECRET
.
Starting with an empty trigger
Start by creating a new trigger in NXT Triggers and select the orgUnit2
-table and ALL
events. This will give you some sample code, but we’ll just remove all of that.
import { HandlerFunctionArgs, gql, invariant } from "businessnxt-dev";
export default async function ({
event,
db,
}: HandlerFunctionArgs<"orgUnit2", Env>) {
if (event.event !== "DELETE") {
}
}
Getting the data we need
First we need to get the data we need to update the project. We need the orgUnit1
, orgUnit2
, orgUnitProcessing
, actualEndDate
, actualStartDate
, changedDate
, and the official
-field from the project.
To simplify creating the query, we can use the playground in Business NXT to create the query. The query will look like this:
query REndDTandR1onR2($companyNo: Int, $orgUnit2No: Int) {
useCompany(no: $companyNo) {
orgUnit2(filter: { orgUnit2No: { _eq: $orgUnit2No } }) {
items {
orgUnit1
orgUnit2No
orgUnitProcessing
actualEndDate
actualStartDate
changedDate
official: joinup_Associate_via_Official {
orgUnit1
}
}
}
}
The complete trigger
import { HandlerFunctionArgs, gql, invariant } from "businessnxt-dev";
const QUERY_REndDTandR1onR2 = gql`
query REndDTandR1onR2($companyNo: Int, $orgUnit2No: Int) {
useCompany(no: $companyNo) {
orgUnit2(filter: { orgUnit2No: { _eq: $orgUnit2No } }) {
items {
orgUnit1
orgUnit2No
orgUnitProcessing ##Susp
actualEndDate
actualStartDate
changedDate
official: joinup_Associate_via_Official {
orgUnit1
}
}
}
}
}
`;
const MUTATION_UpdateOrgUnit2 = gql`
mutation UpdateOrgUnit2(
$companyNo: Int
$orgUnit2No: Int
$update: OrgUnit2_Input!
) {
useCompany(no: $companyNo) {
orgUnit2_update(
filter: { orgUnit2No: { _eq: $orgUnit2No } }
value: $update
) {
affectedRows
}
}
}
`;
export default async function ({
event,
createGraphQLClient,
db,
}: HandlerFunctionArgs<"orgUnit2", Env>) {
if (event.event !== "DELETE") {
const client = await createGraphQLClient();
const rsp = await client.request<any>(QUERY_REndDTandR1onR2, {
companyNo: event.companyNo,
orgUnit2No: event.primaryKeys.orgUnit2No,
});
const orgUnit2 = rsp.useCompany.orgUnit2.items?.[0];
const update = {
actualEndDate:
orgUnit2.actualEndDate === 0 &&
orgUnit2.orgUnitProcessing === (orgUnit2.orgUnitProcessing | 1)
? orgUnit2.changedDate
: undefined,
actualStartDate:
orgUnit2.actualStartDate === 0 ? orgUnit2.changedDate : undefined,
orgUnit1:
orgUnit2.orgUnit1 !== orgUnit2.official?.orgUnit1 &&
orgUnit2.official?.orgUnit1
? orgUnit2.official?.orgUnit1
: undefined,
};
const hasUpdates = Object.values(update).filter((x) => x).length > 0;
if (hasUpdates) {
const rsp = await client.request<any>(MUTATION_UpdateOrgUnit2, {
companyNo: event.companyNo,
orgUnit2No: event.primaryKeys.orgUnit2No,
update,
});
console.log("response", rsp);
}
}
}