Files
Assemblr-Backend/routes/assembly.py

302 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import datetime
from flask import Blueprint, request, jsonify
from flask_jwt_extended import get_jwt_identity
from sqlalchemy.orm import joinedload
import database
from database.enums import AssemblyState
from routes.utils import jwt_protect_blueprint
import sipro.api.orders
import utils.balance
assembly_blueprint = jwt_protect_blueprint(Blueprint('assembly', __name__))
@assembly_blueprint.post('/create')
def create_assembly():
try:
data: dict = request.json
order_id: int = data.get('orderId')
user_id = get_jwt_identity()
existing_assembly = (database.Assembly.query.
options(joinedload(database.Assembly.user)).
filter_by(order_id=order_id).
first())
if existing_assembly:
response = {
'ok': False,
'message': 'Сборка этого товара уже была запущена',
'assemblyId': existing_assembly.id,
'statusCode': 'ASSEMBLY_ALREADY_EXISTS',
'userName': existing_assembly.user.login
}
return jsonify(response)
need_crpt_for_order_response = sipro.api.orders.need_crpt_by_order_id(order_id)
need_crpt_value = need_crpt_for_order_response.get('needCrpt')
if need_crpt_value:
valid_app = request.headers.get('CrptAvailable')
if not valid_app:
response = {
'ok': False,
'message': 'Для сборки этого заказа необходимо приложение с поддержкой Честного Знака',
'assemblyId': -1,
'statusCode': 'USER_ALREADY_HAS_ACTIVE_ASSEMBLY',
}
return jsonify(response)
active_assembly = database.Assembly.query.filter(database.Assembly.user_id == user_id,
database.Assembly.is_active == True).first()
if active_assembly:
response = {
'ok': False,
'message': 'Вы не можете запустить сборку заказа, так как у вас уже есть активная сборка',
'assemblyId': active_assembly.id,
'statusCode': 'USER_ALREADY_HAS_ACTIVE_ASSEMBLY'
}
return jsonify(response)
assembled_assembly = (
database.Assembly.query
.filter(
database.Assembly.order_id == order_id,
database.Assembly.ended_at != None
)
.first()
)
if assembled_assembly:
response = {
'ok': False,
'message': 'Вы уже собирали этот товар',
'assemblyId': assembled_assembly.id,
'statusCode': 'USER_ALREADY_HAS_ACTIVE_ASSEMBLY',
}
return jsonify(response)
assembly = database.Assembly(user_id=user_id,
order_id=order_id,
state=AssemblyState.NOT_STARTED,
created_at=datetime.datetime.now(),
is_active=True)
database.db.session.add(assembly)
database.db.session.commit()
response = {
'ok': True,
'message': 'Сборка успешно запущена!',
'assemblyId': assembly.id,
'statusCode': 'CREATED'
}
return jsonify(response)
except Exception as e:
response = {
'ok': False,
'message': f'Неизвестная ошибка: {e}',
'assemblyId': -1,
'statusCode': 'INVALID_EXCEPTION'
}
return jsonify(response)
def close_assembly_by_id(
assembly_id: int,
):
if not assembly_id or (not isinstance(assembly_id, int)):
response = {
'ok': False,
'message': 'Неверно указан ID сборки'
}
return jsonify(response)
assembly = database.db.session.get(database.Assembly, assembly_id)
if not assembly:
response = {
'ok': False,
'message': 'Указанная сборка не найдена'
}
return jsonify(response)
assembly.is_active = False
assembly.ended_at = datetime.datetime.now()
database.db.session.commit()
order_id = assembly.order_id
sipro_response = sipro.api.orders.close_order(order_id)
reward = sipro_response.get('reward')
ok = sipro_response.get('ok')
if ok:
utils.balance.add_top_up(user_id=assembly.user_id,
amount=reward,
description=f'Начисление за сборку заказа {order_id}',
json_data={'order_id': order_id},
commit=True)
return sipro_response
@assembly_blueprint.post('/close')
def close_assembly():
args = request.json
assembly_id = args.get('assemblyId')
sipro_response = close_assembly_by_id(int(assembly_id))
return sipro_response
@assembly_blueprint.post('/cancel')
def cancel_assembly():
try:
user_id = get_jwt_identity()
assembly = database.Assembly.query.filter(database.Assembly.user_id == user_id,
database.Assembly.is_active == True).first()
if not assembly:
response = {
'ok': False,
'message': 'У вас нет активных сборок'
}
return jsonify(response)
order_id = assembly.order_id
sipro_response = sipro.api.orders.cancel_order_assembly(order_id)
if not sipro_response.get('result'):
response = {
'ok': False,
'message': f'Ошибка: {sipro_response.get("message")}'
}
return jsonify(response)
database.db.session.delete(assembly)
database.db.session.commit()
response = {
'ok': True,
'message': 'Сборка успешно отменена!'
}
return jsonify(response)
except Exception as e:
response = {
'ok': False,
'message': f'Неизвестная ошибка: {e}'
}
return jsonify(response)
@assembly_blueprint.post('/cancelById')
def cancel_assembly_by_id():
try:
assembly_id = request.json.get('assemblyId')
assembly = database.db.session.get(database.Assembly, assembly_id)
if not assembly:
response = {
'ok': False,
'message': f'Сборка {assembly_id} не найдена'
}
return jsonify(response)
database.db.session.delete(assembly)
database.db.session.commit()
response = {
'ok': True,
'message': f'Сборка {assembly_id} успешно отменена!'
}
return jsonify(response)
except Exception as e:
response = {
'ok': False,
'message': f'Неудалось отменить сборку, ошибка: {e}'
}
return jsonify(response)
@assembly_blueprint.get('/hasActive')
def user_has_active_assembly():
user_id = get_jwt_identity()
assemblies_count = database.Assembly.query.filter(database.Assembly.user_id == user_id,
database.Assembly.is_active == True).count()
return jsonify(has=assemblies_count > 0)
@assembly_blueprint.get('/getActive')
def get_active_assembly():
user_id = get_jwt_identity()
assembly = database.Assembly.query.filter(database.Assembly.user_id == user_id,
database.Assembly.is_active == True).first()
response = {
'databaseId': assembly.id,
'createdAt': str(assembly.created_at),
'endedAt': str(assembly.ended_at),
'orderId': assembly.order_id,
'isActive': assembly.is_active,
'state': assembly.state
}
return jsonify(response)
@assembly_blueprint.post('/confirmCurrent')
def confirm_current_assembly():
# confirm current assembly for user
user_id = get_jwt_identity()
assembly = database.Assembly.query.filter(database.Assembly.user_id == user_id,
database.Assembly.is_active == True).first()
if not assembly:
response = {
'ok': False,
'message': 'У вас нет активных сборок'
}
return jsonify(response)
close_assembly_by_id(assembly.id)
response = {
'ok': True,
'message': 'Сборка успешно завершена!',
}
return response
@assembly_blueprint.post('/confirm')
def confirm_assembly():
user_id = get_jwt_identity()
args: dict = request.json
assembly_id = args.get('assemblyId')
if not assembly_id or (not isinstance(assembly_id, int)):
response = {
'ok': False,
'message': 'ID сборки указан неверно'
}
return jsonify(response)
assembly = database.db.session.get(database.Assembly, assembly_id)
if not assembly:
response = {
'ok': False,
'message': 'Неудалось найти указанную сборку'
}
return jsonify(response)
if assembly.user_id != user_id:
response = {
'ok': False,
'message': 'Вы не можете закрыть сборку чужого пользователя'
}
return jsonify(response)
order_id = assembly.order_id
return sipro.api.orders.ship_order(order_id)
@assembly_blueprint.post('/updateState')
def update_assembly_state():
try:
args = request.json
state = args.get('state')
assembly_id = args.get('assemblyId')
rows_to_update = [{
'id': assembly_id,
'state': state
}]
database.db.session.bulk_update_mappings(database.Assembly, rows_to_update)
database.db.session.commit()
return jsonify(ok=True)
except Exception as e:
print('Error while updating')
return jsonify(ok=False)
@assembly_blueprint.get('/needCrpt')
def need_crpt():
order_product_id = request.args.get('orderProductId')
return sipro.api.orders.need_crpt(order_product_id)
@assembly_blueprint.post('/attachCrpt')
def attach_crpt():
order_product_id = request.json.get('orderProductId')
crpt = request.json.get('crpt')
return sipro.api.orders.attach_crpt(order_product_id, crpt)