React Native modal TextInput doesn’t work

View

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import React, { useState, useEffect } from "react";
import {
View,
Text,
TouchableOpacity,
ActivityIndicator,
Modal,
StyleSheet,
Alert
} from "react-native";
import { globalStyles } from "../globalStyles.js";
import { styles } from "./styles.js"; // Importamos los estilos desde styles.js
import * as RootNavigation from "../../utils/navigator/RootNavigation.js";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { PedidosComercialLogic } from "./PedidosComercialLogic";
import { Button } from "@rneui/themed";
import { FlashList } from "@shopify/flash-list";
import { SearchInput } from "../otros/SearchInput";
import { useGlobalContext } from "../../utils/context/GlobalContextProvider.js";
import { useInternetContext } from "../../utils/context/InternetContextProvider.js";
import { PdaUser } from "../../class/PdaUser.class";
import QuantitySelector from "../otros/QuantitySelector.jsx";
import { HOME } from "../../utils/const/navigatorConst.js";
import { getSecureStoreData } from "../../utils/gettersAndSetters/getters.js";
import { SHOW_PRICE_WITH_TAX } from "../../utils/const/secureStoreConst.js";
import PdfTabNavigator from "../otros/pdfView/PdfTabNavigator.jsx";
import ListadoPedidos from "../pedidos/ListadoPedidos.jsx";
const PedidosComercialScreenView = (props) => {
const [clientProducts, setClientProducts] = useState([]);
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(new PdaUser());
const [globalState, setGlobalState] = useGlobalContext();
const [searchText, setSearchText] = useState("");
const selectedClientId = props.cliente.client;
const [showAllProducts, setShowAllProducts] = useState(false);
const [showCobros, setShowCobros] = useState(false);
const [allProducts, setAllProducts] = useState([]);
const [quantities, setQuantities] = useState({});
const [isQuantityModalVisible, setQuantityModalVisible] = useState(false);
const [selectedProduct, setSelectedProduct] = useState(null);
const [isPurchaseModalVisible, setPurchaseModalVisible] = useState(false);
const [totalPurchase, setTotalPurchase] = useState(0);
const [showFinalizeOptionsModal, setShowFinalizeOptionsModal] =
useState(false);
const [internetState, setInternetState] = useInternetContext();
const [showPriceWithTax, setShowPriceWithTax] = useState(false);
const [visibleData, setVisibleData] = useState([]);
const [pdfUrls, setPdfUrls] = useState([]);
const [pendingPayments, setPendingPayments] = useState([]);
const [isPendingPaymentsModalVisible, setPendingPaymentsModalVisible] =
useState(false);
const itemsPerPage = 10;
const [page, setPage] = useState(1);
var DEV = new PedidosComercialLogic({
clientProducts,
setClientProducts,
products,
setProducts,
setLoading,
setUser,
user,
setGlobalState,
globalState,
selectedClientId,
});
useEffect(() => {
async function fetchData() {
const showPriceWithTax = await getSecureStoreData(SHOW_PRICE_WITH_TAX);
setShowPriceWithTax(showPriceWithTax === "true");
await DEV.init();
if (internetState.isConnected) {
try {
await DEV.getProductsByOrders(props.cliente.client);
await DEV.getProducts();
} catch (error) {
console.error("Error al cargar clientes:", error);
}
} else {
try {
await DEV.getLocalProductsByOrders();
await DEV.getLocalProducts();
} catch (error) {
console.error("Error al cargar clientes:", error);
}
}
try {
const totalDue = await DEV.getTotalDueByClient(props.cliente.client);
setPendingPayments(totalDue);
setPendingPaymentsModalVisible(true);
} catch (error) {
console.error("Error fetching total due:", error);
Alert.alert("Error", "Problemas al obtener los pagos pendientes.");
}
}
fetchData();
}, []);
useEffect(() => {
mergeProducts(clientProducts, products);
}, [products, clientProducts]);
useEffect(() => {
setVisibleData(filteredProducts.slice(0, itemsPerPage));
setPage(1);
}, [allProducts, showAllProducts, filteredProducts]);
useEffect(() => {
const filtered = allProducts.filter(
(product) =>
(product.label || "")
.toLowerCase()
.includes(searchText.toLowerCase()) &&
(showAllProducts ? product.client === 0 : product.client === 1)
);
setVisibleData(filtered.slice(0, itemsPerPage));
setPage(1);
}, [searchText, allProducts, showAllProducts]);
const loadMoreData = () => {
const filtered = allProducts.filter(
(product) =>
(product.label || "")
.toLowerCase()
.includes(searchText.toLowerCase()) &&
(showAllProducts ? product.client === 0 : product.client === 1)
);
const startIndex = page * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const newData = filtered.slice(startIndex, endIndex);
setPage(page + 1);
setVisibleData((prevData) => [...prevData, ...newData]);
};
const mergeProducts = async (clientProducts, products) => {
const productMap = new Map();
products.forEach((product) => {
if (product.fkProduct != null) {
productMap.set(product.fkProduct, {
...product,
client: 0,
quantity: 0,
productStock: product.productStock || 0,
});
}
});
clientProducts.forEach((product) => {
if (product.fkProduct != null) {
const existingProduct = productMap.get(product.fkProduct);
if (existingProduct) {
productMap.set(product.fkProduct, {
...existingProduct,
...product,
productStock:
product.productStock || existingProduct.productStock || 0,
client: 1,
});
} else {
productMap.set(product.fkProduct, {
...product,
client: 1,
productStock: product.productStock || 0,
});
}
}
});
const arrayMerge = Array.from(productMap.values());
setAllProducts(arrayMerge);
if (internetState.isConnected) {
await DEV.saveProductsLocal(arrayMerge);
}
setLoading(false);
};
const handleSearch = (text) => {
setSearchText(text);
};
const toggleProductList = () => {
setLoading(true);
setShowAllProducts(!showAllProducts);
setLoading(false);
};
const addProductToClient = (product) => {
setSelectedProduct(product);
setQuantityModalVisible(true);
};
const handleQuantitySave = (quantity, subprice, discount) => {
console.log("CANTIDAD", subprice)
setQuantities((prevQuantities) => ({
...prevQuantities,
[selectedProduct.fkProduct]: quantity,
}));
const updatedClientProducts = clientProducts.map((product) => {
if (product.fkProduct === selectedProduct.fkProduct) {
return {
...product,
quantity,
subprice: subprice,
remise_percent: discount,
client: 1,
};
}
return product;
});
if (
!updatedClientProducts.find(
(product) => product.fkProduct === selectedProduct.fkProduct
)
) {
updatedClientProducts.push({
...selectedProduct,
quantity,
subprice: subprice,
remise_percent: discount,
client: 1,
});
}
setClientProducts(updatedClientProducts);
mergeProducts(updatedClientProducts, products);
setQuantityModalVisible(false);
};
const removeProductFromClient = (fkProduct) => {
setLoading(true);
const remainingClientProducts = clientProducts.filter(
(product) => product.fkProduct !== fkProduct
);
const updatedProducts = products.map((product) => {
if (product.fkProduct === fkProduct) {
return { ...product, client: 0, quantity: 0 };
}
return product;
});
setClientProducts(remainingClientProducts);
setProducts(updatedProducts);
mergeProducts(remainingClientProducts, updatedProducts);
setLoading(false);
};
const handleQuantityChange = (fkProduct, newQuantity) => {
setQuantities((currentQuantities) => ({
...currentQuantities,
[fkProduct]: newQuantity,
}));
if (newQuantity === 0) {
removeProductFromClient(fkProduct);
} else {
const updatedClientProducts = clientProducts.map((product) =>
product.fkProduct === fkProduct
? { ...product, quantity: newQuantity }
: product
);
setClientProducts(updatedClientProducts);
mergeProducts(updatedClientProducts, products);
}
};
const filteredProducts = allProducts.filter(
(product) =>
(product.label || "").toLowerCase().includes(searchText.toLowerCase()) &&
(showAllProducts ? product.client === 0 : product.client === 1)
);
const countProductsWithQuantity = () => {
return allProducts.filter(
(product) => product.client === 1 && quantities[product.fkProduct] > 0
).length;
};
const calculateTotalPurchase = () => {
return allProducts
.reduce((acc, product) => {
if (product.client === 1 && quantities[product.fkProduct]) {
const priceWithDiscount =
product.subprice * (1 - product.remise_percent / 100);
return acc + priceWithDiscount * quantities[product.fkProduct];
}
return acc;
}, 0)
.toFixed(2);
};
const finalizePurchase = async () => {
let filteredProducts = allProducts.filter(
(product) =>
product.client === 1 &&
!Number.isNaN(parseInt(product.quantity)) &&
parseInt(product.quantity) > 0 &&
product.fkProduct != null
);
let pdfUrlsArray = [];
if (!internetState.isConnected) {
await DEV.saveOrderLocally(props.cliente.clientId, filteredProducts, 0);
success = true;
} else {
if (props.cliente.client != null) {
const totalPurchase = filteredProducts.reduce(
(acc, product) =>
acc + parseFloat(product.price) * parseInt(product.quantity),
0
);
setTotalPurchase(totalPurchase.toFixed(2));
const response = await DEV.createOrderFromClient(
props.cliente.client,
filteredProducts.map(product => ({
...product,
price: parseFloat(product.price) // Ensure the price is always multiprices["1"]
})),
0
);
if (response) {
pdfUrlsArray.push(response);
} else {
console.error(
"Error al realizar la compra:",
response.error
);
}
} else {
console.log("El ID del cliente es nulo.");
}
}
if (pdfUrlsArray.length > 0) {
setPdfUrls(pdfUrlsArray);
setPurchaseModalVisible(true);
}
};
const calculateProductPrice = (subprice_ttc, subprice, tva_tx, showPriceWithTax) => {
if (showPriceWithTax) {
return parseFloat(subprice_ttc).toFixed(2);
} else {
return parseFloat(subprice).toFixed(2);
}
};
if(showCobros){
return <ListadoPedidos cliente={props.cliente}/>
}
return (
<View style={[{ flex: 1, padding: 2 }, globalStyles.container]}>
<View style={styles.headerContainer}>
<View style={styles.headerContent}>
<Icon
name={showAllProducts ? "arrow-left" : "cart-plus"}
size={40}
onPress={toggleProductList}
/>
<View style={styles.headerTitle}>
<Text style={styles.headerTitleText}>{props.cliente.name}</Text>
<Text
style={styles.headerTitleText}
>{`TOTAL CARRITO SIN IVA: ${calculateTotalPurchase()} €`}</Text>
</View>
{!showAllProducts ? (
<Icon
name="content-save"
size={40}
onPress={() => setShowFinalizeOptionsModal(true)}
/>
) : (
<Icon
name="content-save"
size={40}
onPress={toggleProductList}
/>
)}
</View>
<View style={styles.buscarStyle}>
<SearchInput
placeholder="Buscar producto..."
onSearch={handleSearch}
/>
</View>
</View>
{loading ? (
<>
<ActivityIndicator size="large" />
</>
) : (
<FlashList
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="handled"
data={visibleData}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => addProductToClient(item)}>
<View
style={[
styles.productContainer,
{
backgroundColor: item.client === 1 ? "#2271b3" : "#FDFD96",
},
]}
>
<View style={styles.productHeader}>
<View style={styles.productHeaderTitle}>
<Text style={styles.productHeaderText}>{item.label}</Text>
</View>
<Icon
name="calculator"
size={50}
onPress={() => addProductToClient(item)}
/>
</View>
<View style={styles.containerRow}>
<View style={styles.priceContainer}>
{!showAllProducts ? (
<>
<View style={styles.priceColumn}>
<Text style={styles.priceText}>
Precio histórico{" "}
{showPriceWithTax ? "IVA" : "SIN IVA"}:{" "}
{`${calculateProductPrice(
item.subprice,
item.subprice_ttc,
item.tva_tx,
showPriceWithTax
)} €`}
</Text>
</View>
<View style={styles.priceColumn}>
{item.realPrice !== 0 ? (
<Text style={styles.priceText}>
Precio {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "}
{`${calculateProductPrice(
item.price,
item.subprice,
item.tva_tx,
showPriceWithTax
)} €`}
</Text>
) : null}
</View>
</>
) : (
<>
<Text style={styles.priceText}>
Precio venta {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "}
{`${calculateProductPrice(
item.subprice,
item.subprice,
item.tva_tx,
showPriceWithTax
)} €`}
</Text>
</>
)}
<Text style={styles.priceText}>
Precio Total:{" "}
{`${
(
parseFloat(item.subprice || 0) *
(quantities[item.fkProduct] || 0) *
(1 - parseFloat(item.remise_percent || 0) / 100)
).toFixed(2) || 0
} €`}
</Text>
<Text style={styles.priceText}>
Stock actual: {item.productStock || 0}
</Text>
</View>
<View style={styles.stockContainer}>
<Text style={styles.stockText}>
Unidades/caja: {item.options_unidades || 0}
</Text>
<Text style={styles.stockText}>
Unidades : {quantities[item.fkProduct] || 0} uds
</Text>
{!showAllProducts ? (
<Text style={styles.stockText}>
Descuento: {item.remise_percent || 0}%
</Text>
) : (
<></>
)}
</View>
</View>
</View>
</TouchableOpacity>
)}
keyExtractor={(item) => item.fkProduct.toString()}
onEndReached={loadMoreData}
onEndReachedThreshold={0.1}
estimatedItemSize={200}
threshold={5}
/>
)}
<View style={styles.footerContainer}>
<Text
style={styles.footerText}
>{`Productos seleccionados: ${countProductsWithQuantity()}`}</Text>
</View>
<Modal
animationType="slide"
transparent={true}
visible={isQuantityModalVisible}
onRequestClose={() => setQuantityModalVisible(!isQuantityModalVisible)}
>
<QuantitySelector
isVisible={isQuantityModalVisible}
onClose={() => setQuantityModalVisible(false)}
onSave={handleQuantitySave}
product={selectedProduct}
showPriceWithTax={showPriceWithTax}
/>
</Modal>
<Modal
animationType="slide"
transparent={true}
visible={showFinalizeOptionsModal}
onRequestClose={() => setShowFinalizeOptionsModal(false)}
>
<View style={styles.modalContainer}>
<View style={styles.modalContent}>
<Text style={styles.modalTitle}>
FINALIZACIÓN DEL PEDIDO
</Text>
<Button
buttonStyle={styles.buttonStyle}
title="Crear pedido completo"
onPress={() => {
finalizePurchase(false);
setShowFinalizeOptionsModal(false);
}}
/>
<Button
buttonStyle={styles.buttonStyle}
title="Cancelar"
onPress={() => setShowFinalizeOptionsModal(false)}
/>
</View>
</View>
</Modal>
<Modal
animationType="slide"
transparent={true}
visible={isPurchaseModalVisible}
onRequestClose={() => setPurchaseModalVisible(false)}
>
<View style={styles.modalContainer}>
<View style={styles.modalContent}>
<Text style={styles.modalTitle}>Pedido creado correctamente</Text>
<Text style={styles.modalSubTitle}>
Total: €{calculateTotalPurchase()}
</Text>
{/* {pdfUrls.length > 0 &&
(console.log("VEAMOS si hay pdfs o no", pdfUrls),
(<PdfTabNavigator pdfUrls={pdfUrls} />))} */}
<Button
buttonStyle={styles.buttonStyle}
title="Ver cobros"
onPress={() => {
setPurchaseModalVisible(false);
props.navigation.navigate("NuevaPantalla");
}}
/>
<Button
buttonStyle={styles.buttonStyle}
title="Home"
onPress={() => {
setPurchaseModalVisible(false);
RootNavigation.navigate(HOME);
}}
/>
</View>
</View>
</Modal>
<Modal
animationType="slide"
transparent={true}
visible={isPendingPaymentsModalVisible}
onRequestClose={() => setPendingPaymentsModalVisible(false)}
>
<View style={modalStyles.modalContainer}>
<View style={modalStyles.modalContent}>
<Text style={modalStyles.modalTitle}>PAGOS PENDIENTES</Text>
{pendingPayments.total_due > 0 ? (
<View>
<Text style={modalStyles.modalSubTitle}>
TOTAL :{pendingPayments.total_due.toFixed(2) }
</Text>
</View>
) : (
<Text style={modalStyles.modalSubTitle}>
No hay pagos pendientes.
</Text>
)}
<Button
buttonStyle={modalStyles.buttonStyle}
title="Ver cobros"
onPress={() => setShowCobros(true)}
/>
<Button
buttonStyle={modalStyles.buttonStyle}
title="Cerrar"
onPress={() => setPendingPaymentsModalVisible(false)}
/>
</View>
</View>
</Modal>
</View>
);
};
export default PedidosComercialScreenView;
</code>
<code>import React, { useState, useEffect } from "react"; import { View, Text, TouchableOpacity, ActivityIndicator, Modal, StyleSheet, Alert } from "react-native"; import { globalStyles } from "../globalStyles.js"; import { styles } from "./styles.js"; // Importamos los estilos desde styles.js import * as RootNavigation from "../../utils/navigator/RootNavigation.js"; import Icon from "react-native-vector-icons/MaterialCommunityIcons"; import { PedidosComercialLogic } from "./PedidosComercialLogic"; import { Button } from "@rneui/themed"; import { FlashList } from "@shopify/flash-list"; import { SearchInput } from "../otros/SearchInput"; import { useGlobalContext } from "../../utils/context/GlobalContextProvider.js"; import { useInternetContext } from "../../utils/context/InternetContextProvider.js"; import { PdaUser } from "../../class/PdaUser.class"; import QuantitySelector from "../otros/QuantitySelector.jsx"; import { HOME } from "../../utils/const/navigatorConst.js"; import { getSecureStoreData } from "../../utils/gettersAndSetters/getters.js"; import { SHOW_PRICE_WITH_TAX } from "../../utils/const/secureStoreConst.js"; import PdfTabNavigator from "../otros/pdfView/PdfTabNavigator.jsx"; import ListadoPedidos from "../pedidos/ListadoPedidos.jsx"; const PedidosComercialScreenView = (props) => { const [clientProducts, setClientProducts] = useState([]); const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); const [user, setUser] = useState(new PdaUser()); const [globalState, setGlobalState] = useGlobalContext(); const [searchText, setSearchText] = useState(""); const selectedClientId = props.cliente.client; const [showAllProducts, setShowAllProducts] = useState(false); const [showCobros, setShowCobros] = useState(false); const [allProducts, setAllProducts] = useState([]); const [quantities, setQuantities] = useState({}); const [isQuantityModalVisible, setQuantityModalVisible] = useState(false); const [selectedProduct, setSelectedProduct] = useState(null); const [isPurchaseModalVisible, setPurchaseModalVisible] = useState(false); const [totalPurchase, setTotalPurchase] = useState(0); const [showFinalizeOptionsModal, setShowFinalizeOptionsModal] = useState(false); const [internetState, setInternetState] = useInternetContext(); const [showPriceWithTax, setShowPriceWithTax] = useState(false); const [visibleData, setVisibleData] = useState([]); const [pdfUrls, setPdfUrls] = useState([]); const [pendingPayments, setPendingPayments] = useState([]); const [isPendingPaymentsModalVisible, setPendingPaymentsModalVisible] = useState(false); const itemsPerPage = 10; const [page, setPage] = useState(1); var DEV = new PedidosComercialLogic({ clientProducts, setClientProducts, products, setProducts, setLoading, setUser, user, setGlobalState, globalState, selectedClientId, }); useEffect(() => { async function fetchData() { const showPriceWithTax = await getSecureStoreData(SHOW_PRICE_WITH_TAX); setShowPriceWithTax(showPriceWithTax === "true"); await DEV.init(); if (internetState.isConnected) { try { await DEV.getProductsByOrders(props.cliente.client); await DEV.getProducts(); } catch (error) { console.error("Error al cargar clientes:", error); } } else { try { await DEV.getLocalProductsByOrders(); await DEV.getLocalProducts(); } catch (error) { console.error("Error al cargar clientes:", error); } } try { const totalDue = await DEV.getTotalDueByClient(props.cliente.client); setPendingPayments(totalDue); setPendingPaymentsModalVisible(true); } catch (error) { console.error("Error fetching total due:", error); Alert.alert("Error", "Problemas al obtener los pagos pendientes."); } } fetchData(); }, []); useEffect(() => { mergeProducts(clientProducts, products); }, [products, clientProducts]); useEffect(() => { setVisibleData(filteredProducts.slice(0, itemsPerPage)); setPage(1); }, [allProducts, showAllProducts, filteredProducts]); useEffect(() => { const filtered = allProducts.filter( (product) => (product.label || "") .toLowerCase() .includes(searchText.toLowerCase()) && (showAllProducts ? product.client === 0 : product.client === 1) ); setVisibleData(filtered.slice(0, itemsPerPage)); setPage(1); }, [searchText, allProducts, showAllProducts]); const loadMoreData = () => { const filtered = allProducts.filter( (product) => (product.label || "") .toLowerCase() .includes(searchText.toLowerCase()) && (showAllProducts ? product.client === 0 : product.client === 1) ); const startIndex = page * itemsPerPage; const endIndex = startIndex + itemsPerPage; const newData = filtered.slice(startIndex, endIndex); setPage(page + 1); setVisibleData((prevData) => [...prevData, ...newData]); }; const mergeProducts = async (clientProducts, products) => { const productMap = new Map(); products.forEach((product) => { if (product.fkProduct != null) { productMap.set(product.fkProduct, { ...product, client: 0, quantity: 0, productStock: product.productStock || 0, }); } }); clientProducts.forEach((product) => { if (product.fkProduct != null) { const existingProduct = productMap.get(product.fkProduct); if (existingProduct) { productMap.set(product.fkProduct, { ...existingProduct, ...product, productStock: product.productStock || existingProduct.productStock || 0, client: 1, }); } else { productMap.set(product.fkProduct, { ...product, client: 1, productStock: product.productStock || 0, }); } } }); const arrayMerge = Array.from(productMap.values()); setAllProducts(arrayMerge); if (internetState.isConnected) { await DEV.saveProductsLocal(arrayMerge); } setLoading(false); }; const handleSearch = (text) => { setSearchText(text); }; const toggleProductList = () => { setLoading(true); setShowAllProducts(!showAllProducts); setLoading(false); }; const addProductToClient = (product) => { setSelectedProduct(product); setQuantityModalVisible(true); }; const handleQuantitySave = (quantity, subprice, discount) => { console.log("CANTIDAD", subprice) setQuantities((prevQuantities) => ({ ...prevQuantities, [selectedProduct.fkProduct]: quantity, })); const updatedClientProducts = clientProducts.map((product) => { if (product.fkProduct === selectedProduct.fkProduct) { return { ...product, quantity, subprice: subprice, remise_percent: discount, client: 1, }; } return product; }); if ( !updatedClientProducts.find( (product) => product.fkProduct === selectedProduct.fkProduct ) ) { updatedClientProducts.push({ ...selectedProduct, quantity, subprice: subprice, remise_percent: discount, client: 1, }); } setClientProducts(updatedClientProducts); mergeProducts(updatedClientProducts, products); setQuantityModalVisible(false); }; const removeProductFromClient = (fkProduct) => { setLoading(true); const remainingClientProducts = clientProducts.filter( (product) => product.fkProduct !== fkProduct ); const updatedProducts = products.map((product) => { if (product.fkProduct === fkProduct) { return { ...product, client: 0, quantity: 0 }; } return product; }); setClientProducts(remainingClientProducts); setProducts(updatedProducts); mergeProducts(remainingClientProducts, updatedProducts); setLoading(false); }; const handleQuantityChange = (fkProduct, newQuantity) => { setQuantities((currentQuantities) => ({ ...currentQuantities, [fkProduct]: newQuantity, })); if (newQuantity === 0) { removeProductFromClient(fkProduct); } else { const updatedClientProducts = clientProducts.map((product) => product.fkProduct === fkProduct ? { ...product, quantity: newQuantity } : product ); setClientProducts(updatedClientProducts); mergeProducts(updatedClientProducts, products); } }; const filteredProducts = allProducts.filter( (product) => (product.label || "").toLowerCase().includes(searchText.toLowerCase()) && (showAllProducts ? product.client === 0 : product.client === 1) ); const countProductsWithQuantity = () => { return allProducts.filter( (product) => product.client === 1 && quantities[product.fkProduct] > 0 ).length; }; const calculateTotalPurchase = () => { return allProducts .reduce((acc, product) => { if (product.client === 1 && quantities[product.fkProduct]) { const priceWithDiscount = product.subprice * (1 - product.remise_percent / 100); return acc + priceWithDiscount * quantities[product.fkProduct]; } return acc; }, 0) .toFixed(2); }; const finalizePurchase = async () => { let filteredProducts = allProducts.filter( (product) => product.client === 1 && !Number.isNaN(parseInt(product.quantity)) && parseInt(product.quantity) > 0 && product.fkProduct != null ); let pdfUrlsArray = []; if (!internetState.isConnected) { await DEV.saveOrderLocally(props.cliente.clientId, filteredProducts, 0); success = true; } else { if (props.cliente.client != null) { const totalPurchase = filteredProducts.reduce( (acc, product) => acc + parseFloat(product.price) * parseInt(product.quantity), 0 ); setTotalPurchase(totalPurchase.toFixed(2)); const response = await DEV.createOrderFromClient( props.cliente.client, filteredProducts.map(product => ({ ...product, price: parseFloat(product.price) // Ensure the price is always multiprices["1"] })), 0 ); if (response) { pdfUrlsArray.push(response); } else { console.error( "Error al realizar la compra:", response.error ); } } else { console.log("El ID del cliente es nulo."); } } if (pdfUrlsArray.length > 0) { setPdfUrls(pdfUrlsArray); setPurchaseModalVisible(true); } }; const calculateProductPrice = (subprice_ttc, subprice, tva_tx, showPriceWithTax) => { if (showPriceWithTax) { return parseFloat(subprice_ttc).toFixed(2); } else { return parseFloat(subprice).toFixed(2); } }; if(showCobros){ return <ListadoPedidos cliente={props.cliente}/> } return ( <View style={[{ flex: 1, padding: 2 }, globalStyles.container]}> <View style={styles.headerContainer}> <View style={styles.headerContent}> <Icon name={showAllProducts ? "arrow-left" : "cart-plus"} size={40} onPress={toggleProductList} /> <View style={styles.headerTitle}> <Text style={styles.headerTitleText}>{props.cliente.name}</Text> <Text style={styles.headerTitleText} >{`TOTAL CARRITO SIN IVA: ${calculateTotalPurchase()} €`}</Text> </View> {!showAllProducts ? ( <Icon name="content-save" size={40} onPress={() => setShowFinalizeOptionsModal(true)} /> ) : ( <Icon name="content-save" size={40} onPress={toggleProductList} /> )} </View> <View style={styles.buscarStyle}> <SearchInput placeholder="Buscar producto..." onSearch={handleSearch} /> </View> </View> {loading ? ( <> <ActivityIndicator size="large" /> </> ) : ( <FlashList keyboardDismissMode="interactive" keyboardShouldPersistTaps="handled" data={visibleData} renderItem={({ item }) => ( <TouchableOpacity onPress={() => addProductToClient(item)}> <View style={[ styles.productContainer, { backgroundColor: item.client === 1 ? "#2271b3" : "#FDFD96", }, ]} > <View style={styles.productHeader}> <View style={styles.productHeaderTitle}> <Text style={styles.productHeaderText}>{item.label}</Text> </View> <Icon name="calculator" size={50} onPress={() => addProductToClient(item)} /> </View> <View style={styles.containerRow}> <View style={styles.priceContainer}> {!showAllProducts ? ( <> <View style={styles.priceColumn}> <Text style={styles.priceText}> Precio histórico{" "} {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "} {`${calculateProductPrice( item.subprice, item.subprice_ttc, item.tva_tx, showPriceWithTax )} €`} </Text> </View> <View style={styles.priceColumn}> {item.realPrice !== 0 ? ( <Text style={styles.priceText}> Precio {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "} {`${calculateProductPrice( item.price, item.subprice, item.tva_tx, showPriceWithTax )} €`} </Text> ) : null} </View> </> ) : ( <> <Text style={styles.priceText}> Precio venta {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "} {`${calculateProductPrice( item.subprice, item.subprice, item.tva_tx, showPriceWithTax )} €`} </Text> </> )} <Text style={styles.priceText}> Precio Total:{" "} {`${ ( parseFloat(item.subprice || 0) * (quantities[item.fkProduct] || 0) * (1 - parseFloat(item.remise_percent || 0) / 100) ).toFixed(2) || 0 } €`} </Text> <Text style={styles.priceText}> Stock actual: {item.productStock || 0} </Text> </View> <View style={styles.stockContainer}> <Text style={styles.stockText}> Unidades/caja: {item.options_unidades || 0} </Text> <Text style={styles.stockText}> Unidades : {quantities[item.fkProduct] || 0} uds </Text> {!showAllProducts ? ( <Text style={styles.stockText}> Descuento: {item.remise_percent || 0}% </Text> ) : ( <></> )} </View> </View> </View> </TouchableOpacity> )} keyExtractor={(item) => item.fkProduct.toString()} onEndReached={loadMoreData} onEndReachedThreshold={0.1} estimatedItemSize={200} threshold={5} /> )} <View style={styles.footerContainer}> <Text style={styles.footerText} >{`Productos seleccionados: ${countProductsWithQuantity()}`}</Text> </View> <Modal animationType="slide" transparent={true} visible={isQuantityModalVisible} onRequestClose={() => setQuantityModalVisible(!isQuantityModalVisible)} > <QuantitySelector isVisible={isQuantityModalVisible} onClose={() => setQuantityModalVisible(false)} onSave={handleQuantitySave} product={selectedProduct} showPriceWithTax={showPriceWithTax} /> </Modal> <Modal animationType="slide" transparent={true} visible={showFinalizeOptionsModal} onRequestClose={() => setShowFinalizeOptionsModal(false)} > <View style={styles.modalContainer}> <View style={styles.modalContent}> <Text style={styles.modalTitle}> FINALIZACIÓN DEL PEDIDO </Text> <Button buttonStyle={styles.buttonStyle} title="Crear pedido completo" onPress={() => { finalizePurchase(false); setShowFinalizeOptionsModal(false); }} /> <Button buttonStyle={styles.buttonStyle} title="Cancelar" onPress={() => setShowFinalizeOptionsModal(false)} /> </View> </View> </Modal> <Modal animationType="slide" transparent={true} visible={isPurchaseModalVisible} onRequestClose={() => setPurchaseModalVisible(false)} > <View style={styles.modalContainer}> <View style={styles.modalContent}> <Text style={styles.modalTitle}>Pedido creado correctamente</Text> <Text style={styles.modalSubTitle}> Total: €{calculateTotalPurchase()} </Text> {/* {pdfUrls.length > 0 && (console.log("VEAMOS si hay pdfs o no", pdfUrls), (<PdfTabNavigator pdfUrls={pdfUrls} />))} */} <Button buttonStyle={styles.buttonStyle} title="Ver cobros" onPress={() => { setPurchaseModalVisible(false); props.navigation.navigate("NuevaPantalla"); }} /> <Button buttonStyle={styles.buttonStyle} title="Home" onPress={() => { setPurchaseModalVisible(false); RootNavigation.navigate(HOME); }} /> </View> </View> </Modal> <Modal animationType="slide" transparent={true} visible={isPendingPaymentsModalVisible} onRequestClose={() => setPendingPaymentsModalVisible(false)} > <View style={modalStyles.modalContainer}> <View style={modalStyles.modalContent}> <Text style={modalStyles.modalTitle}>PAGOS PENDIENTES</Text> {pendingPayments.total_due > 0 ? ( <View> <Text style={modalStyles.modalSubTitle}> TOTAL : €{pendingPayments.total_due.toFixed(2) } </Text> </View> ) : ( <Text style={modalStyles.modalSubTitle}> No hay pagos pendientes. </Text> )} <Button buttonStyle={modalStyles.buttonStyle} title="Ver cobros" onPress={() => setShowCobros(true)} /> <Button buttonStyle={modalStyles.buttonStyle} title="Cerrar" onPress={() => setPendingPaymentsModalVisible(false)} /> </View> </View> </Modal> </View> ); }; export default PedidosComercialScreenView; </code>
import React, { useState, useEffect } from "react";
import {
  View,
  Text,
  TouchableOpacity,
  ActivityIndicator,
  Modal,
  StyleSheet,
  Alert
} from "react-native";
import { globalStyles } from "../globalStyles.js";
import { styles } from "./styles.js"; // Importamos los estilos desde styles.js
import * as RootNavigation from "../../utils/navigator/RootNavigation.js";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { PedidosComercialLogic } from "./PedidosComercialLogic";
import { Button } from "@rneui/themed";
import { FlashList } from "@shopify/flash-list";
import { SearchInput } from "../otros/SearchInput";
import { useGlobalContext } from "../../utils/context/GlobalContextProvider.js";
import { useInternetContext } from "../../utils/context/InternetContextProvider.js";
import { PdaUser } from "../../class/PdaUser.class";
import QuantitySelector from "../otros/QuantitySelector.jsx";
import { HOME } from "../../utils/const/navigatorConst.js";
import { getSecureStoreData } from "../../utils/gettersAndSetters/getters.js";
import { SHOW_PRICE_WITH_TAX } from "../../utils/const/secureStoreConst.js";
import PdfTabNavigator from "../otros/pdfView/PdfTabNavigator.jsx";
import ListadoPedidos from "../pedidos/ListadoPedidos.jsx";

const PedidosComercialScreenView = (props) => {
  const [clientProducts, setClientProducts] = useState([]);
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(new PdaUser());
  const [globalState, setGlobalState] = useGlobalContext();
  const [searchText, setSearchText] = useState("");
  const selectedClientId = props.cliente.client;
  const [showAllProducts, setShowAllProducts] = useState(false);
  const [showCobros, setShowCobros] = useState(false);
  const [allProducts, setAllProducts] = useState([]);
  const [quantities, setQuantities] = useState({});
  const [isQuantityModalVisible, setQuantityModalVisible] = useState(false);
  const [selectedProduct, setSelectedProduct] = useState(null);
  const [isPurchaseModalVisible, setPurchaseModalVisible] = useState(false);
  const [totalPurchase, setTotalPurchase] = useState(0);
  const [showFinalizeOptionsModal, setShowFinalizeOptionsModal] =
    useState(false);
  const [internetState, setInternetState] = useInternetContext();
  const [showPriceWithTax, setShowPriceWithTax] = useState(false);
  const [visibleData, setVisibleData] = useState([]);
  const [pdfUrls, setPdfUrls] = useState([]);
  const [pendingPayments, setPendingPayments] = useState([]);
  const [isPendingPaymentsModalVisible, setPendingPaymentsModalVisible] =
    useState(false);
  const itemsPerPage = 10;
  const [page, setPage] = useState(1);

  var DEV = new PedidosComercialLogic({
    clientProducts,
    setClientProducts,
    products,
    setProducts,
    setLoading,
    setUser,
    user,
    setGlobalState,
    globalState,
    selectedClientId,
  });

  useEffect(() => {
    async function fetchData() {
      const showPriceWithTax = await getSecureStoreData(SHOW_PRICE_WITH_TAX);
      setShowPriceWithTax(showPriceWithTax === "true");
      await DEV.init();
      if (internetState.isConnected) {
        try {
          await DEV.getProductsByOrders(props.cliente.client);
          await DEV.getProducts();
        } catch (error) {
          console.error("Error al cargar clientes:", error);
        }
      } else {
        try {
          await DEV.getLocalProductsByOrders();
          await DEV.getLocalProducts();
        } catch (error) {
          console.error("Error al cargar clientes:", error);
        }
      }

      try {
        const totalDue = await DEV.getTotalDueByClient(props.cliente.client);
        setPendingPayments(totalDue);
        setPendingPaymentsModalVisible(true);
      } catch (error) {
        console.error("Error fetching total due:", error);
        Alert.alert("Error", "Problemas al obtener los pagos pendientes.");
      }
    }
    fetchData();
  }, []);

  useEffect(() => {
    mergeProducts(clientProducts, products);
  }, [products, clientProducts]);

  useEffect(() => {
    setVisibleData(filteredProducts.slice(0, itemsPerPage));
    setPage(1);
  }, [allProducts, showAllProducts, filteredProducts]);

  useEffect(() => {
    const filtered = allProducts.filter(
      (product) =>
        (product.label || "")
          .toLowerCase()
          .includes(searchText.toLowerCase()) &&
        (showAllProducts ? product.client === 0 : product.client === 1)
    );
    setVisibleData(filtered.slice(0, itemsPerPage));
    setPage(1);
  }, [searchText, allProducts, showAllProducts]);

  const loadMoreData = () => {
    const filtered = allProducts.filter(
      (product) =>
        (product.label || "")
          .toLowerCase()
          .includes(searchText.toLowerCase()) &&
        (showAllProducts ? product.client === 0 : product.client === 1)
    );
    const startIndex = page * itemsPerPage;
    const endIndex = startIndex + itemsPerPage;
    const newData = filtered.slice(startIndex, endIndex);

    setPage(page + 1);
    setVisibleData((prevData) => [...prevData, ...newData]);
  };

  const mergeProducts = async (clientProducts, products) => {
    const productMap = new Map();
    products.forEach((product) => {
      if (product.fkProduct != null) {
        productMap.set(product.fkProduct, {
          ...product,
          client: 0,
          quantity: 0,
          productStock: product.productStock || 0,
        });
      }
    });

    clientProducts.forEach((product) => {
      if (product.fkProduct != null) {
        const existingProduct = productMap.get(product.fkProduct);
        if (existingProduct) {
          productMap.set(product.fkProduct, {
            ...existingProduct,
            ...product,
            productStock:
              product.productStock || existingProduct.productStock || 0,
            client: 1,
          });
        } else {
          productMap.set(product.fkProduct, {
            ...product,
            client: 1,
            productStock: product.productStock || 0,
          });
        }
      }
    });

    const arrayMerge = Array.from(productMap.values());
    setAllProducts(arrayMerge);

    if (internetState.isConnected) {
      await DEV.saveProductsLocal(arrayMerge);
    }

    setLoading(false);
  };

  const handleSearch = (text) => {
    setSearchText(text);
  };

  const toggleProductList = () => {
    setLoading(true);
    setShowAllProducts(!showAllProducts);
    setLoading(false);
  };

  const addProductToClient = (product) => {
    setSelectedProduct(product);
    setQuantityModalVisible(true);
  };

  const handleQuantitySave = (quantity, subprice, discount) => {
    console.log("CANTIDAD", subprice)
    setQuantities((prevQuantities) => ({
      ...prevQuantities,
      [selectedProduct.fkProduct]: quantity,
    }));

    const updatedClientProducts = clientProducts.map((product) => {
      if (product.fkProduct === selectedProduct.fkProduct) {
        return {
          ...product,
          quantity,
          subprice: subprice,
          remise_percent: discount,
          client: 1,
        };
      }
      return product;
    });

    if (
      !updatedClientProducts.find(
        (product) => product.fkProduct === selectedProduct.fkProduct
      )
    ) {
      updatedClientProducts.push({
        ...selectedProduct,
        quantity,
        subprice: subprice,
        remise_percent: discount,
        client: 1,
      });
    }

    setClientProducts(updatedClientProducts);
    mergeProducts(updatedClientProducts, products);
    setQuantityModalVisible(false);
  };

  const removeProductFromClient = (fkProduct) => {
    setLoading(true);

    const remainingClientProducts = clientProducts.filter(
      (product) => product.fkProduct !== fkProduct
    );
    const updatedProducts = products.map((product) => {
      if (product.fkProduct === fkProduct) {
        return { ...product, client: 0, quantity: 0 };
      }
      return product;
    });

    setClientProducts(remainingClientProducts);
    setProducts(updatedProducts);
    mergeProducts(remainingClientProducts, updatedProducts);
    setLoading(false);
  };

  const handleQuantityChange = (fkProduct, newQuantity) => {
    setQuantities((currentQuantities) => ({
      ...currentQuantities,
      [fkProduct]: newQuantity,
    }));

    if (newQuantity === 0) {
      removeProductFromClient(fkProduct);
    } else {
      const updatedClientProducts = clientProducts.map((product) =>
        product.fkProduct === fkProduct
          ? { ...product, quantity: newQuantity }
          : product
      );
      setClientProducts(updatedClientProducts);
      mergeProducts(updatedClientProducts, products);
    }
  };

  const filteredProducts = allProducts.filter(
    (product) =>
      (product.label || "").toLowerCase().includes(searchText.toLowerCase()) &&
      (showAllProducts ? product.client === 0 : product.client === 1)
  );

  const countProductsWithQuantity = () => {
    return allProducts.filter(
      (product) => product.client === 1 && quantities[product.fkProduct] > 0
    ).length;
  };

  const calculateTotalPurchase = () => {
    return allProducts
      .reduce((acc, product) => {
        if (product.client === 1 && quantities[product.fkProduct]) {
          const priceWithDiscount =
            product.subprice * (1 - product.remise_percent / 100);

          return acc + priceWithDiscount * quantities[product.fkProduct];
        }
        return acc;
      }, 0)
      .toFixed(2);
  };

  const finalizePurchase = async () => {
    let filteredProducts = allProducts.filter(
      (product) =>
        product.client === 1 &&
        !Number.isNaN(parseInt(product.quantity)) &&
        parseInt(product.quantity) > 0 &&
        product.fkProduct != null
    );
  
    let pdfUrlsArray = [];
  
    if (!internetState.isConnected) {
      await DEV.saveOrderLocally(props.cliente.clientId, filteredProducts, 0);
      success = true;
    } else {
      if (props.cliente.client != null) {
        const totalPurchase = filteredProducts.reduce(
          (acc, product) =>
            acc + parseFloat(product.price) * parseInt(product.quantity),
          0
        );
        setTotalPurchase(totalPurchase.toFixed(2));
  
        const response = await DEV.createOrderFromClient(
          props.cliente.client,
          filteredProducts.map(product => ({
            ...product,
            price: parseFloat(product.price)  // Ensure the price is always multiprices["1"]
          })),
          0
        );
  
        if (response) {
          pdfUrlsArray.push(response);
        } else {
          console.error(
            "Error al realizar la compra:",
            response.error
          );
        }
      } else {
        console.log("El ID del cliente es nulo.");
      }
    }
  
    if (pdfUrlsArray.length > 0) {
      setPdfUrls(pdfUrlsArray);
      setPurchaseModalVisible(true);
    }
  };
  
  

  const calculateProductPrice = (subprice_ttc, subprice, tva_tx, showPriceWithTax) => {
    if (showPriceWithTax) {
      return parseFloat(subprice_ttc).toFixed(2);
    } else {
      return parseFloat(subprice).toFixed(2);
    }
  };

  if(showCobros){
    return <ListadoPedidos cliente={props.cliente}/>
  }

  return (
    <View style={[{ flex: 1, padding: 2 }, globalStyles.container]}>
      <View style={styles.headerContainer}>
        <View style={styles.headerContent}>
          <Icon
            name={showAllProducts ? "arrow-left" : "cart-plus"}
            size={40}
            onPress={toggleProductList}
          />
          <View style={styles.headerTitle}>
            <Text style={styles.headerTitleText}>{props.cliente.name}</Text>
            <Text
              style={styles.headerTitleText}
            >{`TOTAL CARRITO SIN IVA: ${calculateTotalPurchase()} €`}</Text>
          </View>
          {!showAllProducts ? (
            <Icon
              name="content-save"
              size={40}
              onPress={() => setShowFinalizeOptionsModal(true)}
            />
          ) : (
            <Icon
              name="content-save"
              size={40}
              onPress={toggleProductList}
            />
          )}
        </View>
        <View style={styles.buscarStyle}>
          <SearchInput
            placeholder="Buscar producto..."
            onSearch={handleSearch}
          />
        </View>
      </View>
      {loading ? (
        <>
        <ActivityIndicator size="large" />
        </>
        
      ) : (
        <FlashList
          keyboardDismissMode="interactive"
          keyboardShouldPersistTaps="handled"
          data={visibleData}
          renderItem={({ item }) => (
            <TouchableOpacity onPress={() => addProductToClient(item)}>
              <View
                style={[
                  styles.productContainer,
                  {
                    backgroundColor: item.client === 1 ? "#2271b3" : "#FDFD96",
                  },
                ]}
              >
                <View style={styles.productHeader}>
                  <View style={styles.productHeaderTitle}>
                    <Text style={styles.productHeaderText}>{item.label}</Text>
                  </View>
                  <Icon
                    name="calculator"
                    size={50}
                    onPress={() => addProductToClient(item)}
                  />
                </View>
                <View style={styles.containerRow}>
                  <View style={styles.priceContainer}>
                    {!showAllProducts ? (
                      <>
                        <View style={styles.priceColumn}>
                          <Text style={styles.priceText}>
                            Precio histórico{" "}
                            {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "}
                            {`${calculateProductPrice(
                              item.subprice,
                              item.subprice_ttc,
                              item.tva_tx,
                              showPriceWithTax
                            )} €`}
                          </Text>
                        </View>
                        <View style={styles.priceColumn}>
                          {item.realPrice !== 0 ? (
                            <Text style={styles.priceText}>
                              Precio {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "}
                              {`${calculateProductPrice(
                                item.price,
                                item.subprice,
                                item.tva_tx,
                                showPriceWithTax
                              )} €`}
                            </Text>
                          ) : null}
                        </View>
                      </>
                    ) : (
                      <>
                        <Text style={styles.priceText}>
                          Precio venta {showPriceWithTax ? "IVA" : "SIN IVA"}:{" "}
                          {`${calculateProductPrice(
                            item.subprice,
                            item.subprice,
                            item.tva_tx,
                            showPriceWithTax
                          )} €`}
                        </Text>
                      </>
                    )}
                    <Text style={styles.priceText}>
                      Precio Total:{" "}
                      {`${
                        (
                          parseFloat(item.subprice || 0) *
                          (quantities[item.fkProduct] || 0) *
                          (1 - parseFloat(item.remise_percent || 0) / 100)
                        ).toFixed(2) || 0
                      } €`}
                    </Text>
                    <Text style={styles.priceText}>
                      Stock actual: {item.productStock || 0}
                    </Text>
                  </View>
                  <View style={styles.stockContainer}>
                    <Text style={styles.stockText}>
                      Unidades/caja: {item.options_unidades || 0}
                    </Text>
                    <Text style={styles.stockText}>
                      Unidades : {quantities[item.fkProduct] || 0} uds 
                    </Text>
                    {!showAllProducts ? (
                      <Text style={styles.stockText}>
                        Descuento: {item.remise_percent || 0}%
                      </Text>
                    ) : (
                      <></>
                    )}
                  </View>
                </View>
              </View>
            </TouchableOpacity>
          )}
          keyExtractor={(item) => item.fkProduct.toString()}
          onEndReached={loadMoreData}
          onEndReachedThreshold={0.1}
          estimatedItemSize={200}
          threshold={5}
        />
      )}
      <View style={styles.footerContainer}>
        <Text
          style={styles.footerText}
        >{`Productos seleccionados: ${countProductsWithQuantity()}`}</Text>
      </View>
      <Modal
        animationType="slide"
        transparent={true}
        visible={isQuantityModalVisible}
        onRequestClose={() => setQuantityModalVisible(!isQuantityModalVisible)}
      >
        <QuantitySelector
          isVisible={isQuantityModalVisible}
          onClose={() => setQuantityModalVisible(false)}
          onSave={handleQuantitySave}
          product={selectedProduct}
          showPriceWithTax={showPriceWithTax} 

        />
      </Modal>
      <Modal
        animationType="slide"
        transparent={true}
        visible={showFinalizeOptionsModal}
        onRequestClose={() => setShowFinalizeOptionsModal(false)}
      >
        <View style={styles.modalContainer}>
          <View style={styles.modalContent}>
            <Text style={styles.modalTitle}>
              FINALIZACIÓN DEL PEDIDO
            </Text>
            <Button
              buttonStyle={styles.buttonStyle}
              title="Crear pedido completo"
              onPress={() => {
                finalizePurchase(false);
                setShowFinalizeOptionsModal(false);
              }}
            />
            <Button
              buttonStyle={styles.buttonStyle}
              title="Cancelar"
              onPress={() => setShowFinalizeOptionsModal(false)}
            />
          </View>
        </View>
      </Modal>
      <Modal
        animationType="slide"
        transparent={true}
        visible={isPurchaseModalVisible}
        onRequestClose={() => setPurchaseModalVisible(false)}
      >
        <View style={styles.modalContainer}>
          <View style={styles.modalContent}>
            <Text style={styles.modalTitle}>Pedido creado correctamente</Text>
            <Text style={styles.modalSubTitle}>
              Total: €{calculateTotalPurchase()}
            </Text>
            {/* {pdfUrls.length > 0 &&
              (console.log("VEAMOS si hay pdfs o no", pdfUrls),
              (<PdfTabNavigator pdfUrls={pdfUrls} />))} */}
            <Button
              buttonStyle={styles.buttonStyle}
              title="Ver cobros"
              onPress={() => {
                setPurchaseModalVisible(false);
                props.navigation.navigate("NuevaPantalla"); 
              }}
            />
            <Button
              buttonStyle={styles.buttonStyle}
              title="Home"
              onPress={() => {
                setPurchaseModalVisible(false);
                RootNavigation.navigate(HOME);
              }}
            />
          </View>
        </View>
      </Modal>
      <Modal
        animationType="slide"
        transparent={true}
        visible={isPendingPaymentsModalVisible}
        onRequestClose={() => setPendingPaymentsModalVisible(false)}
      >
        <View style={modalStyles.modalContainer}>
          <View style={modalStyles.modalContent}>
            <Text style={modalStyles.modalTitle}>PAGOS PENDIENTES</Text>
            {pendingPayments.total_due > 0 ? (
                <View>
                  <Text style={modalStyles.modalSubTitle}>
                    TOTAL : €{pendingPayments.total_due.toFixed(2) }
                  </Text>
                </View>
            ) : (
              <Text style={modalStyles.modalSubTitle}>
                No hay pagos pendientes.
              </Text>
            )}
            <Button
              buttonStyle={modalStyles.buttonStyle}
              title="Ver cobros"
              onPress={() => setShowCobros(true)}
            />
            <Button
              buttonStyle={modalStyles.buttonStyle}
              title="Cerrar"
              onPress={() => setPendingPaymentsModalVisible(false)}
            />
          </View>
        </View>
      </Modal>
    </View>
  );
};

export default PedidosComercialScreenView;

Quantity selector

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import React, { useState, useEffect } from "react";
import {
View,
Text,
Button,
Modal,
StyleSheet,
TouchableOpacity,
TextInput,
KeyboardAvoidingView,
Platform,
TouchableWithoutFeedback,
Keyboard
} from "react-native";
import { getSecureStoreData } from "../../utils/gettersAndSetters/getters.js"; // Asegúrate de que la ruta sea correcta
import { SHOW_PRICE_WITH_TAX } from "../../utils/const/secureStoreConst.js";
const QuantitySelector = ({ isVisible, onClose, onSave, product }) => {
const [quantity, setQuantity] = useState("0");
const [unitType, setUnitType] = useState("units"); // 'units' or 'pack'
const [unitsPerPack, setUnitsPerPack] = useState(1);
const [price, setPrice] = useState('0.00');
const [discount, setDiscount] = useState("0");
const [showPriceWithTax, setShowPriceWithTax] = useState(false);
useEffect(() => {
const fetchShowPriceWithTax = async () => {
const showPriceWithTax = await getSecureStoreData(SHOW_PRICE_WITH_TAX);
setShowPriceWithTax(showPriceWithTax === "true");
};
fetchShowPriceWithTax();
if (product && product.options_unidades) {
setUnitsPerPack(product.options_unidades);
}
if (product) {
if (showPriceWithTax) {
setPrice(parseFloat(product.subprice_ttc).toFixed(2));
} else {
setPrice(parseFloat(product.subprice).toFixed(2));
}
}
}, [product, showPriceWithTax]);
const handleSave = () => {
const finalQuantity =
unitType === "pack"
? parseInt(quantity, 10) * unitsPerPack
: parseInt(quantity, 10);
const finalPrice = parseFloat(price).toFixed(2);
const finalDiscount = parseFloat(discount).toFixed(2);
onSave(finalQuantity, finalPrice, finalDiscount);
};
---
const handleNumberPress = (number) => {
setQuantity((prevQuantity) =>
prevQuantity === "0"
? number.toString()
: prevQuantity + number.toString()
);
};
const handleClear = () => {
setQuantity("0");
};
const handleBackspace = () => {
setQuantity((prevQuantity) =>
prevQuantity.length > 1 ? prevQuantity.slice(0, -1) : "0"
);
};
const handlePriceChange = (text) => {
const parsed = text.replace(/[^0-9.]/g, "");
setPrice(parsed);
};
const handleDiscountChange = (text) => {
const parsed = text.replace(/[^0-9.]/g, "");
setDiscount(parsed);
};
return (
<Modal visible={isVisible} transparent={true} animationType="slide">
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.modalContainer}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.modalContent}>
<Text style={styles.productText}>Producto {product?.label}</Text>
<View style={styles.switchContainer}>
<TouchableOpacity
style={[
styles.switchButton,
unitType === "units" ? styles.active : styles.inactive,
]}
onPress={() => setUnitType("units")}
>
<Text style={styles.switchText}>Unidades</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.switchButton,
unitType === "pack" ? styles.active : styles.inactive,
]}
onPress={() => setUnitType("pack")}
>
<Text style={styles.switchText}>Envases</Text>
</TouchableOpacity>
</View>
<Text style={styles.quantityDisplay}>{quantity}</Text>
<View style={styles.calculatorContainer}>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((number) => (
<TouchableOpacity
key={number}
style={styles.calculatorButton}
onPress={() => handleNumberPress(number)}
>
<Text style={styles.calculatorButtonText}>{number}</Text>
</TouchableOpacity>
))}
<TouchableOpacity
style={styles.calculatorButton}
onPress={handleBackspace}
>
<Text style={styles.calculatorButtonText}></Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.calculatorButton}
onPress={handleClear}
>
<Text style={styles.calculatorButtonText}>CE</Text>
</TouchableOpacity>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>
Precio de venta {showPriceWithTax ? "CON IVA" : "SIN IVA"}:
</Text>
<TextInput
style={styles.input}
keyboardType="numeric"
value={price}
onChangeText={handlePriceChange}
placeholder="0.00"
placeholderTextColor="#aaa"
clearButtonMode="always"
/>
</View>
<View style={styles.inputContainer}>
<Text style={styles.inputLabel}>Descuento (%):</Text>
<TextInput
style={styles.input}
keyboardType="numeric"
value={discount}
onChangeText={handleDiscountChange}
placeholder="0"
placeholderTextColor="#aaa"
clearButtonMode="always"
/>
</View>
<View style={styles.buttonContainer}>
<Button title="Guardar" onPress={handleSave} />
<Button title="Cancelar" onPress={onClose} />
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</Modal>
);
};
export default QuantitySelector;
</code>
<code>import React, { useState, useEffect } from "react"; import { View, Text, Button, Modal, StyleSheet, TouchableOpacity, TextInput, KeyboardAvoidingView, Platform, TouchableWithoutFeedback, Keyboard } from "react-native"; import { getSecureStoreData } from "../../utils/gettersAndSetters/getters.js"; // Asegúrate de que la ruta sea correcta import { SHOW_PRICE_WITH_TAX } from "../../utils/const/secureStoreConst.js"; const QuantitySelector = ({ isVisible, onClose, onSave, product }) => { const [quantity, setQuantity] = useState("0"); const [unitType, setUnitType] = useState("units"); // 'units' or 'pack' const [unitsPerPack, setUnitsPerPack] = useState(1); const [price, setPrice] = useState('0.00'); const [discount, setDiscount] = useState("0"); const [showPriceWithTax, setShowPriceWithTax] = useState(false); useEffect(() => { const fetchShowPriceWithTax = async () => { const showPriceWithTax = await getSecureStoreData(SHOW_PRICE_WITH_TAX); setShowPriceWithTax(showPriceWithTax === "true"); }; fetchShowPriceWithTax(); if (product && product.options_unidades) { setUnitsPerPack(product.options_unidades); } if (product) { if (showPriceWithTax) { setPrice(parseFloat(product.subprice_ttc).toFixed(2)); } else { setPrice(parseFloat(product.subprice).toFixed(2)); } } }, [product, showPriceWithTax]); const handleSave = () => { const finalQuantity = unitType === "pack" ? parseInt(quantity, 10) * unitsPerPack : parseInt(quantity, 10); const finalPrice = parseFloat(price).toFixed(2); const finalDiscount = parseFloat(discount).toFixed(2); onSave(finalQuantity, finalPrice, finalDiscount); }; --- const handleNumberPress = (number) => { setQuantity((prevQuantity) => prevQuantity === "0" ? number.toString() : prevQuantity + number.toString() ); }; const handleClear = () => { setQuantity("0"); }; const handleBackspace = () => { setQuantity((prevQuantity) => prevQuantity.length > 1 ? prevQuantity.slice(0, -1) : "0" ); }; const handlePriceChange = (text) => { const parsed = text.replace(/[^0-9.]/g, ""); setPrice(parsed); }; const handleDiscountChange = (text) => { const parsed = text.replace(/[^0-9.]/g, ""); setDiscount(parsed); }; return ( <Modal visible={isVisible} transparent={true} animationType="slide"> <KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"} style={styles.modalContainer} > <TouchableWithoutFeedback onPress={Keyboard.dismiss}> <View style={styles.modalContent}> <Text style={styles.productText}>Producto {product?.label}</Text> <View style={styles.switchContainer}> <TouchableOpacity style={[ styles.switchButton, unitType === "units" ? styles.active : styles.inactive, ]} onPress={() => setUnitType("units")} > <Text style={styles.switchText}>Unidades</Text> </TouchableOpacity> <TouchableOpacity style={[ styles.switchButton, unitType === "pack" ? styles.active : styles.inactive, ]} onPress={() => setUnitType("pack")} > <Text style={styles.switchText}>Envases</Text> </TouchableOpacity> </View> <Text style={styles.quantityDisplay}>{quantity}</Text> <View style={styles.calculatorContainer}> {[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((number) => ( <TouchableOpacity key={number} style={styles.calculatorButton} onPress={() => handleNumberPress(number)} > <Text style={styles.calculatorButtonText}>{number}</Text> </TouchableOpacity> ))} <TouchableOpacity style={styles.calculatorButton} onPress={handleBackspace} > <Text style={styles.calculatorButtonText}>⌫</Text> </TouchableOpacity> <TouchableOpacity style={styles.calculatorButton} onPress={handleClear} > <Text style={styles.calculatorButtonText}>CE</Text> </TouchableOpacity> </View> <View style={styles.inputContainer}> <Text style={styles.inputLabel}> Precio de venta {showPriceWithTax ? "CON IVA" : "SIN IVA"}: </Text> <TextInput style={styles.input} keyboardType="numeric" value={price} onChangeText={handlePriceChange} placeholder="0.00" placeholderTextColor="#aaa" clearButtonMode="always" /> </View> <View style={styles.inputContainer}> <Text style={styles.inputLabel}>Descuento (%):</Text> <TextInput style={styles.input} keyboardType="numeric" value={discount} onChangeText={handleDiscountChange} placeholder="0" placeholderTextColor="#aaa" clearButtonMode="always" /> </View> <View style={styles.buttonContainer}> <Button title="Guardar" onPress={handleSave} /> <Button title="Cancelar" onPress={onClose} /> </View> </View> </TouchableWithoutFeedback> </KeyboardAvoidingView> </Modal> ); }; export default QuantitySelector; </code>
import React, { useState, useEffect } from "react";
import {
  View,
  Text,
  Button,
  Modal,
  StyleSheet,
  TouchableOpacity,
  TextInput,
  KeyboardAvoidingView,
  Platform,
  TouchableWithoutFeedback,
  Keyboard
} from "react-native";
import { getSecureStoreData } from "../../utils/gettersAndSetters/getters.js"; // Asegúrate de que la ruta sea correcta
import { SHOW_PRICE_WITH_TAX } from "../../utils/const/secureStoreConst.js";

const QuantitySelector = ({ isVisible, onClose, onSave, product }) => {
  const [quantity, setQuantity] = useState("0");
  const [unitType, setUnitType] = useState("units"); // 'units' or 'pack'
  const [unitsPerPack, setUnitsPerPack] = useState(1);
  const [price, setPrice] = useState('0.00');
  const [discount, setDiscount] = useState("0");
  const [showPriceWithTax, setShowPriceWithTax] = useState(false);

  useEffect(() => {
    const fetchShowPriceWithTax = async () => {
      const showPriceWithTax = await getSecureStoreData(SHOW_PRICE_WITH_TAX);
      setShowPriceWithTax(showPriceWithTax === "true");
    };

    fetchShowPriceWithTax();

    if (product && product.options_unidades) {
      setUnitsPerPack(product.options_unidades);
    }
    if (product) {
      if (showPriceWithTax) {
        setPrice(parseFloat(product.subprice_ttc).toFixed(2));
      } else {
        setPrice(parseFloat(product.subprice).toFixed(2));
      }
    }
  }, [product, showPriceWithTax]);

  const handleSave = () => {
    const finalQuantity =
      unitType === "pack"
        ? parseInt(quantity, 10) * unitsPerPack
        : parseInt(quantity, 10);
    const finalPrice = parseFloat(price).toFixed(2);
    const finalDiscount = parseFloat(discount).toFixed(2);
    onSave(finalQuantity, finalPrice, finalDiscount);
  };

---

  const handleNumberPress = (number) => {
    setQuantity((prevQuantity) =>
      prevQuantity === "0"
        ? number.toString()
        : prevQuantity + number.toString()
    );
  };

  const handleClear = () => {
    setQuantity("0");
  };

  const handleBackspace = () => {
    setQuantity((prevQuantity) =>
      prevQuantity.length > 1 ? prevQuantity.slice(0, -1) : "0"
    );
  };

  const handlePriceChange = (text) => {
    const parsed = text.replace(/[^0-9.]/g, "");
    setPrice(parsed);
  };

  const handleDiscountChange = (text) => {
    const parsed = text.replace(/[^0-9.]/g, "");
    setDiscount(parsed);
  };

  return (
    <Modal visible={isVisible} transparent={true} animationType="slide">
      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : "height"}
        style={styles.modalContainer}
      >
        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
          <View style={styles.modalContent}>
            <Text style={styles.productText}>Producto {product?.label}</Text>
            <View style={styles.switchContainer}>
              <TouchableOpacity
                style={[
                  styles.switchButton,
                  unitType === "units" ? styles.active : styles.inactive,
                ]}
                onPress={() => setUnitType("units")}
              >
                <Text style={styles.switchText}>Unidades</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={[
                  styles.switchButton,
                  unitType === "pack" ? styles.active : styles.inactive,
                ]}
                onPress={() => setUnitType("pack")}
              >
                <Text style={styles.switchText}>Envases</Text>
              </TouchableOpacity>
            </View>
            <Text style={styles.quantityDisplay}>{quantity}</Text>
            <View style={styles.calculatorContainer}>
              {[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((number) => (
                <TouchableOpacity
                  key={number}
                  style={styles.calculatorButton}
                  onPress={() => handleNumberPress(number)}
                >
                  <Text style={styles.calculatorButtonText}>{number}</Text>
                </TouchableOpacity>
              ))}
              <TouchableOpacity
                style={styles.calculatorButton}
                onPress={handleBackspace}
              >
                <Text style={styles.calculatorButtonText}>⌫</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.calculatorButton}
                onPress={handleClear}
              >
                <Text style={styles.calculatorButtonText}>CE</Text>
              </TouchableOpacity>
            </View>
            <View style={styles.inputContainer}>
              <Text style={styles.inputLabel}>
                Precio de venta {showPriceWithTax ? "CON IVA" : "SIN IVA"}:
              </Text>
              <TextInput
                style={styles.input}
                keyboardType="numeric"
                value={price}
                onChangeText={handlePriceChange}
                placeholder="0.00"
                placeholderTextColor="#aaa"
                clearButtonMode="always"
              />
            </View>
            <View style={styles.inputContainer}>
              <Text style={styles.inputLabel}>Descuento (%):</Text>
              <TextInput
                style={styles.input}
                keyboardType="numeric"
                value={discount}
                onChangeText={handleDiscountChange}
                placeholder="0"
                placeholderTextColor="#aaa"
                clearButtonMode="always"
              />
            </View>
            <View style={styles.buttonContainer}>
              <Button title="Guardar" onPress={handleSave} />
              <Button title="Cancelar" onPress={onClose} />
            </View>
          </View>
        </TouchableWithoutFeedback>
      </KeyboardAvoidingView>
    </Modal>
  );
};
export default QuantitySelector;

The keyboard does not appear and I cannot add quantity.

New contributor

Pepe Cda is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật