diff --git a/client/src/common/allocateLandedCostType.js b/client/src/common/allocateLandedCostType.js index 4e915bfec..74bcffacf 100644 --- a/client/src/common/allocateLandedCostType.js +++ b/client/src/common/allocateLandedCostType.js @@ -1,6 +1,6 @@ import intl from 'react-intl-universal'; export default [ - { name: intl.get('bills'), value: 'bills' }, - { name: intl.get('expenses'), value: 'expenses' }, -] \ No newline at end of file + { name: intl.get('bills'), value: 'Bill' }, + { name: intl.get('expenses'), value: 'Expense' }, +]; diff --git a/client/src/containers/Alerts/Bills/BillTransactionDeleteAlert.js b/client/src/containers/Alerts/Bills/BillTransactionDeleteAlert.js new file mode 100644 index 000000000..20c93183c --- /dev/null +++ b/client/src/containers/Alerts/Bills/BillTransactionDeleteAlert.js @@ -0,0 +1,67 @@ +import React from 'react'; +import { Intent, Alert } from '@blueprintjs/core'; +import { FormattedMessage as T } from 'components'; +import intl from 'react-intl-universal'; +import { useDeleteLandedCost } from 'hooks/query'; + +import { AppToaster } from 'components'; + +import withAlertActions from 'containers/Alert/withAlertActions'; +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; + +import { compose } from 'utils'; + +/** + * Bill transaction delete alert. + */ +function BillTransactionDeleteAlert({ + name, + // #withAlertStoreConnect + isOpen, + payload: { BillId }, + // #withAlertActions + closeAlert, +}) { + const { mutateAsync: deleteLandedCostMutate, isLoading } = + useDeleteLandedCost(); + + // Handle cancel delete. + const handleCancelAlert = () => { + closeAlert(name); + }; + + // Handle confirm delete . + const handleConfirmLandedCostDelete = () => { + deleteLandedCostMutate(BillId) + .then(() => { + AppToaster.show({ + message: intl.get('the_landed_cost_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + closeAlert(name); + }) + .catch(() => { + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelAlert} + onConfirm={handleConfirmLandedCostDelete} + loading={isLoading} + > +

{/* */}

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, +)(BillTransactionDeleteAlert); diff --git a/client/src/containers/Drawers/BillDrawer/LocatedLandedCostTable.js b/client/src/containers/Drawers/BillDrawer/LocatedLandedCostTable.js index c50da77e6..1c7c98405 100644 --- a/client/src/containers/Drawers/BillDrawer/LocatedLandedCostTable.js +++ b/client/src/containers/Drawers/BillDrawer/LocatedLandedCostTable.js @@ -1,22 +1,37 @@ import React from 'react'; import { DataTable } from 'components'; import { useLocatedLandedCostColumns, ActionsMenu } from './components'; +import { useBillDrawerContext } from './BillDrawerProvider'; + +import withAlertsActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; /** * Located landed cost table. */ -function LocatedLandedCostTable() { +function LocatedLandedCostTable({ + // #withAlertsActions + openAlert, +}) { const columns = useLocatedLandedCostColumns(); + const { transactions } = useBillDrawerContext(); - const DATA = [ - { - name: 'INV-1000', - amount: '10.000.000', - allocation_method: 'Bill', - }, - ]; + // Handle the transaction delete action. + const handleDeleteTransaction = ({ id }) => { + openAlert('transaction-delete', { BillId: id }); + }; - return ; + return ( + + ); } -export default LocatedLandedCostTable; +export default compose(withAlertsActions)(LocatedLandedCostTable); diff --git a/client/src/containers/Drawers/BillDrawer/components.js b/client/src/containers/Drawers/BillDrawer/components.js index 1e3816c3c..fb181da03 100644 --- a/client/src/containers/Drawers/BillDrawer/components.js +++ b/client/src/containers/Drawers/BillDrawer/components.js @@ -14,7 +14,7 @@ export function ActionsMenu({ row: { original }, payload: { onDelete } }) { icon={} text={intl.get('delete_transaction')} intent={Intent.DANGER} - // onClick={safeCallback(onDelete, original)} + onClick={safeCallback(onDelete, original)} /> ); @@ -24,7 +24,7 @@ export function useLocatedLandedCostColumns() { return React.useMemo(() => [ { Header: intl.get('name'), - accessor: 'name', + accessor: 'description', width: 150, }, { diff --git a/client/src/hooks/query/index.js b/client/src/hooks/query/index.js index 1ce3eef49..cb9f8301c 100644 --- a/client/src/hooks/query/index.js +++ b/client/src/hooks/query/index.js @@ -23,3 +23,4 @@ export * from './exchangeRates'; export * from './contacts'; export * from './subscriptions'; export * from './organization'; +export * from './landedCost'; diff --git a/client/src/hooks/query/landedCost.js b/client/src/hooks/query/landedCost.js new file mode 100644 index 000000000..860835f4c --- /dev/null +++ b/client/src/hooks/query/landedCost.js @@ -0,0 +1,86 @@ +import { useQueryClient, useMutation } from 'react-query'; +import useApiRequest from '../useRequest'; +import { useRequestQuery } from '../useQueryRequest'; + +import t from './types'; + +const commonInvalidateQueries = (queryClient) => { + // Invalidate bills. + queryClient.invalidateQueries(t.BILLS); + queryClient.invalidateQueries(t.BILL); + // Invalidate landed cost. + queryClient.invalidateQueries(t.LANDED_COST); + queryClient.invalidateQueries(t.LANDED_COST_TRANSACTION); +}; + +/** + * Creates a new landed cost. + */ +export function useCreateLandedCost(props) { + const queryClient = useQueryClient(); + const apiRequest = useApiRequest(); + + return useMutation( + (id) => apiRequest.post(`purchases/landed-cost/bills/${id}/allocate`), + { + onSuccess: (res, id) => { + // Common invalidate queries. + commonInvalidateQueries(queryClient); + }, + ...props, + }, + ); +} + +/** + * Deletes the given landed cost. + */ +export function useDeleteLandedCost(props) { + const queryClient = useQueryClient(); + const apiRequest = useApiRequest(); + return useMutation( + (landedCostId) => + apiRequest.delete(`purchases/landed-cost/${landedCostId}`), + { + onSuccess: (res, id) => { + // Common invalidate queries. + commonInvalidateQueries(queryClient); + }, + ...props, + }, + ); +} + +/** + * Retrieve the landed cost transactions. + */ +export function useLandedCostTransaction(query, props) { + return useRequestQuery( + [t.LANDED_COST, query], + { + method: 'get', + url: 'purchases/landed-cost/transactions', + params: { transaction_type: query }, + }, + { + select: (res) => res.data.transactions, + defaultData: [], + ...props, + }, + ); +} + +/** + * Retrieve the bill located landed cost transactions. + */ +export function useBillLocatedLandedCost(id, props) { + return useRequestQuery( + [t.LANDED_COST_TRANSACTION, id], + { method: 'get', url: `purchases/landed-cost/bills/${id}/transactions` }, + { + select: (res) => res.data.transactions, + defaultData: {}, + ...props, + }, + ); +} diff --git a/client/src/hooks/query/types.js b/client/src/hooks/query/types.js index c2bfb67d4..886c07dd3 100644 --- a/client/src/hooks/query/types.js +++ b/client/src/hooks/query/types.js @@ -22,7 +22,7 @@ const FINANCIAL_REPORTS = { PURCHASES_BY_ITEMS: 'PURCHASES_BY_ITEMS', INVENTORY_VALUATION: 'INVENTORY_VALUATION', CASH_FLOW_STATEMENT: 'CASH_FLOW_STATEMENT', - INVENTORY_ITEM_DETAILS:'INVENTORY_ITEM_DETAILS' + INVENTORY_ITEM_DETAILS: 'INVENTORY_ITEM_DETAILS', }; const BILLS = { @@ -117,6 +117,13 @@ const MANUAL_JOURNALS = { MANUAL_JOURNALS: 'MANUAL_JOURNALS', MANUAL_JOURNAL: 'MANUAL_JOURNAL', }; + +const LANDED_COSTS = { + LANDED_COST: 'LANDED_COST', + LANDED_COSTS: 'LANDED_COSTS', + LANDED_COST_TRANSACTION: 'LANDED_COST_TRANSACTION', +}; + export default { ...ACCOUNTS, ...BILLS, @@ -137,4 +144,5 @@ export default { ...SUBSCRIPTIONS, ...EXPENSES, ...MANUAL_JOURNALS, + ...LANDED_COSTS, };