@ironcode/vas-lib 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1619,8 +1619,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1619
1619
  .filter(prop => !nativeProps.includes(prop));
1620
1620
  }
1621
1621
  /**
1622
- * Returns a list of Job static properties i.e. those that are declared by
1623
- * the type
1622
+ * Returns the list of properties of the Job type
1624
1623
  */
1625
1624
  get staticProperties() {
1626
1625
  return Object.getOwnPropertyNames(VasJobModel.empty());
@@ -1640,6 +1639,28 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1640
1639
  .forEach((key) => model.$this[key] = dto[key]);
1641
1640
  return model;
1642
1641
  }
1642
+ /**
1643
+ * This method will instantiate a new JobModel. The difference with this
1644
+ * method of instantiation is that we are coming from a relation frame i.e.
1645
+ * the job has a list of {@link VasFieldDto} instead of a Job document.
1646
+ *
1647
+ */
1648
+ static fromRelational(dto, form) {
1649
+ const model = new VasJobModel(dto.id || '', dto.created || '', dto.serverCreated || '', dto.createdBy || '', dto.modified || '', dto.serverModified || '', dto.modifiedBy || '', dto.createdByName || '', dto.modifiedByName || '', dto.account || '', dto.accessGroup || '', dto.reference || '', dto.jobDate || '', dto.jobStatus || '', dto.jobType || '', dto.assigneeId || '', dto.formId || '', dto.timeZoneOffset || moment$1().utcOffset(), dto.pendingFields || 0, dto.childModified || '', dto.version || 0, dto.fields || [], dto.files || [], dto.createdByDisplayName || '', dto.modifiedByDisplayName || '', dto.geoLocation || getEmptyGeoLocation());
1650
+ form.groups
1651
+ .forEach(group => {
1652
+ group.controls
1653
+ .forEach(control => {
1654
+ var _a;
1655
+ const field = (_a = dto.fields) === null || _a === void 0 ? void 0 : _a.find(f => f.control === control.id);
1656
+ if (!field) {
1657
+ return;
1658
+ }
1659
+ model.getGroup(group.name)[control.name] = field.value;
1660
+ });
1661
+ });
1662
+ return model;
1663
+ }
1643
1664
  /**
1644
1665
  * @param {VasFormModel} formModel
1645
1666
  * @return {Record<string, VasFieldDtoValue>}
@@ -1712,7 +1733,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1712
1733
  .length;
1713
1734
  // add total from files that are pending
1714
1735
  pending += this.files
1715
- .filter(value => value.status !== 'COMPLETED')
1736
+ .filter(value => value.status !== 'COMPLETE')
1716
1737
  .length;
1717
1738
  return {
1718
1739
  pending,
@@ -1720,18 +1741,63 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1720
1741
  };
1721
1742
  }
1722
1743
  /**
1723
- * This method will hydrate the `fields` property of the model. The reason for
1724
- * this is that we have different ways to store the field data. One way, is
1725
- * we store them as dynamic properties of the job. For example job.foo.bar,
1726
- * where `foo` is the name of a Group, and `bar` is the name of a control.
1727
- * Thus, when we create a job using a form in the client, the job object will
1728
- * have its static properties (id, account, reference etc), and also a number
1729
- * of dynamic properties determined by the Groups and Controls. This kind of
1730
- * object is nice to work with in certain circumstances. However, the api
1731
- * works differently. In the API a Job is a record, and references a number of
1732
- * Field records. Each Field stores the value. Comparing these two models we
1733
- * have:
1734
- * A) job with dynamic properties, e.g.
1744
+ * This method will return the dynamic property from the JobModel that
1745
+ * represent a group (from a form).
1746
+ *
1747
+ * @param name the name of the group
1748
+ * @param init if true (default) and group is not found, initialise an empty
1749
+ * group, otherwise throw an error
1750
+ */
1751
+ getGroup(name, init = true) {
1752
+ let prop;
1753
+ if (this.staticProperties.includes(name)) {
1754
+ throw Error(`invalid group name ${name}, not a dynamic property`);
1755
+ }
1756
+ else if (this.$this[name] === undefined) {
1757
+ if (init) {
1758
+ prop = this.$this[name] = {};
1759
+ }
1760
+ else {
1761
+ throw Error(`invalid group name ${name}, not found`);
1762
+ }
1763
+ }
1764
+ else {
1765
+ prop = this.$this[name];
1766
+ if (typeof prop !== 'object') {
1767
+ throw Error(`invalid group name ${name}, not an object`);
1768
+ }
1769
+ }
1770
+ return prop;
1771
+ }
1772
+ /**
1773
+ * @param path path segments
1774
+ */
1775
+ getValueByPath(path = []) {
1776
+ return getValueByPath(path, this.$this);
1777
+ }
1778
+ /**
1779
+ * In order to understand why we need this method it is important to
1780
+ * understand that within the system, Jobs can be represented in one of two
1781
+ * ways, document and relational.
1782
+ *
1783
+ * The important distinction is how values submitted by a form are stored.
1784
+ *
1785
+ * Jobs stored as documents (JSON objects) will store user values, as dynamic
1786
+ * properties of the document.
1787
+ *
1788
+ * Whereas, Jobs stored as relational, will store user values in an array of
1789
+ * {@link VasFieldDto} objects.
1790
+ *
1791
+ * Depending on where we are in the system, either one of these approaches can
1792
+ * be more useful than the other.
1793
+ *
1794
+ * This method, assumes that the JobModel has been instantiated from a
1795
+ * document representation, and serves to hydrate the fields array. In order
1796
+ * to achieve this, knowledge of the {@link VasFormDto} that created the job
1797
+ * is required.
1798
+ *
1799
+ *
1800
+ * Job in document representation
1735
1801
  * {
1736
1802
  * id: <guid>,
1737
1803
  * reference: "something"
@@ -1741,7 +1807,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1741
1807
  * }
1742
1808
  * }
1743
1809
  *
1744
- * B) job with fields
1810
+ * Job in relational representation
1745
1811
  * {
1746
1812
  * id: <guid>,
1747
1813
  * reference: "something"
@@ -1756,46 +1822,11 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1756
1822
  * ]
1757
1823
  * }
1758
1824
  *
1759
- * So, what this method does is given a JobModel in the form of A, read all
1760
- * of those dynamic properties and set them into `fields`. Doing this requires
1761
- * knowledge of the Form that was used to create the job. Moreover, since the
1762
- * dynamic properties do not contain the ids of the fields, we also allow to
1763
- * pass in a `controlFieldIdMap`. This map stores the mapping between Control
1764
- * and the Field that was created in the Job to store the value for that
1765
- * Control. This is useful, if for example you want to compare a Job in form A
1766
- * with a Job in form B, for example if you want to update the Job on the API
1767
- * with a Job that was saved by a client in form A.
1768
- *
1769
- * E.g.
1770
- * Client -> API: client requests form
1771
- * User -> Client: user fills in the form and submits
1772
- * Client -> Firestore: client saves the Job in form A i.e. dynamic props
1773
- * Firestore -> Function: A function is triggered to sync the job to the API
1774
- * Function -> API: Function checks if job already exists, it receives 404
1775
- * Function -> Function: The function calls `hydrateFields(...)`
1776
- * Function -> API: The function POST the Job to /jobs
1777
- * Function -> API: The function POST each field to /fields
1778
- *
1779
- * Similarly, if the user updates the job
1780
- * Client -> API: client requests form
1781
- * User -> Client: user fills in the form and submits an update
1782
- * Client -> Firestore: client saves the Job in form A i.e. dynamic props
1783
- * Firestore -> Function: A function is triggered to sync the job to the API
1784
- * Function -> API: Function checks if job already exists, it receives 200
1785
- * Function -> Function: The function calls `hydrateFields(...)` passing in
1786
- * the map is made by iterating over the fields it
1787
- * received from the API and storing the mappings
1788
- * between controlId and fieldId for each field
1789
- * Function -> API: The function PATCH the Job to /jobs
1790
- * Function -> API: The function POST/PATCH each field to /fields
1791
- * treated as new
1792
1825
  *
1793
- * @param {VasFormModel} formModel the VasFormModel that was used to create
1794
- * the job
1795
- * @param {Map<string, string>} controlFieldIdMap a mapping of control to
1796
- * field ids. This is used to determine whether a new id for the field should
1797
- * be generated, or to reuse an existing one from the map.
1798
- * @param {Array<string>} controlNames if a value is provided, it will be used
1826
+ * @param formModel the VasFormModel that was used to create the job
1827
+ * @param controlFieldIdMap This is used to determine the id each field.
1828
+ * Either one will be found in the map, or a new one is generated.
1829
+ * @param controlNames if a value is provided, it will be used
1799
1830
  * to filter the fields that are returned.
1800
1831
  * @return {Array<VasFieldDto>}
1801
1832
  */
@@ -1827,13 +1858,6 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1827
1858
  });
1828
1859
  this.fields = fields;
1829
1860
  }
1830
- /**
1831
- * @param {string[]} path path segments
1832
- * @return {void}
1833
- */
1834
- getValueByPath(path = []) {
1835
- return getValueByPath(path, this.$this);
1836
- }
1837
1861
  /**
1838
1862
  * A very non sophisticated way to set values in the job via paths
1839
1863
  *
@@ -1848,8 +1872,8 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1848
1872
  * }
1849
1873
  * }
1850
1874
  *
1851
- * @param {any} value the value to set
1852
- * @param {string[]} path path segments
1875
+ * @param value the value to set
1876
+ * @param path path segments
1853
1877
  */
1854
1878
  setValueByPath(value, path = []) {
1855
1879
  switch (path.length) {
@@ -1876,9 +1900,8 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1876
1900
  }
1877
1901
  }
1878
1902
  /**
1879
- * @param {boolean} staticOnly if true, will only output values for the static
1903
+ * @param staticOnly if true, will only output values for the static
1880
1904
  * properties in the dto
1881
- * @return {VasJobDto}
1882
1905
  */
1883
1906
  toDto(staticOnly = false) {
1884
1907
  if (staticOnly) {
@@ -1913,7 +1936,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1913
1936
  }
1914
1937
  const dto = {};
1915
1938
  [...this.staticProperties, ...this.dynamicProperties]
1916
- .forEach(prop => (dto)[prop] = this.$this[prop]);
1939
+ .forEach(prop => dto[prop] = this.$this[prop]);
1917
1940
  return dto;
1918
1941
  }
1919
1942
  /**
@@ -1940,7 +1963,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1940
1963
  *
1941
1964
  * @param {string} value a string with the syntax
1942
1965
  * @param {ParseSyntaxOptions} options
1943
- * @return {string} the results of parsing the syntax on this job
1966
+ * @return the results of parsing the syntax on this job
1944
1967
  */
1945
1968
  parseSyntax(value, options = {
1946
1969
  timeZoneOffset: 0
@@ -1974,7 +1997,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
1974
1997
  result = (this.getValueByPath(path) || '').toString();
1975
1998
  }
1976
1999
  else if (objectKey === 'fields') {
1977
- result = (getValueByPath(path, this.getFields2()) || '').toString();
2000
+ result = (getValueByPath(['fields.' + path.shift(), ...path], this.getFields2()) || '').toString();
1978
2001
  }
1979
2002
  else if (objectKey.length) {
1980
2003
  if (options.objects) {
@@ -2143,9 +2166,59 @@ class VasReportRequestModel extends VasAccountObjectModel {
2143
2166
  }
2144
2167
  }
2145
2168
 
2169
+ class VasVehicleModel extends VasAccountObjectModel {
2170
+ constructor(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account, registration, make, model) {
2171
+ super(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account);
2172
+ this.id = id;
2173
+ this.created = created;
2174
+ this.serverCreated = serverCreated;
2175
+ this.createdBy = createdBy;
2176
+ this.modified = modified;
2177
+ this.serverModified = serverModified;
2178
+ this.modifiedBy = modifiedBy;
2179
+ this.createdByName = createdByName;
2180
+ this.modifiedByName = modifiedByName;
2181
+ this.account = account;
2182
+ this.registration = registration;
2183
+ this.make = make;
2184
+ this.model = model;
2185
+ }
2186
+ static fromDto(dto) {
2187
+ return new VasVehicleModel(dto.id || '', dto.created || '', dto.serverCreated || '', dto.createdBy || '', dto.modified || '', dto.serverModified || '', dto.modifiedBy || '', dto.createdByName || '', dto.modifiedByName || '', dto.account || '', dto.registration || '', dto.make || '', dto.model || '');
2188
+ }
2189
+ toDto() {
2190
+ return {
2191
+ id: this.id,
2192
+ created: this.created,
2193
+ serverCreated: this.serverCreated,
2194
+ createdBy: this.createdBy,
2195
+ modified: this.modified,
2196
+ serverModified: this.serverModified,
2197
+ modifiedBy: this.modifiedBy,
2198
+ createdByName: this.createdByName,
2199
+ modifiedByName: this.modifiedByName,
2200
+ account: this.account,
2201
+ registration: this.registration,
2202
+ make: this.make,
2203
+ model: this.model
2204
+ };
2205
+ }
2206
+ toApiDto(options) {
2207
+ return {
2208
+ id: this.id,
2209
+ created: this.created,
2210
+ modified: this.modified,
2211
+ account: this.account,
2212
+ registration: this.registration,
2213
+ make: this.make,
2214
+ model: this.model
2215
+ };
2216
+ }
2217
+ }
2218
+
2146
2219
  /**
2147
2220
  * Generated bundle index. Do not edit.
2148
2221
  */
2149
2222
 
2150
- export { VasAccountIndexingMode, VasAccountObjectModel, VasBaseModel, VasBranchModel, VasContactModel, VasControlConfigDirection, VasControlModel, VasControlTypeModel, VasFieldModel, VasFileModel, VasFireUserModel, VasFormModel, VasGroupModel, VasInstructionJobFieldModel, VasInstructionJobModel, VasInstructionModel, VasInstructionProviderModel, VasInvitationModel, VasInvitationTypeEnum, VasJobDataModel, VasJobModel, VasMembershipModel, VasNoteModel, VasReportLayoutModel, VasReportModel, VasReportRequestModel, VasRestrictedAccountObjectModel, VasUserModel, getEmptyGeoLocation, isCameraControlValueV1, isFileDto };
2223
+ export { VasAccountIndexingMode, VasAccountObjectModel, VasBaseModel, VasBranchModel, VasContactModel, VasControlConfigDirection, VasControlModel, VasControlTypeModel, VasFieldModel, VasFileModel, VasFireUserModel, VasFormModel, VasGroupModel, VasInstructionJobFieldModel, VasInstructionJobModel, VasInstructionModel, VasInstructionProviderModel, VasInvitationModel, VasInvitationTypeEnum, VasJobDataModel, VasJobModel, VasMembershipModel, VasNoteModel, VasReportLayoutModel, VasReportModel, VasReportRequestModel, VasRestrictedAccountObjectModel, VasUserModel, VasVehicleModel, getEmptyGeoLocation, isCameraControlValueV1, isFileDto };
2151
2224
  //# sourceMappingURL=ironcode-vas-lib.mjs.map