Exemplo n.º 1
0
    def test_keep_document_instance_on_batch_render(self):
        batch = self.create_batch(DocumentBatchTypeEnum.DBT_TEST_TYPE, self.user)
        new_data = {
            'short_name': u'Тест нейм'
        }
        new_batch_data = {
            'data': new_data,
            'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
            'metadata': {}
        }

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 1)
        doc = BatchDocumentDbObject.query.scalar()
        del result['result']['creation_date']
        self.assertEqual(result, {
            'result': {
                'status': u'new',
                'all_docs': [{u'caption': u'Тестовый документ 1', u'document_type': u'test_doc_1', u'file_link': None, u'document_id': doc.id}],
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'Тест нейм'},
                'data': {
                    'short_name': u'Тест нейм'
                },
                'id': batch.id,
                'metadata': {},
                'status_data': {'finalisation_count': u'0'}
            }
        })

        new_data['short_name'] = u'создай второй документ'

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)

        doc_ids = set()
        for d in BatchDocumentDbObject.query.filter_by():
            doc_ids.add(d.id)

        result = self.test_client.post('/batch/finalise/', data={'batch_id': batch.id})
        self.assertEqual(result.status_code, 200)
        self.assertEqual(json.loads(result.data), {'result': True})

        self.assertEqual(BatchDocumentDbObject.query.count(), 2)
        new_doc_ids = set()
        for d in BatchDocumentDbObject.query.filter_by():
            new_doc_ids.add(d.id)

        self.assertEqual(doc_ids, new_doc_ids)
Exemplo n.º 2
0
def schedule_notification_email(batch_id):
    batch = DocumentBatchDbObject.query.filter_by(
        id=batch_id, deleted=False, finalisation_count=0).scalar()
    if not batch or batch.status not in (BatchStatusEnum.BS_NEW,
                                         BatchStatusEnum.BS_EDITED):
        return

    mail_type = 'please_finalise'
    if mail_type in (batch.sent_mails or []):
        return False

    user = batch._owner
    if not user or not user.email:
        return

    manager = BatchManager.init(batch)
    timezone_name = manager.get_batch_timezone(batch_id) or "Europe/Moscow"

    desired_time = current_app.config['NOT_PAID_BATCH_NOTIFY_DESIRED_TIME']
    timeout_td = timedelta(
        seconds=current_app.config['NOT_PAID_BATCH_NOTIFY_TIMEOUT_SECONDS'])
    dt = calc_fixed_time_not_earlier(datetime.utcnow(), desired_time,
                                     timeout_td, timezone_name)

    CeleryScheduler.post(
        "fw.async_tasks.not_paid_check_send.not_finalised_check_and_send",
        task_id="not_finalised_check_and_send%s" % str(batch_id),
        force_replace_task=True,
        kwargs={
            'batch_id':
            str(batch_id),
            'last_change_dt_str':
            batch.last_change_dt.strftime("%Y-%m-%dT%H:%M:%S")
        },
        eta=dt)
Exemplo n.º 3
0
    def run(self):
        self.logger.info(u"Перегенерация пакета документов")
        self.logger.info(u'=' * 50)

        batch_id = get_single(u'batch id: ')
        try:
            ObjectId(batch_id)
        except Exception:
            self.logger.error(u"Invalid batch id")
            return False

        batch = DocumentBatchDbObject.query.filter_by(id=batch_id).scalar()
        if not batch:
            self.logger.error(u"Batch not found")
            return False

        if batch.status == BatchStatusEnum.BS_FINALISED:

            batch.status = BatchStatusEnum.BS_BEING_FINALISED
            sqldb.session.commit()
            async_result = rendering.render_batch.delay(batch_id)

            if not async_result.ready():
                batch.current_task_id = async_result.id
                sqldb.session.commit()

            return True
        elif batch.status == BatchStatusEnum.BS_EDITED:
            manager = BatchManager.init(batch)
            manager.finalize_batch(self.config, self.logger, batch)
            return True
        self.logger.error(u"Invalid current batch status")
        return False
Exemplo n.º 4
0
def render_document_preview(document_object_id):
    document_object_id = document_object_id
    config = celery.conf.get('config')
    request = current_task.request
    sys.path.append(
        os.path.normpath(os.path.abspath(os.path.dirname(__name__))))

    logger = celery.log.get_default_logger()

    with celery.conf['flask_app']().app_context():
        db_doc = BatchDocumentDbObject.query.filter_by(
            id=document_object_id).scalar()
        if not db_doc or db_doc.status not in (UserDocumentStatus.DS_NEW,
                                               UserDocumentStatus.DS_RENDERING_FAILED,
                                               UserDocumentStatus.DS_RENDERING) \
           or db_doc._celery_task_id not in (None, request.id):
            return False

        from fw.documents.batch_manager import BatchManager

        batch_manager = BatchManager.init(db_doc.batch)
        doc_caption = batch_manager.get_batch_caption(db_doc.batch)
        return render_single_document(db_doc, doc_caption,
                                      'preview_watermark.png', config, logger,
                                      request.id)
Exemplo n.º 5
0
def schedule_notification_email(batch_id):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id, deleted=False, finalisation_count=0).scalar()
    if not batch or batch.status not in (BatchStatusEnum.BS_NEW, BatchStatusEnum.BS_EDITED):
        return

    mail_type = 'please_finalise'
    if mail_type in (batch.sent_mails or []):
        return False

    user = batch._owner
    if not user or not user.email:
        return

    manager = BatchManager.init(batch)
    timezone_name = manager.get_batch_timezone(batch_id) or "Europe/Moscow"

    desired_time = current_app.config['NOT_PAID_BATCH_NOTIFY_DESIRED_TIME']
    timeout_td = timedelta(seconds=current_app.config['NOT_PAID_BATCH_NOTIFY_TIMEOUT_SECONDS'])
    dt = calc_fixed_time_not_earlier(datetime.utcnow(), desired_time, timeout_td, timezone_name)

    CeleryScheduler.post(
        "fw.async_tasks.not_paid_check_send.not_finalised_check_and_send",
        task_id="not_finalised_check_and_send%s" % str(batch_id),
        force_replace_task=True,
        kwargs={
            'batch_id': str(batch_id),
            'last_change_dt_str': batch.last_change_dt.strftime("%Y-%m-%dT%H:%M:%S")
        },
        eta=dt
    )
Exemplo n.º 6
0
def render_batch_documents(batch_id=None, document_type=None):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id, _owner=current_user, deleted=False).first()
    if not batch:
        raise errors.BatchNotFound()
    batch_manager = BatchManager.init(batch)

    document_types = json.loads(document_type)
    if not isinstance(document_types, list) and not isinstance(document_types, tuple):
        raise errors.InvalidParameterValue('document_type')

    doc_type_set = set()
    for doc_type in document_types:
        if not batch_manager.check_doc_type_support(batch.batch_type, doc_type):
            raise errors.InvalidParameterValue('document_type')
        doc_type_set.add(doc_type)

    action_descriptor = {
        'plugin': 'doc_builder',
        'action': 'render_group'
    }

    event_data = {
        'doc_types': list(doc_type_set),
        'batch_id': batch.id
    }

    BatchManager.perform_action(action_descriptor, batch, event_data, current_app.logger, current_app.config)
    return {"result": True}
Exemplo n.º 7
0
def render_batch_documents(batch_id=None, document_type=None):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id,
                                                  _owner=current_user,
                                                  deleted=False).first()
    if not batch:
        raise errors.BatchNotFound()
    batch_manager = BatchManager.init(batch)

    document_types = json.loads(document_type)
    if not isinstance(document_types, list) and not isinstance(
            document_types, tuple):
        raise errors.InvalidParameterValue('document_type')

    doc_type_set = set()
    for doc_type in document_types:
        if not batch_manager.check_doc_type_support(batch.batch_type,
                                                    doc_type):
            raise errors.InvalidParameterValue('document_type')
        doc_type_set.add(doc_type)

    action_descriptor = {'plugin': 'doc_builder', 'action': 'render_group'}

    event_data = {'doc_types': list(doc_type_set), 'batch_id': batch.id}

    BatchManager.perform_action(action_descriptor, batch, event_data,
                                current_app.logger, current_app.config)
    return {"result": True}
Exemplo n.º 8
0
def unfinalize_batch(batch_id=None, force=False):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id, _owner=current_user, deleted=False).scalar()
    if not batch:
        raise errors.BatchNotFound()
    if batch.status not in (BatchStatusEnum.BS_FINALISED,):
        raise errors.DocumentBatchDefinalizationError()

    if batch.current_task_id:
        from celery import app as celery
        current_app.logger.debug(u"There are task id: %s" % unicode(batch.current_task_id))
        celery.default_app.control.revoke(batch.current_task_id)
        remove_task_id_run_file(current_app.config, batch.current_task_id)
        batch.current_task_id = None
        batch.batch_rendering_start = None
        sqldb.session.commit()

    batch_manager = BatchManager.init(batch)
    try:
        if not batch_manager.definalize_batch(current_app.config, current_app.logger, batch, force):
            raise errors.DocumentBatchDefinalizationError()
    except Exception:
        batch.status = BatchStatusEnum.BS_FINALISED
        sqldb.session.commit()
        raise errors.DocumentBatchDefinalizationError()

    return {"result": True}
Exemplo n.º 9
0
def unfinalize_batch(batch_id=None, force=False):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id,
                                                  _owner=current_user,
                                                  deleted=False).scalar()
    if not batch:
        raise errors.BatchNotFound()
    if batch.status not in (BatchStatusEnum.BS_FINALISED, ):
        raise errors.DocumentBatchDefinalizationError()

    if batch.current_task_id:
        from celery import app as celery
        current_app.logger.debug(u"There are task id: %s" %
                                 unicode(batch.current_task_id))
        celery.default_app.control.revoke(batch.current_task_id)
        remove_task_id_run_file(current_app.config, batch.current_task_id)
        batch.current_task_id = None
        batch.batch_rendering_start = None
        sqldb.session.commit()

    batch_manager = BatchManager.init(batch)
    try:
        if not batch_manager.definalize_batch(
                current_app.config, current_app.logger, batch, force):
            raise errors.DocumentBatchDefinalizationError()
    except Exception:
        batch.status = BatchStatusEnum.BS_FINALISED
        sqldb.session.commit()
        raise errors.DocumentBatchDefinalizationError()

    return {"result": True}
Exemplo n.º 10
0
    def run(self):
        self.logger.info(u"Перегенерация пакета документов")
        self.logger.info(u'=' * 50)

        batch_id = get_single(u'batch id: ')
        try:
            ObjectId(batch_id)
        except Exception:
            self.logger.error(u"Invalid batch id")
            return False

        batch = DocumentBatchDbObject.query.filter_by(id=batch_id).scalar()
        if not batch:
            self.logger.error(u"Batch not found")
            return False

        if batch.status == BatchStatusEnum.BS_FINALISED:

            batch.status = BatchStatusEnum.BS_BEING_FINALISED
            sqldb.session.commit()
            async_result = rendering.render_batch.delay(batch_id)

            if not async_result.ready():
                batch.current_task_id = async_result.id
                sqldb.session.commit()

            return True
        elif batch.status == BatchStatusEnum.BS_EDITED:
            manager = BatchManager.init(batch)
            manager.finalize_batch(self.config, self.logger, batch)
            return True
        self.logger.error(u"Invalid current batch status")
        return False
Exemplo n.º 11
0
def get_render_batch_documents_state(batch_id=None, document_types=None):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id,
                                                  _owner=current_user,
                                                  deleted=False).first()
    if not batch:
        raise errors.BatchNotFound()

    batch_manager = BatchManager.init(batch)
    try:
        document_types = json.loads(document_types)
        if not isinstance(document_types, list) and not isinstance(
                document_types, tuple):
            raise Exception()
    except Exception:
        raise errors.InvalidParameterValue('document_type')

    doc_type_set = set()
    for doc_type in document_types:
        if not batch_manager.check_doc_type_support(batch.batch_type,
                                                    doc_type):
            raise errors.InvalidParameterValue('document_type')
        doc_type_set.add(doc_type)

    result = []

    for doc_type in doc_type_set:
        doc_obj = BatchDocumentDbObject.query.filter_by(
            batch_id=batch_id, document_type=doc_type).first()
        if not doc_obj:
            result.append({
                'state': UserDocumentStatus.DS_NEW,
                'document_type': doc_type
            })
            continue

        doc_info = {'state': doc_obj.status, 'document_type': doc_type}

        if doc_obj.status == UserDocumentStatus.DS_RENDERED:
            if doc_obj.file:
                doc_info['links'] = {
                    'pdf': FileStorage.get_url(doc_obj.file,
                                               current_app.config),
                    'jpeg': []
                }
                result.append(doc_info)
            else:
                current_app.logger.debug(
                    u"Not found rendered documents for rendered document %s. "
                    u"Returning as rendering_failed" % doc_type)
                result.append({
                    'state': UserDocumentStatus.DS_RENDERING_FAILED,
                    'document_type': doc_type
                })
        else:
            result.append(doc_info)

    return result
Exemplo n.º 12
0
    def test_transit_on_docs_group_generated(self):
        batch = self.create_batch(DocumentBatchTypeEnum.DBT_TEST_TYPE, self.user)
        new_data = {
            'short_name': u'создай второй документ',
            'text_field': u'текстфилд'
        }
        new_batch_data = {
            'data': new_data,
            'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
            'metadata': {}
        }

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)

        result = self.test_client.post('/batch/render_document/', data={
            'batch_id': batch.id,
            'document_type': json.dumps([DocumentTypeEnum.DT_TEST_DOC_1, DocumentTypeEnum.DT_TEST_DOC_2])
        })
        self.assertEqual(result.status_code, 200)
        self.assertEqual(len(self.events), 6)
        sqldb.session.commit()
        batch_db = DocumentBatchDbObject.query.filter_by(id=batch.id).scalar()
        doc1 = BatchDocumentDbObject.query.filter_by(batch_id=batch.id).order_by(BatchDocumentDbObject.creation_date.asc()).first()
        doc2 = BatchDocumentDbObject.query.filter(BatchDocumentDbObject.batch_id==batch.id, BatchDocumentDbObject.id != doc1.id).first()
        self.assertEqual(batch_db.status, 'finalised')
        self.assertEqual(self.events[0]['batch'].id, batch_db.id)
        self.assertEqual(self.events[1]['batch'].id, batch_db.id)
        self.assertEqual(self.events[2]['batch'].id, batch_db.id)
        del self.events[0]['batch']
        del self.events[1]['batch']
        del self.events[2]['batch']
        del self.events[3]['batch']
        del self.events[4]['batch']
        del self.events[5]['batch']
        self.assertEqual(self.events[0], {'event': 'batch_manager.on_field_changed',
                                          'event_data': {'field_name': 'short_name',
                                          'new_value': u'создай второй документ',
                                          'old_value': None}})
        self.assertEqual(self.events[1], {'event': 'batch_manager.on_field_changed',
                                          'event_data': {'field_name': 'text_field',
                                          'new_value': u'текстфилд',
                                          'old_value': None}})
        self.assertEqual(self.events[2], {'event': 'batch_manager.on_fieldset_changed',
                                          'event_data': {'fields': [{'field_name': 'short_name',
                                          'new_value': u'создай второй документ',
                                          'old_value': None}, {'field_name': 'text_field',
                                          'new_value': u'текстфилд',
                                          'old_value': None}]}})
        self.assertEqual(self.events[3], {'event': 'doc_render_success', 'event_data': {'doc_id': doc1.id}})
        self.assertEqual(self.events[4], {'event': 'doc_render_success', 'event_data': {'doc_id': doc2.id}})
        self.assertEqual(self.events[5], {'event': 'doc_group_render_success',
                                          'event_data': {'batch_id': batch_db.id,
                                                         'doc_types': ['test_doc_1', 'test_doc_2']}})
Exemplo n.º 13
0
def get_user_api_structure(auth_user):
    result = {
        'temporal': auth_user.temporal or False,

        'id': unicode(auth_user.uuid),
        'email': auth_user.email or u"",
        'email_confirmed': auth_user.email_confirmed,
        'mobile': auth_user.mobile or u"",
        'mobile_confirmed': auth_user.mobile_confirmed,

        'password_set': bool(auth_user.password and auth_user.password != u'!notset!'),    # bool

        'registration_date': auth_user.signup_date.strftime("%Y-%m-%dT%H:%M:%S"),    # — дата регистрации
        'facebook': None,                   # — идентификатор пользователя в facebook (если есть)
        'vk': None,                         # — идентификатор пользователя в VK (если есть)

        'person': {                         # — физическое лицо
            'name': auth_user.name,
            'surname': auth_user.surname,
            'patronymic': auth_user.patronymic
        },
        'role': ['user']                    # — список ролей пользователя, в виде массива,
                                            # пример: ["user", "support", "moderator", "admin"]
    }

    from fw.documents.batch_manager import BatchManager
    batch = BatchManager.get_last_modified_batch(auth_user.id)

    if batch:
        batch_manager = BatchManager.init(batch)

        batch_caption = batch_manager.get_last_modified_batch_caption(batch)
        batch_type = batch.batch_type
        batch_stage = batch_manager.get_stage(batch)

        last_service_data = {
            'id': batch.id,
            'caption': batch_caption,
            'type': batch_type,
            'stage': batch_stage
        }

        result['last_service'] = last_service_data

    from services.pay.subs_manager import SubscriptionManager

    user_subs = SubscriptionManager.get_user_active_subscription(auth_user.id)

    result['subscription'] = {
        'type': user_subs.type,
        'last_day': user_subs.end_dt.strftime("%Y-%m-%dT%H:%M:%S")
    } if user_subs else None

    return result
Exemplo n.º 14
0
def batch_create(batch_type=None):
    try:
        DocRequisitiesStorage.get_batch_descriptor(batch_type)
    except Exception:
        raise errors.InvalidParameterValue('batch_type')

    batch_manager = BatchManager.init(batch_type=batch_type)
    new_batch = batch_manager.create_batch(current_user)
    sqldb.session.add(new_batch)
    sqldb.session.commit()
    doc_batch = DocumentBatch.db_obj_to_field(new_batch)
    return {'result': doc_batch.get_api_structure()}
Exemplo n.º 15
0
def batch_create(batch_type=None):
    try:
        DocRequisitiesStorage.get_batch_descriptor(batch_type)
    except Exception:
        raise errors.InvalidParameterValue('batch_type')

    batch_manager = BatchManager.init(batch_type=batch_type)
    new_batch = batch_manager.create_batch(current_user)
    sqldb.session.add(new_batch)
    sqldb.session.commit()
    doc_batch = DocumentBatch.db_obj_to_field(new_batch)
    return {'result': doc_batch.get_api_structure()}
Exemplo n.º 16
0
def get_render_batch_documents_state(batch_id=None, document_types=None):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id, _owner=current_user, deleted=False).first()
    if not batch:
        raise errors.BatchNotFound()

    batch_manager = BatchManager.init(batch)
    try:
        document_types = json.loads(document_types)
        if not isinstance(document_types, list) and not isinstance(document_types, tuple):
            raise Exception()
    except Exception:
        raise errors.InvalidParameterValue('document_type')

    doc_type_set = set()
    for doc_type in document_types:
        if not batch_manager.check_doc_type_support(batch.batch_type, doc_type):
            raise errors.InvalidParameterValue('document_type')
        doc_type_set.add(doc_type)

    result = []

    for doc_type in doc_type_set:
        doc_obj = BatchDocumentDbObject.query.filter_by(batch_id=batch_id, document_type=doc_type).first()
        if not doc_obj:
            result.append({
                'state': UserDocumentStatus.DS_NEW,
                'document_type': doc_type
            })
            continue

        doc_info = {
            'state': doc_obj.status,
            'document_type': doc_type
        }

        if doc_obj.status == UserDocumentStatus.DS_RENDERED:
            if doc_obj.file:
                doc_info['links'] = {
                    'pdf': FileStorage.get_url(doc_obj.file, current_app.config),
                    'jpeg': []
                }
                result.append(doc_info)
            else:
                current_app.logger.debug(u"Not found rendered documents for rendered document %s. "
                                         u"Returning as rendering_failed" % doc_type)
                result.append({
                    'state': UserDocumentStatus.DS_RENDERING_FAILED,
                    'document_type': doc_type
                })
        else:
            result.append(doc_info)

    return result
Exemplo n.º 17
0
 def create_batch(self,
                  batch_type,
                  owner,
                  do_not_save_to_db=False,
                  status=None):
     manager = BatchManager.init(batch_type=batch_type)
     batch = manager.create_batch(owner)
     if status is not None:
         batch.status = status
     if not do_not_save_to_db:
         sqldb.session.add(batch)
         sqldb.session.commit()
     return batch
Exemplo n.º 18
0
def notarius_list(batch_id=None):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id, _owner=current_user, deleted=False).scalar()
    if not batch:
        raise errors.InvalidParameterValue('batch_id')

    batch_manager = BatchManager.init(batch)
    assert batch_manager

    region = batch_manager.get_batch_region(batch_id)

    if not region:
        return {'result': []}
    query = NotariusObject.query.filter_by(region=region)
    result = [item.get_api_structure() for item in query]
    return {'result': result}
Exemplo n.º 19
0
def batch_update(batch_id=None, batch=None):
    with current_app.model_cache_context:
        current_batch_db_object = DocumentBatchDbObject.query.filter_by(
            id=batch_id, _owner=current_user, deleted=False).first()
        if not current_batch_db_object:
            raise errors.BatchNotFound()

        if current_batch_db_object.status == BatchStatusEnum.BS_BEING_FINALISED:
            current_app.logger.debug(
                u"Updating batch during finalization - cancelling finalization"
            )

            try:
                BatchManager.cancel_batch_finalization(current_batch_db_object,
                                                       current_app.config,
                                                       current_app.logger)
            except Exception:
                current_app.logger.exception(
                    u"Failed to cancel batch finalisation")
                DocumentBatchDbObject.query.filter_by(
                    id=batch_id,
                    status=BatchStatusEnum.BS_BEING_FINALISED).update(
                        {'status': BatchStatusEnum.BS_EDITED})
                sqldb.session.commit()
                raise errors.DocumentBatchUpdateError()

        manager = BatchManager.init(current_batch_db_object)

        batch_type = current_batch_db_object.batch_type
        batch['batch_type'] = batch_type
        if 'metadata' in batch:
            batch['_metadata'] = batch['metadata']

        new_batch = DocumentBatch.parse_raw_value(batch, api_data=True)

        new_batch_api_data = manager.update_batch(batch_id, new_batch,
                                                  current_user.id,
                                                  current_app.config,
                                                  current_app.logger)

        DocumentBatchDbObject.query.filter_by(id=batch_id).update(
            {'last_change_dt': datetime.utcnow()})
        sqldb.session.commit()
        if batch_type == DocumentBatchTypeEnum.DBT_NEW_LLC:
            schedule_notification_email(batch_id)
        return new_batch_api_data
Exemplo n.º 20
0
def notarius_list(batch_id=None):
    batch = DocumentBatchDbObject.query.filter_by(id=batch_id,
                                                  _owner=current_user,
                                                  deleted=False).scalar()
    if not batch:
        raise errors.InvalidParameterValue('batch_id')

    batch_manager = BatchManager.init(batch)
    assert batch_manager

    region = batch_manager.get_batch_region(batch_id)

    if not region:
        return {'result': []}
    query = NotariusObject.query.filter_by(region=region)
    result = [item.get_api_structure() for item in query]
    return {'result': result}
Exemplo n.º 21
0
def render_document_preview(document_object_id):
    document_object_id = document_object_id
    config = celery.conf.get('config')
    request = current_task.request
    sys.path.append(os.path.normpath(os.path.abspath(os.path.dirname(__name__))))

    logger = celery.log.get_default_logger()

    with celery.conf['flask_app']().app_context():
        db_doc = BatchDocumentDbObject.query.filter_by(id=document_object_id).scalar()
        if not db_doc or db_doc.status not in (UserDocumentStatus.DS_NEW,
                                               UserDocumentStatus.DS_RENDERING_FAILED,
                                               UserDocumentStatus.DS_RENDERING) \
           or db_doc._celery_task_id not in (None, request.id):
            return False

        from fw.documents.batch_manager import BatchManager

        batch_manager = BatchManager.init(db_doc.batch)
        doc_caption = batch_manager.get_batch_caption(db_doc.batch)
        return render_single_document(db_doc, doc_caption, 'preview_watermark.png', config, logger, request.id)
Exemplo n.º 22
0
def _finalize_batch(batch):
    batch_status = batch.status
    if batch_status == BatchStatusEnum.BS_FINALISED:
        return {"result": True}

    if batch_status not in (BatchStatusEnum.BS_NEW, BatchStatusEnum.BS_EDITED):
        raise errors.DocumentBatchFinalizationError()

    docs = batch._documents
    if not docs:
        return {"result": False}

    batch_manager = BatchManager.init(batch)

    try:
        if not batch_manager.finalize_batch(current_app.config, current_app.logger, batch):
            raise errors.DocumentBatchFinalizationError()
    except Exception:
        current_app.logger.exception(u"Finalisation error")
        return {"result": False}

    return {"result": True}
Exemplo n.º 23
0
def _finalize_batch(batch):
    batch_status = batch.status
    if batch_status == BatchStatusEnum.BS_FINALISED:
        return {"result": True}

    if batch_status not in (BatchStatusEnum.BS_NEW, BatchStatusEnum.BS_EDITED):
        raise errors.DocumentBatchFinalizationError()

    docs = batch._documents
    if not docs:
        return {"result": False}

    batch_manager = BatchManager.init(batch)

    try:
        if not batch_manager.finalize_batch(current_app.config,
                                            current_app.logger, batch):
            raise errors.DocumentBatchFinalizationError()
    except Exception:
        current_app.logger.exception(u"Finalisation error")
        return {"result": False}

    return {"result": True}
Exemplo n.º 24
0
def batch_update(batch_id=None, batch=None):
    with current_app.model_cache_context:
        current_batch_db_object = DocumentBatchDbObject.query.filter_by(id=batch_id, _owner=current_user,
                                                                        deleted=False).first()
        if not current_batch_db_object:
            raise errors.BatchNotFound()

        if current_batch_db_object.status == BatchStatusEnum.BS_BEING_FINALISED:
            current_app.logger.debug(u"Updating batch during finalization - cancelling finalization")

            try:
                BatchManager.cancel_batch_finalization(current_batch_db_object,
                                                       current_app.config, current_app.logger)
            except Exception:
                current_app.logger.exception(u"Failed to cancel batch finalisation")
                DocumentBatchDbObject.query.filter_by(id=batch_id, status=BatchStatusEnum.BS_BEING_FINALISED).update(
                    {'status': BatchStatusEnum.BS_EDITED})
                sqldb.session.commit()
                raise errors.DocumentBatchUpdateError()

        manager = BatchManager.init(current_batch_db_object)

        batch_type = current_batch_db_object.batch_type
        batch['batch_type'] = batch_type
        if 'metadata' in batch:
            batch['_metadata'] = batch['metadata']

        new_batch = DocumentBatch.parse_raw_value(batch, api_data=True)

        new_batch_api_data = manager.update_batch(batch_id, new_batch, current_user.id,
                                                  current_app.config, current_app.logger)

        DocumentBatchDbObject.query.filter_by(id=batch_id).update({'last_change_dt': datetime.utcnow()})
        sqldb.session.commit()
        if batch_type == DocumentBatchTypeEnum.DBT_NEW_LLC:
            schedule_notification_email(batch_id)
        return new_batch_api_data
Exemplo n.º 25
0
def render_batch_raw(batch_db_object_id, render_only_failed_docs=False):
    request = current_task.request
    config = celery.conf.get('config')
    eager = celery.conf['CELERY_ALWAYS_EAGER']
    app = celery.conf['flask_app']()
    logger = app.logger

    from fw.documents.batch_manager import BatchManager
    with app.app_context():
        batch_db_object = DocumentBatchDbObject.query.filter_by(
            id=batch_db_object_id).first()
        if not batch_db_object:
            logger.error(
                u"Failed to find batch with id %s in collection %s in db %s" %
                (batch_db_object_id, DocumentBatchDbObject.COLLECTION_NAME,
                 config['db_name']))
            return False

        batch_db_object.current_task_id = request.id
        batch_db_object.batch_rendering_start = datetime.utcnow()
        sqldb.session.commit()

        task_holder = BatchTaskFileIdHolder(
            request.id, config,
            batch_db_object) if not eager else FakeTaskHolder()
        with task_holder as task_file:
            logger.info(u"Generating documents for batch %s" %
                        batch_db_object_id)

            try:
                batch_type = batch_db_object.batch_type

                batch_manager = BatchManager.init(batch_db_object)
                batch_descriptor = DocRequisitiesStorage.get_batch_descriptor(
                    batch_type)
                doc_types_allowed_to_deferred_rendering = batch_descriptor.get(
                    'deferred_render_docs', [])

                watermark = None if batch_db_object.paid else "notpaid_watermark.png"

                has_errors = False
                failed_doc_types = set()
                for doc in batch_db_object._documents:
                    # if not task_file.exists():
                    #     logger.warning(u"Task with id %s has been revoked" % request.id)
                    #     batch_db_object.status = BatchStatusEnum.BS_EDITED
                    #     sqldb.session.commit()
                    #     return True

                    doc_type = doc.document_type
                    if render_only_failed_docs and doc.status != UserDocumentStatus.DS_RENDERING_FAILED:
                        continue

                    render_doc_file = batch_type == DocumentBatchTypeEnum.DBT_NEW_LLC and batch_db_object.paid
                    if not render_single_document(
                            doc, batch_manager.get_title(doc_type), watermark,
                            config, logger, request.id, render_doc_file):
                        has_errors = True
                        if doc_type not in doc_types_allowed_to_deferred_rendering:
                            if not render_only_failed_docs:
                                batch_db_object.status = BatchStatusEnum.BS_EDITED
                                batch_db_object.error_info = {
                                    "error_ext": [{
                                        "field":
                                        "",
                                        "error_code":
                                        0,
                                        "message":
                                        u"Failed to render document %s" %
                                        doc_type
                                    }]
                                }
                            sqldb.session.commit()

                            return False
                    failed_doc_types.add(doc_type)

                if not render_only_failed_docs:
                    batch_db_object.finalisation_count += 1
                    batch_db_object.status = BatchStatusEnum.BS_FINALISED
                    if batch_db_object.batch_rendering_start:
                        try:
                            dt = datetime.utcnow(
                            ) - batch_db_object.batch_rendering_start
                            fs = dt.total_seconds(
                            ) + dt.microseconds / 1000000.
                            zabbix_sender.send('celery_max_time', fs)
                        except Exception:
                            pass
                    batch_db_object.finalisation_date = datetime.utcnow()
                    CeleryScheduler.remove("not_finalised_check_and_send%s" %
                                           str(batch_db_object_id))
                    try:
                        if batch_db_object.batch_rendering_start:
                            dt = datetime.utcnow(
                            ) - batch_db_object.batch_rendering_start
                            seconds = dt.total_seconds()
                            zabbix_sender.send("celery_max_time", seconds)
                    except Exception:
                        pass
                sqldb.session.commit()

                if has_errors:
                    if len(failed_doc_types) == 1 and failed_doc_types.pop(
                    ) in ('reg_fee_invoice', 'ip_reg_fee_invoice'):
                        from services.ifns import ifns_manager
                        if ifns_manager.if_gp_pay_working():
                            logger.error(
                                u"Invalid fee invoice render attempt (service.nalog.ru is working). Cancelling!"
                            )
                            batch_db_object.status = BatchStatusEnum.BS_EDITED
                            sqldb.session.commit()
                            return False
                    async_result = render_batch.apply_async(
                        (batch_db_object_id, ),
                        {'render_only_failed_docs': True},
                        countdown=300)
                    if not async_result.ready():
                        task_file.unbind = True
                        new_task_id = unicode(async_result.id)
                        batch_db_object.current_task_id = new_task_id
                        batch_db_object.batch_rendering_start = datetime.utcnow(
                        )
                        logger.debug(u"Task id: %s" % new_task_id)
                        sqldb.session.commit()
            except Exception:
                logger.exception(u"Failed to render batch %s" %
                                 batch_db_object_id)
                if not render_only_failed_docs:
                    batch_db_object.status = BatchStatusEnum.BS_EDITED
                    sqldb.session.commit()

        if render_only_failed_docs and batch_db_object.paid:
            user = batch_db_object._owner
            addr_to = user.email or ""
            if not addr_to:
                logger.warning(u"Failed to send email: user %s has no email" %
                               unicode(user.id))
            else:
                documents = BatchManager.get_shared_links_to_rendered_docs(
                    batch_db_object, config, logger)

                if batch_db_object.batch_type == DocumentBatchTypeEnum.DBT_NEW_LLC:
                    go_further_url = u"%s://%s/ooo/?id=%s" % (
                        config['WEB_SCHEMA'], config['DOMAIN'],
                        batch_db_object_id)
                    go_further_url = utm_args(go_further_url,
                                              'deferred_docs_ready',
                                              user.id) + u"#page=documents"
                    go_further_url = UserManager.make_auth_url(
                        go_further_url, user).get_url(config)

                    short_name = batch_db_object.data.get('short_name', "")
                    send_email.send_email.delay(addr_to,
                                                "deferred_docs_ready",
                                                go_further_url=go_further_url,
                                                short_name=short_name,
                                                schema=config['WEB_SCHEMA'],
                                                domain=config['DOMAIN'],
                                                docs=documents,
                                                user_id=str(user.id))
                elif batch_db_object.batch_type == DocumentBatchTypeEnum.DBT_NEW_IP:
                    go_further_url = u"%s://%s/ip/?id=%s" % (
                        config['WEB_SCHEMA'], config['DOMAIN'],
                        batch_db_object_id)
                    go_further_url = utm_args(go_further_url,
                                              'deferred_ip_docs_ready',
                                              user.id) + u"#page=documents"
                    go_further_url = UserManager.make_auth_url(
                        go_further_url, user).get_url(config)
                    short_name = ""
                    try:
                        pp_data = batch_db_object.data.get('person')
                        if pp_data and '_id' in pp_data:
                            person_db = PrivatePersonDbObject.query.filter_by(
                                id=pp_data['_id']).scalar()
                            if person_db:
                                person = PrivatePerson.db_obj_to_field(
                                    person_db)
                                short_name = person.get_short_name()
                    except Exception:
                        logger.exception(u"Failed to get batch caption")

                    send_email.send_email.delay(addr_to,
                                                "deferred_ip_docs_ready",
                                                go_further_url=go_further_url,
                                                short_name=short_name,
                                                schema=config['WEB_SCHEMA'],
                                                domain=config['DOMAIN'],
                                                docs=documents,
                                                user_id=str(user.id))

    return True
Exemplo n.º 26
0
def act(action, batch_db, event_data, plugin_config, logger, config):
    assert batch_db
    descriptors = filter(lambda x: x['name'] == action, get_actions())
    action_descriptor = descriptors[0] if descriptors else None
    if not action_descriptor:
        raise ValueError(u'Invalid action: %s for %s plugin' %
                         (action, PLUGIN_NAME))
    args = action_descriptor['args']
    source_data = copy(event_data)
    data = transform_with_schema(source_data, {"fields": args})

    batch_manager = BatchManager.init(batch_db)

    if action == 'render_group':
        doc_id_list = []
        batch_id = data['batch_id'].db_value()
        doc_types = event_data[
            'doc_types'] if 'doc_types' in event_data else plugin_config.get(
                'doc_types', [])
        assert doc_types

        try:
            all_ready = True
            for doc_type in doc_types:
                doc = BatchDocumentDbObject.query.filter_by(
                    document_type=doc_type, batch_id=batch_id).first()
                if doc:
                    doc.data = {}
                    doc.status = UserDocumentStatus.DS_RENDERING
                    doc.tried_to_render = True
                    if doc.file:
                        file_obj = doc.file
                        doc.file = None
                        FileStorage.remove_file(file_obj.id,
                                                current_app.config)
                    sqldb.session.commit()

                else:
                    if not batch_manager.is_document_required(
                            batch_db, doc_type):
                        logger.debug(
                            u"Document %s is not required by its condition. Skipping"
                            % doc_type)
                        continue

                    new_doc = BatchDocumentDbObject(
                        _owner=current_user,
                        document_type=doc_type,
                        batch_id=batch_id,
                        data={},
                        status=UserDocumentStatus.DS_RENDERING,
                        caption=batch_manager.get_title(doc_type),
                        tried_to_render=True)
                    sqldb.session.add(new_doc)
                    sqldb.session.commit()
                    doc = new_doc

                async_result = rendering.render_document_plugin.apply_async(
                    (batch_id, {
                        'doc_id': doc.id
                    }), countdown=2)
                if not async_result.ready():
                    all_ready = False
                    BatchDocumentDbObject.query.filter_by(id=doc.id).update({
                        '_celery_task_id':
                        str(async_result.id),
                        '_celery_task_started':
                        datetime.utcnow()
                    })
                    sqldb.session.commit()

                doc_id_list.append(doc.id)

            check_task_info = DocGroupRenderTaskCheck(batch_id=batch_id,
                                                      doc_id_list=doc_id_list,
                                                      event_data=event_data)
            sqldb.session.add(check_task_info)
            sqldb.session.commit()
            if all_ready:
                rendering.batch_group_gen_check_task.delay()
        except Exception:
            zabbix_sender.send("celery_failures", 1)
            logger.exception(u"Failed to start rendering document group")
            raise
    elif action == 'render_doc':
        pass
    elif action == 'render_doc_by_id':
        pass
    elif action == 'cancel_doc_render':
        pass
    elif action == 'cancel_doc_render_by_id':
        pass
    else:
        raise Exception(u"Invalid action %s for plugin %s" %
                        (action, PLUGIN_NAME))

    # mail_type = data['mail_type'].db_value()
    # target_type = data['target_type'].db_value()
    # target_emails = []
    # if target_type == MailTargetEnum.MTA_BATCH_OWNER:
    #     email = batch_db._owner.email
    #     if email:
    #         target_emails.append(email)
    # elif target_type == MailTargetEnum.MTA_SPECIFIED:
    #     target_emails = data.get('target_email_list', [])
    # else:   #MailTargetEnum.MTA_EVENT_DATA_FIELD
    #     data_field = data.get('event_data_field', None)
    #     if data_field:
    #         email = event_data.get(data_field, None)
    #         if email:
    #             target_emails.append(email)
    #
    # if not target_emails:
    #     core_tasks.send.delay(batch_db.id, '%s:send_fail' % PLUGIN_NAME, event_data)
    #     return False
    #
    # composer = create_composer(mail_type, logger)
    # retry_count = data.get('retry_count')
    # silent = data.get('silent', False)
    # from fw.documents.fields.simple_doc_fields import DocField
    # try:
    #     if isinstance(target_emails, DocField):
    #         target_emails = target_emails.db_value()
    #     if isinstance(retry_count, DocField):
    #         retry_count = retry_count.db_value()
    #     if isinstance(silent, DocField):
    #         silent = silent.db_value()
    #     composer.send_email(target_emails, batch_id, event_data, retry_count, silent=silent)
    # except Exception:
    #     logger.exception(u"Failed to send email")
    #     return False
    return True
Exemplo n.º 27
0
def act(action, batch_db, event_data, plugin_config, logger, config):
    assert batch_db
    descriptors = filter(lambda x: x['name'] == action, get_actions())
    action_descriptor = descriptors[0] if descriptors else None
    if not action_descriptor:
        raise ValueError(u'Invalid action: %s for %s plugin' % (action, PLUGIN_NAME))
    args = action_descriptor['args']
    source_data = copy(event_data)
    data = transform_with_schema(source_data, {"fields": args})

    batch_manager = BatchManager.init(batch_db)

    if action == 'render_group':
        doc_id_list = []
        batch_id = data['batch_id'].db_value()
        doc_types = event_data['doc_types'] if 'doc_types' in event_data else plugin_config.get('doc_types', [])
        assert doc_types

        try:
            all_ready = True
            for doc_type in doc_types:
                doc = BatchDocumentDbObject.query.filter_by(document_type=doc_type, batch_id=batch_id).first()
                if doc:
                    doc.data = {}
                    doc.status = UserDocumentStatus.DS_RENDERING
                    doc.tried_to_render = True
                    if doc.file:
                        file_obj = doc.file
                        doc.file = None
                        FileStorage.remove_file(file_obj.id, current_app.config)
                    sqldb.session.commit()

                else:
                    if not batch_manager.is_document_required(batch_db, doc_type):
                        logger.debug(u"Document %s is not required by its condition. Skipping" % doc_type)
                        continue

                    new_doc = BatchDocumentDbObject(
                        _owner=current_user,
                        document_type=doc_type,
                        batch_id=batch_id,
                        data={},
                        status=UserDocumentStatus.DS_RENDERING,
                        caption=batch_manager.get_title(doc_type),
                        tried_to_render=True
                    )
                    sqldb.session.add(new_doc)
                    sqldb.session.commit()
                    doc = new_doc

                async_result = rendering.render_document_plugin.apply_async((batch_id, {'doc_id': doc.id}), countdown=2)
                if not async_result.ready():
                    all_ready = False
                    BatchDocumentDbObject.query.filter_by(id=doc.id).update({
                        '_celery_task_id': str(async_result.id),
                        '_celery_task_started': datetime.utcnow()
                    })
                    sqldb.session.commit()

                doc_id_list.append(doc.id)

            check_task_info = DocGroupRenderTaskCheck(
                batch_id=batch_id,
                doc_id_list=doc_id_list,
                event_data=event_data
            )
            sqldb.session.add(check_task_info)
            sqldb.session.commit()
            if all_ready:
                rendering.batch_group_gen_check_task.delay()
        except Exception:
            zabbix_sender.send("celery_failures", 1)
            logger.exception(u"Failed to start rendering document group")
            raise
    elif action == 'render_doc':
        pass
    elif action == 'render_doc_by_id':
        pass
    elif action == 'cancel_doc_render':
        pass
    elif action == 'cancel_doc_render_by_id':
        pass
    else:
        raise Exception(u"Invalid action %s for plugin %s" % (action, PLUGIN_NAME))

    # mail_type = data['mail_type'].db_value()
    # target_type = data['target_type'].db_value()
    # target_emails = []
    # if target_type == MailTargetEnum.MTA_BATCH_OWNER:
    #     email = batch_db._owner.email
    #     if email:
    #         target_emails.append(email)
    # elif target_type == MailTargetEnum.MTA_SPECIFIED:
    #     target_emails = data.get('target_email_list', [])
    # else:   #MailTargetEnum.MTA_EVENT_DATA_FIELD
    #     data_field = data.get('event_data_field', None)
    #     if data_field:
    #         email = event_data.get(data_field, None)
    #         if email:
    #             target_emails.append(email)
    #
    # if not target_emails:
    #     core_tasks.send.delay(batch_db.id, '%s:send_fail' % PLUGIN_NAME, event_data)
    #     return False
    #
    # composer = create_composer(mail_type, logger)
    # retry_count = data.get('retry_count')
    # silent = data.get('silent', False)
    # from fw.documents.fields.simple_doc_fields import DocField
    # try:
    #     if isinstance(target_emails, DocField):
    #         target_emails = target_emails.db_value()
    #     if isinstance(retry_count, DocField):
    #         retry_count = retry_count.db_value()
    #     if isinstance(silent, DocField):
    #         silent = silent.db_value()
    #     composer.send_email(target_emails, batch_id, event_data, retry_count, silent=silent)
    # except Exception:
    #     logger.exception(u"Failed to send email")
    #     return False
    return True
Exemplo n.º 28
0
    def test_keep_document_instance_on_update(self):
        batch = self.create_batch(DocumentBatchTypeEnum.DBT_TEST_TYPE, self.user)
        new_data = {
            'short_name': u'Тест нейм'
        }
        new_batch_data = {
            'data': new_data,
            'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
            'metadata': {}
        }

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 1)
        doc = BatchDocumentDbObject.query.scalar()
        del result['result']['creation_date']
        self.assertEqual(result, {
            'result': {
                'status': u'new',
                'all_docs': [{u'caption': u'Тестовый документ 1', u'document_type': u'test_doc_1', u'file_link': None, u'document_id': doc.id}],
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'Тест нейм'},
                'data': {
                    'short_name': u'Тест нейм'
                },
                'id': batch.id,
                'metadata': {},
                'status_data': {'finalisation_count': u'0'}
            }
        })

        new_data['short_name'] = u'создай второй документ'

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 2)
        doc = BatchDocumentDbObject.query.filter_by(id=doc.id).scalar()
        self.assertIsNotNone(doc)
        doc2 = BatchDocumentDbObject.query.filter(BatchDocumentDbObject.id!=doc.id).scalar()
        self.assertIsNotNone(doc2)
        del result['result']['creation_date']
        all_docs = result['result']['all_docs']
        self.assertEqual(len(all_docs), 2)
        del result['result']['all_docs']

        test_docs = [
            {u'caption': u'Тестовый документ 2', u'document_type': u'test_doc_2', u'file_link': None, u'document_id': doc2.id},
            {u'caption': u'Тестовый документ 1', u'document_type': u'test_doc_1', u'file_link': None, u'document_id': doc.id},
        ]
        test_doc_id_set = set()
        for d in all_docs:
            for td in test_docs:
                if d and d == td:
                    test_doc_id_set.add(d['document_id'])

        self.assertEqual(len(test_doc_id_set), len(test_docs))

        self.assertEqual(result, {
            'result': {
                'status': u'new',
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'создай второй документ'},
                'data': {
                    'short_name': u'создай второй документ'
                },
                'id': batch.id,
                'metadata': {},
                'status_data': {'finalisation_count': u'0'}
            }
        })

        new_data['short_name'] = u'не создавай второй документ'

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 1)
        doc = BatchDocumentDbObject.query.filter_by(id=doc.id).scalar()
        self.assertIsNotNone(doc)
        del result['result']['creation_date']
        all_docs = result['result']['all_docs']
        self.assertEqual(len(all_docs), 1)
        del result['result']['all_docs']

        test_docs = [
            {u'caption': u'Тестовый документ 1', u'document_type': u'test_doc_1', u'file_link': None, u'document_id': doc.id},
        ]
        test_doc_id_set = set()
        for d in all_docs:
            for td in test_docs:
                if d and d == td:
                    test_doc_id_set.add(d['document_id'])

        self.assertEqual(len(test_doc_id_set), len(test_docs))

        self.assertEqual(result, {
            'result': {
                'status': u'new',
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'не создавай второй документ'},
                'data': {
                    'short_name': u'не создавай второй документ'
                },
                'id': batch.id,
                'metadata': {},
                'status_data': {'finalisation_count': u'0'}
            }
        })
Exemplo n.º 29
0
    def test_filter_errors_in_document(self):
        batch = self.create_batch(DocumentBatchTypeEnum.DBT_TEST_TYPE, self.user)
        new_data = {
            'short_name': u'Тест нейм' * 30
        }
        new_batch_data = {
            'data': new_data,
            'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
            'metadata': {}
        }

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 1)
        doc = BatchDocumentDbObject.query.scalar()
        del result['result']['creation_date']
        self.assertEqual(result, {
            'result': {
                'status': u'new',
                'all_docs': [{
                    u'caption': u'Тестовый документ 1',
                    u'document_type': u'test_doc_1',
                    u'file_link': None,
                    u'document_id': doc.id
                }],
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'Тест нейм' * 30},
                'error_info': {'error_ext': [{'error_code': 5,
                                              'field': u'short_name'}]},
                'data': {
                    'short_name': u'Тест нейм' * 30
                },
                'id': batch.id,
                'metadata': {},
                'status_data': {'finalisation_count': u'0'}
            }
        })

        new_data['short_name'] = u'создай второй документ'
        new_data['text_field'] = u'err'

        new_batch = DocumentBatch.parse_raw_value(new_batch_data, api_data=False)
        manager = BatchManager.init(batch)
        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 2)
        doc = BatchDocumentDbObject.query.filter_by(id=doc.id).scalar()
        self.assertIsNotNone(doc)
        doc2 = BatchDocumentDbObject.query.filter(BatchDocumentDbObject.id!=doc.id).scalar()
        self.assertIsNotNone(doc2)
        del result['result']['creation_date']
        all_docs = result['result']['all_docs']
        self.assertEqual(len(all_docs), 2)
        del result['result']['all_docs']

        test_docs = [
            {u'caption': u'Тестовый документ 2', u'document_type': u'test_doc_2', u'file_link': None, u'document_id': doc2.id},
            {u'caption': u'Тестовый документ 1', u'document_type': u'test_doc_1', u'file_link': None, u'document_id': doc.id},
        ]
        test_doc_id_set = set()
        for d in all_docs:
            for td in test_docs:
                if d and d == td:
                    test_doc_id_set.add(d['document_id'])

        self.assertEqual(len(test_doc_id_set), len(test_docs))

        self.assertEqual(result, {
            'result': {
                'status': u'new',
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'создай второй документ'},
                'data': {
                    'short_name': u'создай второй документ',
                    'text_field': 'err'
                },
                'id': batch.id,
                'metadata': {},
                'status_data': {'finalisation_count': u'0'}
            }
        })

        result = self.test_client.post('/batch/render_document/', data={
            'batch_id': batch.id,
            'document_type': json.dumps([DocumentTypeEnum.DT_TEST_DOC_2])
        })
        self.assertEqual(result.status_code, 200)
        self.assertEqual(json.loads(result.data), {'result': True})

        doc2 = BatchDocumentDbObject.query.filter_by(document_type = DocumentTypeEnum.DT_TEST_DOC_2).scalar()
        self.assertIsNotNone(doc2)
        self.assertEqual(doc2.status, UserDocumentStatus.DS_RENDERING_FAILED)

        batch = doc2.batch
        self.assertEqual(batch.error_info, {u'error_ext': [{u'error_code': 5, u'field': u'text_field'}]})

        result = manager.update_batch(batch.id, new_batch, self.user.id, None, self.config, current_app.logger)
        self.assertEqual(BatchDocumentDbObject.query.count(), 2)
        doc = BatchDocumentDbObject.query.filter_by(id=doc.id).scalar()
        self.assertIsNotNone(doc)
        doc2 = BatchDocumentDbObject.query.filter(BatchDocumentDbObject.id!=doc.id).scalar()
        self.assertIsNotNone(doc2)
        del result['result']['creation_date']
        all_docs = result['result']['all_docs']
        self.assertEqual(len(all_docs), 2)
        del result['result']['all_docs']

        test_docs = [
            {u'caption': u'Тестовый документ 2', u'document_type': u'test_doc_2', u'file_link': None, u'document_id': doc2.id},
            {u'caption': u'Тестовый документ 1', u'document_type': u'test_doc_1', u'file_link': None, u'document_id': doc.id},
        ]
        test_doc_id_set = set()
        for d in all_docs:
            for td in test_docs:
                if d and d == td:
                    test_doc_id_set.add(d['document_id'])

        self.assertEqual(len(test_doc_id_set), len(test_docs))

        self.assertEqual(result, {
            'result': {
                'status': u'finalised2',
                'name': u'Тестовый батч',
                'paid': 'false',
                'batch_type': DocumentBatchTypeEnum.DBT_TEST_TYPE,
                'result_fields': {u'name': u'создай второй документ'},
                'data': {
                    'short_name': u'создай второй документ',
                    'text_field': 'err'
                },
                'id': batch.id,
                'metadata': {},
                'error_info': {'error_ext': [{'error_code': 5,
                                              'field': u'text_field'}]},
                'status_data': {'finalisation_count': u'0'}
            }
        })
Exemplo n.º 30
0
def render_batch_raw(batch_db_object_id, render_only_failed_docs=False):
    request = current_task.request
    config = celery.conf.get('config')
    eager = celery.conf['CELERY_ALWAYS_EAGER']
    app = celery.conf['flask_app']()
    logger = app.logger

    from fw.documents.batch_manager import BatchManager
    with app.app_context():
        batch_db_object = DocumentBatchDbObject.query.filter_by(id=batch_db_object_id).first()
        if not batch_db_object:
            logger.error(u"Failed to find batch with id %s in collection %s in db %s" % (
                batch_db_object_id, DocumentBatchDbObject.COLLECTION_NAME, config['db_name']))
            return False

        batch_db_object.current_task_id = request.id
        batch_db_object.batch_rendering_start = datetime.utcnow()
        sqldb.session.commit()

        task_holder = BatchTaskFileIdHolder(request.id, config, batch_db_object) if not eager else FakeTaskHolder()
        with task_holder as task_file:
            logger.info(u"Generating documents for batch %s" % batch_db_object_id)

            try:
                batch_type = batch_db_object.batch_type

                batch_manager = BatchManager.init(batch_db_object)
                batch_descriptor = DocRequisitiesStorage.get_batch_descriptor(batch_type)
                doc_types_allowed_to_deferred_rendering = batch_descriptor.get('deferred_render_docs', [])

                watermark = None if batch_db_object.paid else "notpaid_watermark.png"

                has_errors = False
                failed_doc_types = set()
                for doc in batch_db_object._documents:
                    # if not task_file.exists():
                    #     logger.warning(u"Task with id %s has been revoked" % request.id)
                    #     batch_db_object.status = BatchStatusEnum.BS_EDITED
                    #     sqldb.session.commit()
                    #     return True

                    doc_type = doc.document_type
                    if render_only_failed_docs and doc.status != UserDocumentStatus.DS_RENDERING_FAILED:
                        continue

                    render_doc_file = batch_type == DocumentBatchTypeEnum.DBT_NEW_LLC and batch_db_object.paid
                    if not render_single_document(doc, batch_manager.get_title(doc_type), watermark,
                                                  config, logger, request.id, render_doc_file):
                        has_errors = True
                        if doc_type not in doc_types_allowed_to_deferred_rendering:
                            if not render_only_failed_docs:
                                batch_db_object.status = BatchStatusEnum.BS_EDITED
                                batch_db_object.error_info = {
                                    "error_ext": [{
                                        "field": "",
                                        "error_code": 0,
                                        "message": u"Failed to render document %s" % doc_type
                                    }]
                                }
                            sqldb.session.commit()

                            return False
                    failed_doc_types.add(doc_type)

                if not render_only_failed_docs:
                    batch_db_object.finalisation_count += 1
                    batch_db_object.status = BatchStatusEnum.BS_FINALISED
                    if batch_db_object.batch_rendering_start:
                        try:
                            dt = datetime.utcnow() - batch_db_object.batch_rendering_start
                            fs = dt.total_seconds() + dt.microseconds / 1000000.
                            zabbix_sender.send('celery_max_time', fs)
                        except Exception:
                            pass
                    batch_db_object.finalisation_date = datetime.utcnow()
                    CeleryScheduler.remove("not_finalised_check_and_send%s" % str(batch_db_object_id))
                    try:
                        if batch_db_object.batch_rendering_start:
                            dt = datetime.utcnow() - batch_db_object.batch_rendering_start
                            seconds = dt.total_seconds()
                            zabbix_sender.send("celery_max_time", seconds)
                    except Exception:
                        pass
                sqldb.session.commit()

                if has_errors:
                    if len(failed_doc_types) == 1 and failed_doc_types.pop() in ('reg_fee_invoice', 'ip_reg_fee_invoice'):
                        from services.ifns import ifns_manager
                        if ifns_manager.if_gp_pay_working():
                            logger.error(u"Invalid fee invoice render attempt (service.nalog.ru is working). Cancelling!")
                            batch_db_object.status = BatchStatusEnum.BS_EDITED
                            sqldb.session.commit()
                            return False
                    async_result = render_batch.apply_async((batch_db_object_id,), {'render_only_failed_docs': True}, countdown=300)
                    if not async_result.ready():
                        task_file.unbind = True
                        new_task_id = unicode(async_result.id)
                        batch_db_object.current_task_id = new_task_id
                        batch_db_object.batch_rendering_start = datetime.utcnow()
                        logger.debug(u"Task id: %s" % new_task_id)
                        sqldb.session.commit()
            except Exception:
                logger.exception(u"Failed to render batch %s" % batch_db_object_id)
                if not render_only_failed_docs:
                    batch_db_object.status = BatchStatusEnum.BS_EDITED
                    sqldb.session.commit()

        if render_only_failed_docs and batch_db_object.paid:
            user = batch_db_object._owner
            addr_to = user.email or ""
            if not addr_to:
                logger.warning(u"Failed to send email: user %s has no email" % unicode(user.id))
            else:
                documents = BatchManager.get_shared_links_to_rendered_docs(batch_db_object, config, logger)

                if batch_db_object.batch_type == DocumentBatchTypeEnum.DBT_NEW_LLC:
                    go_further_url = u"%s://%s/ooo/?id=%s" % (
                        config['WEB_SCHEMA'], config['DOMAIN'], batch_db_object_id)
                    go_further_url = utm_args(go_further_url, 'deferred_docs_ready', user.id) + u"#page=documents"
                    go_further_url = UserManager.make_auth_url(go_further_url, user).get_url(config)

                    short_name = batch_db_object.data.get('short_name', "")
                    send_email.send_email.delay(addr_to, "deferred_docs_ready",
                                                go_further_url=go_further_url,
                                                short_name=short_name,
                                                schema=config['WEB_SCHEMA'],
                                                domain=config['DOMAIN'],
                                                docs=documents,
                                                user_id=str(user.id)
                                                )
                elif batch_db_object.batch_type == DocumentBatchTypeEnum.DBT_NEW_IP:
                    go_further_url = u"%s://%s/ip/?id=%s" % (
                        config['WEB_SCHEMA'], config['DOMAIN'], batch_db_object_id)
                    go_further_url = utm_args(go_further_url, 'deferred_ip_docs_ready', user.id) + u"#page=documents"
                    go_further_url = UserManager.make_auth_url(go_further_url, user).get_url(config)
                    short_name = ""
                    try:
                        pp_data = batch_db_object.data.get('person')
                        if pp_data and '_id' in pp_data:
                            person_db = PrivatePersonDbObject.query.filter_by(id=pp_data['_id']).scalar()
                            if person_db:
                                person = PrivatePerson.db_obj_to_field(person_db)
                                short_name = person.get_short_name()
                    except Exception:
                        logger.exception(u"Failed to get batch caption")

                    send_email.send_email.delay(addr_to, "deferred_ip_docs_ready",
                                                go_further_url=go_further_url,
                                                short_name=short_name,
                                                schema=config['WEB_SCHEMA'],
                                                domain=config['DOMAIN'],
                                                docs=documents,
                                                user_id=str(user.id)
                                                )

    return True