feat(api,web): politicas comerciais com multi-selecao de produtos, grupos e subgrupos
- Promocao: produtos com busca remota por codigo/descricao (multi) e
grupos com busca por nome/codigo (multi) - backend cria uma promocao
por alvo na mesma transacao ({ids})
- Regra de desconto: grupos e subgrupos multi (subgrupos filtram pelos
grupos escolhidos) - uma regra por alvo
- Edicao continua por linha, com selects de busca no lugar dos inputs
de texto livre
- Modais maiores (760px de largura, corpo com altura minima e rolagem)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -109,26 +109,41 @@ export class PoliticasService {
|
||||
};
|
||||
}
|
||||
|
||||
async createPromocao(body: CreatePromocaoBody): Promise<{ id: number }> {
|
||||
// Cria uma promoção POR ALVO (produto ou grupo). Sem alvo, cria uma linha
|
||||
// genérica (comportamento anterior preservado).
|
||||
async createPromocao(body: CreatePromocaoBody): Promise<{ ids: number[] }> {
|
||||
this.assertManager();
|
||||
const prisma = this.cls.get('prisma');
|
||||
if (!prisma) throw new Error('prisma não disponível no CLS');
|
||||
const idEmpresa = this.cls.get('idEmpresa');
|
||||
const userId = this.cls.get('userId') ?? 'system';
|
||||
|
||||
const p = await prisma.promocao.create({
|
||||
data: {
|
||||
idEmpresa,
|
||||
descricao: body.descricao,
|
||||
codProduto: body.codProduto ?? null,
|
||||
grpProd: body.grpProd ?? null,
|
||||
descPct: body.descPct,
|
||||
dataInicio: new Date(body.dataInicio),
|
||||
dataFim: new Date(body.dataFim),
|
||||
createdBy: userId,
|
||||
},
|
||||
const alvos: { codProduto: string | null; grpProd: string | null }[] = [
|
||||
...(body.codProdutos ?? []).map((c) => ({ codProduto: c, grpProd: null })),
|
||||
...(body.grpProds ?? []).map((g) => ({ codProduto: null, grpProd: g })),
|
||||
];
|
||||
if (alvos.length === 0) alvos.push({ codProduto: null, grpProd: null });
|
||||
|
||||
const ids = await prisma.$transaction(async (tx) => {
|
||||
const created: number[] = [];
|
||||
for (const alvo of alvos) {
|
||||
const p = await tx.promocao.create({
|
||||
data: {
|
||||
idEmpresa,
|
||||
descricao: body.descricao,
|
||||
codProduto: alvo.codProduto,
|
||||
grpProd: alvo.grpProd,
|
||||
descPct: body.descPct,
|
||||
dataInicio: new Date(body.dataInicio),
|
||||
dataFim: new Date(body.dataFim),
|
||||
createdBy: userId,
|
||||
},
|
||||
});
|
||||
created.push(p.id);
|
||||
}
|
||||
return created;
|
||||
});
|
||||
return { id: p.id };
|
||||
return { ids };
|
||||
}
|
||||
|
||||
async updatePromocao(id: number, body: UpdatePromocaoBody): Promise<void> {
|
||||
@@ -257,27 +272,42 @@ export class PoliticasService {
|
||||
};
|
||||
}
|
||||
|
||||
async createRegra(body: CreateRegraDescontoBody): Promise<{ id: number }> {
|
||||
// Cria uma regra POR ALVO: cada grupo selecionado vira regra por grupo e
|
||||
// cada subgrupo vira regra por subgrupo. Sem alvos, regra vale para todos.
|
||||
async createRegra(body: CreateRegraDescontoBody): Promise<{ ids: number[] }> {
|
||||
this.assertManager();
|
||||
const prisma = this.cls.get('prisma');
|
||||
if (!prisma) throw new Error('prisma não disponível no CLS');
|
||||
const idEmpresa = this.cls.get('idEmpresa');
|
||||
const userId = this.cls.get('userId') ?? 'system';
|
||||
|
||||
const r = await prisma.regraDesconto.create({
|
||||
data: {
|
||||
idEmpresa,
|
||||
descricao: body.descricao,
|
||||
codGrupo: body.codGrupo ?? null,
|
||||
codSubgrupo: body.codSubgrupo ?? null,
|
||||
codVendedor: body.codVendedor ?? null,
|
||||
descPct: body.descPct,
|
||||
dataInicio: new Date(body.dataInicio),
|
||||
dataFim: new Date(body.dataFim),
|
||||
createdBy: userId,
|
||||
},
|
||||
const alvos: { codGrupo: number | null; codSubgrupo: number | null }[] = [
|
||||
...(body.codGrupos ?? []).map((g) => ({ codGrupo: g, codSubgrupo: null })),
|
||||
...(body.codSubgrupos ?? []).map((s) => ({ codGrupo: null, codSubgrupo: s })),
|
||||
];
|
||||
if (alvos.length === 0) alvos.push({ codGrupo: null, codSubgrupo: null });
|
||||
|
||||
const ids = await prisma.$transaction(async (tx) => {
|
||||
const created: number[] = [];
|
||||
for (const alvo of alvos) {
|
||||
const r = await tx.regraDesconto.create({
|
||||
data: {
|
||||
idEmpresa,
|
||||
descricao: body.descricao,
|
||||
codGrupo: alvo.codGrupo,
|
||||
codSubgrupo: alvo.codSubgrupo,
|
||||
codVendedor: body.codVendedor ?? null,
|
||||
descPct: body.descPct,
|
||||
dataInicio: new Date(body.dataInicio),
|
||||
dataFim: new Date(body.dataFim),
|
||||
createdBy: userId,
|
||||
},
|
||||
});
|
||||
created.push(r.id);
|
||||
}
|
||||
return created;
|
||||
});
|
||||
return { id: r.id };
|
||||
return { ids };
|
||||
}
|
||||
|
||||
async updateRegra(id: number, body: UpdateRegraDescontoBody): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user