mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 20:30:33 +00:00
feat: Bulk delete customers and expenses.
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
query,
|
||||
validationResult,
|
||||
} from 'express-validator';
|
||||
import { pick } from 'lodash';
|
||||
import { pick, difference } from 'lodash';
|
||||
import asyncMiddleware from '@/http/middleware/asyncMiddleware';
|
||||
import {
|
||||
mapViewRolesToConditionals,
|
||||
@@ -77,6 +77,10 @@ export default {
|
||||
this.deleteCustomer.validation,
|
||||
asyncMiddleware(this.deleteCustomer.handler));
|
||||
|
||||
router.delete('/',
|
||||
this.deleteBulkCustomers.validation,
|
||||
asyncMiddleware(this.deleteBulkCustomers.handler));
|
||||
|
||||
router.get('/',
|
||||
this.listCustomers.validation,
|
||||
asyncMiddleware(this.listCustomers.handler));
|
||||
@@ -380,5 +384,40 @@ export default {
|
||||
|
||||
return res.status(200).send();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Bulk delete customers.
|
||||
*/
|
||||
deleteBulkCustomers: {
|
||||
validation: [
|
||||
query('ids').isArray({ min: 2 }),
|
||||
query('ids.*').isNumeric().toInt(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
const filter = { ...req.query };
|
||||
const { Customer } = req.models;
|
||||
|
||||
const customers = await Customer.query().whereIn('id', filter.ids);
|
||||
const storedCustomersIds = customers.map((customer) => customer.id);
|
||||
|
||||
const notFoundCustomers = difference(filter.ids, storedCustomersIds);
|
||||
|
||||
if (notFoundCustomers.length > 0) {
|
||||
return res.status(404).send({
|
||||
errors: [{ type: 'CUSTOMERS.NOT.FOUND', code: 200 }],
|
||||
});
|
||||
}
|
||||
await Customer.query().whereIn('id', storedCustomersIds).delete();
|
||||
|
||||
return res.status(200).send({ ids: storedCustomersIds });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,6 +42,10 @@ export default {
|
||||
this.deleteExpense.validation,
|
||||
asyncMiddleware(this.deleteExpense.handler));
|
||||
|
||||
router.delete('/',
|
||||
this.deleteBulkExpenses.validation,
|
||||
asyncMiddleware(this.deleteBulkExpenses.handler));
|
||||
|
||||
router.post('/:id',
|
||||
this.updateExpense.validation,
|
||||
asyncMiddleware(this.updateExpense.handler));
|
||||
@@ -195,7 +199,7 @@ export default {
|
||||
});
|
||||
}
|
||||
const { id } = req.params;
|
||||
const { Expense, AccountTransaction } = req.models;
|
||||
const { Expense, Account, AccountTransaction } = req.models;
|
||||
const expense = await Expense.query().findById(id);
|
||||
const errorReasons = [];
|
||||
|
||||
@@ -624,4 +628,62 @@ export default {
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes bulk expenses.
|
||||
*/
|
||||
deleteBulkExpenses: {
|
||||
validation: [
|
||||
query('ids').isArray({ min: 1 }),
|
||||
query('ids.*').isNumeric().toInt(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
const filter = { ...req.query };
|
||||
const { Expense, AccountTransaction, Account, MediaLink } = req.models;
|
||||
|
||||
const expenses = await Expense.query()
|
||||
.whereIn('id', filter.ids)
|
||||
|
||||
const storedExpensesIds = expenses.map(e => e.id);
|
||||
const notFoundExpenses = difference(filter.ids, storedExpensesIds);
|
||||
|
||||
if (notFoundExpenses.length > 0) {
|
||||
return res.status(404).send({
|
||||
errors: [{ type: 'EXPENSES.NOT.FOUND', code: 200 }],
|
||||
});
|
||||
}
|
||||
|
||||
const deleteExpensesOper = Expense.query()
|
||||
.whereIn('id', storedExpensesIds).delete();
|
||||
|
||||
const transactions = await AccountTransaction.query()
|
||||
.whereIn('reference_type', ['Expense'])
|
||||
.whereIn('reference_id', filter.ids)
|
||||
|
||||
const accountsDepGraph = await Account.depGraph().query().remember();
|
||||
const journal = new JournalPoster(accountsDepGraph);
|
||||
|
||||
journal.loadEntries(transactions);
|
||||
journal.removeEntries();
|
||||
|
||||
await MediaLink.query()
|
||||
.where('model_name', 'Expense')
|
||||
.whereIn('model_id', filter.ids)
|
||||
.delete();
|
||||
|
||||
await Promise.all([
|
||||
deleteExpensesOper,
|
||||
journal.deleteEntries(),
|
||||
journal.saveBalance(),
|
||||
]);
|
||||
return res.status(200).send({ ids: filter.ids });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user