Merge branch 'develop'

This commit is contained in:
a.bouhuolia
2022-01-03 11:46:00 +02:00
512 changed files with 20008 additions and 2564 deletions

View File

@@ -26,7 +26,7 @@ export function useResourceData(type, query, props) {
/**
* Retrieve the resource url by the given resource type.
* @param {string} type
* @param {string} type
* @returns {string}
*/
function getResourceUrlFromType(type) {
@@ -42,6 +42,8 @@ function getResourceUrlFromType(type) {
[RESOURCES_TYPES.VENDOR]: '/vendors',
[RESOURCES_TYPES.MANUAL_JOURNAL]: '/manual-journals',
[RESOURCES_TYPES.ACCOUNT]: '/accounts',
[RESOURCES_TYPES.CREDIT_NOTE]: '/sales/credit_notes',
[RESOURCES_TYPES.VENDOR_CREDIT]: '/purchases/vendor-credit',
};
return config[type] || '';
}
@@ -81,7 +83,6 @@ const transformVendors = (response) => ({
items: response.data.vendors,
});
const transformPaymentMades = (response) => ({
items: response.data.bill_payments,
});
@@ -104,7 +105,15 @@ const transformsEstimates = (response) => ({
const transformAccounts = (response) => ({
items: response.data.accounts,
})
});
const transformCreditNotes = (response) => ({
items: response.data.credit_notes,
});
const transformVendorCredits = (response) => ({
items: response.data.vendor_credits,
});
/**
* Detarmines the transformer based on the given resource type.
@@ -122,7 +131,9 @@ const transformResourceData = (type) => (response) => {
[RESOURCES_TYPES.VENDOR]: transformVendors,
[RESOURCES_TYPES.BILL]: transformBills,
[RESOURCES_TYPES.MANUAL_JOURNAL]: transformManualJournals,
[RESOURCES_TYPES.ACCOUNT]: transformAccounts
[RESOURCES_TYPES.ACCOUNT]: transformAccounts,
[RESOURCES_TYPES.CREDIT_NOTE]: transformCreditNotes,
[RESOURCES_TYPES.VENDOR_CREDIT]: transformVendorCredits,
};
return {
...pairs[type](response),

View File

@@ -20,12 +20,19 @@ const commonInvalidateQueries = (queryClient) => {
queryClient.invalidateQueries(t.ACCOUNTS);
queryClient.invalidateQueries(t.ACCOUNT);
// Invalidate financial reports.
queryClient.invalidateQueries(t.FINANCIAL_REPORT);
// Invalidate landed cost.
queryClient.invalidateQueries(t.LANDED_COST);
queryClient.invalidateQueries(t.LANDED_COST_TRANSACTION);
// Invalidate reconcile.
queryClient.invalidateQueries(t.RECONCILE_VENDOR_CREDIT);
queryClient.invalidateQueries(t.RECONCILE_VENDOR_CREDITS);
// Invalidate financial reports.
queryClient.invalidateQueries(t.FINANCIAL_REPORT);
// Invalidate items associated bills transactions.
queryClient.invalidateQueries(t.ITEMS_ASSOCIATED_WITH_BILLS);
};
/**
@@ -182,3 +189,18 @@ export function useRefreshBills() {
},
};
}
export function useBillPaymentTransactions(id, props) {
return useRequestQuery(
[t.BILLS_PAYMENT_TRANSACTIONS, id],
{
method: 'get',
url: `purchases/bills/${id}/payment-transactions`,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}

View File

@@ -0,0 +1,343 @@
import { useQueryClient, useMutation } from 'react-query';
import { useRequestQuery } from '../useQueryRequest';
import { transformPagination } from 'utils';
import useApiRequest from '../useRequest';
import t from './types';
const commonInvalidateQueries = (queryClient) => {
// Invalidate credit note.
queryClient.invalidateQueries(t.CREDIT_NOTES);
queryClient.invalidateQueries(t.CREDIT_NOTE);
// Invalidate items.
queryClient.invalidateQueries(t.ITEMS);
queryClient.invalidateQueries(t.ITEM);
// Invalidate customers.
queryClient.invalidateQueries([t.CUSTOMER]);
queryClient.invalidateQueries(t.CUSTOMERS);
// Invalidate accounts.
queryClient.invalidateQueries(t.ACCOUNTS);
queryClient.invalidateQueries(t.ACCOUNT);
// Invalidate settings.
queryClient.invalidateQueries([t.SETTING, t.SETTING_CREDIT_NOTES]);
// Invalidate refund credit
queryClient.invalidateQueries(t.REFUND_CREDIT_NOTE);
queryClient.invalidateQueries(t.REFUND_CREDIT_NOTE_TRANSACTION);
// Invalidate reconcile.
queryClient.invalidateQueries(t.RECONCILE_CREDIT_NOTE);
queryClient.invalidateQueries(t.RECONCILE_CREDIT_NOTES);
// Invalidate invoices.
queryClient.invalidateQueries(t.SALE_INVOICES);
queryClient.invalidateQueries(t.SALE_INVOICE);
// Invalidate cashflow accounts.
queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
// Invalidate financial reports.
queryClient.invalidateQueries(t.FINANCIAL_REPORT);
};
/**
* Create a new credit note.
*/
export function useCreateCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(values) => apiRequest.post('sales/credit_notes', values),
{
onSuccess: (res, values) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
},
...props,
},
);
}
/**
* Edit the given credit note.
*/
export function useEditCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
([id, values]) => apiRequest.post(`sales/credit_notes/${id}`, values),
{
onSuccess: (res, [id, values]) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate credit note query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
},
);
}
/**
* Delete the given credit note.
*/
export function useDeleteCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation((id) => apiRequest.delete(`sales/credit_notes/${id}`), {
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
});
}
const transformCreditNotes = (res) => ({
creditNotes: res.data.credit_notes,
pagination: transformPagination(res.data.pagination),
filterMeta: res.data.filter_meta,
});
/**
* Retrieve credit notes list with pagination meta.
*/
export function useCreditNotes(query, props) {
return useRequestQuery(
[t.CREDIT_NOTES, query],
{ method: 'get', url: 'sales/credit_notes', params: query },
{
select: transformCreditNotes,
defaultData: {
creditNotes: [],
pagination: {
page: 1,
pageSize: 20,
total: 0,
},
filterMeta: {},
},
...props,
},
);
}
/**
* Retrieve credit note detail of the given id.
* @param {number} id
*
*/
export function useCreditNote(id, props, requestProps) {
return useRequestQuery(
[t.CREDIT_NOTE, id],
{ method: 'get', url: `sales/credit_notes/${id}`, ...requestProps },
{
select: (res) => res.data.credit_note,
defaultData: {},
...props,
},
);
}
export function useRefreshCreditNotes() {
const queryClient = useQueryClient();
return {
refresh: () => {
queryClient.invalidateQueries(t.CREDIT_NOTES);
},
};
}
/**
* Create Round creidt note
*/
export function useCreateRefundCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
([id, values]) =>
apiRequest.post(`sales/credit_notes/${id}/refund`, values),
{
onSuccess: (res, [id, values]) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate credit note query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
},
);
}
/**
* Delete the given refund credit note.
*/
export function useDeleteRefundCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(id) => apiRequest.delete(`sales/credit_notes/refunds/${id}`),
{
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
},
);
}
/**
* Retrieve refund credit note detail of the given id.
* @param {number} id
*
*/
export function useRefundCreditNote(id, props, requestProps) {
return useRequestQuery(
[t.REFUND_CREDIT_NOTE, id],
{ method: 'get', url: `sales/credit_notes/${id}/refund`, ...requestProps },
{
select: (res) => res.data.data,
defaultData: {},
...props,
},
);
}
/**
* Mark the given credit note as opened.
*/
export function useOpenCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation((id) => apiRequest.post(`sales/credit_notes/${id}/open`), {
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate specific
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
});
}
/**
* Retrieve reconcile credit note of the given id.
* @param {number} id
*
*/
export function useReconcileCreditNote(id, props, requestProps) {
return useRequestQuery(
[t.RECONCILE_CREDIT_NOTE, id],
{
method: 'get',
url: `sales/credit_notes/${id}/apply-to-invoices`,
...requestProps,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}
/**
* Create Reconcile credit note.
*/
export function useCreateReconcileCreditNote(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
([id, values]) =>
apiRequest.post(`sales/credit_notes/${id}/apply-to-invoices`, values),
{
onSuccess: (res, [id, values]) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate credit note query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
},
);
}
/**
* Retrieve reconcile credit notes.
*/
export function useReconcileCreditNotes(id, props, requestProps) {
return useRequestQuery(
[t.RECONCILE_CREDIT_NOTES, id],
{
method: 'get',
url: `sales/credit_notes/${id}/applied-invoices`,
...requestProps,
},
{
select: (res) => res.data.data,
defaultData: {},
...props,
},
);
}
/**
* Delete the given reconcile credit note.
*/
export function useDeleteReconcileCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(id) => apiRequest.delete(`sales/credit_notes/applied-to-invoices/${id}`),
{
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
},
);
}
/**
* Retrieve refund credit transaction detail.
* @param {number} id
*
*/
export function useRefundCreditTransaction(id, props, requestProps) {
return useRequestQuery(
[t.REFUND_CREDIT_NOTE_TRANSACTION, id],
{ method: 'get', url: `sales/credit_notes/refunds/${id}`, ...requestProps },
{
select: (res) => res.data.refund_credit,
defaultData: {},
...props,
},
);
}

View File

@@ -9,6 +9,9 @@ import t from './types';
const commonInvalidateQueries = (queryClient) => {
// Invalidate estimates.
queryClient.invalidateQueries(t.SALE_ESTIMATES);
// Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_ESTIMATES);
};
/**
@@ -191,7 +194,7 @@ export function useRefreshEstimates() {
}
/**
*
*
*/
export function useCreateNotifyEstimateBySMS(props) {
const queryClient = useQueryClient();
@@ -214,11 +217,11 @@ export function useCreateNotifyEstimateBySMS(props) {
}
/**
*
* @param {*} estimateId
* @param {*} props
* @param {*} requestProps
* @returns
*
* @param {*} estimateId
* @param {*} props
* @param {*} requestProps
* @returns
*/
export function useEstimateSMSDetail(estimateId, props, requestProps) {
return useRequestQuery(

View File

@@ -28,5 +28,8 @@ export * from './UniversalSearch/UniversalSearch';
export * from './GenericResource';
export * from './jobs';
export * from './misc';
export * from './cashflowAccounts'
export * from './roles'
export * from './cashflowAccounts';
export * from './roles';
export * from './creditNote';
export * from './vendorCredit';
export * from './transactionsLocking';

View File

@@ -27,6 +27,13 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate accounts.
queryClient.invalidateQueries(t.ACCOUNTS);
queryClient.invalidateQueries(t.ACCOUNT);
// Invalidate reconcile.
queryClient.invalidateQueries(t.RECONCILE_CREDIT_NOTE);
queryClient.invalidateQueries(t.RECONCILE_CREDIT_NOTES);
// Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_INVOICES);
};
/**
@@ -269,3 +276,18 @@ export function useInvoiceSMSDetail(invoiceId, query, props) {
},
);
}
export function useInvoicePaymentTransactions(invoiceId, props) {
return useRequestQuery(
[t.SALE_INVOICE_PAYMENT_TRANSACTIONS, invoiceId],
{
method: 'get',
url: `sales/invoices/${invoiceId}/payment-transactions`,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}

View File

@@ -172,3 +172,62 @@ export function useItem(id, props) {
},
);
}
export function useItemAssociatedInvoiceTransactions(id, props) {
return useRequestQuery(
[t.ITEM_ASSOCIATED_WITH_INVOICES, id],
{
method: 'get',
url: `items/${id}/transactions/invoices`,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}
export function useItemAssociatedEstimateTransactions(id, props) {
return useRequestQuery(
[t.ITEM_ASSOCIATED_WITH_ESTIMATES, id],
{
method: 'get',
url: `items/${id}/transactions/estimates`,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}
export function useItemAssociatedReceiptTransactions(id, props) {
return useRequestQuery(
[t.ITEM_ASSOCIATED_WITH_RECEIPTS, id],
{
method: 'get',
url: `items/${id}/transactions/receipts`,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}
export function useItemAssociatedBillTransactions(id, props) {
return useRequestQuery(
[t.ITEMS_ASSOCIATED_WITH_BILLS, id],
{
method: 'get',
url: `items/${id}/transactions/bills`,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}

View File

@@ -30,6 +30,9 @@ const commonInvalidateQueries = (client) => {
// Invalidate the cashflow transactions.
client.invalidateQueries(t.CASH_FLOW_TRANSACTIONS);
client.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
// Invalidate bills payment transactions.
client.invalidateQueries(t.BILLS_PAYMENT_TRANSACTIONS);
};
/**

View File

@@ -28,6 +28,16 @@ const commonInvalidateQueries = (client) => {
// Invalidate the cashflow transactions.
client.invalidateQueries(t.CASH_FLOW_TRANSACTIONS);
client.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
client.invalidateQueries(t.CREDIT_NOTE);
client.invalidateQueries(t.CREDIT_NOTES);
// Invalidate reconcile.
client.invalidateQueries(t.RECONCILE_CREDIT_NOTE);
client.invalidateQueries(t.RECONCILE_CREDIT_NOTES);
// Invalidate invoices payment transactions.
client.invalidateQueries(t.SALE_INVOICE_PAYMENT_TRANSACTIONS);
};
// Transform payment receives.

View File

@@ -24,6 +24,9 @@ const commonInvalidateQueries = (queryClient) => {
queryClient.invalidateQueries(t.CASH_FLOW_TRANSACTIONS);
queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
// Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_RECEIPTS);
// Invalidate the settings.
queryClient.invalidateQueries([t.SETTING, t.SETTING_RECEIPTS]);
};

View File

@@ -95,7 +95,7 @@ export function useSettingsReceipts(props) {
export function useSettingsManualJournals(props) {
return useSettingsQuery(
[t.SETTING, t.SETTING_MANUAL_JOURNALS],
{ group: 'sale_receipts' },
{ group: 'manual_journals' },
props,
);
}
@@ -123,6 +123,27 @@ export function useSettingCashFlow(props) {
);
}
/**
* Retrieve credit notes settings.
*/
export function useSettingsCreditNotes(props) {
return useSettingsQuery(
[t.SETTING, t.SETTING_CREDIT_NOTES],
{ group: 'credit_note' },
props,
);
}
/**
* Retrieve vendor credit settings.
*/
export function useSettingsVendorCredits(props) {
return useSettingsQuery(
[t.SETTING, t.SETTING_VENDOR_CREDITS],
{ group: 'vendor_credit' },
props,
);
}
/**
* Retrieve SMS Notifications settings.
*/

View File

@@ -0,0 +1,115 @@
import { useQueryClient, useMutation } from 'react-query';
import { useRequestQuery } from '../useQueryRequest';
import { transformPagination } from 'utils';
import useApiRequest from '../useRequest';
import { useRequestPdf } from '../utils';
import t from './types';
// Common invalidate queries.
const commonInvalidateQueries = (queryClient) => {
// Invalidate.
queryClient.invalidateQueries(t.TRANSACTION_LOCKING);
queryClient.invalidateQueries(t.TRANSACTIONS_LOCKING);
};
/**
* Create a locking transactions.
*/
export function useCreateLockingTransactoin(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(values) => apiRequest.put('transactions-locking/lock', values),
{
onSuccess: (res, values) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
},
...props,
},
);
}
/**
* Create cancle locking transactions
*/
export function useCancelLockingTransaction(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(values) => apiRequest.put('transactions-locking/cancel-lock', values),
{
onSuccess: (res, values) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
},
...props,
},
);
}
/**
* Create a unlocking partial transactions.
*/
export function useCreateUnlockingPartialTransactions(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(values) => apiRequest.put('transactions-locking/unlock-partial', values),
{
onSuccess: (res, values) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
},
...props,
},
);
}
/**
* Create cancle unlocking partial transactions.
*/
export function useCancelUnlockingPartialTransactions(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(values) =>
apiRequest.put('transactions-locking/cancel-unlock-partial', values),
{
onSuccess: (res, values) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
},
...props,
},
);
}
/**
* Retrive the transactions locking.
*/
export function useTransactionsLocking(query, props) {
return useRequestQuery(
[t.TRANSACTIONS_LOCKING, query],
{ method: 'get', url: 'transactions-locking', params: query },
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}
export function useEditTransactionsLocking(query, props) {
return useRequestQuery(
[t.TRANSACTION_LOCKING, query],
{ method: 'get', url: `transactions-locking/${query}` },
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}

View File

@@ -30,6 +30,7 @@ const BILLS = {
BILLS: 'BILLS',
BILL: 'BILL',
BILLS_DUE: 'BILLS_DUE',
BILLS_PAYMENT_TRANSACTIONS: 'BILLS_PAYMENT_TRANSACTIONS',
};
const VENDORS = {
@@ -46,6 +47,10 @@ const ITEMS = {
ITEMS: 'ITEMS',
ITEM: 'ITEM',
ITEMS_CATEGORIES: 'ITEMS_CATEGORIES',
ITEM_ASSOCIATED_WITH_INVOICES: 'ITEM_ASSOCIATED_WITH_INVOICES',
ITEM_ASSOCIATED_WITH_ESTIMATES: 'ITEM_ASSOCIATED_WITH_ESTIMATES',
ITEM_ASSOCIATED_WITH_RECEIPTS: 'ITEM_ASSOCIATED_WITH_RECEIPTS',
ITEMS_ASSOCIATED_WITH_BILLS: 'ITEMS_ASSOCIATED_WITH_BILLS',
};
const SALE_ESTIMATES = {
@@ -95,6 +100,7 @@ const SALE_INVOICES = {
NOTIFY_SALE_INVOICE_BY_SMS: 'NOTIFY_SALE_INVOICE_BY_SMS',
BAD_DEBT: 'BAD_DEBT',
CANCEL_BAD_DEBT: 'CANCEL_BAD_DEBT',
SALE_INVOICE_PAYMENT_TRANSACTIONS: 'SALE_INVOICE_PAYMENT_TRANSACTIONS',
};
const USERS = {
@@ -108,6 +114,24 @@ const ROLES = {
ROLES_PERMISSIONS_SCHEMA: 'ROLES_PERMISSIONS_SCHEMA',
};
const CREDIT_NOTES = {
CREDIT_NOTE: 'CREDIT_NOTE',
CREDIT_NOTES: 'CREDIT_NOTES',
REFUND_CREDIT_NOTE: 'REFUND_CREDIT_NOTE',
REFUND_CREDIT_NOTE_TRANSACTION: 'REFUND_CREDIT_NOTE_TRANSACTION',
RECONCILE_CREDIT_NOTE: 'RECONCILE_CREDIT_NOTE',
RECONCILE_CREDIT_NOTES: 'RECONCILE_CREDIT_NOTES',
};
const VENDOR_CREDIT_NOTES = {
VENDOR_CREDITS: 'VENDOR_CREDITS',
VENDOR_CREDIT: 'VENDOR_CREDIT',
REFUND_VENDOR_CREDIT: 'REFUND_VENDOR_CREDIT',
REFUND_VENDOR_CREDIT_TRANSACTION: 'REFUND_VENDOR_CREDIT_TRANSACTION',
RECONCILE_VENDOR_CREDIT: 'RECONCILE_VENDOR_CREDIT',
RECONCILE_VENDOR_CREDITS: 'RECONCILE_VENDOR_CREDITS',
};
const SETTING = {
SETTING: 'SETTING',
SETTING_INVOICES: 'SETTING_INVOICES',
@@ -120,6 +144,8 @@ const SETTING = {
SETTING_SMS_NOTIFICATION: 'SETTING_SMS_NOTIFICATION',
SETTING_SMS_NOTIFICATIONS: 'SETTING_SMS_NOTIFICATIONS',
SETTING_EDIT_SMS_NOTIFICATION: 'SETTING_EDIT_SMS_NOTIFICATION',
SETTING_CREDIT_NOTES: 'SETTING_CREDIT_NOTES',
SETTING_VENDOR_CREDITS: 'SETTING_VENDOR_CREDITS',
};
const ORGANIZATIONS = {
@@ -160,6 +186,11 @@ const CASH_FLOW_ACCOUNTS = {
'CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY',
};
const TARNSACTIONS_LOCKING = {
TRANSACTION_LOCKING: 'TRANSACTION_LOCKING',
TRANSACTIONS_LOCKING: 'TRANSACTIONS_LOCKING',
};
export default {
...ACCOUNTS,
...BILLS,
@@ -184,4 +215,7 @@ export default {
...CONTACTS,
...CASH_FLOW_ACCOUNTS,
...ROLES,
...CREDIT_NOTES,
...VENDOR_CREDIT_NOTES,
...TARNSACTIONS_LOCKING,
};

View File

@@ -0,0 +1,360 @@
import { useQueryClient, useMutation } from 'react-query';
import { useRequestQuery } from '../useQueryRequest';
import { transformPagination } from 'utils';
import useApiRequest from '../useRequest';
import t from './types';
const commonInvalidateQueries = (queryClient) => {
// Invalidate vendor credit.
queryClient.invalidateQueries(t.VENDOR_CREDITS);
queryClient.invalidateQueries(t.VENDOR_CREDIT);
// Invalidate items.
queryClient.invalidateQueries(t.ITEMS);
queryClient.invalidateQueries(t.ITEM);
// Invalidate vendors.
queryClient.invalidateQueries([t.VENDORS]);
queryClient.invalidateQueries(t.VENDOR);
// Invalidate accounts.
queryClient.invalidateQueries(t.ACCOUNTS);
queryClient.invalidateQueries(t.ACCOUNT);
// Invalidate settings.
queryClient.invalidateQueries([t.SETTING, t.SETTING_VENDOR_CREDITS]);
// Invalidate refund vendor credit
queryClient.invalidateQueries(t.REFUND_VENDOR_CREDIT);
queryClient.invalidateQueries(t.REFUND_VENDOR_CREDIT_TRANSACTION);
// Invalidate reconcile vendor credit.
queryClient.invalidateQueries(t.RECONCILE_VENDOR_CREDIT);
queryClient.invalidateQueries(t.RECONCILE_VENDOR_CREDITS);
// Invalidate bills.
queryClient.invalidateQueries(t.BILL);
queryClient.invalidateQueries(t.BILLS);
// Invalidate cashflow accounts.
queryClient.invalidateQueries(t.CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY);
// Invalidate financial reports.
queryClient.invalidateQueries(t.FINANCIAL_REPORT);
};
/**
* Create a new vendor credit.
*/
export function useCreateVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(values) => apiRequest.post('purchases/vendor-credit', values),
{
onSuccess: (res, values) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
},
...props,
},
);
}
/**
* Edit the given vendor credit.
*/
export function useEditVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
([id, values]) => apiRequest.post(`purchases/vendor-credit/${id}`, values),
{
onSuccess: (res, [id, values]) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.VENDOR_CREDIT, id]);
},
...props,
},
);
}
/**
* Delete the given vendor credit.
*/
export function useDeleteVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(id) => apiRequest.delete(`purchases/vendor-credit/${id}`),
{
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.VENDOR_CREDIT_NOTE, id]);
},
...props,
},
);
}
const transformVendorCreditsResponse = (response) => ({
vendorCredits: response.data.vendor_credits,
pagination: transformPagination(response.data.pagination),
filterMeta: response.data.filter_meta,
});
/**
* Retrieve vendor credit notes list with pagination meta.
*/
export function useVendorCredits(query, props) {
return useRequestQuery(
[t.VENDOR_CREDITS, query],
{
method: 'get',
url: 'purchases/vendor-credit',
params: query,
},
{
select: transformVendorCreditsResponse,
defaultData: {
vendorCredits: [],
pagination: {
page: 1,
page_size: 12,
total: 0,
},
filterMeta: {},
},
...props,
},
);
}
/**
* Retrieve vendor credit detail of the given id.
* @param {number} id
*
*/
export function useVendorCredit(id, props, requestProps) {
return useRequestQuery(
[t.VENDOR_CREDIT, id],
{ method: 'get', url: `purchases/vendor-credit/${id}`, ...requestProps },
{
select: (res) => res.data.data,
defaultData: {},
...props,
},
);
}
export function useRefreshVendorCredits() {
const queryClient = useQueryClient();
return {
refresh: () => {
queryClient.invalidateQueries(t.VENDOR_CREDITS);
},
};
}
/**
* Create Round vendor creidt
*/
export function useCreateRefundVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
([id, values]) =>
apiRequest.post(`purchases/vendor-credit/${id}/refund`, values),
{
onSuccess: (res, [id, values]) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate credit note query.
queryClient.invalidateQueries([t.VENDOR_CREDIT, id]);
},
...props,
},
);
}
/**
* Delete the given refund vendor credit.
*/
export function useDeleteRefundVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(id) => apiRequest.delete(`purchases/vendor-credit/refunds/${id}`),
{
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.CREDIT_NOTE, id]);
},
...props,
},
);
}
/**
* Retrieve refund credit note detail of the given id.
* @param {number} id
*
*/
export function useRefundVendorCredit(id, props, requestProps) {
return useRequestQuery(
[t.REFUND_VENDOR_CREDIT, id],
{
method: 'get',
url: `purchases/vendor-credit/${id}/refund`,
...requestProps,
},
{
select: (res) => res.data.data,
defaultData: {},
...props,
},
);
}
/**
* Mark the given vendor credit as opened.
*/
export function useOpenVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(id) => apiRequest.post(`purchases/vendor-credit/${id}/open`),
{
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate specific.
queryClient.invalidateQueries([t.VENDOR_CREDIT, id]);
},
...props,
},
);
}
/**
* Create Reconcile vendor credit.
*/
export function useCreateReconcileVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
([id, values]) =>
apiRequest.post(`purchases/vendor-credit/${id}/apply-to-bills`, values),
{
onSuccess: (res, [id, values]) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate credit note query.
queryClient.invalidateQueries([t.VENDOR_CREDIT, id]);
},
...props,
},
);
}
/**
* Retrieve reconcile vendor credit of the given id.
* @param {number} id
*
*/
export function useReconcileVendorCredit(id, props, requestProps) {
return useRequestQuery(
[t.RECONCILE_VENDOR_CREDIT, id],
{
method: 'get',
url: `purchases/vendor-credit/${id}/apply-to-bills`,
...requestProps,
},
{
select: (res) => res.data.data,
defaultData: [],
...props,
},
);
}
/**
* Retrieve reconcile credit notes.
*/
export function useReconcileVendorCredits(id, props, requestProps) {
return useRequestQuery(
[t.RECONCILE_VENDOR_CREDITS, id],
{
method: 'get',
url: `purchases/vendor-credit/${id}/applied-bills`,
...requestProps,
},
{
select: (res) => res.data.data,
defaultData: {},
...props,
},
);
}
/**
* Delete the given reconcile vendor credit.
*/
export function useDeleteReconcileVendorCredit(props) {
const queryClient = useQueryClient();
const apiRequest = useApiRequest();
return useMutation(
(id) => apiRequest.delete(`purchases/vendor-credit/applied-to-bills/${id}`),
{
onSuccess: (res, id) => {
// Common invalidate queries.
commonInvalidateQueries(queryClient);
// Invalidate vendor credit query.
queryClient.invalidateQueries([t.VENDOR_CREDIT, id]);
},
...props,
},
);
}
/**
* Retrieve refund vendor transaction detail.
* @param {number} id
*
*/
export function useRefundVendorCreditTransaction(id, props, requestProps) {
return useRequestQuery(
[t.REFUND_VENDOR_CREDIT_TRANSACTION, id],
{
method: 'get',
url: `purchases/vendor-credit/refunds/${id}`,
...requestProps,
},
{
select: (res) => res.data.refund_credit,
defaultData: {},
...props,
},
);
}

View File

@@ -12,7 +12,7 @@ export default function useApiRequest() {
const setGlobalErrors = useSetGlobalErrors();
const { setLogout } = useAuthActions();
const currentLocale = getCookie('locale');
// Authentication token.
const token = useAuthToken();
@@ -47,7 +47,7 @@ export default function useApiRequest() {
instance.interceptors.response.use(
(response) => response,
(error) => {
const { status } = error.response;
const { status, data } = error.response;
if (status >= 500) {
setGlobalErrors({ something_wrong: true });
@@ -57,7 +57,19 @@ export default function useApiRequest() {
setLogout();
}
if (status === 403) {
setGlobalErrors({ access_denied: true })
setGlobalErrors({ access_denied: true });
}
if (status === 400) {
const lockedError = data.errors.find(
(error) => error.type === 'TRANSACTIONS_DATE_LOCKED',
);
if (lockedError) {
setGlobalErrors({ transactionsLocked: { ...lockedError.data } });
}
if (data.errors.find(e => e.type === 'USER_INACTIVE')) {
setGlobalErrors({ userInactive: true });
setLogout();
}
}
return Promise.reject(error);
},
@@ -65,27 +77,30 @@ export default function useApiRequest() {
return instance;
}, [token, organizationId, setGlobalErrors, setLogout]);
return React.useMemo(() => ({
http,
return React.useMemo(
() => ({
http,
get(resource, params) {
return http.get(`/api/${resource}`, params);
},
get(resource, params) {
return http.get(`/api/${resource}`, params);
},
post(resource, params, config) {
return http.post(`/api/${resource}`, params, config);
},
post(resource, params, config) {
return http.post(`/api/${resource}`, params, config);
},
update(resource, slug, params) {
return http.put(`/api/${resource}/${slug}`, params);
},
update(resource, slug, params) {
return http.put(`/api/${resource}/${slug}`, params);
},
put(resource, params) {
return http.put(`/api/${resource}`, params);
},
put(resource, params) {
return http.put(`/api/${resource}`, params);
},
delete(resource, params) {
return http.delete(`/api/${resource}`, params);
},
}), [http]);
delete(resource, params) {
return http.delete(`/api/${resource}`, params);
},
}),
[http],
);
}

View File

@@ -6,4 +6,6 @@ export * from './useWhen';
export * from './useRequestPdf';
export * from './useAsync';
export * from './useIntersectionObserver';
export * from './useAbilityContext';
export * from './useAbilityContext';
export * from './useCustomCompareEffect';
export * from './useDeepCompareEffect';

View File

@@ -0,0 +1,44 @@
import { DependencyList, EffectCallback, useEffect, useRef } from 'react';
const isPrimitive = (val: any) => val !== Object(val);
type DepsEqualFnType<TDeps extends DependencyList> = (
prevDeps: TDeps,
nextDeps: TDeps,
) => boolean;
const useCustomCompareEffect = <TDeps extends DependencyList>(
effect: EffectCallback,
deps: TDeps,
depsEqual: DepsEqualFnType<TDeps>,
) => {
if (process.env.NODE_ENV !== 'production') {
if (!(deps instanceof Array) || !deps.length) {
console.warn(
'`useCustomCompareEffect` should not be used with no dependencies. Use React.useEffect instead.',
);
}
if (deps.every(isPrimitive)) {
console.warn(
'`useCustomCompareEffect` should not be used with dependencies that are all primitive values. Use React.useEffect instead.',
);
}
if (typeof depsEqual !== 'function') {
console.warn(
'`useCustomCompareEffect` should be used with depsEqual callback for comparing deps list',
);
}
}
const ref = useRef<TDeps | undefined>(undefined);
if (!ref.current || !depsEqual(deps, ref.current)) {
ref.current = deps;
}
useEffect(effect, ref.current);
};
export { useCustomCompareEffect };

View File

@@ -0,0 +1,24 @@
import { DependencyList, EffectCallback } from 'react';
import isDeepEqualReact from 'fast-deep-equal/react';
import { useCustomCompareEffect } from './useCustomCompareEffect';
const isPrimitive = (val: any) => val !== Object(val);
const useDeepCompareEffect = (effect: EffectCallback, deps: DependencyList) => {
if (process.env.NODE_ENV !== 'production') {
if (!(deps instanceof Array) || !deps.length) {
console.warn(
'`useDeepCompareEffect` should not be used with no dependencies. Use React.useEffect instead.',
);
}
if (deps.every(isPrimitive)) {
console.warn(
'`useDeepCompareEffect` should not be used with dependencies that are all primitive values. Use React.useEffect instead.',
);
}
}
useCustomCompareEffect(effect, deps, isDeepEqualReact);
};
export { useDeepCompareEffect };