Exemplo n.º 1
0
class Flight(ComplexModel):

    __namespace__ = 'testing'
    Index = Integer(min_occurs=0, max_occurs=1, nillable=True)
    flightNumber = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    airline = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    airlineIATA = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    flightNumber = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    nChild = Integer(min_occurs=0, max_occurs=1, nillable=True)
    nInfant = Integer(min_occurs=0, max_occurs=1, nillable=True)
    arrivalDateTime = DateTime(min_occurs=0, max_occurs=1, nillable=True)

    from_ = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    to = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    departureDatetime = DateTime(min_occurs=0, max_occurs=1, nillable=False)
    nAdult = Integer(min_occurs=0, max_occurs=1, nillable=False)
    AV = Array(AV.customize(nillable=True))
    LConnections = Array(Connection.customize(nillable=True))
    LFares = Array(Fare.customize(nillable=True))

    validReturns = Array(Unicode(min_occurs=0, max_occurs=1, nillable=False))
    type = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    return_ = Boolean(min_occurs=0, max_occurs=1, nillable=False)
    schedule = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    range = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    info = Unicode(min_occurs=0, max_occurs=1, nillable=False)
Exemplo n.º 2
0
    def test_datetime_format(self):
        n = datetime.datetime.now().replace(microsecond=0)
        format = "%Y %m %d %H %M %S"

        element = etree.Element('test')
        XmlDocument().to_parent_element(DateTime(format=format), n, ns_test, element)
        element = element[0]

        assert element.text == datetime.datetime.strftime(n, format)
        dt = XmlDocument().from_element(DateTime(format=format), element)
        assert n == dt
Exemplo n.º 3
0
class ClosestTicket(ComplexModel):
    __namespace__ = SOAP_NAMESPACE

    timeslotStart = DateTime(doc=u'Начало приёма у врача по талончику')
    timeslotEnd = DateTime(doc=u'Окончание приёма у врача по талончику')
    office = Unicode(doc=u'Кабинет приёма')
    doctor_id = Integer(doc=u'ID врача')

    def __init__(self):
        super(ClosestTicket,
              self).__init__(doc=u'Данные о ближайшем талончике')
Exemplo n.º 4
0
    def test_datetime_fixed_format(self):
        # Soap should ignore formats
        n = datetime.datetime.now().replace(microsecond=0)
        format = "%Y %m %d %H %M %S"

        element = etree.Element('test')
        Soap11().to_parent_element(DateTime(format=format), n,
                                   'some_namespace', element)
        assert element[0].text == n.isoformat()

        dt = Soap11().from_element(DateTime(format=format), element[0])
        assert n == dt
Exemplo n.º 5
0
    def test_datetime_serialize_as(self):
        i = 1234567890123456
        v = datetime.datetime.fromtimestamp(i / 1e6)

        assert ProtocolBase().to_string(DateTime(serialize_as='sec'),
                                        v) == i // 1e6
        assert ProtocolBase().to_string(DateTime(serialize_as='sec_float'),
                                        v) == i / 1e6
        assert ProtocolBase().to_string(DateTime(serialize_as='msec'),
                                        v) == i // 1e3
        assert ProtocolBase().to_string(DateTime(serialize_as='msec_float'),
                                        v) == i / 1e3
        assert ProtocolBase().to_string(DateTime(serialize_as='usec'), v) == i
Exemplo n.º 6
0
class InteropPrimitive(ServiceBase):
    @srpc(AnyXml, _returns=AnyXml)
    def echo_any(xml):
        return xml

    @srpc(AnyDict, _returns=AnyDict)
    def echo_any_as_dict(xml_as_dict):
        return xml_as_dict

    @srpc(Integer, _returns=Integer)
    def echo_integer(i):
        return i

    @srpc(String, _returns=String)
    def echo_string(s):
        return s

    @srpc(DateTime, _returns=DateTime)
    def echo_datetime(dt):
        return dt

    @srpc(DateTime(format='ignored'), _returns=DateTime)
    def echo_datetime_with_invalid_format(dt):
        return dt

    @srpc(Date, _returns=Date)
    def echo_date(d):
        return d

    @srpc(Date(format='ignored'), _returns=Date)
    def echo_date_with_invalid_format(d):
        return d

    @srpc(Time, _returns=Time)
    def echo_time(t):
        return t

    @srpc(Time(format='ignored'), _returns=Time)
    def echo_time_with_invalid_format(t):
        return t

    @srpc(Float, _returns=Float)
    def echo_float(f):
        return f

    @srpc(Double, _returns=Double)
    def echo_double(f):
        return f

    @srpc(Boolean, _returns=Boolean)
    def echo_boolean(b):
        return b

    @srpc(DaysOfWeekEnum, _returns=DaysOfWeekEnum)
    def echo_enum(day):
        return day

    @srpc(Duration, _returns=Duration)
    def echo_duration(dur):
        return dur
Exemplo n.º 7
0
class Session(ComplexModel):
    __namespace__ = SOAP_NAMESPACE

    sessionStart = DateTime(doc=u'Начало смены')
    sessionEnd = DateTime(doc=u'Окончание смены')
    sessionType = SessionType()
    timeslots = Timeslot.customize(
        max_occurs='unbounded',
        doc=u'Информация об отдельных элементах расписания (тайм-слотах)')
    comments = Unicode(
        doc=u'Дополнительная информация о месте приёма или о замещениях')

    def __init__(self):
        super(
            Session,
            self).__init__(doc=u'Группа интервалов (смена) в расписании врача')
Exemplo n.º 8
0
class MessageType(SmevModel):
    Sender = OrgExternalType.customize(type_name="Sender",
                                       min_occurs=1,
                                       max_occurs=1)
    Recipient = OrgExternalType.customize(type_name="Recipient",
                                          min_occurs=1,
                                          max_occurs=1)
    Originator = OrgExternalType.customize(type_name="Originator",
                                           min_occurs=0,
                                           max_occurs=1)
    ServiceName = Unicode(type_name="ServiceName", min_occurs=0, max_occurs=1)
    Service = ServiceType.customize(type_name="Service", max_occurs=1)
    TypeCode = Unicode(type_name="TypeCode",
                       values=["GSRV", "GFNC", "OTHR"],
                       min_occurs=1,
                       max_occurs=1)
    Status = Unicode(type_name="Status",
                     values=["REQUEST", "RESPONSE"],
                     min_occurs=1,
                     max_occurs=1)
    Date = DateTime(type_name="Date", min_occurs=1, max_occurs=1)
    ExchangeType = Integer(type_name="ExchangeType", max_occurs=1)
    RequestIdRef = Unicode(type_name="RequestIdRef", max_occurs=1)
    OriginRequestIdRef = Unicode(type_name="OriginRequestIdRef", max_occurs=1)
    ServiceCode = Unicode(type_name="ServiceCode", max_occurs=1)
    CaseNumber = Unicode(type_name="CaseNumber", max_occurs=1)
    SubMessages = SubMessages(type_name="SubMessages", max_occurs=1)
    TestMsg = Unicode(type_name="TestMsg", max_occurs=1)
Exemplo n.º 9
0
 class SomeService(Service):
     @srpc(DateTime, _returns=DateTime(ge=datetime(2010,1,1,tzinfo=pytz.utc)))
     def some_call(p):
         print(p)
         print(type(p))
         assert type(p) == datetime
         assert p.isoformat() == d
         return p
Exemplo n.º 10
0
class SisMsg(ComplexModel):
    """Container with metadata for Jiva integration messages
    carried in the MQ payload.
    """
    data_source = String(nillable=False, min_occurs=1, max_occurs=1, max_len=50)
    direction = String(nillable=False, min_occurs=1, max_occurs=1, max_len=50)
    interface_name = String(nillable=False, min_occurs=1, max_occurs=1, max_len=50)
    crt_dt = DateTime(nillable=False)
Exemplo n.º 11
0
 class SomeService(Service):
     @srpc(DateTime, _returns=DateTime(timezone=False))
     def some_call(p):
         print(p)
         print(type(p))
         assert type(p) == datetime
         assert p.replace(tzinfo=None).isoformat() == d
         return p
Exemplo n.º 12
0
class NonNillableClass(ComplexModel):
    __namespace__ = "hunk.sunk"

    nillable = False
    min_occurs = 1

    dt = DateTime(min_occurs=1, nillable=False)
    i = Integer(nillable=False)
    s = String(min_len=1, nillable=False)
Exemplo n.º 13
0
    def test_datetime_deserialize(self):
        i = 1234567890123456
        v = datetime.datetime.fromtimestamp(i / 1e6)

        assert ProtocolBase().from_string(
                    DateTime(serialize_as='sec'), i//1e6) == \
                                     datetime.datetime.fromtimestamp(i//1e6)
        assert ProtocolBase().from_string(
                    DateTime(serialize_as='sec_float'), i/1e6) == v

        assert ProtocolBase().from_string(
                    DateTime(serialize_as='msec'), i//1e3) == \
                                     datetime.datetime.fromtimestamp(i/1e3//1000)
        assert ProtocolBase().from_string(
                    DateTime(serialize_as='msec_float'), i/1e3) == v

        assert ProtocolBase().from_string(
                    DateTime(serialize_as='usec'), i) == v
Exemplo n.º 14
0
class Mandatory(object):
    """
    This is spyne.model.primitive.Mandatory, but without min_length=1 for
    the Unicode model.
    """
    Unicode = Unicode(type_name='mandatory_unicode', min_occurs=1, nillable=False)
    Integer = Integer(type_name='mandatory_integer', min_occurs=1, nillable=False)
    Boolean = Boolean(type_name='mandatory_boolean', min_occurs=1, nillable=False)
    DateTime = DateTime(type_name='mandatory_date_time', min_occurs=1, nillable=False)
    ByteArray = ByteArray(type_name='mandatory_byte_array', min_occurs=1, nillable=False)
Exemplo n.º 15
0
class Connection(ComplexModel):

    Index = Integer(min_occurs=0, max_occurs=1, nillable=True)
    flightNumber = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    airline = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    airlineIATA = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    flightNumber = Unicode(min_occurs=0, max_occurs=1, nillable=True)

    from_ = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    fromAirport = Unicode(min_occurs=0, max_occurs=1, nillable=True)
    fromAirportIATA = Unicode(min_occurs=0, max_occurs=1, nillable=True)

    to = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    toAirport = Unicode(min_occurs=0, max_occurs=1, nillable=False)
    toAirportIATA = Unicode(min_occurs=0, max_occurs=1, nillable=False)

    arrivalDateTime = DateTime(min_occurs=0, max_occurs=1, nillable=True)
    departureDatetime = DateTime(min_occurs=0, max_occurs=1, nillable=False)

    AV = Array(AV.customize(nillable=True))
    map = Unicode(min_occurs=0, max_occurs=1, nillable=False)
Exemplo n.º 16
0
    def test_datetime_timezone(self):
        import pytz

        n = datetime.datetime.now(pytz.timezone('EST'))
        element = etree.Element('test')
        XmlDocument().to_parent_element(DateTime(as_time_zone=pytz.utc), n, ns_test, element)
        element = element[0]

        c = n.astimezone(pytz.utc).replace(tzinfo=None)
        self.assertEquals(element.text, c.isoformat())
        dt = XmlDocument().from_element(DateTime, element)
        self.assertEquals(c, dt)
Exemplo n.º 17
0
class GetClosestTicketsRequest(ComplexModel):
    __namespace__ = SOAP_NAMESPACE

    hospitalUid = String(doc=u'Уникальный идентификатор ЛПУ в БД ИС')
    doctors = Integer(min_occurs=1,
                      max_occurs='unbounded',
                      nillable=False,
                      doc=u'Список идентификаторов врачей')
    start = DateTime()

    def __init__(self):
        super(GetClosestTicketsRequest, self).__init__(
            doc=u'Данные запроса на получение ближайших талончиков по врачам')
Exemplo n.º 18
0
class SoapProject (ComplexModel):
    __namespace__ = 'soap'

    builddir = Unicode()
    name = Unicode()
    version = Unicode()
    status = Unicode()
    edit = DateTime()

    def __init__(self, prj):
        self.builddir = prj.builddir
        self.name = prj.name
        self.version = prj.version
        self.status = prj.status
        self.edit = prj.edit
Exemplo n.º 19
0
    def test_datetime_timezone(self):
        import pytz

        n = datetime.datetime.now(pytz.timezone('EST'))
        element = etree.Element('test')
        cls = DateTime(as_timezone=pytz.utc, timezone=False)
        XmlDocument().to_parent(None, cls, n, element, ns_test)
        element = element[0]

        c = n.astimezone(pytz.utc).replace(tzinfo=None)
        self.assertEquals(element.text, c.isoformat())
        dt = XmlDocument().from_element(None, cls, element)
        assert dt.tzinfo is not None
        dt = dt.replace(tzinfo=None)
        self.assertEquals(c, dt)
Exemplo n.º 20
0
class SubMessage(SmevModel):
    SubRequestNumber = Unicode(type_name="SubRequestNumber",
                               min_occurs=1,
                               max_occurs=1)
    Status = Unicode(type_name="Status",
                     min_occurs=1,
                     max_occurs=1,
                     values=("REQUEST", "RESULT", "REJECT", "INVALID",
                             "ACCEPT", "PING", "PROCESS", "NOTIFY", "FAILURE",
                             "CANCEL", "STATE", "PACKET"))
    Originator = OrgExternalType(type_name="Originator", max_occurs=1)
    Date = DateTime(type_name="Date", min_occurs=1, max_occurs=1)
    RequestIdRef = Unicode(type_name="RequestIdRef", max_occurs=1)
    OriginRequestIdRef = Unicode(type_name="OriginRequestIdRef", max_occurs=1)
    ServiceCode = Unicode(type_name="ServiceCode", max_occurs=1)
    CaseNumber = Unicode(type_name="CaseNumber", max_occurs=1)
Exemplo n.º 21
0
class TicketInfo(ComplexModel):
    __namespace__ = SOAP_NAMESPACE

    id = String(doc=u'Уникальный для ИС идентификатор заявки')
    ticketUid = String(doc=u'Уникальный для МИС ЛПУ идентификатор заявки')
    hospitalUid = String(doc=u'Уникальный идентификатор ЛПУ')
    doctorUid = Integer.customize(doc=u'Уникальный идентификатор врача')
    doctor = DoctorInfo.customize(max_occurs=1, doc=u'ФИО врача')
    person = PersonName.customize(max_occurs=1, doc=u'ФИО записавшегося')
    status = TicketStatus.customize(max_occurs=1, doc=u'Статус талончика')
    timeslotStart = DateTime(
        doc=u'Начало приёма у врача, соответствующее данной заявке')
    location = Unicode(
        doc=u'Информация о месте приёма (корпус, этаж, кабинет и т.п.)')
    comment = Unicode(doc=u'Дополнительные указания и информация')
    printableDocument = PrintableDocument()

    def __init__(self):
        super(TicketInfo,
              self).__init__(doc=u'Данные о текущем статусе заявки на приём')
Exemplo n.º 22
0
class WFMPortalService(DjangoServiceBase):
    """WEB API"""

    __in_header__ = AuthDataHeader
    """
    Создание заявки на аутсорсинг персонала
    """
    @rpc(Unicode(sub_name='guid', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         Date(sub_name='start'),
         Date(sub_name='end'),
         OrganizationSoapModel,
         AgencySoapModel,
         Unicode(sub_name='state', min_occurs=1, nillable=False),
         Array(ShiftSoapModel),
         Unicode(sub_name='comments', min_occurs=0, nillable=False),
         Unicode(sub_name='user_name', min_occurs=0, nillable=False),
         Unicode(sub_name='email', min_occurs=0, nillable=False),
         _returns=Unicode,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def setOutsourcingRequest(ctx, guid, headquater, start, end, organization,
                              agency, state, shifts, comments, user_name,
                              email):

        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # TODO remove
        if not headquater:
            db_headquarter = open_headquarter_by_code('mvideo')

        # Магазин, сформировавший запрос
        if headquater:
            db_headquarter = open_headquarter_by_code(headquater.code)
            db_organization = open_organization_by_code(
                organization.code, db_headquarter)
        else:
            db_organization = open_organization_by_code(
                organization.code, None)
            db_headquarter = db_organization.headquater
        if not db_headquarter:
            raise CustomError(
                f'REQUEST {guid}: no headquater with code {headquater.code}')
        if not db_organization:
            raise CustomError(
                f'REQUEST {guid}: no organiztion with code {organization.code}'
            )

        # Агентство, в котором запрашиваем аутсорсинг
        db_agency = open_agency_by_code(agency.code, None)
        if not db_agency:
            raise CustomError(
                f'REQUEST {guid}: no agency with code {agency.code}')

        # Принимаем запросы только в состоянии launched, повторно запросы и запросы без смен не обрабатываем
        if state != 'launched':
            raise CustomError(
                f'REQUEST {guid}: state {state} is differ then launched')
        out_req = OutsourcingRequest.objects.filter(guid=guid).first()
        if out_req or not shifts:
            return {'result': 'ok'}

        # Создаем объект запроса
        if not comments:
            comments = ''
        if not user_name:
            user_name = ''
        if not email:
            email = ''
        out_req = OutsourcingRequest.objects.create(
            guid=guid,
            headquater=db_headquarter,
            organization=db_organization,
            agency=db_agency,
            state='accepted',
            start=start,
            end=end,
            comments=comments,
            user_name=user_name,
            email=email)
        # Создаем связанные с запросом смены
        for s in shifts:
            try:
                job = Job.objects.get(code=s.job.code)
            except Job.DoesNotExist:
                raise CustomError(
                    f'REQUEST {guid}, SHIFT {s.guid}: no job with code {s.job.code}'
                )
            if s.start > s.end:
                raise CustomError(
                    f'REQUEST {guid}, SHIFT {s.guid}: start > end')
            if s.worktime < 0:
                raise CustomError(
                    f'REQUEST {guid}, SHIFT {s.guid}: worktime = {s.worktime} < 0'
                )
            OutsourcingShift.objects.create(guid=s.guid,
                                            headquater=db_headquarter,
                                            state=s.state,
                                            start=s.start,
                                            end=s.end,
                                            worktime=s.worktime,
                                            job=job,
                                            request=out_req,
                                            agency=db_agency,
                                            start_date=s.start)

        # Создаем и отправляем уведомления о новой заявке
        make_notify_data(out_req, 'agency', 'wait_req_template')
        return {'result': 'ok'}

    """
        Получение данных по запросам, чей статус был обновлен раньше определенного времени
    """

    @rpc(DateTime(sub_name='timestamp', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         Integer(sub_name='amount', min_occurs=0, nillable=False),
         _returns=ComplexRequestsResponseSoapModel,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def getOutsourcingRequests(ctx, dt_change, headquater, amount):
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # TODO remove
        if not headquater:
            db_headquarter = open_headquarter_by_code('mvideo')
        else:
            # Клиент
            db_headquarter = open_headquarter_by_code(headquater.code)
        if not db_headquarter:
            raise CustomError(
                f'Headquater {headquater.code} is not registered')

        response = dict()
        response['requests_list'] = []

        # Ограничинваем максимальное количество запросов, возвращаемых за 1 раз
        if not amount or amount < 0:
            amount = 100

        # Поиск смен
        out_requests = OutsourcingRequest.objects.filter(
            headquater=db_headquarter, dt_ready__gt=dt_change, state='ready')
        out_requests = out_requests.order_by('dt_ready')[:amount]

        # Формируем результат
        if not out_requests:
            response['result'] = len(out_requests)
            response['timestamp'] = dt_change
        else:
            response['result'] = len(out_requests)
            response['timestamp'] = out_requests.aggregate(
                timestamp=Max('dt_ready'))['timestamp']
            response['requests_list'] = out_requests

        return response

    """
    Получение данных по запросу и связанным с ним сменам
    """

    @rpc(Unicode(sub_name='guid', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         _returns=ComplexOutsourcingRequestSoapModel,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def getOutsourcingRequest(ctx, guid, headquater):
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # TODO remove
        if not headquater:
            db_headquarter = open_headquarter_by_code('mvideo')
        else:
            # Клиент
            db_headquarter = open_headquarter_by_code(headquater.code)
        if not db_headquarter:
            raise CustomError(
                f'Headquater {headquater.code} is not registered')

        try:
            out_request = OutsourcingRequest.objects.get(
                guid=guid, headquater=db_headquarter)
            shifts = OutsourcingShift.objects.filter(
                request=out_request,
                headquater=db_headquarter).select_related('job')
            out_request.shifts = shifts
            return out_request
        except:
            raise CustomError(
                f'REQUEST {guid}: no OutsourcingRequest is found')

    """
    Получение изменений по сменам на аутсорсинг
    """

    @rpc(DateTime(sub_name='timestamp', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         Integer(sub_name='amount', min_occurs=0, nillable=False),
         _returns=ComplexShiftsResponseSoapModel,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def getOutsourcingShifts(ctx, dt_change, headquater, amount):
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # TODO remove
        if not headquater:
            db_headquarter = open_headquarter_by_code('mvideo')
        else:
            # Клиент
            db_headquarter = open_headquarter_by_code(headquater.code)
        if not db_headquarter:
            raise CustomError(
                f'Headquater {headquater.code} is not registered')

        response = dict()
        response['shifts_list'] = []

        # Ограничинваем максимальное количество смен, возвращаемых за 1 раз
        if not amount or amount < 0:
            amount = 100

        # Поиск смен
        out_shifts = OutsourcingShift.objects.filter(headquater=db_headquarter,
                                                     dt_change__gt=dt_change,
                                                     state='accept')
        out_shifts = out_shifts.order_by('dt_change').select_related(
            'agency_employee')[:amount]

        # Получение ТН сотрудника в организации на основе OrgHistory
        for shift in out_shifts:
            if shift.agency_employee:
                shift.agency_employee.oh_number = shift.get_employee_number_in_organization(
                )
        # Формируем результат
        if not out_shifts:
            response['result'] = len(out_shifts)
            response['timestamp'] = dt_change
        else:
            response['result'] = len(out_shifts)
            response['timestamp'] = out_shifts.aggregate(
                timestamp=Max('dt_change'))['timestamp']
            response['shifts_list'] = out_shifts

        return response

    """
    Получение смен промоутеров
    """

    @rpc(DateTime(sub_name='timestamp', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         AgencySoapModel.customize(min_occurs=0, nillable=False),
         Integer(sub_name='amount', min_occurs=0, nillable=False),
         _returns=ComplexPromoShiftsResponseSoapModel,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def getPromoShifts(ctx, dt_change, headquater, agency, amount):
        return _calc_shifts(ctx,
                            dt_change,
                            headquater,
                            agency,
                            amount,
                            party='promo')

    """
    Получение смен брокеров
    """

    @rpc(DateTime(sub_name='timestamp', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         AgencySoapModel.customize(min_occurs=0, nillable=False),
         Integer(sub_name='amount', min_occurs=0, nillable=False),
         _returns=ComplexPromoShiftsResponseSoapModel,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def getBrokerShifts(ctx, dt_change, headquater, agency, amount):
        return _calc_shifts(ctx,
                            dt_change,
                            headquater,
                            agency,
                            amount,
                            party='broker')

    """
    Удаление смены из заявки на аутсорсинг по решению управляюего магазином
    """

    @rpc(Array(ShiftDeleteSoapModel),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         _returns=Unicode,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def deleteOutsourcingShifts(ctx, shifts, headquater):
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # TODO remove
        if not headquater:
            db_headquarter = open_headquarter_by_code('mvideo')
        else:
            # Клиент
            db_headquarter = open_headquarter_by_code(headquater.code)
        if not db_headquarter:
            raise CustomError(
                f'Headquater {headquater.code} is not registered')

        # Выходим, если массив смен не задан
        if not shifts:
            return {'result': 'ok'}

        # Помечаем смены как удаленные и формируем уведомления
        for shift in shifts:
            # ----------------------------------------------------------
            out_shift = OutsourcingShift.objects.filter(
                guid=shift.guid, headquater=db_headquarter).first()
            if not out_shift:
                continue
            # Создаем и отправляем уведомления об удаленной смене
            make_notify_data(out_shift, 'agency', 'delete_shift_template')

            # Меняем состояние на удалена
            out_shift.state = 'delete'
            out_shift.save(update_fields=['state'])
            # -----------------------------------------------------------
        return {'result': 'ok'}

    """
    Получение изменений в данных сотрудников
    """

    @rpc(DateTime(sub_name='timestamp', min_occurs=1, nillable=False),
         HeadquaterSoapModel.customize(min_occurs=0, nillable=False),
         Integer(sub_name='amount', min_occurs=1, nillable=False),
         _returns=ComplexEmployeeEventResponseSoapModel,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def getEmployeeEvents(ctx, timestamp, headquater, amount):
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # Ограничинваем максимальное количество событий, возвращаемых за 1 раз
        if amount <= 0:
            amount = 100

        # TODO remove
        if not headquater:
            db_headquarter = open_headquarter_by_code('mvideo')
        else:
            # Клиент
            db_headquarter = open_headquarter_by_code(headquater.code)
        if not db_headquarter:
            raise CustomError(
                f'Headquater {headquater.code} is not registered')

        # Поиск событий, начиная с заданного в запросе timestamp
        response = dict()
        response['events_list'] = []
        events = EmployeeEvent.objects.filter(dt_created__gt=timestamp, headquater=db_headquarter). \
                     select_related('agency_employee', 'agency').order_by('id')[:amount]
        # Обогощаем найденные события доп. полями
        for event in events:
            # Тип агентства
            event.agency.party = event.agency.headquater.party
            # Документы сотрудника
            event.agency_employee.documents = EmployeeDoc.objects.filter(
                agency_employee=event.agency_employee).order_by('-id')
            # Обнуляем лишние поля
            if event.kind != 'recruitment':
                event.recruitment_date = None
            if event.kind != 'dismissal':
                event.dismissal_reason = None
                event.dismissal_date = None
                event.blacklist = None
        # Добавляем возвращемые события в ответное сообщение
        response['result'] = len(events)
        if events:
            response['timestamp'] = events.aggregate(
                timestamp=Max('dt_created'))['timestamp']
            response['events_list'] = events
        return response

    """DEPRICATED"""

    @rpc(HeadquaterSoapModel.customize(min_occurs=1, nillable=False),
         OrganizationSoapModel.customize(min_occurs=1, nillable=False),
         AgencySoapModel.customize(min_occurs=1, nillable=False),
         EmployeeMinSoapModel,
         EventSoapModel.customize(sub_name='event'),
         Unicode(sub_name='kind', min_occurs=1, nillable=False),
         Unicode(sub_name='number', min_occurs=0, nillable=False),
         Date(sub_name='recruitment_date', min_occurs=0, nillable=False),
         Date(sub_name='recruitment_state', min_occurs=0, nillable=False),
         Date(sub_name='dismissal_date', min_occurs=0, nillable=False),
         Unicode(sub_name='reject_reason', min_occurs=0, nillable=False),
         Unicode(sub_name='dismissal_reason', min_occurs=0, nillable=False),
         _returns=Unicode,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def setEventHistory(ctx, headquater, organization, agency, employee,
                        employeeevent, kind, number, recruitment_date,
                        recruitment_state, dismissal_date, reject_reason,
                        dismissal_reason):
        raise CustomError('Method is deprocated')

        # TODO изменить проверку доступа с is_superuser

        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        headquater_id = get_headquater_id(headquater.code)

        org = Organization.objects.get(code=organization.code,
                                       headquater_id=headquater_id)
        if not org:
            raise CustomError('No organiztion')

        agn = Agency.objects.get(code=agency.code)
        if not agn:
            raise CustomError('No agency')

        emp = AgencyEmployee.objects.get(number=employee.number, agency=agn)
        if not emp:
            raise CustomError('No employee')

        event = EmployeeEvent.objects.get(guid=employeeevent.guid)

        user = User.objects.get(username=ctx.in_header.login)

        if kind not in dict(EVENT_HISTORY_KIND_CHOICES):
            raise CustomError('No kind')
        elif kind == 'accept_recruitment':

            if not recruitment_date:
                raise CustomError('No recruitment_date')

            if recruitment_state not in ['active', 'inactive']:
                raise CustomError('No recruitment_state')
            """Создаем объект внешнего события"""
            EmployeeHistory.objects.create(user=user,
                                           headquater_id=headquater_id,
                                           organization=org,
                                           event=event,
                                           agency_employee=emp,
                                           agency=agn,
                                           kind=kind,
                                           recruitment_date=recruitment_date,
                                           recruitment_state=recruitment_state)

            if recruitment_state == 'active':
                """Создаем объект назначения"""
                OrgHistory.objects.create(headquater_id=headquater_id,
                                          organization=org,
                                          agency_employee=emp,
                                          number=number,
                                          start=recruitment_date)
            """Устанавливаем EmployeeEvent флаг, что ответ на него получен"""
            event.answer_received = True
            event.save(update_fields=['answer_received'])
        elif kind == 'reject_recruitment':

            if not reject_reason:
                raise CustomError('No reject_reason')
            """Создаем объект внешнего события"""
            EmployeeHistory.objects.create(user=user,
                                           headquater_id=headquater_id,
                                           organization=org,
                                           event=event,
                                           agency_employee=emp,
                                           agency=agn,
                                           kind=kind,
                                           reject_reason=reject_reason)
            """Устанавливаем EmployeeEvent флаг, что ответ на него получен"""
            event.answer_received = True
            event.save(update_fields=['answer_received'])

        elif kind == 'dismissal':

            if not dismissal_date or not dismissal_reason:
                raise CustomError('No dismissal date or reason')
            """Ищем назначение и устанавливаем дату увольнения"""
            org_history = OrgHistory.objects.get(organization=org,
                                                 agency_employee=emp)
            if not org_history:
                raise CustomError('No OrgHistory')
            org_history.end = dismissal_date - timedelta(days=1)
            org_history.save(update_fields=['end'])
            """Ищем смены данного сотрудника после даты увольнения и снимаем назначение"""
            OutsourcingShift.objects.filter(
                agency_employee=emp,
                start_date__gt=dismissal_date - timedelta(days=1),
                headquater_id=headquater_id).update(agency_employee=None)
            """Создаем объект внешнего события"""
            EmployeeHistory.objects.create(user=user,
                                           headquater_id=headquater_id,
                                           organization=org,
                                           event=event,
                                           agency_employee=emp,
                                           agency=agn,
                                           kind=kind,
                                           dismissal_date=dismissal_date,
                                           dismissal_reason=dismissal_reason)
            """Устанавливаем EmployeeEvent флаг, что ответ на него получен"""
            event.answer_received = True
            event.save(update_fields=['answer_received'])
            """Устанавливаем сотруднику дату обновления данных по API"""
            event.agency_employee.last_external_update = timezone.now()
            event.agency_employee.save(update_fields=['last_external_update'])

        return "ok"

    """Подтверждение или отказ в приеме сотрудника из кадровой системы клиента"""

    @rpc(EventSoapModel2.customize(sub_name='event',
                                   min_occurs=1,
                                   nillable=False),
         Unicode(sub_name='status', min_occurs=1, nillable=False),
         Unicode(sub_name='recruitmentState',
                 min_occurs=0,
                 nillable=False,
                 default='active'),
         Date(sub_name='recruitmentDate', min_occurs=0, nillable=False),
         Unicode(sub_name='externalNumber', min_occurs=0, nillable=False),
         Unicode(sub_name='rejectReason', min_occurs=0, nillable=False),
         _returns=Unicode,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def setRecruitmentStatus(ctx, employeeevent, status, recruitmentState,
                             recruitmentDate, externalNumber, rejectReason):
        user = User.objects.get(username=ctx.in_header.login)
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # Проверка параметров
        event = EmployeeEvent.objects.get(guid=employeeevent.guid)
        if not event:
            raise CustomError(f'Event {employeeevent.guid} is undefined')
        if recruitmentState and recruitmentState not in ['active', 'inactive']:
            raise CustomError('No recruitmentState')
        if status not in ['accept', 'reject']:
            return

        # Подтверждение регистрации
        if status == 'accept':
            error = accept_employee_attach(user, event, recruitmentState,
                                           recruitmentDate, externalNumber)
        # Регистрация отклонена
        else:
            error = reject_employee_attach(user, event, rejectReason)
        # Обработчик ошибок
        if error:
            raise CustomError(error)

        # Устанавливаем сотруднику дату обновления данных по API
        event.agency_employee.last_external_update = timezone.now()
        event.agency_employee.save(update_fields=['last_external_update'])

        return

    """Открепление сотрудника от клиента по запросу из кадровой системы"""

    @rpc(HeadquaterSoapModel.customize(min_occurs=1, nillable=False),
         OrganizationSoapModel,
         AgencySoapModel.customize(min_occurs=1, nillable=False),
         Unicode(sub_name='externalNumber', min_occurs=1, nillable=False),
         Date(sub_name='dismissalDate', min_occurs=1, nillable=False),
         Unicode(sub_name='dismissalReason', min_occurs=1, nillable=False),
         Boolean(sub_name='blacklist', min_occurs=1, nillable=False),
         _returns=Unicode,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def dismissEmployee(ctx, headquater, organization, agency, ext_number,
                        dismissal_date, dismissal_reason, blacklist):
        user = User.objects.get(username=ctx.in_header.login)
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # Проверка параметров
        db_headquarter = open_headquarter_by_code(headquater.code)
        if not db_headquarter:
            raise CustomError(f'Headquater {headquater.code} is not found')
        if organization:
            db_organization = open_organization_by_code(
                organization.code, db_headquarter)
            if not db_organization:
                raise CustomError(
                    f'Organization {organization.code} is not found')
        else:
            db_organization = None
        db_agency = open_agency_by_code(agency.code, None)
        if not db_agency:
            raise CustomError(f'Agency {agency.code} is not found')

        # Определяем увольняемого сотрудника
        employees = employees_by_ext_number(db_headquarter, db_agency,
                                            ext_number)
        for employee in employees:
            dismiss_employee(user, employee, dismissal_date, dismissal_reason,
                             blacklist, db_headquarter, db_organization)
            # Устанавливаем сотруднику дату обновления данных по API
            employee.last_external_update = timezone.now()
            employee.save(update_fields=['last_external_update'])
        return

    ########
    @rpc(HeadquaterSoapModel.customize(min_occurs=1, nillable=False),
         Array(OrgunitSoapModel.customize(min_occurs=1, nillable=False)),
         Array(OrglinkSoapModel.customize(min_occurs=0, nillable=False)),
         _returns=Unicode,
         _throws=[AuthenticationError, AuthorizationError, CustomError])
    @soap_logger
    @check_auth_data
    def setOrgunits(ctx, headquater, orgunits, orglinks):
        """Set Orgunits. Синхронизитрует орг. структуру на основе данных из портала планирования"""

        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # Headquarter
        headquater_id = get_headquater_id(headquater.code)

        # Organizations
        orgunits_received = 0
        orgunits_created = 0
        orgunits_errors = 0
        if orgunits:
            for orgunit in orgunits:
                orgunits_received += 1
                org, org_created = Organization.objects.get_or_create(
                    code=orgunit.code, headquater_id=headquater_id)
                if org_created:
                    orgunits_created += 1
                org.name = orgunit.name
                org.address = orgunit.address
                org.kind = 'store'
                if orgunit.parent and org_created:
                    parent_org = Organization.objects.filter(
                        code=orgunit.parent.code,
                        headquater_id=headquater_id).first()
                    if parent_org:
                        org.parent = parent_org
                    else:
                        default, default_created = Organization.objects.get_or_create(
                            code=headquater.code + '_city_undefined',
                            name='Город не определен',
                            headquater_id=headquater_id,
                            kind='city')
                        org.parent = default
                org.last_external_update = timezone.now()
                org.save()

        # OrgLinks
        orglinks_received = 0
        orglinks_created = 0
        orglinks_errors = 0
        if orglinks:
            for orglink_imp in orglinks:
                orglinks_received += 1
                organization = Organization.objects.filter(
                    code=orglink_imp.organization.code).first()
                if not organization:
                    orglinks_errors += 1
                    continue
                agency = Agency.objects.filter(
                    code=orglink_imp.agency.code).first()
                if not agency:
                    orglinks_errors += 1
                    continue
                _, orglink_created = OrgLink.objects.get_or_create(
                    agency=agency,
                    organization=organization,
                    headquater_id=headquater_id)
                if orglink_created:
                    orglinks_created += 1

        return {
            'result': 'ok',
            'orgunits_received': orgunits_received,
            'orgunits_created': orgunits_created,
            'orgunits_errors': orgunits_errors,
            'orglinks_received': orglinks_received,
            'orglinks_created': orglinks_created,
            'orglinks_errors': orglinks_errors,
        }

    @rpc(HeadquarterSoapModel.customize(min_occurs=1, nillable=False),
         UserExtSoapModel.customize(sub_name='user',
                                    min_occurs=1,
                                    nillable=False),
         Array(AccessProfileSoapModel,
               sub_name='accessProfiles').customize(min_occurs=1,
                                                    nillable=False),
         _throws=[
             AuthenticationError, AuthorizationError,
             error.ResourceNotFoundError
         ])
    @soap_logger
    @check_auth_data
    def setUser(ctx, headquarter, user, access_list):
        auth_and_check_perms(ctx.in_header.login, ctx.in_header.password)

        # Обновляем или создаем сотрудника
        user_defaults = {
            'first_name': user.first_name,
            'last_name': user.last_name,
            'email': user.email,
            'is_active': user.is_active
        }
        db_user, created = User.objects.update_or_create(
            username=user.username, defaults=user_defaults)
        db_headquarter = open_headquarter_by_code(headquarter.code)
        db_access_role = None

        # Установка прав доступа
        if access_list is None:
            access_list = []

        for access_profile in access_list:
            try:
                db_organization = open_organization_by_code(
                    access_profile.unit.code, db_headquarter)
            except error.ResourceNotFoundError:
                continue

            if access_profile.role is not None:
                db_access_role = open_role_by_code(access_profile.role.code)

            if db_access_role is None:
                raise error.ResourceNotFoundError('accessRole')

            profile, _ = AccessProfile.objects.update_or_create(
                user=db_user,
                unit_type=ContentType.objects.get_for_model(db_organization),
                unit_id=db_organization.id,
                role=db_access_role,
                headquater=db_headquarter)
Exemplo n.º 23
0
class HeaderType(SmevModel):
    NodeId = Unicode(type_name="NodeId")
    MessageId = Unicode(type_name="MessageId")
    TimeStamp = DateTime(type_name="TimeStamp")
    MessageClass = Unicode(type_name="MessageClass",
                           values=["REQUEST", "RESPONSE"])