#coding: utf-8
'''
Created on 05.05.2015

@author: v.popov
'''
import json
from suds.client import Client
from ru.curs.celesta.showcase.utils import XMLJSONConverter
import sys
from journals import nci_settings
from java.text import SimpleDateFormat

def uploadLeContractor(context, contractor_id):
    u'''Выполняет выгрузку контрагента ЮЛ в систему НСИ. '''

    #userPin = '1C1SMFSRJQIEA1'
    #wsUrl = 'http://192.168.111.80:8080/nsi_test/forall/webservices?wsdl'
    settings_json = nci_settings.getSettingsJSON()
    userPin = settings_json['userPin']
    wsUrl = settings_json['wsUrl']

    wsClient = Client(wsUrl)

    legal_entity = legal_entityCursor(context)
    legal_entity.get(contractor_id)
    contractor_address = legal_entity.address_fact if legal_entity.address_fact else legal_entity.address_post
    contractor_name = legal_entity.shortname if legal_entity.shortname else legal_entity.name
    contractor_guid_nsi = unicode(contractor_id)
    contractor_kpp = legal_entity.kpp
    contractor_inn = legal_entity.inn
    contractor_email = ''

    wsRequest = u'''
        <show:requestAnyXML>
            <command 
            type="insert" 
            param="tryUpdate" 
            system_id="FDPO" 
            pin="%s" 
            grain="rsmusprav" 
            table="contractors">
                <records>
                    <rec>
                        <contractor_address>%s</contractor_address>
                        <contractor_name>%s</contractor_name>
                        <contractor_guid_nsi>%s</contractor_guid_nsi>
                        <contractor_type>Юр. лицо</contractor_type>
                        <contractor_kpp>%s</contractor_kpp>
                        <contractor_inn>%s</contractor_inn>
                        <contractor_email>%s</contractor_email>
                    </rec>
                </records>
            </command>
        </show:requestAnyXML>
    ''' % (userPin, contractor_address, contractor_name, contractor_guid_nsi, contractor_kpp, contractor_inn, contractor_email)
    wsXmlOut = wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.insert.celesta")
    if '<error' not in wsXmlOut:
        # ЮЛ синхронизировано
        legal_entity.sync_nsi = True
        legal_entity.update()
        context.message(u'Введенное Юр. лицо добавлено в единую систему НСИ.')


def uploadPayedContract(context, contract_id):
    u'''Выполняет выгрузку платного договора в систему НСИ. '''

    #userPin = '1C1SMFSRJQIEA1'
    #wsUrl = 'http://192.168.111.80:8080/nsi_test/forall/webservices?wsdl'
    settings_json = nci_settings.getSettingsJSON()
    userPin = settings_json['userPin']
    wsUrl = settings_json['wsUrl']

    wsClient = Client(wsUrl)

    contract = contractCursor(context)
    contract.get(contract_id)
    contractor_guid_nsi = unicode(contract.customer)
    contract_date = unicode(contract.form_date)
    contract_guid_nsi = unicode(contract.id)
    contract_number = unicode(contract.number)
    contract_sum = unicode(contract.contract_price_num)
    wsRequest = u'''
        <show:requestAnyXML>
            <command 
            type="insert" 
            param="tryUpdate" 
            system_id="FDPO" 
            pin="%s" 
            grain="rsmusprav" 
            table="contracts">
                <records>
                    <rec>
                        <contract_date>%s</contract_date>
                        <contract_guid_nsi>%s</contract_guid_nsi>
                        <contract_type>С покупателем</contract_type>
                        <contract_number>%s</contract_number>
                        <contract_sum>%s</contract_sum>
                        <contractor_guid_nsi>%s</contractor_guid_nsi>
                    </rec>
                </records>
            </command>
        </show:requestAnyXML>
    ''' % (userPin, contract_date, contract_guid_nsi, contract_number, contract_sum, contractor_guid_nsi)
    # если ЮЛ - проверяем, что оно синхронизировано
    if contract.contract_type == 'legalEntityPayed':
        legal_entity = legal_entityCursor(context)
        legal_entity.get(contract.customer)
        if not legal_entity.sync_nsi:
            # синхронизируем
            uploadLeContractor(context, contract.customer)

        wsXmlOut = wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.insert.celesta")
        if '<error' not in wsXmlOut:
            contract.sync_nsi = True
            contract.update()
            context.message(u'Договор успешно добавлен в единую систему НСИ.')
    # если ФЛ - пока оставляем
    elif contract.contract_type == 'personPayed':
        pass

def uploadOnePerson(context, person_id):
    u'''Выполняет выгрузку ФЛ в систему НСИ. '''

    #userPin = '1C1SMFSRJQIEA1'
    #wsUrl = 'http://192.168.111.80:8080/nsi_test/forall/webservices?wsdl'
    settings_json = nci_settings.getSettingsJSON()
    userPin = settings_json['userPin']
    wsUrl = settings_json['wsUrl']

    df = SimpleDateFormat("yyyy-MM-dd")
    wsClient = Client(wsUrl)

    reg_data = reg_dataCursor(context)
    reg_data.setRange('person_id', person_id)
    if reg_data.tryFirst():
        person_guid = person_id
        family_name = reg_data.surname
        first_name = reg_data.name
        second_name = reg_data.patronymic if reg_data.patronymic else ''
        birth_date = df.format(reg_data.birth_date) if reg_data.birth_date else ''
        if reg_data.sex == u'муж':
            gender = u'М'
        elif reg_data.sex == u'жен':
            gender = u'Ж'
        else:
            gender = ''
        email = reg_data.email if reg_data.email else ''
        inn = ''
        if reg_data.citizenship == u'Российская Федерация':
            pass_type = u'Паспорт гражданина Российской Федерации'
            pass_ser = reg_data.passport_series
            pass_num = reg_data.passport_number
            pass_is_by = reg_data.who_issue
            pass_date = df.format(reg_data.when_issue) if reg_data.when_issue else ''
        else:
            pass_type = ''
            pass_ser = ''
            pass_num = ''
            pass_is_by = ''
            pass_date = ''
        snils = reg_data.snils if reg_data.snils else ''

        wsRequest = u'''
                <show:requestAnyXML>
                <command 
                type="insert" 
                param="tryUpdate" 
                system_id="FDPO" 
                pin="%s" 
                grain="rsmusprav" 
                table="persons_all">
                     <records>
                        <rec>
                            <person_guid>%s</person_guid>
                            <family_name>%s</family_name>
                            <first_name>%s</first_name>
                            <second_name>%s</second_name>
                            <birth_date>%s</birth_date>
                            <gender>%s</gender>
                            <email>%s</email>
                            <inn>%s</inn>
                            <pass_type>%s</pass_type>
                            <pass_ser>%s</pass_ser>
                            <pass_num>%s</pass_num>
                            <pass_is_by>%s</pass_is_by>
                            <pass_date>%s</pass_date>
                            <snils>%s</snils>
                         </rec>
                   </records>
                </command>
            </show:requestAnyXML>
        ''' % (userPin, person_guid, family_name, first_name, second_name, birth_date, gender, email, inn, pass_type, pass_ser, pass_num, pass_is_by, pass_date, snils)
        wsXmlOut = wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.insert.celesta")
        if '<error' not in wsXmlOut:
            # ФЛ синхронизировано
            reg_data.sync_nsi = True
            reg_data.update()
            context.message(u'Введенное Физ. лицо добавлено в единую систему НСИ.')

def uploadPersonsFlute(context, params):
    u'''Выгружаем ФЛ при помощи флейты. '''

    settings_json = nci_settings.getSettingsJSON()
    userPin = settings_json['userPin']
    wsUrl = settings_json['wsUrl']

    arg_dict = json.loads(params.params)
    df = SimpleDateFormat("yyyy-MM-dd")
    wsClient = Client(wsUrl)

    reg_data = reg_dataCursor(context)
    reg_data1 = reg_dataCursor(context)
    counter = 0
    pagesize = 100
    if 'mode' in arg_dict and arg_dict['mode'] == 'allAnsync':
        reg_data.setRange('sync_nsi', False)
    reg_data_count = reg_data.count()
    while counter < reg_data_count:
        reg_data.limit(counter, pagesize)
        recs = []
        counter += pagesize
        reg_data_uids = []
        for reg_data in reg_data.iterate():
            reg_data_uids.append(reg_data.uid)
            person_guid = reg_data.person_id
            family_name = reg_data.surname
            first_name = reg_data.name
            second_name = reg_data.patronymic if reg_data.patronymic else ''
            birth_date = df.format(reg_data.birth_date) if reg_data.birth_date else ''
            if reg_data.sex == u'муж':
                gender = u'М'
            elif reg_data.sex == u'жен':
                gender = u'Ж'
            else:
                gender = ''
            email = reg_data.email if reg_data.email else ''
            inn = ''
            if reg_data.citizenship == u'Российская Федерация':
                pass_type = u'Паспорт гражданина Российской Федерации'
                pass_ser = reg_data.passport_series
                pass_num = reg_data.passport_number
                pass_is_by = reg_data.who_issue
                pass_date = df.format(reg_data.when_issue) if reg_data.when_issue else ''
            else:
                pass_type = ''
                pass_ser = ''
                pass_num = ''
                pass_is_by = ''
                pass_date = ''
            snils = reg_data.snils if reg_data.snils else ''

            rec = u'''<rec>
                        <person_guid>%s</person_guid>
                        <family_name>%s</family_name>
                        <first_name>%s</first_name>
                        <second_name>%s</second_name>
                        <birth_date>%s</birth_date>
                        <gender>%s</gender>
                        <email>%s</email>
                        <inn>%s</inn>
                        <pass_type>%s</pass_type>
                        <pass_ser>%s</pass_ser>
                        <pass_num>%s</pass_num>
                        <pass_is_by>%s</pass_is_by>
                        <pass_date>%s</pass_date>
                        <snils>%s</snils>
                     </rec>''' % (person_guid, family_name, first_name, second_name, birth_date, gender, email, inn, pass_type, pass_ser, pass_num, pass_is_by, pass_date, snils)

            recs.append({'person_guid': person_guid, 'rec': rec, 'reg_data_id': reg_data.uid})

        wsRequest = u'''
                <show:requestAnyXML>
                <command 
                type="insert" 
                param="tryUpdate" 
                system_id="FDPO" 
                pin="%s" 
                grain="rsmusprav" 
                table="persons_all">
                     <records>
                        %s
                   </records>
                </command>
            </show:requestAnyXML>
        ''' % (userPin, "".join([x['rec'] for x in recs if 'rec' in x]))
        try:
            wsXmlOut = wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.insert.celesta")
            if '<error' not in wsXmlOut:
                # ФЛ синхронизировано
                for rd_uid in reg_data_uids:
                    reg_data1.get(rd_uid)
                    reg_data1.sync_nsi = True
                    reg_data1.update()
                context.commit()
        except:
            # идем по одной записи и пытаемся выгрузить
            for rec in recs:
                try:
                    wsRequest = u'''
                            <show:requestAnyXML>
                            <command 
                            type="insert" 
                            param="tryUpdate" 
                            system_id="FDPO" 
                            pin="%s" 
                            grain="rsmusprav" 
                            table="persons_all">
                                 <records>
                                    %s
                               </records>
                            </command>
                        </show:requestAnyXML>
                                ''' % (userPin, rec['rec'])
                    wsXmlOut = wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.insert.celesta")
                    if '<error' not in wsXmlOut:
                        # ФЛ синхронизировано
                        reg_data1.get(rec['reg_data_id'])
                        reg_data1.sync_nsi = True
                        reg_data1.update()
                        context.commit()
                except:
                    pass

def syncReport(table, package_id):
    u'Отчет о синхронизации.'

    settings_json = nci_settings.getSettingsJSON()
    userPin = settings_json['userPin']
    wsUrl = settings_json['wsUrl']

    wsClient = Client(wsUrl)

    wsRequest = u'''
            <show:requestAnyXML>
            <command 
            type="report"
            pin="%s"
            grain="rsmusprav"
            table="%s"
            system_id="FDPO"
            package_id="%s">
                <error>False</error>
                <error_mes/>            
            </command>
        </show:requestAnyXML>
                ''' % (userPin, table, package_id)
    wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.syncReport.celesta")


def selectPayments(context):
    u'Загружка оплат в ФДПО.'

    payments_nsi = payments_nsiCursor(context)
    settings_json = nci_settings.getSettingsJSON()
    userPin = settings_json['userPin']
    wsUrl = settings_json['wsUrl']

    wsClient = Client(wsUrl)

    wsRequest = u'''
            <show:requestAnyXML>
                <command 
                type="select" 
                param="" 
                sync="1" 
                system_id="FDPO" 
                pin="%s" 
                grain="rsmusprav" 
                table="payment_facts_input_fdpo">
                </command>
            </show:requestAnyXML>
                ''' % userPin
    wsXmlOut = wsClient.service.handle(request=wsRequest, procName="webservices.funcTest.select.celesta")
    if '<error' not in wsXmlOut:
        # данные по оплатам получены
        wsXmlOut_json = json.loads(XMLJSONConverter.xmlToJson(wsXmlOut))
        records = wsXmlOut_json['records']
        package_id = records['@package_id']
        payments = records['rec']
        if isinstance(payments, list):
            for payment in payments:
                payments_nsi.id = int(float(payment['id']))
                payments_nsi.contract_guid_nsi = payment['contract_guid_nsi']
                payments_nsi.payment_date = payment['payment_date']
                payments_nsi.payment_sum = payment['payment_sum']
                payments_nsi.contractor_guid_nsi = payment['contractor_guid_nsi']
                if not payments_nsi.tryUpdate():
                    payments_nsi.insert()

        elif isinstance(payments, dict):
            payment = payments
            payments_nsi.id = int(float(payment['id']))
            payments_nsi.contract_guid_nsi = payment['contract_guid_nsi']
            payments_nsi.payment_date = payment['payment_date']
            payments_nsi.payment_sum = payment['payment_sum']
            payments_nsi.contractor_guid_nsi = payment['contractor_guid_nsi']
            if not payments_nsi.tryUpdate():
                payments_nsi.insert()
        context.commit()
        # факт синхронизации подтверждаем
        syncReport('payment_facts_input_fdpo', package_id)

    else:
        context.message(u'При загружке оплат произошла ошибка.')

def selectPaymentsFlute(context, params):
    u'Загрузка оплат через флейту.'

    selectPayments(context)


def updateContractForPaymentFlute(context, params):
    u'Обновление договоров по оплатам.'

    contract = contractCursor(context)
    payments_nsi = payments_nsiCursor(context)
    contract.setFilter('contract_type', "'legalEntityPayed'|'personPayed'")
    contract.setComplexFilter('money_in_rnimu is null or money_in_rnimu=0')
    for contract in contract.iterate():
        payments_nsi.setRange('contract_guid_nsi', contract.id)
        payment_total = 0
        for payments_nsi in payments_nsi.iterate():
            payment_total += payments_nsi.payment_sum
        # если суммы совпадают - обновляем признак договора
        if payment_total == contract.contract_price_num:
            contract.money_in_rnimu = True
            contract.update()
            context.commit()