From 062f10a25d43b875d187cf582b2ecf96d075ec26 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Thu, 25 Mar 2021 23:09:49 +0300 Subject: refactor: move services to separate folder --- src/services/account/index.ts | 17 ++++++ src/services/constants.ts | 11 ++++ src/services/contractors/ContractorForm.tsx | 14 +++++ src/services/contractors/ContractorPanel.tsx | 34 +++++++++++ src/services/contractors/index.ts | 22 +++++++ src/services/index.ts | 20 +++++++ src/services/products/ProductForm.tsx | 15 +++++ src/services/products/index.ts | 20 +++++++ src/services/transfers/TransferForm.tsx | 44 ++++++++++++++ src/services/transfers/TransfersUpload.tsx | 44 ++++++++++++++ src/services/transfers/index.ts | 35 +++++++++++ src/services/waybills/WaybillForm.tsx | 86 ++++++++++++++++++++++++++++ src/services/waybills/WaybillPanel.tsx | 42 ++++++++++++++ src/services/waybills/index.ts | 27 +++++++++ 14 files changed, 431 insertions(+) create mode 100644 src/services/account/index.ts create mode 100644 src/services/constants.ts create mode 100644 src/services/contractors/ContractorForm.tsx create mode 100644 src/services/contractors/ContractorPanel.tsx create mode 100644 src/services/contractors/index.ts create mode 100644 src/services/index.ts create mode 100644 src/services/products/ProductForm.tsx create mode 100644 src/services/products/index.ts create mode 100644 src/services/transfers/TransferForm.tsx create mode 100644 src/services/transfers/TransfersUpload.tsx create mode 100644 src/services/transfers/index.ts create mode 100644 src/services/waybills/WaybillForm.tsx create mode 100644 src/services/waybills/WaybillPanel.tsx create mode 100644 src/services/waybills/index.ts (limited to 'src/services') diff --git a/src/services/account/index.ts b/src/services/account/index.ts new file mode 100644 index 0000000..5b5eb10 --- /dev/null +++ b/src/services/account/index.ts @@ -0,0 +1,17 @@ +const service = { + route: 'account', + name: 'Рассчётный счёт', + tableFields: [ + { key: 'date', label: 'Дата', transform: (date: string) => new Date(date).toLocaleDateString() }, + { key: 'amount', label: 'Сумма' }, + ], + actions: [ + { + name: 'Загрузить выписку', + route: '/transfers/upload', + }, + ], + rowLink: (item: any) => `/transfers?date=${item.date}`, +}; + +export default service; diff --git a/src/services/constants.ts b/src/services/constants.ts new file mode 100644 index 0000000..1461d9c --- /dev/null +++ b/src/services/constants.ts @@ -0,0 +1,11 @@ +export const operationNames = { + in: 'Приход', + out: 'Расход', +}; + +export const waybillStatusNames = { + waiting: 'Ожидание', + executed: 'Проведена', + cancelled: 'Отменена', +}; + diff --git a/src/services/contractors/ContractorForm.tsx b/src/services/contractors/ContractorForm.tsx new file mode 100644 index 0000000..d300efc --- /dev/null +++ b/src/services/contractors/ContractorForm.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { Form } from 'formik'; +import Input from '../../components/Input'; + +const ContractorForm: React.FC = () => { + return ( +
+ + +
+ ); +}; + +export default ContractorForm; diff --git a/src/services/contractors/ContractorPanel.tsx b/src/services/contractors/ContractorPanel.tsx new file mode 100644 index 0000000..ce94c48 --- /dev/null +++ b/src/services/contractors/ContractorPanel.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { useHistory } from 'react-router-dom'; +import Button from '../../components/Button'; +import { patch, baseURL } from '../../requests'; +import { PanelProps } from '../../containers/Service/ServiceContext'; + + +const ContractorPanel: React.FC = ({ item, mutate }) => { + const history = useHistory(); + + return ( +
+ + Долг контрагента: {item.debt} + +
+ + + + +
+
+ ); +}; + +export default ContractorPanel; diff --git a/src/services/contractors/index.ts b/src/services/contractors/index.ts new file mode 100644 index 0000000..124e338 --- /dev/null +++ b/src/services/contractors/index.ts @@ -0,0 +1,22 @@ +import Form from './ContractorForm'; +import Panel from './ContractorPanel'; + +const service = { + route: 'contractors', + name: 'Контрагенты', + nameSingular: 'Контрагент', + tableFields: [ + { key: 'vatId', label: 'УНП' }, + { key: 'name', label: 'Название' }, + { key: 'debt', label: 'Долг' }, + ], + default: { + name: '', + vatId: '', + debt: 0, + }, + Form, + Panel, +}; + +export default service; diff --git a/src/services/index.ts b/src/services/index.ts new file mode 100644 index 0000000..7f559f2 --- /dev/null +++ b/src/services/index.ts @@ -0,0 +1,20 @@ +import contractors from './contractors'; +import waybills from './waybills'; +import transfers from './transfers'; +import products from './products'; +import account from './account'; +import { registerServiceHooks } from '../hooks/useAPIClient'; +import { ServiceParams } from '../containers/Service/ServiceContext'; + +const services = [ + contractors, + products, + waybills, + transfers, + account, +] as ServiceParams[]; + +services.forEach((service: any) => registerServiceHooks(service.route)); + +export default services; + diff --git a/src/services/products/ProductForm.tsx b/src/services/products/ProductForm.tsx new file mode 100644 index 0000000..62f0e70 --- /dev/null +++ b/src/services/products/ProductForm.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { Form } from 'formik'; +import Input from '../../components/Input'; + + +const ProductForm: React.FC = () => { + return ( +
+ + +
+ ); +}; + +export default ProductForm; diff --git a/src/services/products/index.ts b/src/services/products/index.ts new file mode 100644 index 0000000..7e1509a --- /dev/null +++ b/src/services/products/index.ts @@ -0,0 +1,20 @@ +import Form from './ProductForm'; + +const service = { + route: 'products', + name: 'Товары', + nameSingular: 'Товар', + tableFields: [ + { key: 'name', label: 'Название' }, + { key: 'price', label: 'Цена' }, + { key: 'quantity', label: 'На складе' }, + ], + default: { + name: '', + price: '', + quantity: 0, + }, + Form, +}; + +export default service; diff --git a/src/services/transfers/TransferForm.tsx b/src/services/transfers/TransferForm.tsx new file mode 100644 index 0000000..3502609 --- /dev/null +++ b/src/services/transfers/TransferForm.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { Form, FormikProps } from 'formik'; +import moment from 'moment'; +import Input from '../../components/Input'; +import Select from '../../components/Select'; +import hooks from '../../hooks/useAPIClient'; + + +const mapper = (item: any) => ({ key: item._id, label: item.name }); + + +const TransferForm: React.FC> = ({ setFieldValue, values }) => { + const { data: contractors } = hooks.contractors.useList(); + + if (!values.date) setFieldValue('date', moment().format('YYYY-MM-DD')); + if (!values.contractorId && contractors?.length) setFieldValue('contractorId', contractors[0]._id); + + return ( +
+
+ +
+
+ +
+
+ ); +}; + +export default TransferForm; diff --git a/src/services/transfers/TransfersUpload.tsx b/src/services/transfers/TransfersUpload.tsx new file mode 100644 index 0000000..1c81b08 --- /dev/null +++ b/src/services/transfers/TransfersUpload.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { useHistory } from 'react-router-dom'; +import { Form, Formik } from 'formik'; +import Button from '../../components/Button'; +import Input from '../../components/Input'; +import Page, { Action } from '../../containers/Page'; +import { post } from '../../requests'; + +const TransfersUpload: React.FC = () => { + const history = useHistory(); + + const handleSubmitFile = () => { + const reader = new FileReader(); + const element = document.getElementById('file') as HTMLInputElement; + const file = element?.files?.[0]; + if (file) { + reader.readAsDataURL(file); + reader.onload = (e: any) => { + const uri = e.target.result; + post('/uploads', { uri }).then(history.goBack); + }; + } + }; + + const actions: Action[] = [ + { name: 'Назад', variant: 'outlined', onClick: history.goBack }, + { name: 'Загрузить', type: 'submit', form: 'form' }, + ]; + + return ( + + +
+ +
+
+
+ ); +}; + +export default TransfersUpload; diff --git a/src/services/transfers/index.ts b/src/services/transfers/index.ts new file mode 100644 index 0000000..09f6e04 --- /dev/null +++ b/src/services/transfers/index.ts @@ -0,0 +1,35 @@ +import Form from './TransferForm'; +import UploadPage from './TransfersUpload'; + +import { operationNames } from '../constants'; + +const service = { + route: 'transfers', + name: 'Переводы', + nameSingular: 'Перевод', + tableFields: [ + { key: 'date', label: 'Дата', transform: (date: string) => new Date(date).toLocaleDateString() }, + { key: 'contractor.name', label: 'Контрагент' }, + { key: 'operation', label: 'Операция', transform: (op: 'in' | 'out') => operationNames[op] }, + { key: 'amount', label: 'Сумма' }, + ], + actions: [ + { + name: 'Загрузить выписку', + route: '/transfers/upload', + variant: 'outlined', + }, + { + name: 'Добавить', + route: '/transfers/add', + }, + ], + default: { + operation: 'in', + records: [], + }, + routes: { upload: UploadPage }, + Form, +}; + +export default service; diff --git a/src/services/waybills/WaybillForm.tsx b/src/services/waybills/WaybillForm.tsx new file mode 100644 index 0000000..c11ab9e --- /dev/null +++ b/src/services/waybills/WaybillForm.tsx @@ -0,0 +1,86 @@ +import React from 'react'; +import { Form, FormikProps } from 'formik'; +import _ from 'lodash'; +import moment from 'moment'; +import Input from '../../components/Input'; +import Button from '../../components/Button'; +import Select from '../../components/Select'; +import Paper from '../../components/Paper'; +import hooks from '../../hooks/useAPIClient'; + + +const mapper = (item: any) => ({ key: item._id, label: item.name }); + + +const WaybillForm: React.FC> = ({ setFieldValue, values }) => { + const { data: products } = hooks.products.useList(); + const { data: contractors } = hooks.contractors.useList(); + + if (!values.date) setFieldValue('date', moment().format('YYYY-MM-DD')); + if (!values.contractorId && contractors?.length) setFieldValue('contractorId', contractors[0]._id); + + const handleAddRecord = () => setFieldValue('records', [...values.records, { + productId: _.map(products, '_id').reduce((acc, id) => { + return acc || (!_.map(values.records, 'productId').includes(id) && id); + }, false), + price: '', + quantity: 1, + }]); + + const handleRemoveRecord = (index: number) => () => { + const records = [...values.records]; + records.splice(index, 1); + setFieldValue('records', records); + }; + + return ( +
+ + + + {values.records.map((record: any, index: number) => ( + + + +
+ +
+ +
+ ))} + +
+ ); +}; + +export default WaybillForm; diff --git a/src/services/waybills/WaybillPanel.tsx b/src/services/waybills/WaybillPanel.tsx new file mode 100644 index 0000000..101a871 --- /dev/null +++ b/src/services/waybills/WaybillPanel.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { useHistory } from 'react-router-dom'; +import Button from '../../components/Button'; +import { patch, baseURL } from '../../requests'; +import { PanelProps } from '../../containers/Service/ServiceContext'; + + +const WaybillPanel: React.FC = ({ item, mutate }) => { + const history = useHistory(); + + const handleChangeStatus = (status: any) => patch(`/waybills/${item._id}`, { status }) + .then(() => { + history.push('/waybills'); + mutate({ ...item, status }); + }); + + const handlePrint = () => window.open(`${baseURL}/spreadsheets/${item._id}`, '_blank'); + + const handleExecute = () => handleChangeStatus('executed'); + const handleCancel = () => handleChangeStatus('cancelled'); + + const executed = item.status === 'executed'; + + return ( +
+
+ + + Итоговая сумма: ${item.total} + +
+
+ ); +}; + +export default WaybillPanel; diff --git a/src/services/waybills/index.ts b/src/services/waybills/index.ts new file mode 100644 index 0000000..f8a4be6 --- /dev/null +++ b/src/services/waybills/index.ts @@ -0,0 +1,27 @@ +import Form from './WaybillForm'; +import Panel from './WaybillPanel'; +import { waybillStatusNames, operationNames } from '../constants'; + +const service = { + route: 'waybills', + name: 'Накладные', + nameSingular: 'Накладная', + tableFields: [ + { + key: 'status', + label: 'Статус', + transform: (status: 'waiting' | 'executed' | 'cancelled') => waybillStatusNames[status], + }, + { key: 'operation', label: 'Операция', transform: (op: 'in' | 'out') => operationNames[op] }, + { key: 'total', label: 'Сумма' }, + { key: 'contractor.name', label: 'Контрагент' }, + ], + default: { + operation: 'in', + records: [], + }, + Form, + Panel, +}; + +export default service; -- cgit v1.2.3