new(basic.gblib): FIND can now have more than one filter with multiple datatypes.
This commit is contained in:
parent
23d048c9fd
commit
b6962f058b
3 changed files with 149 additions and 26 deletions
|
@ -98,7 +98,7 @@ export class DialogKeywords {
|
|||
const user = await this.min.userProfile.get(step.context, {});
|
||||
const sec = new SecService();
|
||||
const userFull = await sec.getUserFromSystemId(user.systemUser.userId);
|
||||
|
||||
|
||||
switch (userFull.locale) {
|
||||
case 'pt':
|
||||
return [day, month, year].join('/');
|
||||
|
@ -120,6 +120,32 @@ export class DialogKeywords {
|
|||
await step.endDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns specified date week day in format 'Mon'.
|
||||
*
|
||||
* @example day = WEEKDAY (date)
|
||||
*
|
||||
*/
|
||||
public getWeekFromDate(date) {
|
||||
if (!(date instanceof Date)) {
|
||||
date = new Date(date);
|
||||
}
|
||||
return date.toLocaleString('en-us', { weekday: 'short' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified time in format hh:dd.
|
||||
*
|
||||
* @example hour = HOUR (date)
|
||||
*
|
||||
*/
|
||||
public getHourFromDate(date) {
|
||||
if (!(date instanceof Date)) {
|
||||
date = new Date(date);
|
||||
}
|
||||
return date.getHours() + ':' + date.getMinutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current time in format hh:dd.
|
||||
*
|
||||
|
@ -288,7 +314,7 @@ export class DialogKeywords {
|
|||
return 'whatsapp';
|
||||
}
|
||||
return 'webchat';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -162,7 +162,9 @@ export class GBVMService extends GBService {
|
|||
mobile = this.userMobile(step);
|
||||
from = mobile;
|
||||
ubound = function(list){return list.length};
|
||||
isArray = function(list){return Array.isArray(list) };
|
||||
isarray = function(list){return Array.isArray(list) };
|
||||
weekday = this.getWeekFromDate;
|
||||
hour = this.getHourFromDate;
|
||||
headers = {};
|
||||
|
||||
${code}
|
||||
|
@ -423,8 +425,10 @@ export class GBVMService extends GBService {
|
|||
|
||||
parsedCode = this.handleThisAndAwait(parsedCode);
|
||||
|
||||
parsedCode = parsedCode.replace(/(now)(?=(?:[^"]|"[^"]*")*$)/gi, 'await this.getNow(step)');
|
||||
parsedCode = parsedCode.replace(/(today)(?=(?:[^"]|"[^"]*")*$)/gi, 'await this.getToday(step)');
|
||||
parsedCode = parsedCode.replace(/(\bnow\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'await this.getNow()');
|
||||
parsedCode = parsedCode.replace(/(\btoday\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'await this.getToday(step)');
|
||||
parsedCode = parsedCode.replace(/(\bweekday\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'weekday');
|
||||
parsedCode = parsedCode.replace(/(\bhour\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'hour');
|
||||
|
||||
parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true });
|
||||
fs.writeFileSync(jsfile, parsedCode);
|
||||
|
@ -485,7 +489,9 @@ export class GBVMService extends GBService {
|
|||
code = code.replace(/this\./gm, 'await this.');
|
||||
code = code.replace(/function/gm, 'async function');
|
||||
code = code.replace('ubound = async', 'ubound ='); // TODO: Improve this.
|
||||
code = code.replace('isArray = async', 'isArray ='); // TODO: Waiting for a real compiler.
|
||||
code = code.replace('hour = await', 'hour ='); // TODO: Improve this.
|
||||
code = code.replace('weekday = await', 'weekday ='); // TODO: Improve this.
|
||||
code = code.replace('isArray = async', 'isArray ='); // TODO: Waiting for a compiler.
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -270,11 +270,11 @@ export class SystemKeywords {
|
|||
*
|
||||
* @example
|
||||
*
|
||||
* rows = FIND "file.xlsx", "A2=active"
|
||||
* rows = FIND "file.xlsx", "A2=active", "A2 < 12/06/2010 15:00"
|
||||
* i = 1
|
||||
* do while i < ubound(row)
|
||||
* row = rows[i]
|
||||
* send sms to "+" + row.mobile, "Hello " + row.namee + "! "
|
||||
* send sms to "+" + row.mobile, "Hello " + row.name + "! "
|
||||
* loop
|
||||
*
|
||||
*/
|
||||
|
@ -285,11 +285,6 @@ export class SystemKeywords {
|
|||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||
|
||||
let document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||
|
||||
if (args.length > 1) {
|
||||
throw `File '${file}' has a FIND call with more than 1 arguments. Check the .gbdialog associated.`;
|
||||
}
|
||||
|
||||
let maxLines = 100;
|
||||
if (this.dk.user.basicOptions && this.dk.user.basicOptions.maxLines) {
|
||||
if (this.dk.user.basicOptions.maxLines.toString().toLowerCase() !== "default") {
|
||||
|
@ -299,9 +294,6 @@ export class SystemKeywords {
|
|||
|
||||
// Creates workbook session that will be discarded.
|
||||
|
||||
const filter = args[0].split('=');
|
||||
const columnName = filter[0];
|
||||
const value = filter[1];
|
||||
let sheets = await client
|
||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`)
|
||||
.get();
|
||||
|
@ -310,16 +302,69 @@ export class SystemKeywords {
|
|||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:Z${maxLines}')`)
|
||||
.get();
|
||||
|
||||
let getFilter = async (text) => {
|
||||
let filter;
|
||||
const operators = [/\<\=/, /\>\=/, /\</, /\>/, /\bin\b/, /\bnot in\b/, /\=/];
|
||||
let done = false;
|
||||
await CollectionUtil.asyncForEach(operators, async op => {
|
||||
var re = new RegExp(op, "g");
|
||||
const parts = text.split(re);
|
||||
|
||||
if (parts.length === 2 && !done) {
|
||||
filter = {
|
||||
columnName: parts[0].trim(),
|
||||
operator: op.toString().replace(/\//g, '').replace(/\\/g, '').replace(/\b/g, ''),
|
||||
value: parts[1].trim()
|
||||
};
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
function isValidDate(date) {
|
||||
if (!(date instanceof Date)) {
|
||||
date = new Date(date);
|
||||
}
|
||||
return !isNaN(date.valueOf());
|
||||
}
|
||||
function isValidNumber(number) {
|
||||
return !isNaN(number);
|
||||
}
|
||||
|
||||
// Increments columnIndex by looping until find a column match.
|
||||
|
||||
let columnIndex = 0;
|
||||
const filters = [];
|
||||
const header = results.text[0];
|
||||
for (; columnIndex < header.length; columnIndex++) {
|
||||
|
||||
if (header[columnIndex].toLowerCase() === columnName.toLowerCase()) {
|
||||
break;
|
||||
await CollectionUtil.asyncForEach(args, async arg => {
|
||||
const filter = await getFilter(arg);
|
||||
if (!filter) {
|
||||
throw new Error(`BASIC: FIND filter has an error: ${arg} check this and publish .gbdialog again.`);
|
||||
}
|
||||
}
|
||||
|
||||
let columnIndex = 0;
|
||||
for (; columnIndex < header.length; columnIndex++) {
|
||||
if (header[columnIndex].toLowerCase() === filter.columnName.toLowerCase()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
filter.columnIndex = columnIndex;
|
||||
|
||||
if (isValidDate(filter.value)) {
|
||||
filter.value = new Date(filter.value);
|
||||
filter.dataType = 'date';
|
||||
}
|
||||
else if (isValidNumber(filter.value)) {
|
||||
filter.value = Number.parseInt(filter.value);
|
||||
filter.dataType = 'number';
|
||||
} else {
|
||||
filter.value = filter.value;
|
||||
filter.dataType = 'string';
|
||||
}
|
||||
|
||||
filters.push(filter);
|
||||
});
|
||||
|
||||
// As BASIC uses arrays starting with 1 (one) as index,
|
||||
// a ghost element is added at 0 (zero) position.
|
||||
|
@ -328,15 +373,60 @@ export class SystemKeywords {
|
|||
table.push({ 'this is a hidden base 0': 'element' });
|
||||
let foundIndex = 0;
|
||||
|
||||
|
||||
// Fills the row variable.
|
||||
|
||||
for (; foundIndex < results.text.length; foundIndex++) {
|
||||
let filterAcceptCount = 0;
|
||||
await CollectionUtil.asyncForEach(filters, async filter => {
|
||||
|
||||
let result = results.text[foundIndex][columnIndex];
|
||||
let result = results.text[foundIndex][filter.columnIndex];
|
||||
|
||||
// Filter results action.
|
||||
switch (filter.dataType) {
|
||||
case 'string':
|
||||
switch (filter.operator) {
|
||||
case '=':
|
||||
if (result && result.toLowerCase().trim() === filter.value.toLowerCase().trim()) {
|
||||
filterAcceptCount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'number':
|
||||
switch (filter.operator) {
|
||||
case '=':
|
||||
if (result && result.trim() === filter.value.trim()) {
|
||||
filterAcceptCount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if (result && result.toLowerCase().trim() === value.toLowerCase().trim()) {
|
||||
case 'date':
|
||||
const resultDate = new Date(result);
|
||||
switch (filter.operator) {
|
||||
case '<':
|
||||
if (resultDate.getTime() < filter.value.getTime())
|
||||
filterAcceptCount++;
|
||||
break;
|
||||
case '>':
|
||||
if (resultDate.getTime() > filter.value.getTime())
|
||||
filterAcceptCount++;
|
||||
break;
|
||||
case '<=':
|
||||
if (resultDate.getTime() <= filter.value.getTime())
|
||||
filterAcceptCount++;
|
||||
break;
|
||||
case '>=':
|
||||
if (resultDate.getTime() >= filter.value.getTime())
|
||||
filterAcceptCount++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (filterAcceptCount === filters.length) {
|
||||
let row = {};
|
||||
const xlRow = results.text[foundIndex];
|
||||
for (let colIndex = 0; colIndex < xlRow.length; colIndex++) {
|
||||
|
@ -346,6 +436,7 @@ export class SystemKeywords {
|
|||
row['line'] = foundIndex + 1;
|
||||
table.push(row);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (table.length === 1) {
|
||||
|
@ -643,7 +734,7 @@ export class SystemKeywords {
|
|||
const options = {
|
||||
url: url,
|
||||
headers: headers,
|
||||
qs:qs,
|
||||
qs: qs,
|
||||
};
|
||||
|
||||
let result = await request.get(options);
|
||||
|
|
Loading…
Add table
Reference in a new issue