WIP Financial accounting module.

This commit is contained in:
Ahmed Bouhuolia
2020-01-25 23:34:08 +02:00
parent 488709088b
commit 77c67cc4cb
26 changed files with 1414 additions and 354 deletions

View File

@@ -19,18 +19,18 @@ export default {
router.use(jwtAuth);
// router.post('/:id',
// this.editItem.validation,
// asyncMiddleware(this.editCategory.handler));
router.post('/:id',
this.editItem.validation,
asyncMiddleware(this.editItem.handler));
router.post('/',
permit('create'),
// permit('create'),
this.newItem.validation,
asyncMiddleware(this.newItem.handler));
// router.delete('/:id',
// this.deleteItem.validation,
// asyncMiddleware(this.deleteItem.handler));
router.delete('/:id',
this.deleteItem.validation,
asyncMiddleware(this.deleteItem.handler));
// router.get('/:id',
// this.getCategory.validation,
@@ -49,14 +49,14 @@ export default {
newItem: {
validation: [
check('name').exists(),
check('type_id').exists().isInt(),
check('buy_price').exists().isNumeric(),
check('type').exists().trim().escape().isIn(['service', 'product']),
check('cost_price').exists().isNumeric(),
check('sell_price').exists().isNumeric(),
check('cost_account_id').exists().isInt(),
check('sell_account_id').exists().isInt(),
check('category_id').optional().isInt(),
check('custom_fields').isArray({ min: 1 }),
check('custom_fields').optional().isArray({ min: 1 }),
check('custom_fields.*.key').exists().isNumeric().toInt(),
check('custom_fields.*.value').exists(),
@@ -70,13 +70,16 @@ export default {
code: 'validation_error', ...validationErrors,
});
}
const form = { ...req.body };
const form = {
custom_fields: [],
...req.body,
};
const errorReasons = [];
const costAccountPromise = Account.where('id', form.cost_account_id).fetch();
const sellAccountPromise = Account.where('id', form.sell_account_id).fetch();
const costAccountPromise = Account.query().findById(form.cost_account_id);
const sellAccountPromise = Account.query().findById(form.sell_account_id);
const itemCategoryPromise = (form.category_id)
? ItemCategory.where('id', form.category_id).fetch() : null;
? ItemCategory.query().findById(form.category_id) : null;
// Validate the custom fields key and value type.
if (form.custom_fields.length > 0) {
@@ -98,6 +101,76 @@ export default {
errorReasons.push({ type: 'FIELD_KEY_NOT_FOUND', code: 150, fields: notFoundFields });
}
}
const [costAccount, sellAccount, itemCategory] = await Promise.all([
costAccountPromise, sellAccountPromise, itemCategoryPromise,
]);
if (!costAccount) {
errorReasons.push({ type: 'COST_ACCOUNT_NOT_FOUND', code: 100 });
}
if (!sellAccount) {
errorReasons.push({ type: 'SELL_ACCOUNT_NOT_FOUND', code: 120 });
}
if (!itemCategory && form.category_id) {
errorReasons.push({ type: 'ITEM_CATEGORY_NOT_FOUND', code: 140 });
}
if (errorReasons.length > 0) {
return res.boom.badRequest(null, { errors: errorReasons });
}
const item = await Item.query().insertAndFetch({
name: form.name,
type: form.type,
cost_price: form.cost_price,
sell_price: form.sell_price,
sell_account_id: form.sell_account_id,
cost_account_id: form.cost_account_id,
currency_code: form.currency_code,
note: form.note,
});
return res.status(200).send({ id: item.id });
},
},
/**
* Edit the given item.
*/
editItem: {
validation: [
check('name').exists(),
check('type').exists().trim().escape().isIn(['product', 'service']),
check('cost_price').exists().isNumeric(),
check('sell_price').exists().isNumeric(),
check('cost_account_id').exists().isInt(),
check('sell_account_id').exists().isInt(),
check('category_id').optional().isInt(),
check('note').optional(),
],
async handler(req, res) {
const validationErrors = validationResult(req);
if (!validationErrors.isEmpty()) {
return res.boom.badData(null, {
code: 'validation_error', ...validationErrors,
});
}
const { id } = req.params;
const form = {
custom_fields: [],
...req.body,
};
const item = await Item.query().findById(id);
if (!item) {
return res.boom.notFound(null, { errors: [
{ type: 'ITEM.NOT.FOUND', code: 100 },
]});
}
const errorReasons = [];
const costAccountPromise = Account.query().findById(form.cost_account_id);
const sellAccountPromise = Account.query().findById(form.sell_account_id);
const itemCategoryPromise = (form.category_id)
? ItemCategory.query().findById(form.category_id) : null;
const [costAccount, sellAccount, itemCategory] = await Promise.all([
costAccountPromise, sellAccountPromise, itemCategoryPromise,
@@ -114,41 +187,19 @@ export default {
if (errorReasons.length > 0) {
return res.boom.badRequest(null, { errors: errorReasons });
}
const item = Item.forge({
name: req.body.name,
type_id: 1,
buy_price: req.body.buy_price,
sell_price: req.body.sell_price,
currency_code: req.body.currency_code,
note: req.body.note,
const updatedItem = await Item.query().findById(id).patch({
name: form.name,
type: form.type,
cost_price: form.cost_price,
sell_price: form.sell_price,
currency_code: form.currency_code,
sell_account_id: form.sell_account_id,
cost_account_id: form.cost_account_id,
category_id: form.category_id,
note: form.note,
});
await item.save();
return res.status(200).send();
},
},
/**
* Edit the given item.
*/
editItem: {
validation: [],
async handler(req, res) {
const { id } = req.params;
const validationErrors = validationResult(req);
if (!validationErrors.isEmpty()) {
return res.boom.badData(null, {
code: 'validation_error', ...validationErrors,
});
}
const item = await Item.where('id', id).fetch();
if (!item) {
return res.boom.notFound();
}
return res.status(200).send();
return res.status(200).send({ id: updatedItem.id });
},
},
@@ -159,7 +210,7 @@ export default {
validation: [],
async handler(req, res) {
const { id } = req.params;
const item = await Item.where('id', id).fetch();
const item = await Item.query().findById(id);
if (!item) {
return res.boom.notFound(null, {
@@ -167,7 +218,9 @@ export default {
});
}
await item.destroy();
// Delete the fucking the given item id.
await Item.query().findById(item.id).delete();
return res.status(200).send();
},
},