Thiago Augusto Borges
Disponível em GitHub
Alterar sua ConnectionString no appsettings.json
Rodar a migration 20250213053121_SaleV2Migration ou gerar uma nova
dotnet ef database update
Executar o projeto
Ambev.DeveloperEvaluation.WebApi
DeveloperStore Team - Sale API
Field | Type | Description |
---|---|---|
saleNumber |
string |
Número único da venda. |
saleDate |
string (date-time) |
Data e hora da venda. |
customer |
object |
Informações do cliente. |
→ customerId |
string (UUID) |
Identificador único do cliente (External Identity). |
→ name |
string |
Nome do cliente (denormalizado). |
→ email |
string |
E-mail do cliente (denormalizado). |
branch |
object |
Informações da filial. |
→ branchId |
string (UUID) |
Identificador único da filial (External Identity). |
→ name |
string |
Nome da filial (denormalizado). |
→ address |
string |
Endereço da filial (denormalizado). |
items |
array |
Lista de itens da venda. |
→ productId |
string (UUID) |
Identificador único do produto (External Identity). |
→ quantity |
integer |
Quantidade do produto. |
→ unitPrice |
number |
Preço unitário do produto. |
→ discount |
number |
Desconto aplicado ao item . |
→ totalAmount |
number |
Valor total do item (quantity * unitPrice - discount ). |
totalAmount |
number |
Valor total da venda (soma dos valores dos itens). |
isCancelled |
boolean |
Indica se a venda foi cancelada. |
-
External Identities:
customerId
,branchId
eproductId
são identificadores externos, referenciando entidades de outros domínios.
-
Denormalização:
- Campos como
customer.name
,branch.name
ebranch.address
são denormalizados.
- Campos como
-
Regras de Negócio:
- Descontos são aplicados automaticamente com base na quantidade de itens:
- 4+ itens: 10% de desconto.
- 10-20 itens: 20% de desconto.
- Mais de 20 itens: Não permitido (lança uma exceção).
- O valor total de cada item (
totalAmount
) é calculado comoquantity * unitPrice - discount
.
- Descontos são aplicados automaticamente com base na quantidade de itens:
-
Cancelamento de Venda:
- Uma venda pode ser cancelada por meio do endpoint
PATCH /sales/{id}/cancel
. - O campo
isCancelled
é atualizado paratrue
quando uma venda é cancelada.
- Uma venda pode ser cancelada por meio do endpoint
-
Paginação e Ordenação:
- O endpoint
GET /sales
suporta paginação e ordenação:Page
: Número da página (padrão: 1).PageSize
: Número de itens por página (padrão: 10).
- O endpoint
-
Validações:
- Todos os campos obrigatórios são validados antes de processar a requisição.
- Quantidades inválidas (ex.: acima de 20 itens) resultam em erro.
- Description: Retrieve a list of all sales
- Query Parameters:
Page
(optional): Page number for pagination (default: 1)PageSize
(optional): Number of items per page (default: 10)Filters
(optional): Ordering of results (e.g., "saleNumber, saleDate")
- Response:
{ "items": [ { "id": "string (UUID)", "saleNumber": "string", "saleDate": "string (date-time)", "customerId": "string (UUID)", "branchId": "string (UUID)", "items": [ { "productId": "string (UUID)", "quantity": "integer", "unitPrice": "number", "discount": "number", "totalAmount": "number" } ], "totalAmount": "number", "isCancelled": "boolean" } ], "page": "integer", "pageSize": "integer", "totalCount": "integer" }
- Description: Create a new sale
- Request Body:
{ "saleNumber": "string", "saleDate": "string (date-time)", "customerId": "string (UUID)", "branchId": "string (UUID)", "items": [ { "productId": "string (UUID)", "quantity": "integer", "unitPrice": "number" } ] }
- Response:
{ "id": "string (UUID)", "saleNumber": "string", "saleDate": "string (date-time)", "customerId": "string (UUID)", "branchId": "string (UUID)", "items": [ { "productId": "string (UUID)", "quantity": "integer", "unitPrice": "number", "discount": "number", "totalAmount": "number" } ], "totalAmount": "number", "isCancelled": "boolean" }
- Description: Retrieve a specific sale by ID
- Path Parameters:
id
: Sale ID (UUID)
- Response:
{ "id": "string (UUID)", "saleNumber": "string", "saleDate": "string (date-time)", "customerId": "string (UUID)", "branchId": "string (UUID)", "items": [ { "productId": "string (UUID)", "quantity": "integer", "unitPrice": "number", "discount": "number", "totalAmount": "number" } ], "totalAmount": "number", "isCancelled": "boolean" }
- Description: Update a specific sale
- Path Parameters:
id
: Sale ID (UUID)
- Request Body:
{ "saleNumber": "string", "saleDate": "string (date-time)", "customerId": "string (UUID)", "branchId": "string (UUID)", "items": [ { "productId": "string (UUID)", "quantity": "integer", "unitPrice": "number" } ] }
- Response:
{ "id": "string (UUID)", "saleNumber": "string", "saleDate": "string (date-time)", "customerId": "string (UUID)", "branchId": "string (UUID)", "items": [ { "productId": "string (UUID)", "quantity": "integer", "unitPrice": "number", "discount": "number", "totalAmount": "number" } ], "totalAmount": "number", "isCancelled": "boolean" }
- Description: Delete a specific sale
- Path Parameters:
id
: Sale ID (UUID)
- Response:
{ "message": "string" }
- Description: Cancel a specific sale
- Path Parameters:
id
: Sale ID (UUID)
- Response:
{ "message": "string" }