other means
This commit is contained in:
14
app.json
14
app.json
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"expo": {
|
"expo": {
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"react-native-keyevent-expo-config-plugin"
|
[
|
||||||
|
"expo-build-properties",
|
||||||
|
{
|
||||||
|
"android": {
|
||||||
|
"usesCleartextTraffic": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
],
|
],
|
||||||
"name": "Assemblr",
|
"name": "Assemblr",
|
||||||
"slug": "Assemblr",
|
"slug": "Assemblr",
|
||||||
@@ -25,7 +32,10 @@
|
|||||||
"foregroundImage": "./src/assets/adaptive-icon.png",
|
"foregroundImage": "./src/assets/adaptive-icon.png",
|
||||||
"backgroundColor": "#ffffff"
|
"backgroundColor": "#ffffff"
|
||||||
},
|
},
|
||||||
"package": "com.anonymous.Assemblr"
|
"package": "com.anonymous.Assemblr",
|
||||||
|
"permissions": [
|
||||||
|
"INTERNET"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"web": {
|
"web": {
|
||||||
"favicon": "./src/assets/favicon.png"
|
"favicon": "./src/assets/favicon.png"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
"babel-plugin-module-resolver": "^5.0.0",
|
"babel-plugin-module-resolver": "^5.0.0",
|
||||||
"expo": "~49.0.8",
|
"expo": "~49.0.8",
|
||||||
|
"expo-build-properties": "~0.8.3",
|
||||||
"expo-secure-store": "~12.3.1",
|
"expo-secure-store": "~12.3.1",
|
||||||
"expo-splash-screen": "~0.20.5",
|
"expo-splash-screen": "~0.20.5",
|
||||||
"expo-status-bar": "~1.6.0",
|
"expo-status-bar": "~1.6.0",
|
||||||
@@ -37,13 +38,13 @@
|
|||||||
"react-native-keyevent-expo-config-plugin": "^1.0.49",
|
"react-native-keyevent-expo-config-plugin": "^1.0.49",
|
||||||
"react-native-modal": "^13.0.1",
|
"react-native-modal": "^13.0.1",
|
||||||
"react-native-paper": "^5.10.6",
|
"react-native-paper": "^5.10.6",
|
||||||
"react-native-progress": "^5.0.1",
|
|
||||||
"react-native-radio-buttons-group": "^3.0.5",
|
"react-native-radio-buttons-group": "^3.0.5",
|
||||||
"react-native-reanimated": "3.3.0",
|
"react-native-reanimated": "3.3.0",
|
||||||
"react-native-responsive-dimensions": "^3.1.1",
|
"react-native-responsive-dimensions": "^3.1.1",
|
||||||
"react-native-responsive-fontsize": "^0.5.1",
|
"react-native-responsive-fontsize": "^0.5.1",
|
||||||
"react-native-safe-area-context": "4.6.3",
|
"react-native-safe-area-context": "4.6.3",
|
||||||
"react-native-screens": "~3.22.0",
|
"react-native-screens": "~3.22.0",
|
||||||
|
"react-native-svg": "13.9.0",
|
||||||
"react-native-toast-message": "^2.1.7",
|
"react-native-toast-message": "^2.1.7",
|
||||||
"react-native-vector-icons": "^10.0.0",
|
"react-native-vector-icons": "^10.0.0",
|
||||||
"react-native-web": "~0.19.6",
|
"react-native-web": "~0.19.6",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {logout} from "../features/auth/authSlice";
|
|||||||
import {store} from "../redux/store";
|
import {store} from "../redux/store";
|
||||||
|
|
||||||
const apiClient = axios.create({
|
const apiClient = axios.create({
|
||||||
|
// baseURL: 'https://assemblr.denco.store',
|
||||||
baseURL: 'http://192.168.1.101:5000',
|
baseURL: 'http://192.168.1.101:5000',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -26,12 +27,12 @@ apiClient.interceptors.request.use(async (config) => {
|
|||||||
|
|
||||||
return config;
|
return config;
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
|
console.log("очко")
|
||||||
|
|
||||||
if (error.response && error.response.status === 401) {
|
if (error.response && error.response.status === 401) {
|
||||||
console.log("очко")
|
console.log("очко")
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// return Promise.reject(error);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ const assemblyApi = {
|
|||||||
let response = await apiClient.post(`${router}/close`, {assemblyId});
|
let response = await apiClient.post(`${router}/close`, {assemblyId});
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
cancel: async (): Promise<{ ok: boolean, message: string }> => {
|
||||||
|
let response = await apiClient.post(`${router}/cancel`);
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
getActive: async (): Promise<Assembly> => {
|
getActive: async (): Promise<Assembly> => {
|
||||||
let response = await apiClient.get(`${router}/getActive`);
|
let response = await apiClient.get(`${router}/getActive`);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {SupplierProduct} from "../types/supplierProduct";
|
|
||||||
import apiClient from "./apiClient";
|
import apiClient from "./apiClient";
|
||||||
|
import {Product} from "../types/product";
|
||||||
|
|
||||||
const router = '/barcode';
|
const router = '/barcode';
|
||||||
|
|
||||||
const barcodeApi = {
|
const barcodeApi = {
|
||||||
searchProducts: async (barcode: string): Promise<SupplierProduct[]> => {
|
searchProducts: async (barcode: string): Promise<Product[]> => {
|
||||||
let response = await apiClient.get(`${router}/searchProducts?barcode=${barcode}`);
|
let response = await apiClient.get(`${router}/searchProducts?barcode=${barcode}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/api/generalApi.ts
Normal file
12
src/api/generalApi.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import apiClient from "./apiClient";
|
||||||
|
import {ShippingWarehouse} from "../types/shippingWarehouse";
|
||||||
|
|
||||||
|
const router = '/general';
|
||||||
|
|
||||||
|
const generalApi = {
|
||||||
|
getShippingWarehouses: async (): Promise<ShippingWarehouse[]> => {
|
||||||
|
let response = await apiClient.get(`${router}/getShippingWarehouses`);
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export default generalApi;
|
||||||
@@ -1,22 +1,24 @@
|
|||||||
import apiClient from "./apiClient";
|
import apiClient from "./apiClient";
|
||||||
import {Order} from "../types/order";
|
import {Order} from "../types/order";
|
||||||
|
import * as inspector from "inspector";
|
||||||
|
|
||||||
const router = '/orders';
|
const router = '/orders';
|
||||||
|
|
||||||
const ordersApi = {
|
const ordersApi = {
|
||||||
getOrders: async (page: number, orderBy: string, desc: boolean, shipmentDate: string, status: number): Promise<Order[]> => {
|
getOrders: async (page: number, orderBy: string, desc: boolean, shipmentDate: string, status: number, shipmentWarehouseId: number): Promise<Order[]> => {
|
||||||
const params = {
|
const params = {
|
||||||
page: page,
|
page: page,
|
||||||
orderBy: orderBy,
|
orderBy: orderBy,
|
||||||
desc: Number(desc), // Преобразование boolean в Number (0 или 1)
|
desc: Number(desc), // Преобразование boolean в Number (0 или 1)
|
||||||
status: status,
|
status: status,
|
||||||
shipmentDate: shipmentDate
|
shipmentDate: shipmentDate,
|
||||||
|
shipmentWarehouseId: shipmentWarehouseId
|
||||||
};
|
};
|
||||||
let response = await apiClient.get(`${router}/getOrders`, {params})
|
let response = await apiClient.get(`${router}/getOrders`, {params})
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
getOrdersBySupplierProduct: async (supplierProductId: number): Promise<Order[]> => {
|
getOrdersByProduct: async (productId: number): Promise<Order[]> => {
|
||||||
let response = await apiClient.get(`${router}/getBySupplierProductId?supplierProductId=${supplierProductId}`);
|
let response = await apiClient.get(`${router}/getByProductId?productId=${productId}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
getOrderById: async (orderId: number): Promise<Order> => {
|
getOrderById: async (orderId: number): Promise<Order> => {
|
||||||
|
|||||||
@@ -5,8 +5,5 @@ const userApi = {
|
|||||||
let response = await apiClient.post('/auth/login', {login, password});
|
let response = await apiClient.post('/auth/login', {login, password});
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
test: async () => {
|
|
||||||
await apiClient.post('/auth/protected');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
export default userApi;
|
export default userApi;
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 35 KiB |
BIN
src/assets/icons/settings/close.png
Normal file
BIN
src/assets/icons/settings/close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,31 +1,21 @@
|
|||||||
import {FC} from "react";
|
import React, {FC, useState} from "react";
|
||||||
import {Props} from "react-native-paper";
|
|
||||||
import {StyleSheet, View} from "react-native";
|
import {StyleSheet, View} from "react-native";
|
||||||
import {BottomSheetModalProvider} from "@gorhom/bottom-sheet";
|
|
||||||
import {useSelector} from "react-redux";
|
import {useSelector} from "react-redux";
|
||||||
import {RootState} from "../../../redux/store";
|
import {RootState} from "../../../redux/store";
|
||||||
import Modal from "react-native-modal";
|
import Modal from "react-native-modal";
|
||||||
import {background, blue} from "../../../css/colors";
|
import {background} from "../../../css/colors";
|
||||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
||||||
import * as Progress from 'react-native-progress';
|
|
||||||
import DTitle from "../../DTitle/DTitle";
|
import DTitle from "../../DTitle/DTitle";
|
||||||
import {RFPercentage} from "react-native-responsive-fontsize";
|
|
||||||
|
|
||||||
const LoadingModal: FC = () => {
|
const LoadingModal: FC = () => {
|
||||||
const isVisible = useSelector((state: RootState) => state.loadingModal.isVisible);
|
const isVisible = useSelector((state: RootState) => state.loadingModal.isVisible);
|
||||||
const loadingText = useSelector((state: RootState) => state.loadingModal.loadingText);
|
const loadingText = useSelector((state: RootState) => state.loadingModal.loadingText);
|
||||||
|
const [ch, sCh] = useState(false);
|
||||||
return (
|
return (
|
||||||
<Modal isVisible={isVisible}>
|
<Modal isVisible={isVisible}>
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<DTitle style={{textAlign: "center"}}>{loadingText}</DTitle>
|
<DTitle style={{textAlign: "center"}}>{loadingText}</DTitle>
|
||||||
<View style={styles.progressBarWrapper}>
|
<View style={styles.progressBarWrapper}>
|
||||||
<Progress.Circle size={RFPercentage(20)}
|
|
||||||
color={blue}
|
|
||||||
indeterminate={true}
|
|
||||||
style={styles.progressBar}
|
|
||||||
borderWidth={responsiveWidth(1)}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import DTitle from "../../DTitle/DTitle";
|
|||||||
import DText from "../../DText/DText";
|
import DText from "../../DText/DText";
|
||||||
import {RFPercentage} from "react-native-responsive-fontsize";
|
import {RFPercentage} from "react-native-responsive-fontsize";
|
||||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
||||||
|
import {Product} from "../../../types/product";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
product: SupplierProduct;
|
product: Product;
|
||||||
onPress: (product: SupplierProduct) => void;
|
onPress: (product: Product) => void;
|
||||||
}
|
}
|
||||||
const SelectProductElement: FC<Props> = React.memo(({product, onPress}) => {
|
const SelectProductElement: FC<Props> = React.memo(({product, onPress}) => {
|
||||||
return (
|
return (
|
||||||
@@ -24,18 +25,7 @@ const SelectProductElement: FC<Props> = React.memo(({product, onPress}) => {
|
|||||||
|
|
||||||
<DText>{product.productName}</DText>
|
<DText>{product.productName}</DText>
|
||||||
<DText style={{textAlign: "justify"}}>{}</DText>
|
<DText style={{textAlign: "justify"}}>{}</DText>
|
||||||
{product.supplierName &&
|
<DText>Артикул DENCO: {product.dencoArticle}</DText>
|
||||||
<DText>Поставщик: {product.supplierName}</DText>
|
|
||||||
}
|
|
||||||
{product.supplierArticle &&
|
|
||||||
<DText>Артикул: {product.supplierArticle}</DText>
|
|
||||||
}
|
|
||||||
{product.inBlock &&
|
|
||||||
<DText>В блоке: {product.inBlock}</DText>
|
|
||||||
}
|
|
||||||
{product.shelfNumber &&
|
|
||||||
<DText>Номер полки: {product.shelfNumber}</DText>
|
|
||||||
}
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import FlashListSeparator from "../../FlashListSeparator/FlashListSeparator";
|
|||||||
import DTitle from "../../DTitle/DTitle";
|
import DTitle from "../../DTitle/DTitle";
|
||||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
||||||
import {background} from "../../../css/colors";
|
import {background} from "../../../css/colors";
|
||||||
|
import {Product} from "../../../types/product";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
products: SupplierProduct[];
|
products: Product[];
|
||||||
onSelected: (product: SupplierProduct) => void
|
onSelected: (product: Product) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ const SelectProductModal: FC<Props> = ({visible, products, onSelected}) => {
|
|||||||
data={products}
|
data={products}
|
||||||
showsHorizontalScrollIndicator={false}
|
showsHorizontalScrollIndicator={false}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
keyExtractor={(product) => product.supplierProductId.toString()}
|
keyExtractor={(product) => product.productId.toString()}
|
||||||
renderItem={(product) => <SelectProductElement product={product.item} onPress={onSelected}/>}
|
renderItem={(product) => <SelectProductElement product={product.item} onPress={onSelected}/>}
|
||||||
ItemSeparatorComponent={FlashListSeparator}
|
ItemSeparatorComponent={FlashListSeparator}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -13,12 +13,11 @@ import DateTimePicker from '@react-native-community/datetimepicker';
|
|||||||
import {RootState} from "../../../redux/store";
|
import {RootState} from "../../../redux/store";
|
||||||
import {
|
import {
|
||||||
closeOrdersFilterModal,
|
closeOrdersFilterModal,
|
||||||
OrderStatus,
|
|
||||||
orderStatuses,
|
orderStatuses,
|
||||||
setDesc,
|
setDesc,
|
||||||
setOrderBy, setShipmentDate, setStatus
|
setOrderBy, setShipmentDate, setShippingWarehouse, setStatus
|
||||||
} from "../../../features/ordersFilter/ordersFilterSlice";
|
} from "../../../features/ordersFilter/ordersFilterSlice";
|
||||||
import {retry} from "@reduxjs/toolkit/query";
|
import ShippingWarehouseSelect from "../../ShippingWarehouseSelect/ShippingWarehouseSelect";
|
||||||
|
|
||||||
export type SortingModalHandles = {
|
export type SortingModalHandles = {
|
||||||
present: () => void;
|
present: () => void;
|
||||||
@@ -49,6 +48,8 @@ const createRadioButton = (element: SortingModalElement) => {
|
|||||||
|
|
||||||
const SortingModal = () => {
|
const SortingModal = () => {
|
||||||
const state = useSelector((state: RootState) => state.ordersFilter);
|
const state = useSelector((state: RootState) => state.ordersFilter);
|
||||||
|
const shipmentWarehouseSelectorState = useSelector((state: RootState) => state.shippingWarehouseSelect);
|
||||||
|
|
||||||
const elements = [
|
const elements = [
|
||||||
{id: 'createdOnAsc', value: 'createdOnAsc', label: 'Дата создания по возрастанию'},
|
{id: 'createdOnAsc', value: 'createdOnAsc', label: 'Дата создания по возрастанию'},
|
||||||
{id: 'createdOnDesc', value: 'createdOnDesc', label: 'Дата создания по убыванию'},
|
{id: 'createdOnDesc', value: 'createdOnDesc', label: 'Дата создания по убыванию'},
|
||||||
@@ -73,6 +74,9 @@ const SortingModal = () => {
|
|||||||
if (state.isVisible) present();
|
if (state.isVisible) present();
|
||||||
else dismiss();
|
else dismiss();
|
||||||
}, [state.isVisible]);
|
}, [state.isVisible]);
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(setShippingWarehouse(shipmentWarehouseSelectorState.selectedShippingWarehouse));
|
||||||
|
}, [shipmentWarehouseSelectorState.selectedShippingWarehouse]);
|
||||||
return (
|
return (
|
||||||
<BottomSheetModal
|
<BottomSheetModal
|
||||||
ref={modalRef}
|
ref={modalRef}
|
||||||
@@ -99,26 +103,26 @@ const SortingModal = () => {
|
|||||||
radioButtons={elements.map(createRadioButton)}/>
|
radioButtons={elements.map(createRadioButton)}/>
|
||||||
|
|
||||||
|
|
||||||
<View style={{
|
<View style={styles.selectors}>
|
||||||
borderWidth: responsiveWidth(0.1),
|
<View style={styles.selector}>
|
||||||
borderRadius: responsiveWidth(1)
|
<Picker selectedValue={state.status}
|
||||||
}}>
|
onValueChange={(value, event) => dispatch(setStatus(value))}>
|
||||||
|
{orderStatuses.map((status) => {
|
||||||
|
return (
|
||||||
|
<Picker.Item
|
||||||
|
key={status.key}
|
||||||
|
label={status.label}
|
||||||
|
value={status.key}
|
||||||
|
style={{fontSize: responsiveWidth(3)}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Picker>
|
||||||
|
</View>
|
||||||
|
|
||||||
<Picker selectedValue={state.status}
|
<ShippingWarehouseSelect/>
|
||||||
onValueChange={(value, event) => dispatch(setStatus(value))}>
|
|
||||||
{orderStatuses.map((status) => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Picker.Item
|
|
||||||
key={status.key}
|
|
||||||
label={status.label}
|
|
||||||
value={status.key}
|
|
||||||
style={{fontSize: responsiveWidth(3)}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Picker>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<BasicButton onPress={() => setShowShipmentPicker(oldValue => !oldValue)}
|
<BasicButton onPress={() => setShowShipmentPicker(oldValue => !oldValue)}
|
||||||
label={"Выбрать дату отгрузки"}/>
|
label={"Выбрать дату отгрузки"}/>
|
||||||
{showShipmentPicker &&
|
{showShipmentPicker &&
|
||||||
@@ -162,7 +166,13 @@ const styles = StyleSheet.create({
|
|||||||
|
|
||||||
marginTop: "auto"
|
marginTop: "auto"
|
||||||
},
|
},
|
||||||
|
selectors: {
|
||||||
|
rowGap: responsiveHeight(1)
|
||||||
|
},
|
||||||
|
selector: {
|
||||||
|
borderWidth: responsiveWidth(0.1),
|
||||||
|
borderRadius: responsiveWidth(1)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,7 @@ const ScanModal: FC = () => {
|
|||||||
const visible = useSelector((state: RootState) => state.scanModal.isVisible);
|
const visible = useSelector((state: RootState) => state.scanModal.isVisible);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if (visible) inputRef.current?.focus();
|
if (visible) inputRef.current?.focus();
|
||||||
if (visible){
|
|
||||||
dispatch(setScannedData('4750735280715'));
|
|
||||||
dispatch(closeScanModal())
|
|
||||||
}
|
|
||||||
}, [visible]);
|
}, [visible]);
|
||||||
return (
|
return (
|
||||||
<Modal isVisible={visible}>
|
<Modal isVisible={visible}>
|
||||||
|
|||||||
@@ -9,17 +9,18 @@ import barcodeApi from "../../api/barcodeApi";
|
|||||||
import {useDispatch, useSelector} from "react-redux";
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
import {openScanModal, setScannedData} from "../../features/scanModal/scanModalSlice";
|
import {openScanModal, setScannedData} from "../../features/scanModal/scanModalSlice";
|
||||||
import {RootState} from "../../redux/store";
|
import {RootState} from "../../redux/store";
|
||||||
|
import {Product} from "../../types/product";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onSearch?: (text: string) => void;
|
onSearch?: (text: string) => void;
|
||||||
onSupplierProductSelected?: (supplierProduct: SupplierProduct) => void
|
onProductSelected?: (product: Product) => void
|
||||||
}
|
}
|
||||||
const SearchBar: FC<Props> = ({onSearch, onSupplierProductSelected}) => {
|
const SearchBar: FC<Props> = ({onSearch, onProductSelected}) => {
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [searchInput, setSearchInput] = useState<string>("");
|
const [searchInput, setSearchInput] = useState<string>("");
|
||||||
const textInputRef = useRef<TextInput>(null);
|
const textInputRef = useRef<TextInput>(null);
|
||||||
const [products, setProducts] = useState<SupplierProduct[]>([]);
|
const [products, setProducts] = useState<Product[]>([]);
|
||||||
|
|
||||||
const scannedData = useSelector((state: RootState) => state.scanModal.scannedData);
|
const scannedData = useSelector((state: RootState) => state.scanModal.scannedData);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -28,14 +29,22 @@ const SearchBar: FC<Props> = ({onSearch, onSupplierProductSelected}) => {
|
|||||||
setProducts(response)
|
setProducts(response)
|
||||||
});
|
});
|
||||||
}, [scannedData]);
|
}, [scannedData]);
|
||||||
const selectProductModalVisible = products.length > 0;
|
useEffect(() => {
|
||||||
|
if (products.length == 0 || products.length > 1 || !onProductSelected) return;
|
||||||
|
onProductSelected(products[0]);
|
||||||
|
setProducts([]);
|
||||||
|
dispatch(setScannedData(undefined));
|
||||||
|
}, [products]);
|
||||||
|
const selectProductModalVisible = products.length > 1;
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<SelectProductModal visible={selectProductModalVisible} products={products} onSelected={(product) => {
|
<SelectProductModal visible={selectProductModalVisible}
|
||||||
if (onSupplierProductSelected) onSupplierProductSelected(product);
|
products={products}
|
||||||
setProducts([]);
|
onSelected={(product) => {
|
||||||
dispatch(setScannedData(undefined));
|
if (onProductSelected) onProductSelected(product);
|
||||||
}}/>
|
setProducts([]);
|
||||||
|
dispatch(setScannedData(undefined));
|
||||||
|
}}/>
|
||||||
<BasicButton onPress={() => {
|
<BasicButton onPress={() => {
|
||||||
if (!onSearch) return;
|
if (!onSearch) return;
|
||||||
onSearch(searchInput);
|
onSearch(searchInput);
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import {FC, useEffect} from "react";
|
||||||
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
|
import {RootState} from "../../redux/store";
|
||||||
|
import {Picker} from "@react-native-picker/picker";
|
||||||
|
import generalApi from "../../api/generalApi";
|
||||||
|
import {
|
||||||
|
initializeShippingWarehouseSelect,
|
||||||
|
selectShippingWarehouse
|
||||||
|
} from "../../features/shippingWarehouseSelect/shippingWarehouseSelectSlice";
|
||||||
|
import {responsiveWidth} from "react-native-responsive-dimensions";
|
||||||
|
import {View} from "react-native";
|
||||||
|
|
||||||
|
const ShippingWarehouseSelect: FC = () => {
|
||||||
|
const state = useSelector((state: RootState) => state.shippingWarehouseSelect);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
useEffect(() => {
|
||||||
|
if (state.initialized) return;
|
||||||
|
generalApi.getShippingWarehouses().then(shippingWarehouses =>
|
||||||
|
dispatch(initializeShippingWarehouseSelect(shippingWarehouses)))
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<View style={{
|
||||||
|
borderWidth: responsiveWidth(0.1),
|
||||||
|
borderRadius: responsiveWidth(1)
|
||||||
|
}}>
|
||||||
|
<Picker
|
||||||
|
selectedValue={state.selectedShippingWarehouse?.id}
|
||||||
|
onValueChange={(value, event) => dispatch(selectShippingWarehouse({shippingWarehouseId: value}))}
|
||||||
|
>
|
||||||
|
{state.shippingWarehouses.map(shippingWarehouse => (
|
||||||
|
<Picker.Item
|
||||||
|
key={shippingWarehouse.id}
|
||||||
|
label={shippingWarehouse.name}
|
||||||
|
value={shippingWarehouse.id}
|
||||||
|
style={{fontSize: responsiveWidth(3)}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Picker>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ShippingWarehouseSelect
|
||||||
@@ -25,6 +25,7 @@ export const assembly = createSlice({
|
|||||||
state.initialOrder = action.payload;
|
state.initialOrder = action.payload;
|
||||||
state.order = action.payload;
|
state.order = action.payload;
|
||||||
state.selectedProductId = 0;
|
state.selectedProductId = 0;
|
||||||
|
state.localState = ASSEMBLY_STATE.NOT_STARTED;
|
||||||
},
|
},
|
||||||
setAssembly: (state, action: PayloadAction<Assembly>) => {
|
setAssembly: (state, action: PayloadAction<Assembly>) => {
|
||||||
state.assembly = action.payload;
|
state.assembly = action.payload;
|
||||||
@@ -80,11 +81,20 @@ export const assembly = createSlice({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
state.selectedProduct = state.order.products.find(product => product.databaseId == action.payload.orderProductId);
|
state.selectedProduct = state.order.products.find(product => product.databaseId == action.payload.orderProductId);
|
||||||
|
},
|
||||||
|
setLocalState: (state, action: PayloadAction<ASSEMBLY_STATE>) => {
|
||||||
|
state.localState = action.payload;
|
||||||
},
|
},
|
||||||
selectProduct: (state, action: PayloadAction<number>) => {
|
selectProduct: (state, action: PayloadAction<number>) => {
|
||||||
if (!state.order) return;
|
if (!state.order) return;
|
||||||
state.selectedProduct = state.order.products[action.payload];
|
state.selectedProduct = state.order.products[action.payload];
|
||||||
|
},
|
||||||
|
reset: (state) => {
|
||||||
|
state.assembly = undefined;
|
||||||
|
state.order = undefined;
|
||||||
|
state.localState = ASSEMBLY_STATE.NOT_STARTED
|
||||||
|
state.selectedProductId = undefined;
|
||||||
|
state.selectedProduct = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -96,6 +106,8 @@ export const {
|
|||||||
setAssembly,
|
setAssembly,
|
||||||
startAssembly,
|
startAssembly,
|
||||||
endAssembly,
|
endAssembly,
|
||||||
confirmAssembly
|
confirmAssembly,
|
||||||
|
setLocalState,
|
||||||
|
reset
|
||||||
} = assembly.actions;
|
} = assembly.actions;
|
||||||
export default assembly.reducer;
|
export default assembly.reducer;
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import {createSlice, PayloadAction} from "@reduxjs/toolkit";
|
import {createSlice, PayloadAction} from "@reduxjs/toolkit";
|
||||||
|
import {ShippingWarehouse} from "../../types/shippingWarehouse";
|
||||||
|
import ShippingWarehouseSelect from "../../components/ShippingWarehouseSelect/ShippingWarehouseSelect";
|
||||||
|
|
||||||
export enum OrderStatus {
|
export enum OrderStatus {
|
||||||
ALL = -1,
|
ALL = -1,
|
||||||
@@ -42,15 +44,20 @@ export interface OrdersFilterState {
|
|||||||
status: OrderStatus;
|
status: OrderStatus;
|
||||||
shipmentDate: string;
|
shipmentDate: string;
|
||||||
page: number;
|
page: number;
|
||||||
|
shippingWarehouse: ShippingWarehouse
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: OrdersFilterState = {
|
const initialState: OrdersFilterState = {
|
||||||
isVisible: false,
|
isVisible: false,
|
||||||
orderBy: "createdOn",
|
orderBy: "shipmentDate",
|
||||||
desc: true,
|
desc: true,
|
||||||
shipmentDate: (new Date()).toISOString(),
|
shipmentDate: (new Date()).toISOString(),
|
||||||
status: OrderStatus.AWAITING_PACKAGING,
|
status: OrderStatus.AWAITING_PACKAGING,
|
||||||
page: 0
|
page: 0,
|
||||||
|
shippingWarehouse: {
|
||||||
|
id: -1,
|
||||||
|
name: 'Все склады отгрузки'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ordersFilterSlice = createSlice({
|
export const ordersFilterSlice = createSlice({
|
||||||
@@ -75,14 +82,18 @@ export const ordersFilterSlice = createSlice({
|
|||||||
setShipmentDate: (state, action: PayloadAction<string>) => {
|
setShipmentDate: (state, action: PayloadAction<string>) => {
|
||||||
state.shipmentDate = action.payload;
|
state.shipmentDate = action.payload;
|
||||||
},
|
},
|
||||||
|
setShippingWarehouse: (state, action: PayloadAction<ShippingWarehouse>) => {
|
||||||
|
state.shippingWarehouse = action.payload;
|
||||||
|
},
|
||||||
setPage: (state, action: PayloadAction<number>) => {
|
setPage: (state, action: PayloadAction<number>) => {
|
||||||
|
console.log(action)
|
||||||
state.page = action.payload;
|
state.page = action.payload;
|
||||||
},
|
},
|
||||||
nextPage: (state) => {
|
nextPage: (state) => {
|
||||||
state.page = state.page + 1
|
state.page = state.page + 1
|
||||||
},
|
},
|
||||||
refreshPagination: (state) => {
|
refreshPagination: (state) => {
|
||||||
state.page = 0
|
state.page = -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -95,6 +106,8 @@ export const {
|
|||||||
setOrderBy,
|
setOrderBy,
|
||||||
setDesc,
|
setDesc,
|
||||||
setStatus,
|
setStatus,
|
||||||
setShipmentDate
|
setShipmentDate,
|
||||||
|
setPage,
|
||||||
|
setShippingWarehouse
|
||||||
} = ordersFilterSlice.actions;
|
} = ordersFilterSlice.actions;
|
||||||
export default ordersFilterSlice.reducer;
|
export default ordersFilterSlice.reducer;
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import {createSlice, PayloadAction} from "@reduxjs/toolkit";
|
||||||
|
import {ShippingWarehouse} from "../../types/shippingWarehouse";
|
||||||
|
|
||||||
|
export interface ShippingWarehouseSelectState {
|
||||||
|
shippingWarehouses: ShippingWarehouse[]
|
||||||
|
selectedShippingWarehouse: ShippingWarehouse
|
||||||
|
initialized: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: ShippingWarehouseSelectState = {
|
||||||
|
shippingWarehouses: [],
|
||||||
|
selectedShippingWarehouse: {
|
||||||
|
id: -1,
|
||||||
|
name: "Все склады отгрузки"
|
||||||
|
},
|
||||||
|
initialized: false
|
||||||
|
}
|
||||||
|
|
||||||
|
export const shippingWarehouseSelect = createSlice({
|
||||||
|
name: 'shippingWarehouse',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
initializeShippingWarehouseSelect: (state, action: PayloadAction<ShippingWarehouse[]>) => {
|
||||||
|
state.shippingWarehouses = action.payload;
|
||||||
|
state.initialized = true;
|
||||||
|
if (state.shippingWarehouses.length > 0) state.selectedShippingWarehouse = state.shippingWarehouses[0];
|
||||||
|
},
|
||||||
|
selectShippingWarehouse: (state, action: PayloadAction<{ shippingWarehouseId: number }>) => {
|
||||||
|
let selectedWarehouse = state.shippingWarehouses.find(wh => wh.id == action.payload.shippingWarehouseId);
|
||||||
|
if (!selectedWarehouse) return;
|
||||||
|
state.selectedShippingWarehouse = selectedWarehouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const {initializeShippingWarehouseSelect, selectShippingWarehouse} = shippingWarehouseSelect.actions;
|
||||||
|
export default shippingWarehouseSelect.reducer;
|
||||||
@@ -9,6 +9,7 @@ import assemblyReducer from 'features/assembly/assemblySlice';
|
|||||||
import printingReducer from 'features/printing/printingSlice';
|
import printingReducer from 'features/printing/printingSlice';
|
||||||
import reprintModalReducer from 'features/reprintModal/reprintModalSlice';
|
import reprintModalReducer from 'features/reprintModal/reprintModalSlice';
|
||||||
import ordersFilterReducer from 'features/ordersFilter/ordersFilterSlice';
|
import ordersFilterReducer from 'features/ordersFilter/ordersFilterSlice';
|
||||||
|
import shippingWarehouseSelectReducer from 'features/shippingWarehouseSelect/shippingWarehouseSelectSlice';
|
||||||
import {useDispatch} from "react-redux";
|
import {useDispatch} from "react-redux";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
@@ -21,7 +22,8 @@ export const store = configureStore({
|
|||||||
printing: printingReducer,
|
printing: printingReducer,
|
||||||
reprintModal: reprintModalReducer,
|
reprintModal: reprintModalReducer,
|
||||||
imageZoomModal: imageZoomModalReducer,
|
imageZoomModal: imageZoomModalReducer,
|
||||||
ordersFilter: ordersFilterReducer
|
ordersFilter: ordersFilterReducer,
|
||||||
|
shippingWarehouseSelect: shippingWarehouseSelectReducer
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import flashListSeparator from "../../components/FlashListSeparator/FlashListSep
|
|||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {openScanModal} from "../../features/scanModal/scanModalSlice";
|
import {openScanModal} from "../../features/scanModal/scanModalSlice";
|
||||||
import ordersApi from "../../api/ordersApi";
|
import ordersApi from "../../api/ordersApi";
|
||||||
|
import DTitle from "../../components/DTitle/DTitle";
|
||||||
|
|
||||||
function BarcodeScreen() {
|
function BarcodeScreen() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@@ -26,27 +27,32 @@ function BarcodeScreen() {
|
|||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<SearchBar onSupplierProductSelected={product => {
|
<SearchBar onProductSelected={product => {
|
||||||
ordersApi.getOrdersBySupplierProduct(product.supplierProductId).then(setOrders)
|
ordersApi.getOrdersByProduct(product.productId).then(setOrders)
|
||||||
}}/>
|
}}/>
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
<FlashList
|
{orders.length > 0 ? <FlashList
|
||||||
|
keyboardShouldPersistTaps={"never"}
|
||||||
|
data={orders}
|
||||||
|
keyExtractor={(item: Order) => item.orderNumber.toString()}
|
||||||
|
renderItem={({item}) =>
|
||||||
|
<OrderCard onSelect={(order) => {
|
||||||
|
dispatch(setOrder(order));
|
||||||
|
navigator.navigate("Home");
|
||||||
|
}} order={item}/>}
|
||||||
|
showsHorizontalScrollIndicator={false}
|
||||||
|
showsVerticalScrollIndicator={true}
|
||||||
|
onEndReachedThreshold={0.1}
|
||||||
|
estimatedItemSize={720}
|
||||||
|
ItemSeparatorComponent={flashListSeparator}
|
||||||
|
/> :
|
||||||
|
<View style={{justifyContent: "center", flex: 1}}>
|
||||||
|
<DTitle style={{
|
||||||
|
textAlign: "center",
|
||||||
|
}}>Нет заказов по данному
|
||||||
|
товару</DTitle>
|
||||||
|
</View>}
|
||||||
|
|
||||||
keyboardShouldPersistTaps={"never"}
|
|
||||||
data={orders}
|
|
||||||
keyExtractor={(item: Order) => item.orderNumber.toString()}
|
|
||||||
renderItem={({item}) =>
|
|
||||||
<OrderCard onSelect={(order) => {
|
|
||||||
dispatch(setOrder(order));
|
|
||||||
navigator.navigate("Home");
|
|
||||||
}} order={item}/>}
|
|
||||||
showsHorizontalScrollIndicator={false}
|
|
||||||
showsVerticalScrollIndicator={true}
|
|
||||||
onEndReachedThreshold={0.1}
|
|
||||||
estimatedItemSize={720}
|
|
||||||
ItemSeparatorComponent={flashListSeparator}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ import {closeScanModal, setScannedData} from "../../features/scanModal/scanModal
|
|||||||
import LoadingModal from "../../components/Modals/LoadingModal/LoadingModal";
|
import LoadingModal from "../../components/Modals/LoadingModal/LoadingModal";
|
||||||
import ReprintModal from "../../components/Modals/ReprintModal/ReprintModal";
|
import ReprintModal from "../../components/Modals/ReprintModal/ReprintModal";
|
||||||
import assemblyApi from "../../api/assemblyApi";
|
import assemblyApi from "../../api/assemblyApi";
|
||||||
import {assembly, setAssembly, setOrder} from "../../features/assembly/assemblySlice";
|
import {assembly, setAssembly, setLocalState, setOrder} from "../../features/assembly/assemblySlice";
|
||||||
import ordersApi from "../../api/ordersApi";
|
import ordersApi from "../../api/ordersApi";
|
||||||
import ImageZoomModal from "../../components/Modals/ImageZoomModal/ImageZoomModal";
|
import ImageZoomModal from "../../components/Modals/ImageZoomModal/ImageZoomModal";
|
||||||
import SortingModal from "../../components/Modals/SortingModal/SortingModal";
|
import SortingModal from "../../components/Modals/SortingModal/SortingModal";
|
||||||
|
import {setLoadingText} from "../../features/loadingModal/loadingModalSlice";
|
||||||
|
import {ASSEMBLY_STATE} from "../../types/assembly";
|
||||||
|
|
||||||
function CommonPage() {
|
function CommonPage() {
|
||||||
const dim = useSelector((state: RootState) => state.interface.dim);
|
const dim = useSelector((state: RootState) => state.interface.dim);
|
||||||
@@ -31,6 +33,7 @@ function CommonPage() {
|
|||||||
dispatch(login({accessToken: token}));
|
dispatch(login({accessToken: token}));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadAssembly = async () => {
|
const loadAssembly = async () => {
|
||||||
assemblyApi.hasActive().then(({has}) => {
|
assemblyApi.hasActive().then(({has}) => {
|
||||||
if (!has) return;
|
if (!has) return;
|
||||||
@@ -38,6 +41,7 @@ function CommonPage() {
|
|||||||
ordersApi.getOrderById(assembly.orderId).then(order => {
|
ordersApi.getOrderById(assembly.orderId).then(order => {
|
||||||
dispatch(setAssembly(assembly));
|
dispatch(setAssembly(assembly));
|
||||||
dispatch(setOrder(order));
|
dispatch(setOrder(order));
|
||||||
|
dispatch(setLocalState(assembly.state as ASSEMBLY_STATE));
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import * as SecureStore from 'expo-secure-store';
|
|||||||
|
|
||||||
function LoginScreen() {
|
function LoginScreen() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [loginValue, setLoginValue] = useState('dsnon');
|
const [loginValue, setLoginValue] = useState('');
|
||||||
const [passwordValue, setPasswordValue] = useState('ochko');
|
const [passwordValue, setPasswordValue] = useState('');
|
||||||
const handleLogin = async () => {
|
const handleLogin = async () => {
|
||||||
const response = await userApi.login(loginValue, passwordValue);
|
const response = await userApi.login(loginValue, passwordValue);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import {View, Text, Image, StyleSheet, Button, TouchableOpacity} from "react-native";
|
import {View, Image, StyleSheet, TouchableOpacity} from "react-native";
|
||||||
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
import {responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
||||||
import DText from "../../components/DText/DText";
|
import DText from "../../components/DText/DText";
|
||||||
import {RFPercentage} from "react-native-responsive-fontsize";
|
import {RFPercentage} from "react-native-responsive-fontsize";
|
||||||
import DTitle from "../../components/DTitle/DTitle";
|
import DTitle from "../../components/DTitle/DTitle";
|
||||||
import BasicButton from "../../components/BasicButton/BasicButton";
|
import BasicButton from "../../components/BasicButton/BasicButton";
|
||||||
import Hyperlink from "../../components/Hyperlink/Hyperlink";
|
|
||||||
import React, {FC, useEffect, useState} from "react";
|
import React, {FC, useEffect, useState} from "react";
|
||||||
import userApi from "../../api/userApi";
|
|
||||||
import {StatusBar} from "expo-status-bar";
|
|
||||||
import * as Progress from 'react-native-progress';
|
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
import {RootState} from "../../redux/store";
|
import {RootState} from "../../redux/store";
|
||||||
import {closeLoadingModal, openLoadingModal, setLoadingText} from "../../features/loadingModal/loadingModalSlice";
|
import {closeLoadingModal, openLoadingModal, setLoadingText} from "../../features/loadingModal/loadingModalSlice";
|
||||||
@@ -182,13 +178,14 @@ const OrderScreen: FC<OrderScreenProps> = ({order}) => {
|
|||||||
}
|
}
|
||||||
const printLabel = () => {
|
const printLabel = () => {
|
||||||
if (!order) return;
|
if (!order) return;
|
||||||
|
let printer = printingService.getInstance().getPrinter(order.baseMarketplace);
|
||||||
dispatch(setLoadingText('Идет печать этикетки...'))
|
dispatch(setLoadingText('Идет печать этикетки...'))
|
||||||
dispatch(openLoadingModal())
|
dispatch(openLoadingModal())
|
||||||
printingApi.getLabel(order.databaseId).then(pdfData => {
|
printingApi.getLabel(order.databaseId).then(pdfData => {
|
||||||
printingService.getInstance().printPdf('wildberries', pdfData).then((response) => {
|
printingService.getInstance().printPdf(printer, pdfData).then((response) => {
|
||||||
dispatch(closeLoadingModal());
|
dispatch(closeLoadingModal());
|
||||||
if (response) return;
|
if (response) return;
|
||||||
dispatch(setPrinterName({printerName: 'wildberries'}));
|
dispatch(setPrinterName({printerName: printer}));
|
||||||
dispatch(openReprintModal());
|
dispatch(openReprintModal());
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,37 +4,63 @@ import ordersApi from "../../api/ordersApi";
|
|||||||
import {setOrder} from "../../features/assembly/assemblySlice";
|
import {setOrder} from "../../features/assembly/assemblySlice";
|
||||||
import {RootState} from "../../redux/store";
|
import {RootState} from "../../redux/store";
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
import {refreshPagination} from "../../features/ordersFilter/ordersFilterSlice";
|
import {
|
||||||
|
refreshPagination,
|
||||||
|
setOrderBy,
|
||||||
|
setPage,
|
||||||
|
setShippingWarehouse
|
||||||
|
} from "../../features/ordersFilter/ordersFilterSlice";
|
||||||
|
|
||||||
|
|
||||||
const useOrders = () => {
|
const useOrders = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [orders, setOrders] = useState<Order[]>([]);
|
const [orders, setOrders] = useState<Order[]>([]);
|
||||||
|
const [isInitialized, setIsInitialized] = useState(false);
|
||||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||||
const filterState = useSelector((state: RootState) => state.ordersFilter);
|
const filterState = useSelector((state: RootState) => state.ordersFilter);
|
||||||
|
const fetchOrders = async (): Promise<Order[]> => {
|
||||||
|
return ordersApi.getOrders(
|
||||||
|
filterState.page,
|
||||||
|
filterState.orderBy,
|
||||||
|
filterState.desc,
|
||||||
|
filterState.shipmentDate,
|
||||||
|
filterState.status,
|
||||||
|
filterState.shippingWarehouse.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const appendOrders = (newOrders: Order[]) => {
|
||||||
|
setOrders([...newOrders, ...orders]);
|
||||||
|
}
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
if (filterState.page == 0) return;
|
|
||||||
setIsRefreshing(true);
|
|
||||||
setOrders([]);
|
setOrders([]);
|
||||||
dispatch(refreshPagination());
|
dispatch(setPage(0));
|
||||||
|
fetchOrders().then(setOrders);
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (filterState.isVisible) return;
|
if (!isInitialized || filterState.isVisible) return;
|
||||||
|
fetchOrders().then(appendOrders);
|
||||||
ordersApi.getOrders(filterState.page, filterState.orderBy, filterState.desc, filterState.shipmentDate, filterState.status).then(response => {
|
|
||||||
setOrders(oldOrders => [...oldOrders, ...response]);
|
|
||||||
setIsRefreshing(false);
|
|
||||||
});
|
|
||||||
}, [filterState.page]);
|
}, [filterState.page]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (filterState.isVisible) return;
|
if (!isInitialized || filterState.isVisible) return;
|
||||||
setOrders([]);
|
fetchOrders().then(setOrders)
|
||||||
setIsRefreshing(true);
|
}, [filterState.orderBy,
|
||||||
dispatch(refreshPagination());
|
filterState.desc,
|
||||||
}, [filterState.orderBy, filterState.desc, filterState.status, filterState.shipmentDate, filterState.isVisible]);
|
filterState.status,
|
||||||
|
filterState.shipmentDate,
|
||||||
|
filterState.isVisible,
|
||||||
|
filterState.shippingWarehouse
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchOrders().then(newOrders=>{
|
||||||
|
setOrders(newOrders);
|
||||||
|
setIsInitialized(true);
|
||||||
|
|
||||||
|
})
|
||||||
|
}, []);
|
||||||
return {refresh, isRefreshing, orders};
|
return {refresh, isRefreshing, orders};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {NavigationProp, useNavigation} from "@react-navigation/native";
|
|||||||
import {TabNavigatorParamList} from "../MainScreen/MainScreen";
|
import {TabNavigatorParamList} from "../MainScreen/MainScreen";
|
||||||
import useOrders from "../OrderScreen/useOrders";
|
import useOrders from "../OrderScreen/useOrders";
|
||||||
import {nextPage, openOrdersFilterModal} from "../../features/ordersFilter/ordersFilterSlice";
|
import {nextPage, openOrdersFilterModal} from "../../features/ordersFilter/ordersFilterSlice";
|
||||||
|
import DTitle from "../../components/DTitle/DTitle";
|
||||||
|
|
||||||
function OrdersScreen() {
|
function OrdersScreen() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@@ -52,6 +53,10 @@ function OrdersScreen() {
|
|||||||
ItemSeparatorComponent={flashListSeparator}
|
ItemSeparatorComponent={flashListSeparator}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
{orders.length <= 0 &&
|
||||||
|
<DTitle style={{flex: 1, textAlign: "center"}}>Нет заказов по заданному фильтру</DTitle>
|
||||||
|
}
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import {Button, Text, View, StyleSheet, TouchableOpacity, Image, ScrollView, GestureResponderEvent} from "react-native";
|
import {View, StyleSheet, TouchableOpacity, Image, ScrollView, GestureResponderEvent} from "react-native";
|
||||||
import {useAppDispatch} from "../../redux/store";
|
|
||||||
import * as process from "process";
|
|
||||||
import {responsiveFontSize, responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
import {responsiveFontSize, responsiveHeight, responsiveWidth} from "react-native-responsive-dimensions";
|
||||||
import {background, blue, gray} from "../../css/colors";
|
import {blue, gray} from "../../css/colors";
|
||||||
import {RFPercentage} from "react-native-responsive-fontsize";
|
import {RFPercentage} from "react-native-responsive-fontsize";
|
||||||
import DText from "../../components/DText/DText";
|
import DText from "../../components/DText/DText";
|
||||||
import DTitle from "../../components/DTitle/DTitle";
|
import DTitle from "../../components/DTitle/DTitle";
|
||||||
import {ScreenStackHeaderLeftView} from "react-native-screens";
|
|
||||||
import Separator from "../../components/Separator/Separator";
|
import Separator from "../../components/Separator/Separator";
|
||||||
import {BottomSheetModal} from "@gorhom/bottom-sheet";
|
import {BottomSheetModal} from "@gorhom/bottom-sheet";
|
||||||
import {useMemo, useRef, useState} from "react";
|
import {useMemo, useRef, useState} from "react";
|
||||||
import {openApp} from "rn-openapp";
|
import assemblyApi from "../../api/assemblyApi";
|
||||||
import SelectProductModal from "../../components/Modals/SelectProductModal/SelectProductModal";
|
import Toast from "react-native-toast-message";
|
||||||
import selectProductModal from "../../components/Modals/SelectProductModal/SelectProductModal";
|
import {useDispatch} from "react-redux";
|
||||||
|
import {reset} from "../../features/assembly/assemblySlice";
|
||||||
|
|
||||||
|
|
||||||
type SettingsElementProps = {
|
type SettingsElementProps = {
|
||||||
icon: any;
|
icon: any;
|
||||||
@@ -58,6 +57,7 @@ function ProfileScreen() {
|
|||||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||||
const snapPoints = useMemo(() => ['25%', '40%'], []);
|
const snapPoints = useMemo(() => ['25%', '40%'], []);
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
@@ -76,9 +76,18 @@ function ProfileScreen() {
|
|||||||
>
|
>
|
||||||
<SettingsElement icon={require('assets/icons/settings/withdraw.png')} title={'Вывод'}/>
|
<SettingsElement icon={require('assets/icons/settings/withdraw.png')} title={'Вывод'}/>
|
||||||
<SettingsElement icon={require('assets/icons/settings/statistics.png')} title={'Статистика'}/>
|
<SettingsElement icon={require('assets/icons/settings/statistics.png')} title={'Статистика'}/>
|
||||||
|
<SettingsElement icon={require('assets/icons/settings/printer.png')} title={'Принтеры'}/>
|
||||||
<SettingsElement onPress={() => {
|
<SettingsElement onPress={() => {
|
||||||
openApp('assemblrprintingservice');
|
assemblyApi.cancel().then(response => {
|
||||||
}} icon={require('assets/icons/settings/printer.png')} title={'Принтеры'}/>
|
|
||||||
|
Toast.show({
|
||||||
|
type: response.ok ? "success" : "error",
|
||||||
|
text1: "Отмена сборки",
|
||||||
|
text2: response.message,
|
||||||
|
});
|
||||||
|
dispatch(reset());
|
||||||
|
})
|
||||||
|
}} icon={require('assets/icons/settings/close.png')} title={'Отменить сборку'}/>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
@@ -187,7 +196,7 @@ const styles = StyleSheet.create({
|
|||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
borderRadius: 100,
|
borderRadius: 100,
|
||||||
borderWidth: RFPercentage(0.3),
|
borderWidth: RFPercentage(0.3),
|
||||||
padding: RFPercentage(1),
|
padding: RFPercentage(1.5),
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center"
|
alignItems: "center"
|
||||||
|
|
||||||
|
|||||||
6
src/types/product.ts
Normal file
6
src/types/product.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export type Product = {
|
||||||
|
productId: number;
|
||||||
|
dencoArticle: number;
|
||||||
|
productName: string;
|
||||||
|
thumbUrl: string;
|
||||||
|
}
|
||||||
4
src/types/shippingWarehouse.ts
Normal file
4
src/types/shippingWarehouse.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export type ShippingWarehouse = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import {blue100} from "react-native-paper/lib/typescript/styles/themes/v2/colors";
|
||||||
|
|
||||||
class PrintingService {
|
class PrintingService {
|
||||||
private static instance: PrintingService | null = null;
|
private static instance: PrintingService | null = null;
|
||||||
@@ -17,9 +18,24 @@ class PrintingService {
|
|||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private newAbortSignal(timeoutMs: number) {
|
||||||
|
const abortController = new AbortController();
|
||||||
|
setTimeout(() => abortController.abort(), timeoutMs || 0);
|
||||||
|
|
||||||
|
return abortController.signal;
|
||||||
|
}
|
||||||
|
|
||||||
private async print(printer: string, type: string, bytes: Uint8Array): Promise<boolean> {
|
private async print(printer: string, type: string, bytes: Uint8Array): Promise<boolean> {
|
||||||
let response = await axios.post(`http://${this.apiUrl}:${this.port}/print/${printer}/${type}`, bytes.buffer);
|
try {
|
||||||
return response.data.ok;
|
let response = await axios.post(`http://${this.apiUrl}:${this.port}/print/${printer}/${type}`, bytes.buffer, {
|
||||||
|
timeout: 20 * 1000,
|
||||||
|
signal: this.newAbortSignal(20 * 1000)
|
||||||
|
});
|
||||||
|
return response.data.ok;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async printPdf(printer: string, pdfBytes: Uint8Array): Promise<boolean> {
|
public async printPdf(printer: string, pdfBytes: Uint8Array): Promise<boolean> {
|
||||||
@@ -29,6 +45,11 @@ class PrintingService {
|
|||||||
public async printImage(printer: string, imageBytes: Uint8Array): Promise<boolean> {
|
public async printImage(printer: string, imageBytes: Uint8Array): Promise<boolean> {
|
||||||
return this.print(printer, "image", imageBytes);
|
return this.print(printer, "image", imageBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getPrinter(baseMarketplace: number): string {
|
||||||
|
if (baseMarketplace == 0) return "wildberries";
|
||||||
|
return "ozon";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PrintingService;
|
export default PrintingService;
|
||||||
Reference in New Issue
Block a user