```markdown
## 库位相关

#### 检查站点是否存在

* 方法说明

  检查站点是否存在。

```python
async def is_point_exist(point_name: str) -> bool
```

* 输入参数

  point_name，站点名。
* 输出参数
* True，该站点存在。
* False，该站点不存在。
* 异常

  本方法抛出异常。

#### 检查库位是否存在

* 方法说明

  检查库位名是否存在

```python
async def check_site_existed_by_site_id(site_id: str) -> bool
```

* 输入参数
* site_id，库位名称。
* 输出参数
* True，该库位存在。
* False，该库位不存在。
* 异常

  本方法抛出异常。

#### 检查库区是否存在

* 方法说明

  检查库区名是否存在

```python
async def check_site_group_existed_by_group_name(group_name: str) -> bool
```

* 输入参数
* group_name，库区名称。
* 输出参数
* True，该库区存在。
* False，该库区不存在。
* 异常

  本方法抛出异常。

#### 根据条件获取库位

* 方法说明

  根据条件获取库位

```python
async def find_sites_by_condition(conditions: str, sort: str) -> str
```

* 输入参数
* conditions，查询条件，模糊查询用'%'标记

  ```python
  {
    "area": "area01",  # 区域名
    "content": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货物
    "depth": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 深
    "filled": True,     # 是否有货
    "group_names": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库区名
    "level": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货架层数
    "locked": True,  # 是否已锁定
    "locked_by": "12345",  # 锁定的任务实例id
    "no": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位编号
    "row_num": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货架行
    "site_ids": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位id
    "tags": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位标签
    "type": 1     # 库位类别，1物理库位，0逻辑库位
  }
  ```
* sort，根据site_id排序："ASC"顺序排序，"DESC"倒序排序
* 输出参数

  库位列表json

```python
  [{
      "area": "area01",    # 区域
      "content": "abc-1",     # 货物
      "depth": "abc-1",  # 深
      "disabled": True,  # 禁用
      "filled": 1,  # 占用
      "group_names": "abc",  # 库区名
      "level": "abc-1",  # 层
      "locked": 1,  # 锁定
      "locked_by": "123456",  # 锁定的任务id
      "no": "abc-1",  # 编号
      "preparing": True,  # 准备中
      "row_num": "abc-1",  # 列
      "site_id": "abc-1",  # 库位id
      "tags": "abc-1",  # 标签
      "type": 1,  # 库位类型
      "working": True  # 工作中
      },
      {
      "area": "area01",
      "content": "abc-2",
      "depth": "abc-2",
      "disabled": True,
      "filled": 1,
      "group_names": "abc",
      "level": "abc-2",
      "locked": 1,
      "locked_by": "123456",
      "no": "abc-2",
      "preparing": True,
      "row_num": "abc-2",
      "site_id": "abc-2",
      "tags": "abc-2",
      "type": 1,
      "working": True
  }]
```

如果输出值没有满足条件的库位，方法将返回字符串"null"。

* 异常

  本方法抛出异常。
* 例子

  1.根据库位id查询库位是否有货

```python
  def test():
      condition = {
          "site_ids": ["E1-1"],
          "filled": True
      }
      site = jj.find_sites_by_condition(json.dumps(condition), "ASC")
```

2.查询某一库区内的所有库位

```python
  def test():
      condition = {
          "group_names": ["E1"]
      }
      site = jj.find_sites_by_condition(json.dumps(condition), "ASC")
```

#### 根据条件获取有效库位

* 方法说明

  根据条件获取有效库位，即未禁用（disabled=0）并且同步成功（sync_failed=0）的库位。

```python
async def find_available_sites_by_condition(conditions: str, sort: str) -> str
```

* 输入参数
* conditions，查询条件，模糊查询用'%'标记

  ```python
  {
    "area": "area01",  # 区域名
    "content": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货物
    "depth": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 深
    "filled": True,     # 是否有货
    "group_names": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库区名
    "level": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货架层数
    "locked": True,  # 是否已锁定
    "locked_by": "12345",  # 锁定的任务实例id
    "no": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位编号
    "row_num": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货架行
    "site_ids": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位id
    "tags": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位标签
    "type": 1     # 库位类别，1物理库位，0逻辑库位
  }
  ```
* sort，根据site_id排序："ASC"顺序排序，"DESC"倒序排序
* 输出参数
* 包含库位列表的 JSON 字符串，转换成 JSON 对象之后的示例数据如下所示：

  ```python
  [{
      "area": "area01",    # 区域
      "content": "abc-1",     # 货物
      "depth": "abc-1",  # 深
      "disabled": True,  # 禁用
      "filled": 1,  # 占用
      "group_names": "abc",  # 库区名
      "level": "abc-1",  # 层
      "locked": 1,  # 锁定
      "locked_by": "123456",  # 锁定的任务id
      "no": "abc-1",  # 编号
      "preparing": True,  # 准备中
      "row_num": "abc-1",  # 列
      "site_id": "abc-1",  # 库位id
      "tags": "abc-1",  # 标签
      "type": 1,  # 是否物理库位
      "working": True  # 工作中
      },
      {
      "area": "area01",
      "content": "abc-2",
      "depth": "abc-2",
      "disabled": True,
      "filled": 1,
      "group_names": "abc",
      "level": "abc-2",
      "locked": 1,
      "locked_by": "123456",
      "no": "abc-2",
      "preparing": True,
      "row_num": "abc-2",
      "site_id": "abc-2",
      "tags": "abc-2",
      "type": 1,
      "working": True
  }]
  ```
* 如果没有符合条件的库位，则返回值为 `"null"` ，而不是 `[]` 。
* 异常

  本方法抛出异常。

#### 根据扩展字段获取有效库位

* 方法说明

  根据扩展字段获取有效库位，即未禁用（disabled=0）并且同步成功（sync_failed=0）的库位。

```python
async def find_available_sites_by_ext_fields(conditions: str) -> str
```

* 输入参数
* conditions，查询条件，模糊查询用'%'标记

  ```python
  [
    {
      "attribute_name": "ext5",
      "attribute_value": "ex%"
    },
    {
      "attribute_name": "ext10",
      "attribute_value": "%ex"
    },
    {
      "attribute_name": "ex100",
      "attribute_value": "ex3"
    },
    {
      "attribute_name": "ex101",
      "attribute_value": "%ex"
    },
    {
      "attribute_name": "filled",  # 是否占用
      "attribute_value": "0"
    },
    {
      "attribute_name": "locked",  # 是否锁定
      "attribute_value": "0"
    },
    {
      "attribute_name": "area",  # 区域
      "attribute_value": "new"
    },
    {
      "attribute_name": "group_name",  # 库区名
      "attribute_value": "CYJ-IN-UP"
    },
    {
      "attribute_name": "site_id",  # 库位id
      "attribute_value": "CYJ-IN-01"
    }
  ]
  ```
* 请求示例

```python
    conditions = [{"attribute_name": "ext5", "attribute_value": "ex%"}, {"attribute_name": "ext10", "attribute_value": "%ex"}, {"attribute_name": "ex100", "attribute_value": "ex3"}, {"attribute_name": "ex101", "attribute_value": "%ex"}, {"attribute_name": "filled", "attribute_value": "0"}, {"attribute_name": "locked", "attribute_value": "0"}, {"attribute_name": "area", "attribute_value": "new"}, {"attribute_name": "group_name", "attribute_value": "CYJ-IN-UP"}, {"attribute_name": "site_id", "attribute_value": "CYJ-IN-01"}]
    data = jj.find_available_sites_by_ext_fields(json.dumps(conditions))
```

* 库位列表json
* 包含库位列表的 JSON 字符串，转换成 JSON 对象之后的示例数据如下所示：

  ```python
  [
    {
      "area": "new",
      "content": None,
      "filled": 1,
      "group_name": None,
      "locked": 0,
      "locked_by": None,
      "site_id": "CYJ-IN-01",
      "site_name": None,
      "tags": "CYJ-IN-UP",
      "type": None
    }
  ]
  ```
* 如果没有符合条件的库位，则返回值为 `"null"` ，而不是 `[]` 。
* 异常

  本方法抛出异常。

#### 根据条件更新库位

* 方法说明

  根据条件更新库位

```python
async def update_sites_by_condition(conditions: str, values: str) -> int
```

* 输入参数
* conditions，更新条件，模糊查询用'%'标记

  ```python
  {
    "area": "area01",  # 区域名
    "content": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货物
    "depth": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 深
    "filled": True,     # 是否有货
    "group_names": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库区名
    "level": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货架层数
    "locked": True,  # 是否已锁定
    "locked_by": "12345",  # 锁定的任务实例id
    "no": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位编号
    "row_num": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 货架行
    "site_ids": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位id
    "tags": ["abc", "'%bc'", "'%b%'", "'ab%'"],  # 库位标签
    "type": 1     # 库位类别，1物理库位，0逻辑库位
  }
  ```
* values，修改的字段

  ```python
  {
    "area": "abc",   # 区域
    "content": "abc",  # 货物
    "depth": "2",   # 深
    "disabled": True,  # 禁用
    "filled": True,  # 有货
    "group_name": "abc",  # 库区名
    "level": "3",  # 层
    "locked": True,   # 锁定
    "locked_by": "12345",   # 锁定的任务id
    "no": "10",   # 编号
    "preparing": True,   # 准备中
    "row_num": "5",   # 行
    "site_id": "site_01",   # 库位名
    "tags": "abc",   # 标签
    "type": 1,   # 是否物理库位
    "working": True  # 工作中
  }
  ```
* 输出参数
* 更新成功的数据库记录行数
* 异常

  本方法抛出异常。
* 例子

​ 1.根据库位id查询有货未加锁的库位并进行加锁

```python
def test():
    task_id = jj.current_time_millis()
    condition = {
        "site_ids": ["E1-1"],
        "filled": True,
        "disabled": False,
        "locked": False
    }
    value = {
        "locked": True,
        "locked_by": str(task_id)
    }
    site = jj.update_sites_by_condition(json.dumps(condition), json.dumps(value))
```

​ 2.更新库区内的有货未加锁的所有库位并进行加锁

```python
def test():
    task_id = jj.current_time_millis()
    condition = {
        "group_names": ["E1"],
        "filled": True,
        "disabled": False,
        "locked": False
    }
    value = {
        "locked": True,
        "locked_by": str(task_id)
    }
    site = jj.update_sites_by_condition(json.dumps(condition), json.dumps(value))
```

#### 根据条件更新库位扩展字段值

* 方法说明

  根据库位id和扩展字段名更新扩展字段的值

```python
async def update_site_ext_field_by_id_and_ext_field_name(conditions: str) -> None
```

* 输入参数
* conditions，库位id、扩展字段名和更新值

```python
  [
          {
              "site_id": "Loc-01",
              "ext_field_name": "test",
              "update_value": "111"
          },
          {
              "site_id": "Loc-02",
              "ext_field_name": "test",
              "update_value": "222"
          },
          {
              "site_id": "Loc-03",
              "ext_field_name": "test",
              "update_value": "333"
          }
  ]
```

* 输出参数

  无。
* 异常

  本方法抛出异常
* 例子
* 更新Loc-01、Loc-02、Loc-03的扩展字段test的值分别为111、222、333

```python
def test():
    conditions = [
        {
            "site_id": "Loc-01",
            "ext_field_name": "test",
            "update_value": "111"
        },
        {
            "site_id": "Loc-02",
            "ext_field_name": "test",
            "update_value": "222"
        },
        {
            "site_id": "Loc-03",
            "ext_field_name": "test",
            "update_value": "333"
        }
    ]

    jj.update_site_ext_field_by_id_and_ext_field_name(json.dumps(conditions))
```