How to add a quantity in paypal orders in reactjs - reactjs

I'm trying to add the qty of an order. this is what I have and it wont work :(.
it works without qty but then it defaults to 1. Also how would i add a second product? it will only allow me to have the one
window.paypal.Buttons({
createOrder: (data, actions, err) => {
return actions.order.create({
intent: "CAPTURE",
purchase_units: [
{
description: "cool tablet",
amount: {
currency_code: "CAD",
value: 650.00,
},
quantity: 2,
},
{
description: "ink",
amount: {
currency_code: "CAD",
value: 777.00,
}
}
]
})
},
onApprove: async (data, actions)=>{
const order = await (actions.order.capture());
console.log(order);
},
onError: (err) => {
console.log(err);
}
})
.render(paypal.current)
}, []);

You need a single purchase unit, a single amount with the required breakdown object, and an items array with line item detail. See the API reference at https://developer.paypal.com/docs/api/orders/v2/#orders_create
Here is an example:
"purchase_units": [{
"description": "DESCRIPTION GOES HERE",
"amount": {
"value": "3.00",
"currency_code": "CAD",
"breakdown": {
"item_total": {
"currency_code": "CAD",
"value": "3.00"
}
}
},
"items": [
{
"name": "item one",
"quantity": "1",
"unit_amount": {
"currency_code": "CAD",
"value": "1.00"
}
},
{
"name": "item two",
"quantity": "1",
"unit_amount": {
"currency_code": "CAD",
"value": "2.00"
}
}
]
}
]

Related

How can I get the totalPrice of product inside a nested document?

How can I get the total price of specific item, I'm trying to multiply the quantity and the price and then POST it, but I'm having a hard time on how can I save the total amount of specific item
OrderSchema.js
const OrderSchema = new mongoose.Schema({
userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
products: [
{
productId:{
type: mongoose.Schema.Types.ObjectId, ref: 'Product'
},
quantity: {
type: Number,
default: 1,
},
sellerId: {
type: mongoose.Schema.Types.ObjectId, ref: 'User'
},
totalPrice: {
type: Number,
default: 0,
}
}
],
}, {timestamps: true}
)
export default mongoose.model('Order', OrderSchema)
Order.js
const handleSubmit = async (e) =>{
e.preventDefault()
if(orderSummary?.location === ""){
toast.error("Please input location..")
}else{
try {
await userRequest.post(`/order`,{
userId: currentUser._id,
products: cart.products.map((item) =>({
productId: item._id,
quantity: item.quantity,
sellerId: item.seller_id._id,
totalPrice: Number(item.quantity * item._id.price)
})),
})
} catch (error) {
toast.error("Please put a Location and Time!")
}
}
}
in this image, I want to get the total amount of specific product, so the first product should have a 369.
But when I call my get all orders, this is what I get
{
"_id": "63b1b4de5a95bd4df7f9443b",
"userId": {
"_id": "63b18af8363f51fa50801dd0",
"studentId": "1234567892"
},
"products": [
{
"productId": {
"_id": "63b16fc58fe585c7b81c748d",
"title": "asd",
"price": "123"
},
"quantity": 3,
"sellerId": {
"_id": "63b160689f50f852e056afaf",
"studentId": "1234567890"
},
"_id": "63b1b4de5a95bd4df7f9443c"
},
{
"productId": {
"_id": "63b16ff08fe585c7b81c7496",
"title": "asd21",
"price": "213"
},
"quantity": 3,
"sellerId": {
"_id": "63b160689f50f852e056afaf",
"studentId": "1234567890"
},
"_id": "63b1b4de5a95bd4df7f9443d"
}
],
}
What I'm trying to get here when I call order.js
{
"_id": "63b1b4de5a95bd4df7f9443b",
"userId": {
"_id": "63b18af8363f51fa50801dd0",
"studentId": "1234567892"
},
"products": [
{
"productId": {
"_id": "63b16fc58fe585c7b81c748d",
"title": "asd",
"price": "123"
},
"quantity": 3,
"sellerId": {
"_id": "63b160689f50f852e056afaf",
"studentId": "1234567890"
},
"totalPrice": "369"
},
{
"productId": {
"_id": "63b16ff08fe585c7b81c7496",
"title": "asd21",
"price": "213"
},
"quantity": 3,
"sellerId": {
"_id": "63b160689f50f852e056afaf",
"studentId": "1234567890"
},
"totalPrice": "639"
}
],
}
You can use a virtual field to calculate the totalPrice value:
const OrderSchema = new mongoose.Schema(
{
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
products: [
{
productId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Product",
},
quantity: {
type: Number,
default: 1,
},
sellerId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
// NOTE: Remove this
// totalPrice: {
// type: Number,
// default: 0,
// },
},
],
},
{
timestamps: true,
// NOTE: Add this or it may not work
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
OrderSchema.virtual("totalPrice").get(function () {
if (!this.productId) return undefined; // Guard clause in case it is not populated
return this.productId * this.quantity;
});
export default mongoose.model("Order", OrderSchema);
This acts almost exactly like a normal field, however, it is not actually a part of the document. So if you were to query for the least totalPrice, it would act as if the field does not exist.
Pros:
Very performant, since it does not query data
Does not require any complex/hard to read code for such a simple task
Cons:
Requires the productId field to be populated
Cannot be searched in a query
Given that in most cases, you WILL need the productId field populated, this is a better suited solution. Let me know if there are any errors, since I can't really test this without making a whole project.

How to prevent fields in react-json-schema-form from appearing row by row

I am creating forms using React-json-schema-form. I don't understand how am I suppose to change the layout of the forms I create. They appear in rows by default and adding classes to each field in the uiSchema does not reflect the desired change. I tried adding col-3 etc and they neither change size nor stop appearing in rows.
Its so complex to figure out. My understand would be to change the default behaviour of the fields. But, I'm sure it should be able to be designed out of the box right?
This is what I want to do but its outdated and I still don't know how to use it. https://github.com/audibene-labs/react-jsonschema-form-layout.
How do I change the layout?
import React, { Component, Fragment } from "react";
import axios, { existing_api, new_api, public_path } from "../../../Api/api";
import 'bootstrap/dist/css/bootstrap.css';
//import Form from "#rjsf/core";
import Form from "#rjsf/bootstrap-4";
class POSView extends Component {
constructor(props) {
super(props);
this.state = {
hotelId: 1,
isActive: 1,
formData: { 'recordIn': 10096 },
schema: props.schema || {
"title": "POS",
"description": "Add POS Invoice - Rooms",
"type": "object",
"properties": {
"customer": { "title": "Customer", "type": 'string', "default": '' },
"room": { "title": "Room", "type": 'integer', "default": '' },
"address": { "title": "Address", "type": 'string' },
"company": { "title": "Company", "type": 'string' },
"dueAmount": { "title": "Due Amount", "type": 'string' },
"roomRate": { "title": "Room Rate", "type": 'string' },
"recordIn": { "title": "Record In", "type": 'number', enum: [10096, 10097], enumNames: ["Guest Ledger Control A/c", "Accounts Receivable"] },
"department": { "title": "Department", "type": 'number', enum: [1, 2], enumNames: ["Head Office", "Accounts"] },
"id": { "title": "ID", "type": 'string' },
"invoiceNumber": { "title": "Invoice Number", "type": 'string' },
"invoiceDate": { "title": "Invoice Date", "type": 'string', "format": "date-time" },
"btcCompany": { "title": "BTC Company", "type": 'number', enum: [1, 2], enumNames: ["Limited Standard", "Standard Limited"] },
"itemsAndServices":
{
"title": "Item And Service",
"description": "Add items and Services",
"type": "array",
"items": {
"type": "object",
//"required": [''],
"properties":
{
"Number": { "type": "number" },
"Item Name": {
"title": "Item Name",
"type": "string"
},
"Item Notes": {
"title": "Item Notes",
"type": "string"
},
"Qty": {
"title": "Qty",
"type": "number"
},
"Unit": {
"title": "Unit",
"type": "string"
},
"Price": {
"title": "Price",
"type": "number"
},
"%": {
"title": "%",
"type": "number"
},
"Extended": {
"title": "Extended",
"type": "number"
}
}
}
},
"payment":
{
"title": "Payment",
"description": "",
"type": "array",
"items": {
"type": "object",
//"required": [''],
"properties":
{
"date": { "title": "Date", "type": "string", format: "date-time" },
"amount": { "title": "Amount", "type": "number" },
"cheque": { "title": "Cheque #", "type": "integer" },
"memo": { "title": "Memo", "type": "string" },
"recordIn": { "title": "Record In", "type": 'number', enum: [10096, 10097], enumNames: ["Guest Ledger Control A/c", "Accounts Receivable"] },
// dynamically populate
}
}
}
}
},
uiSchema: props.uiSchema || {
// customer:{'className':""},
// room:{'className':"", },
// address: {'className':"", "ui:disabled": true, },
// company: {'className':"", "ui:disabled": true, },
// dueAmount: {'className':"", "ui:disabled": true, },
// roomRate: {'className':"", "ui:disabled": true, },
// recordIn:{'className':"", },
// department:{'className':"", },
// id:{'className':"", },
// invoiceNumber: {'className':"", "ui:disabled": true, },
// invoiceDate:{'className':"", },
// btcCompany:{'className':"", },
// itemsAndServices:{'className':""},
//items: { className: "container col-offset-6 col-md-3" }
// 'ui:field': 'layout', HOW I expected the default library to work
// 'ui:layout': [
// {
// customer: { md: 6 },
// room: { md: 6 }
// }, {
// address: { md: 12 }
// }, {
// company: { md: 6 },
// dueAmount: { md: 6 }
// }
// ]
// },
// fields:
// {
// layout: LayoutField
}
};
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
};
onChange({ formData }) {
formData.address = "";
console.log(formData);
this.state.schema.description = "this is beta plus plus";
this.setState({
formData: formData,
});
}
handleSubmit({ formData }) {
// Submit to an api
console.log(formData);
}
render() {
return (
<div className="container">
<div className="col-4">
{/* <div class="row">
<h1 class="col">First Form</h1>
</div><br /> */}
<div>
<Form
schema={this.state.schema}
formData={this.state.formData}
uiSchema={this.state.uiSchema}
//fields={this.state.fields}
onChange={this.onChange}
onSubmit={this.handleSubmit} />
</div>
</div>
</div>
);
}
}
export default POSView;

MongoDB $push in Array of Array Error: No value exists in scope for the shorthand property 'elements'

I wish to add data into Elements but get error. How to solve this mongodb/typescript problem?
Attempt 1 Error: No value exists in scope for the shorthand property 'elements'. Either declare one or provide an initializer.ts(18004)
Attempt 1
async add<T extends { id: string; parentID: string, elementNum: number, name: string, link: string}>(collectionName: string, args: T) {
const db = await this.getDB();
const collection = db.collection(collectionName);
return new Promise((resolve, reject) => {
collection.updateOne({ id: args.id }, {$push: {elements[args.elementNum]: {id: uuid(), name: args.name, link: args.link, elements: [] }}}, (err, res) => {
if (err) {
reject(err);
}
resolve(res);
});
});
}
Attempt 2
changed the following
collection.updateOne({ id: args.id }, {$push: {elements: {id: uuid(), name: args.name, link: args.link, elements: [] }}},
Attempt 2 results in Null added in the end
{
"id": "1",
"name": "wk1",
"iconFile": "icon.png",
"elements": [
[
{
"id": "2",
"name": "element2",
"link": "https",
"elements": [
{
"id": "1",
"name": "element1",
"link": "https:"
}
]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http:/"
}
]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http://"
}
]
},
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http://www."
}
]
}
],
null,
]
}
What I want to achieve is the following
{
"id": "1",
"name": "wk1",
"iconFile": "icon.png",
"elements": [
[
{
"id": "2",
"name": "element2",
"link": "https",
"elements": [
{
"id": "1",
"name": "element1",
"link": "https:"
}
]
},
{
"id": "newid",
"name": "newname",
"link": "newlink"
"elements":[]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
.......
]
}
Demo - https://mongoplayground.net/p/Dnmg3lL2891
Use - $[]
The all positional operator $[] indicates that the update operator
should modify all elements in the specified array field.
The $[] operator has the following form:
{ <update operator>: { "<array>.$[]" : value } }
db.collection.update({ _id: 1, "add.id": "1"},
{ $push: { "add.$[].elements": { id: "3", name: "a", link: "" } } })
Demo to push array instead of object - https://mongoplayground.net/p/dh3NSutIv4-
db.collection.update({ _id: 1, "add.id": "1"},
{ $push: { "add.$[].elements": [{ id: "3", name: "a", link: "" }] } })
const args = {};
args.elementNum = 0;
const update = {
[`add.$[].elements.${args.elementNum}`]: {
a: 1
}
};
console.log(update);
//collection.updateOne({ id: args.id }, update); // use like this

How to convert the JSON into nested Array format in typescript?

I am trying to convert the JSON to nested array format. The following one is my JSON data:
{
"items": {
"BMW": {
"group": "car",
"title": "BMW car"
},
"320": {
"group": "BMW",
"title": "320 Mod"
},
"X3": {
"group": "BMW",
"title": "X3"
},
"X5": {
"group": "BMW",
"title": "X5 Mod"
},
"Ford": {
"group": "car",
"title": "Ford car"
},
"Fiesta": {
"group": "Ford",
"title": "Fiesta Mod"
},
"Focus": {
"group": "Ford",
"title": "Focus Mod"
}
}
}
The JSON data has group. Based on that group I need to convert dynamically into desired array format. Below array is my expected output. Can anyone please help me to write program in typescript.
arrayObj = [
{
Name: "BMW car",
id:"BMW",
group: "car",
children: [
{ Name: "320 Mod", id:"320", group: "BMW" },
{ Name: "X3 Mod", id:"X3", group: "BMW" },
{ Name: "X5 Mod", id:"X5", group: "BMW" }
]
},
{
Name: "Ford car",
group: "car",
id: "Ford",
children: [
{ Name: "Fiesta Mod", id:"Fiesta", group: "Ford" },
{ Name: "Focus Mod", id:"Focus", group: "Ford" }
]
}
];
You can use reduce() function to achieve this, see code below
const initialObject = {
"items": {
"BMW": {
"group": "car",
"title": "BMW"
},
"320": {
"group": "BMW",
"title": "320"
},
"X3": {
"group": "BMW",
"title": "X3"
},
"X5": {
"group": "BMW",
"title": "X5"
},
"Ford": {
"group": "car",
"title": "Ford"
},
"Fiesta": {
"group": "Ford",
"title": "Fiesta"
},
"Focus": {
"group": "Ford",
"title": "Focus"
}
}
}
const finalData = Object.values(Object.values(initialObject.items).reduce((prev, {group, title}) => {
let children = prev[group]?.children
if (!children) {
children = []
}
children.push({name: title, group })
return {...prev, [group]: {
name: group,
group:title,
children
}}
}, {}))
console.log(finalData)

Filter data of an array in setState in reactjs

In the code below, I am trying to make an array and remove duplicates from array with reactjs:
The array called names is set in state:
this.state = {
names = []
}
How can I remove the duplicated names and place them into the array
const data = [
{
"obj": {
"no": "1",
"info": [
{
"name": "maya"
},
{
"name": "mina"
}
]
}
},
{
"obj": {
"no": "2",
"info": [
{
"name": "maya"
}
]
}
},
{
"obj": {
"no": "3",
"info": [
{
"name": "mina"
},
{
"name": "Mike"
}
]
}
}
]
data.map((elem) => {
for(let i = 0 ; i < elem.info.length;i++){
let name_info = elem.info[i].name
this.setState({
names: [...this.state.names, name_info]
})
}
})
expected output :["maya","mina",Mike]
If you're fan of one line
[...(new Set(data.map(d => d['obj']['info']).flat().map(info => info['name'])))]
Step by step explanation:
First map takes the input returns only info part of each entry:
data.map(d => d['obj']['info']) yields array of array containing info.
[[{ name: "maya" }, { name: "mina" }], [{ name: "maya" }], [{ name: "mina" }, { name: "Mike" }]]
flat() takes the input from previous map which is the array of array and yields array of elements, so it becomes
[{ name: "maya" }, { name: "mina" }, { name: "maya" }, { name: "mina" }, { name: "Mike" }]
map() takes the input from previous flat which is array of object (which contains name) and returns array of name value.
So you got [ "maya", "mina", "maya", "mina", "Mike" ]
The final array is given to Set, by definition set cannot contain same element more than one. Set of previous array is [ "maya", "mina", "Mike" ].
As final step, set is converted to the array by using spread operator.
const data = [
{
"obj": {
"no": "1",
"info": [
{
"name": "maya"
},
{
"name": "mina"
}
]
}
},
{
"obj": {
"no": "2",
"info": [
{
"name": "maya"
}
]
}
},
{
"obj": {
"no": "3",
"info": [
{
"name": "mina"
},
{
"name": "Mike"
}
]
}
}
];
let names = [];
data.forEach(item => {
Object.values(item)[0].info.forEach(person => {
if(names.indexOf(person.name) === -1)
{
names.push(person.name)
}
})
})
console.log(names);
I think this can help you
First, this is a helper function to get just the unique value of an array
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
And, this is how can get the result you want
const newNames = data.map((elem) => elem.obj.info.map(info => info.name)).flat().filter(onlyUnique)
You can then use it like this
this.setState({
names: [...this.state.names, ...newNames]
})
const data = [{
"obj": {
"no": "1",
"info": [{
"name": "maya"
}, {
"name": "mina"
}]
}
}, {
"obj": {
"no": "2",
"info": [{
"name": "maya"
}]
}
}, {
"obj": {
"no": "3",
"info": [{
"name": "mina"
}, {
"name": "Mike"
}]
}
}]
const names = data.flatMap(obj => obj.obj.info.map(info => info.name));
const unique = names.filter((name, i) => names.indexOf(name) === i);
console.log(unique);

Resources