@journeyapps/cc-util-data
v1.2.2
Published
Simplified Journey JSON Data for better use with Handlebars and PDF document generation
Downloads
94
Readme
cc-util-data
The purpose of this module is to enable Journey Apps cloud code to easily generate a json payload for use in PDF/Excel reports.
Normally you would manually get all the data before you add it to a handlebars template or a Excel report. To overcome this, this module exists. Its sole purpose is to easily gather the data for your PDF or Excel report without any hassles.
As a added benefit, you can also upload your PDF to the backend for reference at a later stage.
Documentation
All code is clearly documented, please see code for more details. View an example below.
Installation
Per machine
yarn add @journeyapps/cc-util-data --save
Per CloudCode task
yarn add @journeyapps/cc-util-data
Deploying
yarn version
Usage
This might not be apparent at the very start, but there is a specific way of using this to retrieve the correct data.
The main function fetchData
has 3 parameters:
/**
* Retrieves the Data of the object with its children.
* @param {string} ObjectID ID of the main object, the main object is the model
* @param {string} model The Entry model name. Found in <model name="<here>" label="label">
* @param {array} relatedModels Array of related models by name. Found in <has-many model="<here second>" name="<here first>" /> or <belongs-to model="<here second>" name="<here first>" />
* @return {JSON} JSON object representing the data
*/
async fetchData(objectID, model, relatedModels) { ... }
/**
* Uploads a Attachment to the backend.
* @param {JourneyAttachment} attachment Journey Apps attachment object
* @param {Object} object Destination Object for upload
* @param {String} [field="generated_report"] Field to upload to, defaults to generated_report
*/
async uploadAttachment(attachment, object, field = "generated_report") {
It is extremely important to use the name of the relationships and only the model name as a fallback. The related models do not include the main model as this is derived.
Example fetchData:
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings']);
await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'booking',['room', 'room.hotel']);
Notice the difference between a hotel has_many rooms vs a booking belongs_to a room.
Example uploadAttachment:
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
let _hotel = DB.hotel.first();
let _attachmentContent = await _hotel.broshure.toBase64();
let _attachment = {
content: _attachmentContent,
filename: "test.pdf"
}
let _object = DB.hotel.first('87cbe05a-904a-4255-b020-dd9d9ccedc3e');
await _data.uploadAttachment(_attachment, _object, 'broshure');
Cloud Code:
When accessing the Data Model of the current environment the Cloud Code task is running in, we only need to pass in the this.backend
object, which contains all the config cc-util-data
requires.
index.js:
// make sure config.js has the relevant credentials
const config = require('./config');
const ccUtilData = require('@journeyapps/cc-util-data');
export async function run() {
const _options = {
validateMediaUploaded: true
};
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
var _data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings']);
//Do something with the data
}
options
You have the ability to pass in some options, these define some behavior of the module. Below are the defaults.
/**
* Default options used by the util data
* @type {Object}
*/
const DEFAULT_OPTIONS = {
/**
* If true, signatures and photos will be validate for state=uploaded
* @type {Boolean}
*/
validateMediaUploaded?: true,
/**
* If true, the util wil auto download the images that it finds.
* @type {Boolean}
*/
preloadImages?: false,
/**
* Sets the default image to pre download
* @type {string} original | fullscreen | thumbnail
*/
preloadImageSize?: 'fullscreen',
/**
* Set the format to download the pre image in
* @type {string} buffer | base64
*/
preLoadImageFormat?: 'buffer',
/**
* Sets to false to hide all the logs that get printed
* @type {boolean}
*/
printLogs?: true,
/**
* Enable sorting of json result for easier navigation
*/
sorting?: true,
/**
* Items to sort to the top of the list
*/
sortToTop?: ['id', 'type', 'display']
/**
* Disables batch fetching in order to allow custom skipping in has many queries
* (Limit query parameters are required to keep queries smaller than 1000 objects)
*/
disableBatchFetching?: boolean
};
How To:
Signature/Photo:
A special flag
ready
gets added on every (not null) photo or signature field that can be used in handlebars to check if the signature has been uploaded. A signature can be directly reference by using a img object and passing in the URL. The PDF document compiler takes care of the rest.{{#if signature}} <div class="signature"> {{#if signature.ready}} <img class="img-responsive" src="{{signature.original}}"> {{/if}} </div> {{/if}}
Loading Images
You are able to preload images by setting the option flat
preloadImages
. You can also retrieve the images afterwards the same way you can with JourneyApps DB. Note,preloadImages
will fail if the image is not ready.
let _d = await _data.fetchData('6e59d067-7d41-4b7b-8794-d9de46b3a2b4', 'room');
// Original
let _url = await _d.photo.url;
let _buffer = await _d.photo.toBuffer();
let _base64 = await _d.photo.toBase64();
// Fullscreen
let _url = await _d.photo.fullscreen.url;
let _buffer = await _d.photo.fullscreen.toBuffer();
let _base64 = await _d.photo.fullscreen.toBase64();
// Thumbnail
let _url = await _d.photo.thumbnail.url;
let _buffer = await _d.photo.thumbnail.toBuffer();
let _base64 = await _d.photo.thumbnail.toBase64();
Adding queries to a
has_many
relationshipWhen dealing with a
has_many
relationship, you might only want to get the object with specific values. The queries are placed at the end of a related object between{
and}
. They only work forhas_many
relationships and can contain anything you can use with the Backend API. See https://docs.journeyapps.com/reference#api-querying-objects
// make sure config.js has the relevant credentials
const config = require('./config');
const ccUtilData = require('@journeyapps/cc-util-data');
export async function run() {
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
//Get bookings where the price is greater than 300
let _data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings{q[price.gt]=300}']);
//Get all the bookings for the family room
_data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms{q[name]=Family}', 'rooms.bookings']);
//Do something with the data
}
Use a different environment
We can specify a custom environment by explicitly adding the
url
,username
andpassword
to the configuration.config.js:
// KitchenSink Credentials used let config = { url: 'https://run-testing-us.journeyapps.com/api/v4/5989b1c2ecc8cf019e5d3db0', username: '<USERNAME>', password: '<PASSWORD>' } OR let config = { url: 'https://run-testing-us.journeyapps.com/api/v4/5e981f8e076011390e571e79', authorization: 'Bearer <TOKEN>' }
index.js:
// make sure config.js has the relevant credentials const config = require('./config'); const ccUtilData = require('@journeyapps/cc-util-data'); export async function run() { let _ccUtilData = new ccUtilData(config); //Pass in the custom config containing the credentials var _data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings']); //Do something with the data }
License
See the LICENSE file.