---
# System prepended metadata

title: Pricing Service

---

Sure, here's a RESTful API structure based on your schema:

 ### **Layer Table**:

1. **CREATE** a new layer:

   **Endpoint:** `/api/layers`
   
   **HTTP Method:** `POST`
   
   **Request Body:** 
   
   ```json
   {
     "name": "Layer Name",
     "type": "B2B",
     "parent_layer_id": 1,
     "rule": "PRICE",
     "default_discount": 10,
     "metadata": {
       "refers_to": ["BranchX", "BranchY", "BranchZ"]
     }
   }
   ```
   
2. **READ** all layers:

   **Endpoint:** `/api/layers`
   
   **HTTP Method:** `GET`
   
   **Filters (query_params):** `name, type, rule, refer`

3. **READ** a specific layer by `layer_id`:

   **Endpoint:** `/api/layers/{layer_id}`
   
   **HTTP Method:** `GET`
 
4. **UPDATE** a specific layer by `layer_id`:

   **Endpoint:** `/api/layers/{layer_id}`
   
   **HTTP Method:** `PUT` or `PATCH`
   
   **Request Body (for PUT):** 
   ```json
   {
     "name": "New Layer Name",
     "type": "B2C",
     "parent_layer_id": 1,
     "rule": "DISCOUNT",
     "default_discount": 10,
     "metadata": {
       "refers_to": ["BranchA", "BranchB"]
     }
   }
   ```
For `PATCH`, send only the fields you wish to update.    

5. **DELETE** a specific layer by `layer_id`:

   **Endpoint:** `/api/layers/{layer_id}`
   
   **HTTP Method:** `DELETE` //delete lógico

6. **Validations:**
   - não deve ter tabelas com mesmo nome
   - 'default_discount' deve ser null ou não existir se 'rule' for PRICE
   - 'default_discount' deve ser diferente de null se 'rule' for DISCOUNT
   - 'parent_layer' deve ser do tipo PRICE
   - 'parent_layer' não deve ter 'parent_layer' (não queremos recursividade)
   
### **Pricing Table**:

1. **CREATE** new pricing:

   **Endpoint:** `/api/pricings`
   
   **HTTP Method:** `POST`
   
   **Request Body:** 
   ```json
   {
     "init_date": "2023-10-04T14:30:00", //seta essa mesma data como finish_date do preço do mesmo produto e tabela
     "layer_id": 1,
     "product_id": 1001,
     "value": 5999 //preço ou % de desconto - se layer for DISCOUNT, esse valor deve ser entre 0 e 100
   }
   ```
   
2. **READ** all pricings:

   **Endpoint:** `/api/pricings`
   
   **Params:** `?product_id=1001&active=[true|false]`
   
   **HTTP Method:** `GET`
    ```json
   [{
     "id": 1,
     "init_date": "2023-10-04T15:00:00",
     "finish_date": "2023-11-04T15:00:00", // null se for o preço corrente
     "layer_id": 1,
     "product_id": 1001,  
     "value": 1000,
     "value_rule": "price" //valor vem da "rule" da "layer"
     "price": 1000 //calculated price base on layer rule
   }{
     "id": 2,
     "init_date": "2023-10-04T15:00:00",
     "finish_date": "2023-11-04T15:00:00", // null se for o preço corrente
     "layer_id": 2,
     "product_id": 1001,  
     "value": 20,
     "value_rule": "discount" //valor vem da "rule" da "layer"
     "price": 800 //calculated price base on layer rule
   },{
     "id": 3,
     "init_date": "2023-10-04T15:00:00",
     "finish_date": "2023-11-04T15:00:00", // null se for o preço corrente
     "layer_id": 3,
     "product_id": 1001,  
     "value": 750,
     "value_rule": "price" //valor vem da "rule" da "layer"
     "price": 750 //calculated price base on layer rule
   },{
     "id": 4,
     "init_date": "2023-10-04T15:00:00",
     "finish_date": "2023-11-04T15:00:00", // null se for o preço corrente
     "layer_id": 4,//tabela base é a tabela 1
     "product_id": 1001,  
     "value": null,
     "value_rule": "price" //valor vem da "rule" da "layer"
     "price": 1000 //calculated price base on layer rule
   }]
   ```
   **Description:**Retorna todos os preços dos produtos de id 1,3e4.
   
   **Validations:**
   - Se o filtro active for true, retorna somente preços ativos, ou seja, cujo data corrente é maior que init_date e menor que finish_date ou null

3. **READ** specific pricing by `pricing_id`:
   **Endpoint:** `/api/pricings/{pricing_id}`
   **HTTP Method:** `GET`
   ```json
   [{
     "id": 1
     "init_date": "2023-10-04T15:00:00",
     "finish_date": "2023-11-04T15:00:00",
     "layer_id": 2,
     "product_id": 1002,
     "value": 6499,
     "price": 6499 //calculated price
   }]
   ```

4. **UPDATE** specific pricing by `pricing_id`:
   **Endpoint:** `/api/pricings/{pricing_id}`
   **HTTP Method:** `PUT` or `PATCH`
   **Request Body (for PUT):** 
   ```json
   {
     "init_date": "2023-10-04T15:00:00",
     "finish_date": "2023-11-04T15:00:00",
     "layer_id": 2,
     "product_id": 1002,
     "value": 6499
   }
   ```

   For `PATCH`, send only the fields you wish to update.

5. **DELETE** specific pricing by `pricing_id`:
   **Endpoint:** `/api/pricings/{pricing_id}`
   **HTTP Method:** `DELETE` //seta data fim 


6. **FILTER** pricings by `layer_id`:
   **Endpoint:** `/api/pricings/layer/{layer_id}?product_ids=1,2,3`
   **HTTP Method:** `GET`
   **Description:** Retorna o preço dos produtos 1,2 e 3 para a tabela {layer_id}
   
**Validations:**
   - 'init_date' deve ser maior que now() e diferente de null
   - 'finish_date' não poderá ser setado manualmente - não queremos um agendamento de termino por enquanto. somente um agendamento para iniciar.
   - ao criar um novo preço, deve-se:

     1 - buscar um preço para o mesmo 'product_id', 'layer_id' e 'finish_date' for igual null
     
     2 - setar o 'finish_date' desse preço com o 'init_date' do preço que está sendo registrado
     
   - o campo 'price' é um campo calculado a partir do 'value' baseado na 'rule' da layer
     - caso 'rule' da layer seja PRICE, price = value
     - caso 'rule' da layer seja DISCOUNT, price = layer.parent_layer.value * value%
