I am trying to figure out the backend logic to build a car booking system where a user will choose a date and enter the amount of time he needs the car for. Then the system will generate available slots with a start and end time. Every time user returns the car the owner will wash the car for 10 minutes so the next slot's start time will be previous end + 10 minutes.
For example user books the car on 2022-09-04 and books the slot for 30 minutes. Now the available slots will be 12:00 AM-12:30 AM and the next slot will be 12:40 AM-1:10 AM and so on for the whole day. The user can choose whichever slots he wants.
Here is the UI if it helps.
Before user input: https://imgur.com/jYzQ4Oa
After user input: https://imgur.com/wkjmqtM
If another user wants to book a slot for 20 minutes I want existing available slots to adjust with that time without conflicting with the booked slots.
I have generated initial slots(no slot is booked yet) in the front end for 30minutes duration.
I will move this in the backend after I figure out the logic. I am using Nodejs and mongodb in the backend.
I haven't worked with date-time before that's why kinda struggling.
import { addMinutes} from "date-fns";
const availableSlots = [
{
id: uuidv4(),
start: new Date(date.setHours(0, 0, 0, 0)).toISOString(),//date=user selected date
end: "",
},
];
const handleSubmit = (e) => {
e.preventDefault();
const inputValue = parseInt(e.target.time.value);
if (inputValue > 0) {
let end;
let start;
const timeToWash = 10
for (let i = 0; i < 1440 / (inputValue + timeToWash); i++) {
if (i < 1) {
end = addMinutes(new Date(availableSlots[i].start), inputValue);
end = end.toISOString();
availableSlots[i] = {
id: uuidv4(),
start: availableSlots[0].start,
end: end,
};
} else {
start = addMinutes(
new Date(availableSlots[i - 1].start),
inputValue + timeToWash
);
start = start.toISOString();
end = addMinutes(new Date(start), inputValue);
end = end.toISOString();
availableSlots[i] = {
id: uuidv4(),
start: start,
end: end,
};
}
}
}
};
I am trying to implement, through Gun, a tree structure that allows to express relationships between companies, subsidiaries of these companies and their products.
The structure that I have done is as follows:
there is a root node: this is the main seller of some product (for example, sensors) and all its children (depth nodes 1) are its customers;
there are children nodes, not leaves, from level depth 1 on: these are the customers of the root knot; they can have different branches; there can be sub-sub-sub-branches of a branch and so on, there are no limits to the number of sub-subbranches;
there are leaf knots: these are the products contained in a branch, a sub-branch, a sub-sub-branch...
Here's how I thought of this:
create a client set;
put clients nodes inside client set;
create a branch set;
put branches nodes inside branch set;
link branches set to client set;
create a sensor set;
put sensors nodes inside sensor set;
link sensors set to branches set.
Somethink like this:
[clients]
/\
/ \
(MecDoland) (FrankMirros)
| |
[branches] [branches]
/ | \ |
(NY) (CA) (DA) ...
| | |
| [sensors]...
| |
| ...
[sensors]
/|\
......
Here's my implementation
const Gun = require('gun')
const gun = new Gun()
// Just a util function
function printError(ack) {
if (ack.err) {
console.log(ack.err)
}
}
// [clients]
const clients = gun.get('clients') // group
// (MecDoland)
const mac = clients.get('MecDoland').put({ data: 12 })
// (FrankMirros)
const pm = clients.get('FrankMirros').put({ data: 13 })
console.log('Adding to "clients" set MecDoland...')
// [clients] -> (MecDoland)
clients.set(mac, printError)
console.log('Adding to "clients" set philip morris...')
// [clients] -> (FrankMirros)
clients.set(pm, printError)
// [branches]
const branches = gun.get('branches') // group
// (MecDolandNY)
const macny = gun.get('MacDonaldNY').put({ data: 1 }, printError)
// (MecDolandCA)
const macca = gun.get('MecDolandCA').put({ data: 2 }, printError)
// [branches] -> (MecDolandNY)
branches.set(macny, printError)
// [branches] -> (MecDolandCA)
branches.set(macca, printError)
// [MecDoland] -> [branches]
mac.set(branches, printError)
//clients.map().once(v => console.log('CLIENT:',v))
//branches.map().once(v => console.log('BRANCH:',v._))
const sensors = gun.get('sensorsMecDolandNY') // group
const temp = gun.get('temperatue').put({ measure: 'celsius', value: 37 })
const press = gun.get('pressure').put({ measure: 'Bar', value: 2 })
sensors.set(temp)
sensors.set(press)
macny.set(sensors)
// Show all clients
gun
.get('clients')
.map()
.once(v => console.log(v))
There are two points that I haven't been able to clarify:
1 - I don't know if I am using Gun sets well: I tried to add some relationships but didn't work out; consider the following instructions:
macDoland.get('client').put(rootNode)
frankMirrors.get('client').put(rootNode)
I tried to put a client relationship for both customer nodes, but printing rootNode showed me that rootNode had client relationship only with frankMirrors node! The first relationship with macDoland node disappeared so I started using Gun sets.
My code works (more or less) but I don't know if I am using Gun set properly and if this is the right way to do it, given the kind of relationship I want to build between main vendors, customers, customers' branches and sensors in each branch.
2 - I'd like to make this approach more generic and scalable: for now there are clients, branches and sensors; this may change in future and the number of levels between clients and sensors may increase.
This means that there may be an arbitrary number of levels between client nodes (depth 1) and sensors (max depth): for example, a very small client may be without branches and thus its client node smallCompany would directly be linked to its sensors; for another example, a gigantic client may have (say) five level of depths and I don't want to hard-code Gun set names such as macDolandNySubSubSubSubBranch.
How could I provide scalability for an arbitrary number of sub-branches?
I have this,
[{"cart_id":"5BqDu","product":[{"id":1,"qty":"11","name":"test product","pv":"100","price":"23","sub_price":253,"sub_pv":1100},{"id":2,"qty":"11","name":"test product 2","pv":"null","price":"11","sub_price":121,"sub_pv":null}],"shipping":{"member_id":"00000000","member_pass":"0987654321","receiver":"asasdsdasd123","full_address":"Taman ABC Lorong ccc Bagan Gajar, 11100 Pulau pINANG.","postcode":"21313213","country":"malaysia","phone_no":"321312"}},{"cart_id":"xEopa","product":[{"id":2,"qty":"1","name":"test product 2","pv":"null","price":"11","sub_price":11,"sub_pv":null}],"shipping":{"member_id":"09876543","member_pass":"11232312","receiver":"sdasdsadas","full_address":"adsadzcfdhg43324","postcode":"12323","country":"malaysia","phone_no":"321312"}},{"cart_id":"0WyEm","product":[{"id":2,"qty":"5","name":"test product 2","pv":"null","price":"11","sub_price":55,"sub_pv":null},{"id":1,"qty":"3","name":"test product","pv":"100","price":"23","sub_price":69,"sub_pv":300}],"shipping":{"member_id":"12345678","member_pass":"0987654321","receiver":"MR ABCDEF","full_address":"NO. 123, LORONG ABC, TAMAN AMAN CCC, BAGAN AJAM, 11100 KUALA LUMPUR, MALAYSIA.","postcode":"123453","country":"MALAYSIA","phone_no":"0123456789"}},{"cart_id":"ox9IK","product":[{"id":1,"qty":"2","name":"test product","pv":"100","price":"23","sub_price":46,"sub_pv":200},{"id":2,"qty":"5","name":"test product 2","pv":"null","price":"11","sub_price":55,"sub_pv":null}],"shipping":""},{"cart_id":"jz2j2","product":[{"id":1,"qty":"1","name":"test product","pv":"100","price":"23","sub_price":23,"sub_pv":100},{"id":2,"qty":"4","name":"test product 2","pv":"null","price":"11","sub_price":44,"sub_pv":null}],"shipping":""},{"cart_id":"6eE0x","product":[{"id":1,"qty":"1","name":"test product","pv":"100","price":"23","sub_price":23,"sub_pv":100}],"shipping":{"member_id":"S4567890","member_pass":"atomy123","receiver":"Siew","full_address":"56, Jalan Emas 8, Taman Bukit Beruang.","postcode":"75750","country":"Malaysia","phone_no":"0198907654"}},{"cart_id":"iRw6b","product":[{"id":2,"qty":"1","name":"test product 2","pv":"null","price":"11","sub_price":11,"sub_pv":null}],"shipping":{"member_id":"12345670","member_pass":"121334","receiver":"sdfsdaf","full_address":"sgdfgdfs","postcode":"12341","country":"Malaysia","phone_no":"0192321008"}},{"cart_id":"bbKf9","product":[{"id":2,"qty":"1","name":"test product 2","pv":"null","price":"11","sub_price":11,"sub_pv":null}],"shipping":{"member_id":"S6789212","member_pass":"12345678","receiver":"Mary","full_address":"Taman Tasik Utama","postcode":"12233","country":"Malaysia","phone_no":"0197321830"}},{"cart_id":"B1DLq","product":[{"id":2,"qty":"5","name":"test product 2","pv":"null","price":"11","sub_price":55,"sub_pv":null},{"id":1,"qty":"1","name":"test product","pv":"100","price":"23","sub_price":23,"sub_pv":100}],"shipping":{"member_id":"09876556","member_pass":"hijk","receiver":"sim","full_address":"Taman Tasik Utama","postcode":"12233","country":"Malaysia","phone_no":"0987654321"}}]
I only need product id from all
What can I do ?
Try this:
let carts = / * the data you posted above */
let ids = [];
carts.forEach(cart => {
const products = cart.product;
products.forEach(product => {
ids.push(product.id);
});
});
Note that there are no check that handles a missing if property so you might want to add that.
I am trying to extend the wit-ai weather example by adding wit/datetime to the mix.
For example a user might type "How cold will it be in Berlin in 1 hour?" and the weather bot will bring back the data for the weather in 1 hour in Berlin.
So far this works, but when I try to setup missingDate in order to ask the date if it's missing it behaves kind of funny.
A dialogue would be:
- How cold will it be in Berlin?
- In what time?
- In 1 hour.
Instead, after the 1 hour step, I get asked again for the location which is in the context, but instead is triggered again.
My action is named getForecast({context, entities}) and I have defined it as below:
actions:
[...],
getForecast({ context, entities }) {
console.log(`The current context is: ${JSON.stringify(context)}`);
console.log(`Wit extracted ${JSON.stringify(entities)}`);
// extract entity
var location = firstEntityValue(entities, "location");
var date = firstEntityValue(entities, "datetime");
// if the entity exists, do a remote weather call.
if (date) {
context.date = date;
delete context.missingDate;
} else {
context.missingDate = true;
delete context.date;
delete context.forecast;
}
if (location) {
context.forecast = '38 degrees';
context.location = location;
delete context.missingLocation;
} else {
context.missingLocation = true;
delete context.forecast;
}
// return the context object
return Promise.resolve(context);
}
I have created vendor bill with nlapiCreateRecord, I can see the Bill record in the system with all items I want, but I can't relate it / link it to specific Purchase Order natively. When I'm using nlapiTransformRecord I'm deleting all records first from the PO and I'm adding new line items from CSV, but the native link/relationship between PO and Vendor Bill is missing. Here is my code created for the Bill Import from CSV:
function BillImport() {
var fromrecord;
var fromid;
var torecord;
var record;
var qty;
fromrecord = 'purchaseorder';
fromid = 23664;
torecord = 'vendorbill';
var loadedBillFile = nlapiLoadFile(5034);
var loadedBillString = loadedBillFile.getValue();
var BillLines = loadedBillString.split('\r\n'); //split on newlines
record = nlapiTransformRecord(fromrecord, fromid, torecord);
//trecord.setFieldValue('location', 1);
//trecord.setFieldValue('tranid', 'TEST!');
//var record = nlapiCreateRecord('vendorbill');
for (var j = record.getLineItemCount('item'); j>=1; j--)
{
record.removeLineItem('item',j);
}
for (var i = 1; i < BillLines.length; i++) {
var cols = BillLines[i].split(';');
var dsplit = cols[4].split(".");
var date = new Date(dsplit[2],dsplit[1],dsplit[0]);
currentDate = date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear();
var entity = cols[0]; // OK HEAD
var currency = cols[1]; // OK LINE
var taxcode = cols[2]; // SKIP
var tranid = cols[3]; // OK HEAD
var trandate = currentDate; // OK HEAD FORMAT 11/3/2016
var location = 21;//cols[5]; // OK HEAD (ID of Location)
var item = cols[6]; // OK LINE
var quantity = cols[7];
var rate = parseFloat(cols[8]); // FLOAT
var amount = parseFloat(cols[9]);
var po = cols[10];
record.selectNewLineItem('item');
// Head Level
record.setFieldValue('createdfromstatus','');
record.setFieldValue('entity', entity);
record.setFieldValue('tranid', tranid);
record.setFieldValue('trandate', trandate);
record.setFieldValue('location', location);
// Line Level
record.setCurrentLineItemValue('item','item', item);
record.setCurrentLineItemValue('item','quantity', quantity);
record.setCurrentLineItemValue('item','rate', rate);
record.setCurrentLineItemValue('item','amount', amount);
//record.setCurrentLineItemValue('item','orderdoc', po);
//record.setCurrentLineItemValue('item','podocnum', po);
record.commitLineItem('item');
}
var id = nlapiSubmitRecord(record, true);
//trecord.setLineItemValue('item', 'amount', 1, 3 );
//var idl = nlapiSubmitRecord(trecord, true);
}
Here is the example CSV file:
Entity;Currency;Taxcode;Tranid;TranDate;Location;Item;Quantity;Rate;Amount;PO Internal ID
2449;USD;0.00 ;224676;11.3.2016;21;885;1;10;50;23664
2449;USD;0.00 ;224676;11.3.2016;21;870;2;10;120;23664
2449;USD;0.00 ;224676;11.3.2016;21;890;3;3;45;23664
2449;USD;0.00 ;224676;11.3.2016;21;948;4;4,66;38,5;23664
2449;USD;0.00 ;224676;11.3.2016;21;886;5;19,54;720;23664
I'm
If you don't want it to transform into a Vendor Bill (probably to avoid the PO from changing status) then you will need to create a custom relationship. You do this by:
Create a custom field on the Vendor Bill form of type "List/Record" and have the it be of "Transaction" type and check "Record is Parent". Save the Custom Field.
Go back to the custom field and edit it. Go to the display tab and select a "Parent Subtab", I usually select "Related Records". Save.
Now you just need to create a new Vendor Bill from scratch and save the record id of the PO in the Vendor Bill using the new custom field. Leave the "Created From" field blank, otherwise you would be linking them natively. The Bill should be listed under the "Related Records" tab or whichever subtab you selected on the PO.
Vendor bill import via CSV method is doable but you can bill the Purchase Order completely and not partially i.e. if you try to import a bill mentioning any referenced Purchase Order's link in it, it'll create a bill for all the remaining unbilled quantities of the Purchase Order rather than the quantity you have mentioned.
Actually if you mention any quantity AND Purchase Order link BOTH in the CSV file then it will throw an error.
Below is the part I found from the SuiteAnswers with answer id as 10020.
Refer the supporting image here