# LaTiendaCOOP backend

This README aims to document functionality of backend as well as required steps to get it up and running.

## Table of Contents

- [First Steps](#first-steps)
  - [Load location data](#load-location-data)
  - [Load taxonomy data](#load-taxonomy-data)
- [Endpoints](#endpoints)
- [Shop Integrations](#shop-integrations)
  - [WooCommerce](#woocommerce)
- [Product Search](#product-search)
- [Massive Data Load Endpoints](#massive-data-load-endpoints)
  - [COOP and Managing User Data Load](#coop-and-managing-user-data-load)
  - [Product Data Load](#product-data-load)
- [GeoIP Setup](#geoip-setup)
- [Tags](#tags)
- [Development Utils](#development-utils)
  - [Fake product data generation](#fake-product-data-generation)


## First Steps

- Clone repository:
  `git clone git@bitbucket.org:enreda/back-latienda.git`

- Use docker image for Postgis

```
docker run --name postgis -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -d -p 5432:5432 postgis/postgis
```

- Create file `.env` from `example.env` and populate fields correctly

From inside the project's folder:

- Make migrations:

```
python manage.py makemigrations core geo companies products history stats
python manage.py migrate
```

- Start server in development mode: `python manage.py runserver`


### Load Location Data

To load initial location data use: `python manage.py loadgisdata`


### Load Taxonomy Data

This data serves as initial Tags

To load initial set of tags: `python manage.py addtaxonomy`


## Endpoints


## Pagination

By default a `LimitOffsetPagination` pagination is enabled

Examples: `http://127.0.0.1:8000/api/v1/products/?limit=10&offset=0`

The response data has the following keys:
```
dict_keys(['count', 'next', 'previous', 'results'])
```

### User Management

Creation:

- endpoint: /api/v1/users/
- method: GET
- payload:
```json
{
  "email": "test@email.com",
  "full_name": "TEST NAME",
  "password": "VENTILADOR2ES1234499.89",
}
```

Change password:

- endpoint: api/v1/user/change_password/{user.pk}/
- method: POST
- payload:
```json
{
  "old_password": "my_old_password",
  "password": "SUPERSECRETNEWPASSWORD",
  "password2": "SUPERSECRETNEWPASSWORD"
}
```

Update user profile:
- endpoint: api/v1/users/<int:pk>/
- method: PUT
- payload:
```json
{
  "email": "new_user@email.com",
  "full_name": "Mr. TEST NAME",
}
```


### Authentication

Implemented using `djangorestframework-simplejwt`


New token pair endpoint: `/api/v1/token/`

Response:
```json
{
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYxMjI3MTcwNSwianRpIjoiZDU4YTgzYzFkYzFkNDI5MTljMGQ0NzcxNzljNzUxYTQiLCJ1c2VyX2lkIjo4fQ.yln80W5lONSyHwwqF4qBBHteqLuRfdLLWuaQANr_vxc",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjEyMTg4OTA1LCJqdGkiOiIzNGIxMzM3NmU4MWI0OWY5YjU3ZmUxM2M5NThmZWZkYiIsInVzZXJfaWQiOjh9.aRDCUvKj7LCvixjPLC9ghy0h7rfRwR6Lo3A7HX4kSHE"
}
```
Refresh expired token endpoint: `/api/v1/token/refresh/`


### Users

Endpoint url: `/api/v1/users/`

To get info on authenticated user: `/api/v1/my_user/`

Authenticated users cannot create new users

User are active by default

To create user:
```json
{
    "email": "test_user23@mail.com",
    "full_name": "Mr Test User",
    "password": "wqertewqr32qrewqr",
    "provider": "TWITTER"
}
```


### Companies

Endpoint url: `/api/v1/companies/`

To get company linked to authenticated user: `/api/v1/my_company/`

### Products

Endpoint url: `/api/v1/products/`

To get products linked to authenticated user: `/api/v1/my_products/`

### History

Endpoint url: `/api/v1/history/`:

Historical records about product importation


### Stats
Endpoint url: `/api/v1/stats/`

logs about user interaction with products links


### Locations

Location ednpoints:

- `/api/v1/countries/`
- `/api/v1/regions/`
- `/api/v1/provinces/`
- `/api/v1/cities/`


## Shop Integrations

We provide integrations with online shop platforms

It requires the json field `Company.credentials` to have the appropiate format and values

Endoint: `/api/v1/companies/{PK}/import_products/`

The software to handle different platform imports can be found in `utils`

### WooCommerce

Credential format:

```json
{
  "key": "qwerweqr",
  "secret": "asdfsa",
}
```

Method: `utils.woocommerce.migrate_shop_products`


## Product Search

Endpoint: `/api/v1/product_search/`

Query parameters:

  - `q`: text from the search input box


Response format:

```json
{
  "filters": {
    "singles": ["tag1", "tag2"],  // for tags that aren't nested
    "entry_1": ["subtag_1", "subtag_2"],  // for tree tags like entry_1/subtag_1
    "entry_2": ["subtag_1", "subtag_2"]   // one per penultimate tag in tree
  },
  "products" : [],    // list of serialized instances, in order of relevancy
}

```

Check out `products.tests..ProductSearchTest` for a practical case.


## Massive Data Load Endpoints

### COOP and Managing User Data Load

For massive load of data from COOPs and the managing user.

CSV headers: `email,cif,nombre-coop,nombre-corto,url,es-tienda`

Only admin users have access to endoint

### Product Data Load

Endpoint: `/api/v1/load_products/`

For massive load of product data.

CSV headers: `id,nombre-producto,descripcion,imagen,url,precio,gastos-envio,cond-envio,descuento,stock,tags,categoria,identificadores`

Only admin users have access to endoint


## GeoIP Setup

Module: `geoip2`

- Download the `GeoLite2 City` and `GeoLite2 Country` binary datasets from maxmind.com
- Unzip files into `datasets/` folder
- Set `settings.GEOIP_PATH` to datasets folder

Optional:

- install `libmaxminddb` C library for improved performance:

  `sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin`


## Tags

Both `Company` and `Product` models make use of tags.

### Load shopping taxonomy

To create the initial set of tags, we can use the `addtaxonomy` management command.
Reads the data from `datasets/shop-taxonomy.es-ES.txt` which is from google shopping


### Top-level tags

In order to extract the top level tags for use as categories, we can use the `extractparenttas` management command.
It saves the results to `datasets/top_tags.txt`


## Development Utils

### Fake product data generation

To create a dataset of fake companies and products:

`python manage.py addtestdata`

Creates 10 Companies, with 10 products each.

WARNING: the script deletes existing instances of both Company and Product
