302 lines
11 KiB
Python
302 lines
11 KiB
Python
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('ok'):
|
||
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)
|