Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit 869338b

Browse files
authored
Merge pull request #44 from ZERO-Q-Ltd/Kamana
stable
2 parents cbfbbab + 3d5c23b commit 869338b

File tree

83 files changed

+2311
-3715
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+2311
-3715
lines changed

functions/package-lock.json

+407-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

functions/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"bluebird": "^3.7.0",
1717
"firebase-admin": "^8.6.0",
1818
"firebase-functions": "^3.2.0",
19+
"intuit-oauth": "^2.0.2",
1920
"jxon": "^2.0.0-beta.5",
2021
"lodash": "^4.17.15",
2122
"moment": "^2.24.0",
@@ -36,4 +37,4 @@
3637
"node": "8"
3738
},
3839
"private": true
39-
}
40+
}

functions/src/index.ts

+91-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
import * as admin from "firebase-admin";
22
import * as functions from 'firebase-functions';
3+
import * as requester from "request";
34
import { QuickBooks } from './libs/qbmain';
45
import { CompanySync } from "./models/Cloud/CompanySync";
56
import { OrderCreate } from './models/Cloud/OrderCreate';
6-
import { DaudiCustomer, emptyDaudiCustomer } from './models/Daudi/customer/Customer';
7+
import { EmptyQboConfig } from "./models/Cloud/QboEnvironment";
8+
import { emptyDaudiCustomer } from './models/Daudi/customer/Customer';
9+
import { Order } from "./models/Daudi/order/Order";
710
import { SMS } from './models/Daudi/sms/sms';
811
import { MyTimestamp } from './models/firestore/firestoreTypes';
12+
import { QboOrder } from "./models/Qbo/QboOrder";
13+
import { toObject } from "./models/utils/SnapshotUtils";
914
import { creteOrder, updateOrder } from './tasks/crud/daudi/Order';
15+
import { ReadAndInstantiate, readQboConfig } from "./tasks/crud/daudi/QboConfig";
1016
import { updateCustomer } from './tasks/crud/qbo/customer/update';
1117
import { createQboOrder } from './tasks/crud/qbo/Order/create';
12-
import { createQbo } from './tasks/sharedqb';
1318
import { sendsms } from './tasks/sms/sms';
1419
import { ordersms } from './tasks/sms/smscompose';
1520
import { processSync } from './tasks/syncdb/processSync';
1621
import { validorderupdate } from './validators/orderupdate';
17-
import { readQboConfig, ReadAndInstantiate } from "./tasks/crud/daudi/QboConfig";
18-
import { toArray, toObject } from "./models/utils/SnapshotUtils";
19-
import { EmptyQboConfig, QboCofig } from "./models/Cloud/QboEnvironment";
20-
import { QboOrder } from "./models/Qbo/QboOrder";
21-
import { Order } from "./models/Daudi/order/Order";
22-
import * as requester from "request";
22+
import { createQbo } from "./tasks/sharedqb";
23+
import { EquityBulk } from "./models/ipn/EquityBulk";
24+
import { paymentFcm } from "./tasks/FCM/paymentFcm";
25+
import { resolveIpn } from "./tasks/resolvepayment";
2326

2427
admin.initializeApp(functions.config().firebase);
2528
admin.firestore().settings({ timestampsInSnapshots: true });
@@ -39,10 +42,11 @@ function markAsRunning(eventID: string) {
3942
*/
4043
exports.createEstimate = functions.https.onCall((data: OrderCreate, context) => {
4144
console.log(data)
45+
// return creteOrder(data.order, data.omcId)
46+
4247
return ReadAndInstantiate(data.omcId).then((result) => {
4348
console.log(result.qbo)
44-
const est = new createQboOrder(data.order, result.config)
45-
return result.qbo.createEstimate(est.formulate()).then((createResult) => {
49+
return result.qbo.createEstimate(new createQboOrder(data.order, result.config).QboOrder).then((createResult) => {
4650
/**
4751
* Only send sn SMS when estimate creation is complete
4852
* Make the two processes run parallel so that none is blocking
@@ -60,8 +64,7 @@ exports.createInvoice = functions.https.onCall((data: OrderCreate, context) => {
6064
console.log(data)
6165
return ReadAndInstantiate(data.omcId).then((result) => {
6266
console.log(result.qbo)
63-
const inv = new createQboOrder(data.order, result.config)
64-
return result.qbo.createInvoice(inv.formulate()).then((createResult) => {
67+
return result.qbo.createInvoice(new createQboOrder(data.order, result.config).QboOrder).then((createResult) => {
6568
/**
6669
* Only send sn SMS when invoice creation is complete
6770
* Make the two processes run parallel so that none is blocking
@@ -258,3 +261,79 @@ exports.onUserStatusChanged = functions.database
258261
});
259262
}
260263
});
264+
265+
exports.ipnsandbox_db = functions.firestore
266+
.document("/sandboxpayments/{ipnid}")
267+
.onCreate((snap, context) => {
268+
// console.log(snap);
269+
// A new customer has been updated
270+
const eventID = context.eventId;
271+
if (isAlreadyRunning(eventID)) {
272+
console.log(
273+
"Ignore it because it is already running (eventId):",
274+
eventID
275+
);
276+
return true;
277+
}
278+
markAsRunning(eventID);
279+
const ipn = snap.data() as EquityBulk;
280+
return resolveIpn(ipn, context.params.ipnid).then(() => {
281+
ipn.daudiFields.status = 2;
282+
return paymentFcm(ipn);
283+
});
284+
});
285+
exports.ipnprod_db = functions.firestore
286+
.document("/prodpayments/{ipnid}")
287+
.onCreate((snap, context) => {
288+
// console.log(snap);
289+
// A new customer has been updated
290+
const eventID = context.eventId;
291+
if (isAlreadyRunning(eventID)) {
292+
console.log(
293+
"Ignore it because it is already running (eventId):",
294+
eventID
295+
);
296+
return true;
297+
} else {
298+
markAsRunning(eventID);
299+
const ipn = snap.data() as EquityBulk;
300+
return resolveIpn(ipn, context.params.ipnid).then(() => {
301+
ipn.daudiFields.status = 2;
302+
return paymentFcm(ipn);
303+
});
304+
}
305+
});
306+
307+
/**
308+
* a way for the client app to execute a cloud function directly
309+
*/
310+
311+
exports.ipnsandboxcallable = functions.https.onCall((data, context) => {
312+
const ipn = data as EquityBulk;
313+
console.log(data);
314+
return resolveIpn(ipn, ipn.billNumber.toString()).then(() => {
315+
/**
316+
* force the fcm to send a payment received msg, because otherwise the new ipn data wont be known
317+
* unless we make a db read before sending, which at this point is unneccessary
318+
*/
319+
ipn.daudiFields.status = 2;
320+
return paymentFcm(ipn);
321+
});
322+
});
323+
324+
/**
325+
* a way for the client app to execute a cloud function directly
326+
*/
327+
328+
exports.ipnprodcallable = functions.https.onCall((data, context) => {
329+
const ipn = data as EquityBulk;
330+
console.log(data);
331+
return resolveIpn(ipn, ipn.billNumber.toString()).then(() => {
332+
/**
333+
* force the fcm to send a payment received msg, because otherwise the new ipn data wont be known
334+
* unless we make a db read before sending, which at this point is unneccessary
335+
*/
336+
ipn.daudiFields.status = 2;
337+
return paymentFcm(ipn);
338+
});
339+
});

functions/src/libs/qbmain.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { Bill } from "../models/Qbo/Bill";
2121

2222
const version = "2.0.24";
2323
const APP_CENTER_BASE = "https://appcenter.intuit.com";
24-
const V3_endpoint_BASE_URL = "https://sandbox-quickbooks.api.intuit.com/v3/company/";
24+
const V3_endpoint_BASE_URL = "https://quickbooks.api.intuit.com/v3/company/";
2525
const QUERY_OPERATORS = ["=", "IN", "<", ">", "<=", ">=", "LIKE"];
2626
const RECONNECT_URL = APP_CENTER_BASE + "/api/v1/connection/reconnect";
2727
const DISCONNECT_URL = APP_CENTER_BASE + "/api/v1/connection/disconnect";
@@ -2324,12 +2324,12 @@ function request(verb: string, options: any, entity): Promise<any> {
23242324
}
23252325
return new Promise(function (resolve, reject) {
23262326
// if (!token) reject('null token')
2327-
requester(opts, function (err, res, body) {
2327+
requester(opts, (err, res, body) => {
23282328
if (debug) {
23292329
console.log("invoking endpoint: " + url);
2330-
console.log(entity || "");
2330+
console.log(util.inspect(entity, false, null, false /* enable colors */) || "");
23312331
// console.log(opts)
2332-
console.log(JSON.stringify(body, null, 2));
2332+
console.log(util.inspect(body, false, null, false /* enable colors */));
23332333
}
23342334
if (err ||
23352335
res.statusCode >= 300 ||

functions/src/models/Cloud/QboAuthConfig.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ export const EmptyQBOAuthCOnfig: QBOAuthCOnfig = {
1616
authConfig: null,
1717
}
1818
export interface AuthConfig {
19-
previousDCT: MyTimestamp;
2019
accessToken: string;
2120
refreshToken: string;
22-
accesstokenExpiry: MyTimestamp;
23-
refreshtokenExpiry: MyTimestamp;
24-
time: MyTimestamp;
21+
createdAt: MyTimestamp;
2522
}
+28-23
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
1-
import {deepCopy} from '../../../models/utils/deepCopy';
2-
import {MyTimestamp} from '../../firestore/firestoreTypes';
3-
import {BaseStockModel} from './BaseStockModel';
4-
import {QbRef} from './QbRef';
5-
import {EmptyStockQty, StockQty} from './StockQty';
1+
import { deepCopy } from "../../../models/utils/deepCopy";
2+
import { MyTimestamp } from "../../firestore/firestoreTypes";
3+
import { BaseStockModel } from "./BaseStockModel";
4+
import { QbRef } from "./QbRef";
5+
import { EmptyStockQty, StockQty } from "./StockQty";
66

7-
export interface ASE extends BaseStockModel {
7+
export interface ASE extends Omit<BaseStockModel, "qty"> {
88
ase: QbRef;
9+
qty: number;
910
}
1011

11-
export const emptyASEs: ASE = {
12-
Id: null,
13-
fuelType: null,
14-
Amount: null,
15-
ase: {
16-
QbId: null,
17-
qty: 0
18-
},
19-
price: 0,
20-
qty: deepCopy<StockQty>(EmptyStockQty),
21-
depot: {
22-
name: null,
23-
Id: null
24-
},
25-
active: false,
26-
date: new MyTimestamp(0, 0)
27-
};
12+
export function newAse(): ASE {
13+
return {
14+
...{
15+
Id: null,
16+
fuelType: null,
17+
Amount: null,
18+
ase: {
19+
QbId: null,
20+
qty: 0
21+
},
22+
price: 0,
23+
qty: 0,
24+
depot: {
25+
name: null,
26+
Id: null
27+
},
28+
active: false,
29+
date: new MyTimestamp(0, 0)
30+
}
31+
};
32+
}
+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
export interface QbRef {
22
QbId: string;
3+
/**
4+
* Sometimes we concartenate different Qb Objects to the same value
5+
* In the case of entry where the same entryId canot be repeated
6+
* It is thus important to keep a separate copy of the quantity here
7+
* This value is not used for calcuations and is Created ONLY ONCE
8+
*/
39
qty: number;
410
}

functions/src/models/Daudi/omc/AdminConfig.ts

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {QBOAuthCOnfig} from '../../Cloud/QboAuthConfig';
2-
import {MyTimestamp} from '../../firestore/firestoreTypes';
3-
import {deepCopy} from '../../utils/deepCopy';
4-
import {AdminType} from '../admin/AdminType';
5-
import {DaudiMeta} from '../universal/Meta';
6-
import {Metadata} from '../universal/Metadata';
1+
import { QBOAuthCOnfig } from '../../Cloud/QboAuthConfig';
2+
import { MyTimestamp } from '../../firestore/firestoreTypes';
3+
import { deepCopy } from '../../utils/deepCopy';
4+
import { AdminType } from '../admin/AdminType';
5+
import { DaudiMeta } from '../universal/Meta';
6+
import { Metadata } from '../universal/Metadata';
77

88
export interface AdminConfig {
99
adminTypes: Array<AdminType>;
@@ -29,12 +29,9 @@ export const emptyqboAuth: QBOAuthCOnfig = {
2929
clientSecret: '',
3030
webhooksVerifier: '',
3131
authConfig: {
32-
previousDCT: MyTimestamp.fromDate(new Date()),
3332
accessToken: '',
3433
refreshToken: '',
35-
accesstokenExpiry: MyTimestamp.fromDate(new Date()),
36-
refreshtokenExpiry: MyTimestamp.fromDate(new Date()),
37-
time: MyTimestamp.fromDate(new Date())
34+
createdAt: MyTimestamp.fromDate(new Date())
3835
}
3936
};
4037

+26-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { deepCopy } from '../../utils/deepCopy';
2-
import { FuelType } from '../fuel/FuelType';
3-
import { emptytaxExempt, TaxExempt } from './TaxExempt';
1+
import { deepCopy } from "../../../../../functions/src/models/utils/deepCopy";
2+
import { FuelType } from "../fuel/FuelType";
3+
import { emptytaxExempt, TaxExempt } from "./TaxExempt";
44

55
export interface Stock {
66
qty: {
@@ -18,24 +18,28 @@ export interface Stock {
1818
};
1919
}
2020

21-
export const EmptyOMCStock: Stock = {
22-
qty: {
23-
ago: {
24-
allocation: 0,
25-
ase: 0
21+
export function newStock(): Stock {
22+
return {
23+
...{
24+
qty: {
25+
ago: {
26+
allocation: 0,
27+
ase: 0
28+
},
29+
ik: {
30+
allocation: 0,
31+
ase: 0
32+
},
33+
pms: {
34+
allocation: 0,
35+
ase: 0
36+
}
37+
},
2638
},
27-
ik: {
28-
allocation: 0,
29-
ase: 0
39+
taxExempt: {
40+
ago: deepCopy<TaxExempt>(emptytaxExempt),
41+
ik: deepCopy<TaxExempt>(emptytaxExempt),
42+
pms: deepCopy<TaxExempt>(emptytaxExempt)
3043
},
31-
pms: {
32-
allocation: 0,
33-
ase: 0
34-
}
35-
},
36-
taxExempt: {
37-
ago: deepCopy<TaxExempt>(emptytaxExempt),
38-
ik: deepCopy<TaxExempt>(emptytaxExempt),
39-
pms: deepCopy<TaxExempt>(emptytaxExempt)
40-
},
41-
};
44+
};
45+
}

functions/src/models/Daudi/order/truck/Truck.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {MyTimestamp} from '../../../firestore/firestoreTypes';
2-
import {AssociatedUser} from '../../admin/AssociatedUser';
3-
import {Compartment} from './Compartment';
1+
import { MyTimestamp } from '../../../firestore/firestoreTypes';
2+
import { AssociatedUser } from '../../admin/AssociatedUser';
3+
import { Compartment } from './Compartment';
44

55
export interface Expiry {
6-
timeCreated: MyTimestamp;
6+
timeCreated: Date;
77
expiry: MyTimestamp;
88
user: AssociatedUser;
99
}

functions/src/models/Qbo/QboOrder.ts

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export interface QboOrder {
6363
PrivateNote?: string
6464
DepartmentRef?: ReferenceType,
6565
ClassRef: ReferenceType,
66+
Balance?: number;
67+
6668
}
6769

6870

functions/src/models/Qbo/subTypes/Line.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import {SalesItemLineDetail} from "./SalesItemLineDetail";
2-
import {DiscountLineDetail} from "./DiscountLineDetail";
3-
import {SubTotalLineDetail} from "./SubTotalLineDetail";
4-
import {LineDetailType} from "../enums/LineDetailType";
5-
import {GroupLineDetail} from "./GroupLineDetail";
1+
import { SalesItemLineDetail } from "./SalesItemLineDetail";
2+
import { DiscountLineDetail } from "./DiscountLineDetail";
3+
import { SubTotalLineDetail } from "./SubTotalLineDetail";
4+
import { LineDetailType } from "../enums/LineDetailType";
5+
import { GroupLineDetail } from "./GroupLineDetail";
66

77
/**
88
* Individual line items of a transaction.

functions/src/models/Qbo/subTypes/SalesItemLineDetail.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {TaxCodeRef} from "./TaxCodeRef";
2-
import {ItemRef} from "./ItemRef";
1+
import { TaxCodeRef } from "./TaxCodeRef";
2+
import { ItemRef } from "./ItemRef";
33

44
export interface SalesItemLineDetail {
55
TaxCodeRef: TaxCodeRef;

0 commit comments

Comments
 (0)