Skip to content

Commit

Permalink
Merge pull request #297 from app-masters/consumo-com-produto
Browse files Browse the repository at this point in the history
Consumo com produto
  • Loading branch information
jfbaraky authored Jun 9, 2020
2 parents a9ea9e3 + 3bea90f commit ac35557
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 6 deletions.
90 changes: 90 additions & 0 deletions backend/src/models/consumptions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Sequelize, { Op } from 'sequelize';
import db from '../schemas';
import { Consumption, SequelizeConsumption } from '../schemas/consumptions';
import { ConsumptionProducts } from '../schemas/consumptionProducts';
import { PlaceStore } from '../schemas/placeStores';
import { Family } from '../schemas/families';
import moment from 'moment';
Expand Down Expand Up @@ -278,6 +279,95 @@ export const addConsumption = async (
return db.consumptions.create({ ...values, placeStoreId });
};

/**
* Create a new consumption on the store
* @param values consumption object
* @param placeStoreId logged user place store ID
* @returns Promise<List of items>
*/
export const addConsumptionProduct = async (values: Consumption): Promise<SequelizeConsumption> => {
const family = await db.families.findByPk(values.familyId);
if (!family) {
// Invalid family ID
throw { status: 422, message: 'Família não encontrada' };
}

//Get family benefit and its products.
const familyBenefit = await db.benefits.findAll({
where: { groupName: family.groupName }
});
//Get all products by benefit
const benefitsIds = familyBenefit.map((item) => {
return item.id;
});
const listOfProductsAvailable = await db.benefitProducts.findAll({
where: {
benefitsId: benefitsIds as number[]
},
include: [{ model: db.products, as: 'products' }]
});
//Get all family Consumptions
const familyConsumption = await db.consumptions.findAll({
where: { familyId: family.id as number }
});
//Get all Product used by family consumption
const consumptionIds = familyConsumption.map((item) => {
return item.id;
});
const productsFamilyConsumption = await db.consumptionProducts.findAll({
where: {
consumptionsId: consumptionIds as number[]
}
});
//Get difference between available products and consumed products
const differenceProducts = listOfProductsAvailable.map((product) => {
const items = productsFamilyConsumption.filter((f) => f.productsId === product.productsId);
let amount = 0;
if (items.length > 0)
amount = items
.map((item) => {
return item.amount;
})
.reduce((a, b) => a + b);
let amountDifference = product.amount;
if (amount) {
amountDifference = product.amount - amount;
}
return {
productId: product.productsId,
amountAvailable: amountDifference,
amountGranted: product.amount,
amountConsumed: amount ? amount : 0
};
});
//Compare differenceProducts with the new products
let canConsumeAll = true;
values.products?.map((product) => {
const prodDiff = differenceProducts.find((f) => f.productId === product.id);
if (!prodDiff) {
throw { status: 422, message: 'Produto não disponivel' };
} else {
if (prodDiff.amountAvailable < product.amount) canConsumeAll = false;
}
});
if (canConsumeAll) {
values.value = 0;
const newConsumption = await db.consumptions.create({ ...values }).then(async (consumption) => {
const consumptionProducts = values.products?.map((item) => {
return { productsId: item.id, consumptionsId: consumption.id, amount: item.amount };
});
if (consumptionProducts) {
await db.consumptionProducts.bulkCreate(consumptionProducts);
}
return consumption;
});
return newConsumption;
} else {
logging.critical('Family cannot consume', { family, values });
throw { status: 402, message: 'Não foi possível inserir consumo' };
}
};

/**
* Get report for consumptions on the place on the interval
* @param minDate start of interval
Expand Down
16 changes: 11 additions & 5 deletions backend/src/routes/consumptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ router.post('/', async (req, res) => {
proofImageUrl = data.url;
}
}
const item = await consumptionModel.addConsumption({ ...req.body, proofImageUrl });
const isTicket = process.env.CONSUMPTION_TYPE === 'ticket';

// Scrape the purchase data, but don't wait for it
consumptionModel.scrapeConsumption(item);

return res.send(item);
let item;
if (isTicket) {
item = await consumptionModel.addConsumption({ ...req.body, proofImageUrl });
// Scrape the purchase data, but don't wait for it
consumptionModel.scrapeConsumption(item);
return res.send(item);
} else {
item = await consumptionModel.addConsumptionProduct({ ...req.body });
return res.send(item);
}
} catch (error) {
logging.error(error);
return res.status(error.status || 500).send(error.message);
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ router.use('/users', jwtMiddleware, userRoutes);
router.use('/institutions', jwtMiddleware, institutionRoutes);
router.use('/benefits', jwtMiddleware, benefitRoutes);
router.use('/families', jwtMiddleware, familyRoutes);
router.use('/consumptions', jwtMiddleware, consumptionRoutes);
router.use('/consumptions', consumptionRoutes);
router.use('/dashboard', jwtMiddleware, dashboardRoutes);
router.use('/products', jwtMiddleware, productsRoutes);
router.use('/static', jwtMiddleware, express.static(`${path.dirname(__dirname)}/../database/storage`));
Expand Down
4 changes: 4 additions & 0 deletions backend/src/schemas/benefitProducts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Sequelize, Model, DataTypes, BuildOptions, ModelCtor } from 'sequelize';
import { Product } from './products';
import { Benefit } from './benefits';

// Simple item type
export interface BenefitProduct {
Expand All @@ -11,6 +12,9 @@ export interface BenefitProduct {
createdAt?: number | Date | null;
updatedAt?: number | Date | null;
deletedAt?: number | Date | null;
//Join
products?: Product[];
benefits?: Benefit[];
}
// Sequelize returns type
export type SequelizeBenefitProduct = BenefitProduct & Model;
Expand Down
5 changes: 5 additions & 0 deletions backend/src/schemas/benefits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface Benefit {
createdAt?: number | Date | null;
updatedAt?: number | Date | null;
deletedAt?: number | Date | null;
//Join
benefitProducts?: BenefitProduct[];
}
// Sequelize returns type
export type SequelizeBenefit = Benefit & Model;
Expand Down Expand Up @@ -73,6 +75,9 @@ export const initBenefitSchema = (sequelize: Sequelize): SequelizeBenefitModel =
foreignKey: 'institutionId',
as: 'institution'
});
Schema.hasMany(models.benefitProducts, {
foreignKey: 'benefitsId',
as: 'benefitProducts'
Schema.hasMany(models.benefitProducts, {
foreignKey: 'benefitsId',
as: 'benefitProduct',
Expand Down
6 changes: 6 additions & 0 deletions backend/src/schemas/consumptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Sequelize, Model, DataTypes, BuildOptions, ModelCtor } from 'sequelize';
import { Product } from './products';
import { ConsumptionProducts } from './ConsumptionProducts';

export interface PurchaseData {
place?: string;
Expand All @@ -9,6 +11,7 @@ export interface PurchaseData {
}[];
products: {
name?: string;
amount?: number;
totalValue?: number;
}[];
}
Expand All @@ -27,6 +30,9 @@ export interface Consumption {
createdAt?: number | Date | null;
updatedAt?: number | Date | null;
deletedAt?: number | Date | null;
//Join
products: (Product & { amount: number })[] | null;
consumptionProducts?: ConsumptionProducts[];
}
// Sequelize returns type
export type SequelizeConsumption = Consumption & Model;
Expand Down

0 comments on commit ac35557

Please sign in to comment.