testing dynamics gp integration

deepsource-autofix-76c6eb20
Dan Gowans 2023-03-06 13:51:07 -05:00
parent e58b9d32ab
commit fe12e1d172
30 changed files with 558 additions and 261 deletions

View File

@ -11,7 +11,10 @@ export const config = {
lotOccupancy: {}, lotOccupancy: {},
workOrders: {}, workOrders: {},
adminCleanup: {}, adminCleanup: {},
printPdf: {} printPdf: {},
dynamicsGP: {
integrationIsEnabled: false
}
} }
}; };
export default config; export default config;

View File

@ -13,7 +13,10 @@ export const config: Config = {
lotOccupancy: {}, lotOccupancy: {},
workOrders: {}, workOrders: {},
adminCleanup: {}, adminCleanup: {},
printPdf: {} printPdf: {},
dynamicsGP: {
integrationIsEnabled: false
}
} }
} }

View File

@ -48,4 +48,8 @@ config.settings.map.mapCityDefault = 'Sault Ste. Marie';
config.settings.workOrders.workOrderNumberLength = 6; config.settings.workOrders.workOrderNumberLength = 6;
config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7; config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7;
config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30; config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30;
config.settings.dynamicsGP = {
integrationIsEnabled: true,
lookupOrder: ['diamond/cashReceipt', 'invoice']
};
export default config; export default config;

View File

@ -66,4 +66,9 @@ config.settings.workOrders.workOrderNumberLength = 6
config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7 config.settings.workOrders.workOrderMilestoneDateRecentBeforeDays = 7
config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30 config.settings.workOrders.workOrderMilestoneDateRecentAfterDays = 30
config.settings.dynamicsGP = {
integrationIsEnabled: true,
lookupOrder: ['diamond/cashReceipt', 'invoice']
}
export default config export default config

View File

@ -8,4 +8,5 @@ config.users = {
canUpdate: ['*testUpdate'], canUpdate: ['*testUpdate'],
isAdmin: ['*testAdmin'] isAdmin: ['*testAdmin']
}; };
config.settings.dynamicsGP.integrationIsEnabled = false;
export default config; export default config;

View File

@ -13,4 +13,6 @@ config.users = {
isAdmin: ['*testAdmin'] isAdmin: ['*testAdmin']
} }
config.settings.dynamicsGP!.integrationIsEnabled = false
export default config export default config

View File

@ -1,5 +1,6 @@
import './polyfills.js'; import './polyfills.js';
import type * as configTypes from '../types/configTypes'; import type * as configTypes from '../types/configTypes';
import type { config as MSSQLConfig } from 'mssql';
export declare function getProperty(propertyName: 'application.applicationName'): string; export declare function getProperty(propertyName: 'application.applicationName'): string;
export declare function getProperty(propertyName: 'application.logoURL'): string; export declare function getProperty(propertyName: 'application.logoURL'): string;
export declare function getProperty(propertyName: 'application.httpPort'): number; export declare function getProperty(propertyName: 'application.httpPort'): number;
@ -48,4 +49,7 @@ export declare function getProperty(propertyName: 'settings.workOrders.calendarE
export declare function getProperty(propertyName: 'settings.workOrders.prints'): string[]; export declare function getProperty(propertyName: 'settings.workOrders.prints'): string[];
export declare function getProperty(propertyName: 'settings.adminCleanup.recordDeleteAgeDays'): number; export declare function getProperty(propertyName: 'settings.adminCleanup.recordDeleteAgeDays'): number;
export declare function getProperty(propertyName: 'settings.printPdf.contentDisposition'): 'attachment' | 'inline'; export declare function getProperty(propertyName: 'settings.printPdf.contentDisposition'): 'attachment' | 'inline';
export declare function getProperty(propertyName: 'settings.dynamicsGP.integrationIsEnabled'): boolean;
export declare function getProperty(propertyName: 'settings.dynamicsGP.mssqlConfig'): MSSQLConfig;
export declare function getProperty(propertyName: 'settings.dynamicsGP.lookupOrder'): configTypes.DynamicsGPLookup[];
export declare const keepAliveMillis: number; export declare const keepAliveMillis: number;

View File

@ -50,6 +50,8 @@ configFallbackValues.set('settings.workOrders.prints', [
]); ]);
configFallbackValues.set('settings.adminCleanup.recordDeleteAgeDays', 60); configFallbackValues.set('settings.adminCleanup.recordDeleteAgeDays', 60);
configFallbackValues.set('settings.printPdf.contentDisposition', 'attachment'); configFallbackValues.set('settings.printPdf.contentDisposition', 'attachment');
configFallbackValues.set('settings.dynamicsGP.integrationIsEnabled', false);
configFallbackValues.set('settings.dynamicsGP.lookupOrder', ['invoice']);
export function getProperty(propertyName) { export function getProperty(propertyName) {
const propertyNameSplit = propertyName.split('.'); const propertyNameSplit = propertyName.split('.');
let currentObject = config; let currentObject = config;

View File

@ -6,6 +6,9 @@ import { config } from '../data/config.js'
import type * as configTypes from '../types/configTypes' import type * as configTypes from '../types/configTypes'
// eslint-disable-next-line node/no-extraneous-import
import type { config as MSSQLConfig } from 'mssql'
/* /*
* SET UP FALLBACK VALUES * SET UP FALLBACK VALUES
*/ */
@ -94,6 +97,9 @@ configFallbackValues.set('settings.adminCleanup.recordDeleteAgeDays', 60)
configFallbackValues.set('settings.printPdf.contentDisposition', 'attachment') configFallbackValues.set('settings.printPdf.contentDisposition', 'attachment')
configFallbackValues.set('settings.dynamicsGP.integrationIsEnabled', false)
configFallbackValues.set('settings.dynamicsGP.lookupOrder', ['invoice'])
/* /*
* Set up function overloads * Set up function overloads
*/ */
@ -211,6 +217,18 @@ export function getProperty(
propertyName: 'settings.printPdf.contentDisposition' propertyName: 'settings.printPdf.contentDisposition'
): 'attachment' | 'inline' ): 'attachment' | 'inline'
export function getProperty(
propertyName: 'settings.dynamicsGP.integrationIsEnabled'
): boolean
export function getProperty(
propertyName: 'settings.dynamicsGP.mssqlConfig'
): MSSQLConfig
export function getProperty(
propertyName: 'settings.dynamicsGP.lookupOrder'
): configTypes.DynamicsGPLookup[]
export function getProperty(propertyName: string): unknown { export function getProperty(propertyName: string): unknown {
const propertyNameSplit = propertyName.split('.') const propertyNameSplit = propertyName.split('.')

View File

@ -0,0 +1,2 @@
import type { DynamicsGPDocument } from '../types/recordTypes.js';
export declare function getDynamicsGPDocument(documentNumber: string): Promise<DynamicsGPDocument | undefined>;

View File

@ -0,0 +1,62 @@
import * as gp from '@cityssm/dynamics-gp/gp.js';
import * as diamond from '@cityssm/dynamics-gp/diamond.js';
import * as configFunctions from './functions.config.js';
if (configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled')) {
gp.setMSSQLConfig(configFunctions.getProperty('settings.dynamicsGP.mssqlConfig'));
diamond.setMSSQLConfig(configFunctions.getProperty('settings.dynamicsGP.mssqlConfig'));
}
async function _getDynamicsGPDocument(documentNumber, lookupType) {
let document;
switch (lookupType) {
case 'invoice': {
const invoice = await gp.getInvoiceByInvoiceNumber(documentNumber);
if (invoice) {
document = {
documentType: 'Invoice',
documentNumber: invoice.invoiceNumber,
documentDate: invoice.documentDate,
documentDescription: [
invoice.comment1,
invoice.comment2,
invoice.comment3,
invoice.comment4
],
documentTotal: invoice.documentAmount
};
}
break;
}
case 'diamond/cashReceipt': {
const receipt = await diamond.getCashReceiptByDocumentNumber(documentNumber);
if (receipt) {
document = {
documentType: 'Cash Receipt',
documentNumber: receipt.documentNumber.toString(),
documentDate: receipt.documentDate,
documentDescription: [
receipt.description,
receipt.description2,
receipt.description3,
receipt.description4,
receipt.description5
],
documentTotal: receipt.total
};
}
}
}
return document;
}
export async function getDynamicsGPDocument(documentNumber) {
if (!configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled')) {
return;
}
let document;
for (const lookupType of configFunctions.getProperty('settings.dynamicsGP.lookupOrder')) {
document = await _getDynamicsGPDocument(documentNumber, lookupType);
if (document !== undefined) {
break;
}
}
return document;
}

View File

@ -0,0 +1,95 @@
/* eslint-disable unicorn/filename-case */
import * as gp from '@cityssm/dynamics-gp/gp.js'
import * as diamond from '@cityssm/dynamics-gp/diamond.js'
import * as configFunctions from './functions.config.js'
import type { DynamicsGPLookup } from '../types/configTypes'
import type { DynamicsGPDocument } from '../types/recordTypes.js'
if (configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled')) {
gp.setMSSQLConfig(
configFunctions.getProperty('settings.dynamicsGP.mssqlConfig')
)
diamond.setMSSQLConfig(
configFunctions.getProperty('settings.dynamicsGP.mssqlConfig')
)
}
async function _getDynamicsGPDocument(
documentNumber: string,
lookupType: DynamicsGPLookup
): Promise<DynamicsGPDocument | undefined> {
let document: DynamicsGPDocument | undefined
switch (lookupType) {
case 'invoice': {
const invoice = await gp.getInvoiceByInvoiceNumber(documentNumber)
if (invoice) {
document = {
documentType: 'Invoice',
documentNumber: invoice.invoiceNumber,
documentDate: invoice.documentDate,
documentDescription: [
invoice.comment1,
invoice.comment2,
invoice.comment3,
invoice.comment4
],
documentTotal: invoice.documentAmount
}
}
break
}
case 'diamond/cashReceipt': {
const receipt = await diamond.getCashReceiptByDocumentNumber(
documentNumber
)
if (receipt) {
document = {
documentType: 'Cash Receipt',
documentNumber: receipt.documentNumber.toString(),
documentDate: receipt.documentDate,
documentDescription: [
receipt.description,
receipt.description2,
receipt.description3,
receipt.description4,
receipt.description5
],
documentTotal: receipt.total
}
}
}
}
return document
}
export async function getDynamicsGPDocument(
documentNumber: string
): Promise<DynamicsGPDocument | undefined> {
if (
!configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled')
) {
return
}
let document: DynamicsGPDocument | undefined
for (const lookupType of configFunctions.getProperty(
'settings.dynamicsGP.lookupOrder'
)) {
document = await _getDynamicsGPDocument(documentNumber, lookupType)
if (document !== undefined) {
break
}
}
return document
}

View File

@ -1,5 +1,7 @@
import { acquireConnection } from './pool.js'; import { acquireConnection } from './pool.js';
import { dateIntegerToString, timeIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js'; import { dateIntegerToString, timeIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js';
import * as configFunctions from '../functions.config.js';
import * as gpFunctions from '../functions.dynamicsGP.js';
export async function getLotOccupancyTransactions(lotOccupancyId, connectedDatabase) { export async function getLotOccupancyTransactions(lotOccupancyId, connectedDatabase) {
const database = connectedDatabase ?? (await acquireConnection()); const database = connectedDatabase ?? (await acquireConnection());
database.function('userFn_dateIntegerToString', dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString);
@ -17,6 +19,16 @@ export async function getLotOccupancyTransactions(lotOccupancyId, connectedDatab
if (connectedDatabase === undefined) { if (connectedDatabase === undefined) {
database.release(); database.release();
} }
if (configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled')) {
for (const transaction of lotOccupancyTransactions) {
if ((transaction.externalReceiptNumber ?? '') !== '') {
const gpDocument = await gpFunctions.getDynamicsGPDocument(transaction.externalReceiptNumber);
if (gpDocument !== undefined) {
transaction.dynamicsGPDocument = gpDocument;
}
}
}
}
return lotOccupancyTransactions; return lotOccupancyTransactions;
} }
export default getLotOccupancyTransactions; export default getLotOccupancyTransactions;

View File

@ -6,6 +6,9 @@ import {
timeIntegerToString timeIntegerToString
} from '@cityssm/expressjs-server-js/dateTimeFns.js' } from '@cityssm/expressjs-server-js/dateTimeFns.js'
import * as configFunctions from '../functions.config.js'
import * as gpFunctions from '../functions.dynamicsGP.js'
import type * as recordTypes from '../../types/recordTypes' import type * as recordTypes from '../../types/recordTypes'
export async function getLotOccupancyTransactions( export async function getLotOccupancyTransactions(
@ -35,6 +38,20 @@ export async function getLotOccupancyTransactions(
database.release() database.release()
} }
if (configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled')) {
for (const transaction of lotOccupancyTransactions) {
if ((transaction.externalReceiptNumber ?? '') !== '') {
const gpDocument = await gpFunctions.getDynamicsGPDocument(
transaction.externalReceiptNumber!
)
if (gpDocument !== undefined) {
transaction.dynamicsGPDocument = gpDocument
}
}
}
}
return lotOccupancyTransactions return lotOccupancyTransactions
} }

429
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
}, },
"scripts": { "scripts": {
"start": "cross-env NODE_ENV=production node ./bin/www", "start": "cross-env NODE_ENV=production node ./bin/www",
"dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/www.js", "dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:*,dynamics-gp:* TEST_DATABASES=true nodemon ./bin/www.js",
"dev:test:process": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/wwwProcess.js", "dev:test:process": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/wwwProcess.js",
"dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon ./bin/www.js", "dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon ./bin/www.js",
"cy:open": "cypress open --config-file cypress.config.js", "cy:open": "cypress open --config-file cypress.config.js",
@ -36,6 +36,7 @@
"@cityssm/bulma-js": "^0.4.0", "@cityssm/bulma-js": "^0.4.0",
"@cityssm/bulma-webapp-js": "^1.5.0", "@cityssm/bulma-webapp-js": "^1.5.0",
"@cityssm/date-diff": "^2.2.3", "@cityssm/date-diff": "^2.2.3",
"@cityssm/dynamics-gp": "^0.2.1",
"@cityssm/expressjs-server-js": "^2.3.3", "@cityssm/expressjs-server-js": "^2.3.3",
"@cityssm/ntfy-publish": "^0.2.1", "@cityssm/ntfy-publish": "^0.2.1",
"@cityssm/pdf-puppeteer": "^2.0.0-beta.1", "@cityssm/pdf-puppeteer": "^2.0.0-beta.1",
@ -90,13 +91,14 @@
"@types/http-errors": "^2.0.1", "@types/http-errors": "^2.0.1",
"@types/leaflet": "^1.9.1", "@types/leaflet": "^1.9.1",
"@types/mocha": "^10.0.1", "@types/mocha": "^10.0.1",
"@types/mssql": "^8.1.2",
"@types/node-windows": "^0.1.2", "@types/node-windows": "^0.1.2",
"@types/papaparse": "^5.3.7", "@types/papaparse": "^5.3.7",
"@types/randomcolor": "^0.5.7", "@types/randomcolor": "^0.5.7",
"@types/session-file-store": "^1.2.2", "@types/session-file-store": "^1.2.2",
"@types/uuid": "^9.0.1", "@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.54.0", "@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.0", "@typescript-eslint/parser": "^5.54.1",
"axe-core": "^4.6.3", "axe-core": "^4.6.3",
"bulma": "^0.9.4", "bulma": "^0.9.4",
"bulma-divider": "^0.2.0", "bulma-divider": "^0.2.0",

View File

@ -1455,14 +1455,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
tableRowElement.className = 'container--lotOccupancyTransaction'; tableRowElement.className = 'container--lotOccupancyTransaction';
tableRowElement.dataset.transactionIndex = tableRowElement.dataset.transactionIndex =
lotOccupancyTransaction.transactionIndex.toString(); lotOccupancyTransaction.transactionIndex.toString();
let externalReceiptNumberHTML = '';
if (lotOccupancyTransaction.externalReceiptNumber !== '') {
externalReceiptNumberHTML = cityssm.escapeHTML((_a = lotOccupancyTransaction.externalReceiptNumber) !== null && _a !== void 0 ? _a : '');
if (los.dynamicsGPIntegrationIsEnabled) {
if (lotOccupancyTransaction.dynamicsGPDocument === undefined) {
externalReceiptNumberHTML += ` <span data-tooltip="No Matching Document Found">
<i class="fas fa-times-circle has-text-danger" aria-label="No Matching Document Found"></i>
</span>`;
}
else {
externalReceiptNumberHTML +=
lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2) === lotOccupancyTransaction.transactionAmount.toFixed(2)
? ` <span data-tooltip="Matching Document Found">
<i class="fas fa-check-circle has-text-success" aria-label="Matching Document Found"></i>
</span>`
: ` <span data-tooltip="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}">
<i class="fas fa-check-circle has-text-warning" aria-label="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}"></i>
</span>`;
}
}
externalReceiptNumberHTML += '<br />';
}
tableRowElement.innerHTML = tableRowElement.innerHTML =
'<td>' + '<td>' +
((_a = lotOccupancyTransaction.transactionDateString) !== null && _a !== void 0 ? _a : '') + ((_b = lotOccupancyTransaction.transactionDateString) !== null && _b !== void 0 ? _b : '') +
'</td>' + '</td>' +
('<td>' + ('<td>' +
(lotOccupancyTransaction.externalReceiptNumber === '' externalReceiptNumberHTML +
? ''
: cityssm.escapeHTML((_b = lotOccupancyTransaction.externalReceiptNumber) !== null && _b !== void 0 ? _b : '') + '<br />') +
'<small>' + '<small>' +
cityssm.escapeHTML((_c = lotOccupancyTransaction.transactionNote) !== null && _c !== void 0 ? _c : '') + cityssm.escapeHTML((_c = lotOccupancyTransaction.transactionNote) !== null && _c !== void 0 ? _c : '') +
'</small>' + '</small>' +

View File

@ -365,14 +365,34 @@ function renderLotOccupancyTransactions() {
tableRowElement.className = 'container--lotOccupancyTransaction'; tableRowElement.className = 'container--lotOccupancyTransaction';
tableRowElement.dataset.transactionIndex = tableRowElement.dataset.transactionIndex =
lotOccupancyTransaction.transactionIndex.toString(); lotOccupancyTransaction.transactionIndex.toString();
let externalReceiptNumberHTML = '';
if (lotOccupancyTransaction.externalReceiptNumber !== '') {
externalReceiptNumberHTML = cityssm.escapeHTML((_a = lotOccupancyTransaction.externalReceiptNumber) !== null && _a !== void 0 ? _a : '');
if (los.dynamicsGPIntegrationIsEnabled) {
if (lotOccupancyTransaction.dynamicsGPDocument === undefined) {
externalReceiptNumberHTML += ` <span data-tooltip="No Matching Document Found">
<i class="fas fa-times-circle has-text-danger" aria-label="No Matching Document Found"></i>
</span>`;
}
else {
externalReceiptNumberHTML +=
lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2) === lotOccupancyTransaction.transactionAmount.toFixed(2)
? ` <span data-tooltip="Matching Document Found">
<i class="fas fa-check-circle has-text-success" aria-label="Matching Document Found"></i>
</span>`
: ` <span data-tooltip="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}">
<i class="fas fa-check-circle has-text-warning" aria-label="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}"></i>
</span>`;
}
}
externalReceiptNumberHTML += '<br />';
}
tableRowElement.innerHTML = tableRowElement.innerHTML =
'<td>' + '<td>' +
((_a = lotOccupancyTransaction.transactionDateString) !== null && _a !== void 0 ? _a : '') + ((_b = lotOccupancyTransaction.transactionDateString) !== null && _b !== void 0 ? _b : '') +
'</td>' + '</td>' +
('<td>' + ('<td>' +
(lotOccupancyTransaction.externalReceiptNumber === '' externalReceiptNumberHTML +
? ''
: cityssm.escapeHTML((_b = lotOccupancyTransaction.externalReceiptNumber) !== null && _b !== void 0 ? _b : '') + '<br />') +
'<small>' + '<small>' +
cityssm.escapeHTML((_c = lotOccupancyTransaction.transactionNote) !== null && _c !== void 0 ? _c : '') + cityssm.escapeHTML((_c = lotOccupancyTransaction.transactionNote) !== null && _c !== void 0 ? _c : '') +
'</small>' + '</small>' +

View File

@ -515,16 +515,45 @@ function renderLotOccupancyTransactions(): void {
tableRowElement.dataset.transactionIndex = tableRowElement.dataset.transactionIndex =
lotOccupancyTransaction.transactionIndex!.toString() lotOccupancyTransaction.transactionIndex!.toString()
let externalReceiptNumberHTML = ''
if (lotOccupancyTransaction.externalReceiptNumber !== '') {
externalReceiptNumberHTML = cityssm.escapeHTML(
lotOccupancyTransaction.externalReceiptNumber ?? ''
)
if (los.dynamicsGPIntegrationIsEnabled) {
if (lotOccupancyTransaction.dynamicsGPDocument === undefined) {
externalReceiptNumberHTML += ` <span data-tooltip="No Matching Document Found">
<i class="fas fa-times-circle has-text-danger" aria-label="No Matching Document Found"></i>
</span>`
} else {
externalReceiptNumberHTML +=
lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(
2
) === lotOccupancyTransaction.transactionAmount.toFixed(2)
? ` <span data-tooltip="Matching Document Found">
<i class="fas fa-check-circle has-text-success" aria-label="Matching Document Found"></i>
</span>`
: ` <span data-tooltip="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(
2
)}">
<i class="fas fa-check-circle has-text-warning" aria-label="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(
2
)}"></i>
</span>`
}
}
externalReceiptNumberHTML += '<br />'
}
tableRowElement.innerHTML = tableRowElement.innerHTML =
'<td>' + '<td>' +
(lotOccupancyTransaction.transactionDateString ?? '') + (lotOccupancyTransaction.transactionDateString ?? '') +
'</td>' + '</td>' +
('<td>' + ('<td>' +
(lotOccupancyTransaction.externalReceiptNumber === '' externalReceiptNumberHTML +
? ''
: cityssm.escapeHTML(
lotOccupancyTransaction.externalReceiptNumber ?? ''
) + '<br />') +
'<small>' + '<small>' +
cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '') + cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '') +
'</small>' + '</small>' +

View File

@ -378,12 +378,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
function getWorkOrderURL(workOrderId = '', edit = false, time = false) { function getWorkOrderURL(workOrderId = '', edit = false, time = false) {
return getRecordURL('workOrders', workOrderId, edit, time); return getRecordURL('workOrders', workOrderId, edit, time);
} }
/*
* Settings
*/
const dynamicsGPIntegrationIsEnabled = exports.dynamicsGPIntegrationIsEnabled;
/* /*
* Declare LOS * Declare LOS
*/ */
const los = { const los = {
urlPrefix, urlPrefix,
apiKey: document.querySelector('main').dataset.apiKey, apiKey: document.querySelector('main').dataset.apiKey,
dynamicsGPIntegrationIsEnabled,
highlightMap, highlightMap,
initializeUnlockFieldButtons, initializeUnlockFieldButtons,
initializeDatePickers, initializeDatePickers,

View File

@ -520,6 +520,12 @@ declare const bulmaJS: BulmaJS
return getRecordURL('workOrders', workOrderId, edit, time) return getRecordURL('workOrders', workOrderId, edit, time)
} }
/*
* Settings
*/
const dynamicsGPIntegrationIsEnabled = exports.dynamicsGPIntegrationIsEnabled as boolean
/* /*
* Declare LOS * Declare LOS
*/ */
@ -527,6 +533,7 @@ declare const bulmaJS: BulmaJS
const los: globalTypes.LOS = { const los: globalTypes.LOS = {
urlPrefix, urlPrefix,
apiKey: document.querySelector('main')!.dataset.apiKey!, apiKey: document.querySelector('main')!.dataset.apiKey!,
dynamicsGPIntegrationIsEnabled,
highlightMap, highlightMap,
initializeUnlockFieldButtons, initializeUnlockFieldButtons,
initializeDatePickers, initializeDatePickers,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,4 @@
import type { config as MSSQLConfig } from 'mssql';
export interface Config { export interface Config {
application: ConfigApplication; application: ConfigApplication;
session: ConfigSession; session: ConfigSession;
@ -60,8 +61,14 @@ export interface Config {
printPdf: { printPdf: {
contentDisposition?: 'attachment' | 'inline'; contentDisposition?: 'attachment' | 'inline';
}; };
dynamicsGP?: {
integrationIsEnabled: boolean;
mssqlConfig?: MSSQLConfig;
lookupOrder?: DynamicsGPLookup[];
};
}; };
} }
export type DynamicsGPLookup = 'diamond/cashReceipt' | 'invoice';
interface ConfigApplication { interface ConfigApplication {
applicationName?: string; applicationName?: string;
backgroundURL?: string; backgroundURL?: string;

View File

@ -1,3 +1,5 @@
import type { config as MSSQLConfig } from 'mssql'
export interface Config { export interface Config {
application: ConfigApplication application: ConfigApplication
session: ConfigSession session: ConfigSession
@ -60,9 +62,16 @@ export interface Config {
printPdf: { printPdf: {
contentDisposition?: 'attachment' | 'inline' contentDisposition?: 'attachment' | 'inline'
} }
dynamicsGP?: {
integrationIsEnabled: boolean
mssqlConfig?: MSSQLConfig
lookupOrder?: DynamicsGPLookup[]
}
} }
} }
export type DynamicsGPLookup = 'diamond/cashReceipt' | 'invoice'
interface ConfigApplication { interface ConfigApplication {
applicationName?: string applicationName?: string
backgroundURL?: string backgroundURL?: string

View File

@ -31,6 +31,7 @@ export interface LOS {
WorkOrderCloseDate: string; WorkOrderCloseDate: string;
workOrderCloseDate: string; workOrderCloseDate: string;
}; };
dynamicsGPIntegrationIsEnabled: boolean;
getRandomColor: (seedString: string) => string; getRandomColor: (seedString: string) => string;
setUnsavedChanges: () => void; setUnsavedChanges: () => void;
clearUnsavedChanges: () => void; clearUnsavedChanges: () => void;

View File

@ -42,6 +42,8 @@ export interface LOS {
workOrderCloseDate: string workOrderCloseDate: string
} }
dynamicsGPIntegrationIsEnabled: boolean
getRandomColor: (seedString: string) => string getRandomColor: (seedString: string) => string
setUnsavedChanges: () => void setUnsavedChanges: () => void

View File

@ -145,6 +145,14 @@ export interface LotOccupancyTransaction extends Record {
transactionAmount: number; transactionAmount: number;
externalReceiptNumber?: string; externalReceiptNumber?: string;
transactionNote?: string; transactionNote?: string;
dynamicsGPDocument?: DynamicsGPDocument;
}
export interface DynamicsGPDocument {
documentType: 'Invoice' | 'Cash Receipt';
documentNumber: string;
documentDate: Date;
documentDescription: string[];
documentTotal: number;
} }
export interface LotOccupancyOccupant extends Record { export interface LotOccupancyOccupant extends Record {
lotOccupancyId?: number; lotOccupancyId?: number;

View File

@ -191,6 +191,15 @@ export interface LotOccupancyTransaction extends Record {
transactionAmount: number transactionAmount: number
externalReceiptNumber?: string externalReceiptNumber?: string
transactionNote?: string transactionNote?: string
dynamicsGPDocument?: DynamicsGPDocument
}
export interface DynamicsGPDocument {
documentType: 'Invoice' | 'Cash Receipt'
documentNumber: string
documentDate: Date
documentDescription: string[]
documentTotal: number
} }
export interface LotOccupancyOccupant extends Record { export interface LotOccupancyOccupant extends Record {

View File

@ -27,6 +27,7 @@
workOrderOpenDate: "<%= configFunctions.getProperty('aliases.workOrderOpenDate') %>", workOrderOpenDate: "<%= configFunctions.getProperty('aliases.workOrderOpenDate') %>",
workOrderCloseDate: "<%= configFunctions.getProperty('aliases.workOrderCloseDate') %>" workOrderCloseDate: "<%= configFunctions.getProperty('aliases.workOrderCloseDate') %>"
}; };
exports.dynamicsGPIntegrationIsEnabled = <%= configFunctions.getProperty('settings.dynamicsGP.integrationIsEnabled') %>;
</script> </script>
<script src="<%= urlPrefix %>/lib/cityssm-bulma-js/bulma-js.js"></script> <script src="<%= urlPrefix %>/lib/cityssm-bulma-js/bulma-js.js"></script>
<script src="<%= urlPrefix %>/lib/cityssm-bulma-webapp-js/cityssm.min.js"></script> <script src="<%= urlPrefix %>/lib/cityssm-bulma-webapp-js/cityssm.min.js"></script>