text: import requests
  import base64
  from typing import List
  from typing import Optional
  from typing import Type
  
  from marshmallow import Schema
  from marshmallow.exceptions import ValidationError
  
  from portals import strings
  from portals.wwits import exceptions as wwitsExceptions
  from portals.wwits.apis.rest import WwitsResponse
  from portals.wwits.groups.communication.autopage_qry.schemas import AutoPageQrySchema
  from portals.wwits.groups.communication.autopage_update.schemas import (
      AutoPageUpdateSchema,
  )
  from portals.wwits.groups.service.wo_update_site_addr.schemas import (
      WOUpdateSiteAddrSchema,
  )
  from portals.wwits.groups.employee.query_tech_schedular.schemas import (
      TechSchedularSchema,
  )
  from portals.wwits.groups.employee.update_tech_schedular.schemas import (
      UpdateTechSchedularSchema,
  )
  from portals.wwits.groups.service_setup.query_entitlements.schemas import (
      EntitlementsSchema,
  )
  from portals.wwits.urls import wwits_url
  
  from portals.wwits.groups.access.session_start.schemas import (
      StartSessionSchema,
  )
  from portals.wwits.groups.access.session_end.schemas import EndSessionSchema
  from portals.wwits.groups.batch.request_for_open.schemas import (
      ReqForOpenSchema,
  )
  from portals.wwits.groups.batch.request_for_part.schemas import (
      ReqForPartSchema,
  )
  from portals.wwits.groups.batch.remark_new.schemas import (
      RemarkNewSchema,
  )
  
  
  from portals.wwits.groups.general.code.schemas import GetCodesSchema
  from portals.wwits.groups.general.query_table.schemas import QueryTableSchema
  from portals.wwits.groups.general.csrclassparms.schemas import CSRClassSchema
  from portals.wwits.groups.service_setup.canned_special_instructions.schemas import (
      CannedSpecialInstructionDataSchema,
  )
  from portals.wwits.groups.service_setup.update_canned_special_instructions.schemas import (  # noqa
      UpdateCannedSpecialInstructionsSchema,
  )
  from portals.wwits.groups.service_setup.update_tech_class.schemas import (
      UpdateTechClassSchema,
  )
  from portals.wwits.groups.service_setup.query_tech_class.schemas import (
      QueryTechClassSchema,
  )
  from portals.wwits.groups.service_setup.product_reference.schemas import (  # noqa
      ProductRefSchema,
  )
  from portals.wwits.groups.service.wo_update.schemas import WOUpdateSchema
  from portals.wwits.groups.service.wo_labor.schemas import WOLaborSchema
  from portals.wwits.groups.service.wo_remarks.schemas import WORemarksSchema
  from portals.wwits.groups.service.wo_detail.schemas import (
      WorkOrderDetailSchema,
  )
  from portals.wwits.groups.service.wo_labor_line.schemas import (
      WOLaborLineSchema,
  )
  from portals.wwits.groups.service.wo_labor_line_update.schemas import (
      WOLaborLineUpdateSchema,
  )
  from portals.wwits.groups.service.wo_labor_activities.schemas import (
      LaborActivitiesSchema,
  )
  from portals.wwits.groups.service.wo_labor_activity.schemas import (
      WOLaborActivitySchema,
  )
  from portals.wwits.groups.service.wo_update_labor_activity.schemas import (
      WOUpdateLaborActitySchema,
  )
  from portals.wwits.groups.employee.csr.schemas import OrganizationCSRSchema
  from portals.wwits.groups.employee.csrs.schemas import (
      OrganizationCSRsSchema,
  )
  from portals.wwits.groups.organization.org.schemas import (
      OrganizationChangesSchema,
  )
  from portals.wwits.groups.employee.csr_update.schemas import (
      OrganizationCSRUpdateSchema,
  )
  from portals.wwits.groups.certification.query_csr_skills.schemas import (
      QueryCSRSkillSchema,
  )
  from portals.wwits.groups.certification.query_skills.schemas import QuerySkillSchema
  from portals.wwits.groups.certification.update_csr_skills.schemas import (
      UpdateCSRSkillSchema,
  )
  from portals.wwits.groups.certification.update_skills.schemas import UpdateSkillSchema
  from portals.wwits.groups.territory.query_csr_territory.schemas import QueryCSRSchema
  from portals.wwits.groups.territory.update_csr_territory.schemas import UpdateCSRSchema
  from portals.wwits.groups.communication.notify.schemas import NotifySchema
  from portals.wwits.groups.communication.confirm_page.schemas import ConfirmPageSchema
  from portals.wwits.groups.communication.query_page.schemas import QueryPageSchema
  from portals.wwits.groups.service.wo_customer.schemas import WOCustomerSchema
  from portals.wwits.groups.service.wo_parts.schemas import WOPartsSchema
  from portals.wwits.groups.service.wo_part_line.schemas import WOPartLineSchema
  from portals.wwits.groups.service.wo_part_line_update.schemas import (
      WOPartLineUpdateSchema,
  )
  from portals.wwits.groups.service.wo_insert_remark.schemas import (
      WOInsertRemarkSchema,
  )
  from portals.wwits.groups.service_action.wo_assign.schemas import (
      WOAssignSchema,
  )
  from portals.wwits.groups.service_action.wo_reopen.schemas import (
      WOReOpenSchema,
  )
  from portals.wwits.groups.service_action.wo_close.schemas import WOCloseSchema
  from portals.wwits.groups.service_action.wo_eta.schemas import WOEtaSchema
  from portals.wwits.groups.service_action.wo_schedule.schemas import (
      WOScheduleSchema,
  )
  from portals.wwits.groups.service_action.wo_actual_travel.schemas import (
      WOActualTravelSchema,
  )
  from portals.wwits.groups.access.user_customers.schemas import (
      UserCustomerSchema,
  )
  from portals.wwits.groups.access.function_authorize_list.schemas import (
      FunctionAuthorizeListSchema,
  )
  from portals.wwits.groups.access.user_info.schemas import (
      UserInfoSchema,
  )
  from portals.wwits.groups.access.user_vendors.schemas import (
      UserVendorsSchema,
  )
  
  QUE_ENVIRONMENT = None
  VERSION = "v1"
  SOURCE = "WMP"
  
  
  def set_environment(environment):
      global QUE_ENVIRONMENT
      QUE_ENVIRONMENT = environment
  
  
  def encode_base64(str_):
      return base64.b64encode(str_.encode()).decode("utf-8")
  
  
  def rest_url(suffix: str) -> str:
      return wwits_url(f"/WWITS-RESTServer/{suffix.lstrip('/')}")
  
  
  class BaseGroup:
      @property
      def base_url(self):
          raise NotImplementedError
  
      headers = {
          "Content-Type": "application/json",
          "Accept": "application/json",
      }
  
      def get_url(
          self, user_id: str, session: int, prefix: str = "", suffix: str = ""
      ) -> str:
          url = f"{self.base_url}"
  
          if prefix:
              url = f"{url}/{prefix}"
  
          url = f"{url}/{VERSION}/{QUE_ENVIRONMENT}/{user_id}/{session}/{SOURCE}"
  
          if suffix:
              url = f"{url}/{suffix}"
  
          return url
  
      @staticmethod
      def check_required_params(
          params_required: List[str],
          params_passed: dict,
          ex_params: Optional[List[str]] = None,
      ) -> None:
          for param in params_required:
              if param not in params_passed:
                  raise KeyError(f"{param} parameter not provided")
  
          if ex_params:
              param_set = set(ex_params)
              intersection = param_set & params_passed.keys()
              if len(intersection) != 1:
                  raise KeyError(f"Either one of {ex_params} should be passed")
  
      @staticmethod
      def remove_empty(dict_: dict) -> dict:
          """Method to remove blank/None parameters from
          the dictionary.
  
          Returns:
              dict: New dictionary with non blank/None parameters
          """
          return {k: v for k, v in dict_.items() if v not in ("", None)}
  
      def make_response(
          self,
          schema: Type[Schema],
          url: str,
          request_type: str = "get",
          headers: dict = None,
          params: dict = None,
          json: dict = None,
          results_key: str = None,
      ) -> WwitsResponse:
          """Method to create a response object which will
          be used in the WMP project. It makes a request to the
          given URL with provided params, headers, json. Then
          serializes the response using the given schema and returns
          the same wrapped in WwitsResponse object.
          """
          if not headers:
              headers = self.headers
          request = getattr(requests, request_type.lower())
          try:
              response = request(url, headers=headers, params=params, json=json)
              schema = schema().load(response.json())
          except ValidationError as exc:
              raise wwitsExceptions.SchemaValidationException(
                  f"Error validating {schema.__name__}"
              ) from exc
          except TypeError as exc:
              raise wwitsExceptions.ModelTypeException(
                  f"Error creating models for {schema.__name__}"
              ) from exc
  
          return WwitsResponse(schema, results_key)
  
  
  class GTAccess(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Access")
  
      def start_session(self, user: str, password: str) -> WwitsResponse:
          auth_value = encode_base64(f"{user}:{password}")
          headers = {
              "Content-Type": "application/json",
              "Accept": "application/json",
          }
          headers["authorization"] = f"Basic {auth_value}"
          url = f"{self.base_url}/Session/{VERSION}/" f"{QUE_ENVIRONMENT}/{SOURCE}/Start"
          response = requests.get(url, headers=headers)
          schema = StartSessionSchema().load(response.json())
          return WwitsResponse(schema)
  
      def end_session(self, user_id: str, session: int):
          url = (
              f"{self.base_url}/Session/{VERSION}/"
              f"{QUE_ENVIRONMENT}/{SOURCE}/End/{user_id}/{session}"
          )
          return self.make_response(EndSessionSchema, url, request_type="post")
  
      def UserCustomers(self, user_id: str, session: int):
          url = self.get_url(user_id, session, prefix="UserCustomers/")
          return self.make_response(UserCustomerSchema, url, results_key="DataList")
  
      def FunctionAuthorizeList(self, user_id: str, session: int):
          url = self.get_url(user_id, session, prefix="FunctionAuthorizeList/")
          return self.make_response(
              FunctionAuthorizeListSchema, url, results_key="DataList"
          )
  
      def GetUserInfo(self, user_id: str, session: int):
          url = self.get_url(user_id, session, prefix="UserInfo/")
          return self.make_response(UserInfoSchema, url)
  
      def GetUserVendorInfo(self, user_id: str, session: int):
          url = self.get_url(user_id, session, prefix="UserVendors")
          return self.make_response(UserVendorsSchema, url, results_key="DataList")
  
  
  class GTCallInterface(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Callinterface")
  
      def request_for_open(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          url = self.get_url(user_id, session, suffix="RequestForOpen/")
          return self.make_response(
              ReqForOpenSchema, url, request_type="put", json={"Parms": params}
          )
  
      def request_for_part(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          pf_seq = kwargs.get("PfSeq")
          url = self.get_url(user_id, session, suffix=f"RequestForPart/{pf_seq}")
          return self.make_response(
              ReqForPartSchema, url, request_type="put", json={"Parms": params}
          )
  
      def remark_new(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          url = self.get_url(user_id, session, suffix="RemarkNew/")
          return self.make_response(
              RemarkNewSchema, url, request_type="put", json={"Parms": params}
          )
  
      def cancel_wo(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          url = self.get_url(user_id, session, suffix="CancelWO/")
          return self.make_response(
              ReqForOpenSchema, url, request_type="put", json={"Parms": params}
          )
  
  
  class GTService(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Service/WO")
  
      def GetCallDetailV3(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          self.check_required_params([], params, ["Ordernum", "CustCall"])
          url = self.get_url(user_id, session)
          return self.make_response(
              WorkOrderDetailSchema, url, params=params, results_key="WO"
          )
  
      def QueryLaborItems(
          self, user_id: str, session: int, work_order_id: str, select_csr: str
      ) -> WwitsResponse:
          params = dict(SelectCSR=select_csr) if select_csr else {}
          suffix = f"{work_order_id}/Labor"
          url = self.get_url(user_id, session, suffix=suffix)
          return self.make_response(
              WOLaborSchema, url, params=params, results_key="Labor"
          )
  
      def GetCallRemarks(
          self, user_id: str, session: int, work_order_id: str, lang_id: str = ""
      ) -> WwitsResponse:
          suffix = f"{work_order_id}/Remarks"
          params = dict(LangID=lang_id) if lang_id else {}
          url = self.get_url(user_id, session, suffix=suffix)
          return self.make_response(
              WORemarksSchema, url, params=params, results_key="Remarks"
          )
  
      def GetLaborItem(
          self,
          user_id: str,
          session: int,
          order_no: str,
          **kwargs,
      ) -> WwitsResponse:
          suffix = f"{order_no}/LaborItem"
          url = self.get_url(user_id, session, suffix=suffix)
          return self.make_response(WOLaborLineSchema, url, params=kwargs)
  
      def QueryLaborActivities(
          self, user_id: str, session: int, work_order: str
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix=f"{work_order}/LbrActs")
          return self.make_response(LaborActivitiesSchema, url, results_key="LbrActs")
  
      def GetLaborActivity(
          self, user_id: str, session: int, work_order: str, line_no: int
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix=f"{work_order}/LbrAct/{line_no}")
          return self.make_response(WOLaborActivitySchema, url)
  
      def QueryCustomerOrders(
          self,
          user_id: str,
          session: int,
          custcode: str,
          opensince: str,
          wostatus: str,
          **kwargs,
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix="CustomerOrders")
          params = dict(CustCode=custcode, OpenSince=opensince, WOStatus=wostatus)
          params.update(kwargs)
          return self.make_response(
              WOCustomerSchema, url, json=dict(Parms=params), results_key="Orders"
          )
  
      def GetCallParts(
          self, user_id: str, session: int, order_no: str, mode: str = ""
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix=f"{order_no}/Parts")
          params = {"mode": mode} if mode else {}
          return self.make_response(WOPartsSchema, url, params=params, results_key="WO")
  
      def GetCallPartDetail(
          self, user_id: str, session: int, order_no: str, line_no: int, **kwargs
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix=f"{order_no}/Part/{line_no}")
          return self.make_response(
              WOPartLineSchema, url, params=kwargs, results_key="WO"
          )
  
      def InsertCallRemark(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix=f"{order_no}/Remark")
          return self.make_response(
              WOInsertRemarkSchema,
              url,
              request_type="post",
              json=dict(Parms=kwargs),
          )
  
      def UpdateCallPart(
          self,
          user_id: str,
          session: int,
          order_no: str,
          line_num: int = 0,
          **kwargs,
      ) -> WwitsResponse:
          params_required = [
              "Mode",
              "QTYOrd",
              "FromWhse",
              "ChgWhse",
          ]
          if kwargs["Mode"] in ("U", "D"):
              params_required.extend(("Entity", "EntityRecid", "EntityCount"))
          if kwargs.get("PartRetCd", None):
              params_required.append("NonRetCd")
          elif kwargs.get("PartRetCd") in (1, 3, 4):
              params_required.extend(("RetWaybill", "RetCarrier", "RetDate"))
  
          self.check_required_params(params_required, kwargs)
          url = self.get_url(user_id, session, suffix=f"{order_no}/Part/{line_num}")
          return self.make_response(
              WOPartLineUpdateSchema,
              url,
              request_type="put",
              json=dict(Parms=kwargs),
          )
  
      def UpdateCallDetail(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(
              [
                  "Entity",
                  "EntityRecid",
                  "EntityCount",
                  "ParmNames",
                  "ParmValues",
              ],
              kwargs,
          )
          url = self.get_url(user_id, session, suffix=f"{order_no}")
          return self.make_response(
              WOUpdateSchema, url, request_type="put", params=kwargs
          )
  
      def UpdateLaborV2(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, suffix=f"{order_no}/Labor")
          params_required = [
              "Mode",
              "Csr",
              "StopCode",
              "ProcessType",
              "StCdOvride",
              "MileageTo",
              "MileageFrom",
          ]
          if kwargs.get("Mode") in ("U", "D"):
              params_required.extend(["Entity", "EntityRecid", "EntityCount"])
          self.check_required_params(params_required, kwargs)
          return self.make_response(
              WOLaborLineUpdateSchema,
              url,
              request_type="put",
              json=dict(Parms=kwargs),
          )
  
      def UpdateLaborActivity(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          params_required = [
              "Entity",
              "EntityRecid",
              "EntityCount",
              "LineNum",
              "ProdRef",
              "AvgRepair",
              "Qty",
              "CSRCode",
              "Mode",
          ]
          self.check_required_params(params_required, kwargs)
          suffix = f"{order_no}/LbrAct"
          url = self.get_url(user_id, session, suffix=suffix)
          return self.make_response(
              WOUpdateLaborActitySchema,
              url,
              request_type="put",
              json={"Parms": kwargs},
          )
  
      def UpdateSiteAddr(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          suffix = f"{order_no}/SiteAddress"
          url = self.get_url(user_id, session, suffix=suffix)
          return self.make_response(
              WOUpdateSiteAddrSchema,
              url,
              request_type="put",
              json={"Parms": kwargs},
          )
  
  
  class GTGeneral(BaseGroup):
      @property
      def base_url(self):
          return rest_url("General")
  
      def GetCodes(self, user_id: str, session: int, stop_code: str) -> WwitsResponse:
          stop_code = strings.encode_special_characters(stop_code)
          url = self.get_url(user_id, session, prefix="Codes", suffix=stop_code)
          return self.make_response(GetCodesSchema, url, results_key="GetCodes")
  
      def QueryTable(
          self, user_id: str, session: int, tablename: str, **kwargs
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="Table", suffix=tablename)
          return self.make_response(
              QueryTableSchema, url, params=kwargs, results_key="Table"
          )
  
      def CSRClassParms(self, user_id: str, session: int, csrcode: str) -> WwitsResponse:
          params = {"csrcode": csrcode}
          url = self.get_url(user_id, session, prefix="CSRClassParms", suffix="Class")
          return self.make_response(
              CSRClassSchema, url, params=params, results_key="CSRClassParms"
          )
  
  
  class GTEmployee(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Employee")
  
      def GetCSRInfoV3(self, user_id: str, session: int, csrcode: str) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="CSR", suffix=csrcode)
          return self.make_response(OrganizationCSRSchema, url, results_key="CSRData")
  
      def QueryCSRV2(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="CSRs")
          params = self.remove_empty(kwargs)
          return self.make_response(
              OrganizationCSRsSchema, url, params=params, results_key="CSRsInfo"
          )
  
      def UpdateCSRInfoV6(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          self.check_required_params(
              [
                  "CSRCode",
                  "Mode",
                  "Entity",
                  "EntityRecid",
                  "EntityCount",
              ],
              kwargs,
          )
          url = self.get_url(user_id, session, prefix="CSRUpd")
          return self.make_response(
              OrganizationCSRUpdateSchema,
              url,
              results_key="CSRJSON",
              request_type="post",
              json={"tblw": [kwargs]},
          )
  
      def QueryTechSchedule(
          self, user_id: str, session: int, type_query: str, type_list: str
      ) -> WwitsResponse:
  
          url = self.get_url(
              user_id, session, suffix=f"{type_query}/{type_list}", prefix="TechSchedule"
          )
          return self.make_response(
              TechSchedularSchema, url, results_key="TechSched", request_type="get"
          )
  
      def UpdateTechSchedule(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="TechSchedule")
          return self.make_response(
              UpdateTechSchedularSchema,
              url,
              request_type="put",
              params=kwargs,
          )
  
  
  class GTOrganization(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Organization")
  
      def Org(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          self.check_required_params(["LastUpdDtmOld"], kwargs)
          url = self.get_url(user_id, session, prefix="Org", suffix="Changes")
          return self.make_response(
              OrganizationChangesSchema,
              url,
              params=kwargs,
              results_key="OrgChanges",
          )
  
  
  class GTCommunication(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Communication")
  
      def PageTech(
          self, user_id: str, session: int, Mode: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params([], kwargs, ["csrcode", "OrderNum"])
          if Mode == "W":
              assert "OrderNum" in kwargs
          elif Mode == "O":
              assert "csrcode" in kwargs
          url = self.get_url(
              user_id,
              session,
              prefix="Notify",
              suffix=f"{Mode}",
          )
          return self.make_response(NotifySchema, url, request_type="post", params=kwargs)
  
      def ConfirmPage(
          self, user_id: str, session: int, ConfirmType: str, CSRCode: str, **kwargs
      ) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          url = self.get_url(
              user_id, session, prefix="ConfirmPage", suffix=f"{ConfirmType}/{CSRCode}"
          )
          return self.make_response(
              ConfirmPageSchema, url, params=params, request_type="post"
          )
  
      def QueryPage(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="TechPageList")
          params = self.remove_empty(kwargs)
          return self.make_response(
              QueryPageSchema, url, params=params, results_key="TechPageList"
          )
  
      def AutoPageQry(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="AutoPageQry")
          params = self.remove_empty(kwargs)
          return self.make_response(
              AutoPageQrySchema, url, params=params, results_key="AutoPage"
          )
  
      def AutoPageUpdate(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="AutoPage")
          return self.make_response(
              AutoPageUpdateSchema,
              url,
              request_type="POST",
              json={"tblw": [kwargs]},
              results_key="AutoPageJSON",
          )
  
  
  class GTCertifications(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Certifications")
  
      def QueryCSRSkill(
          self, user_id: str, session: int, Code: str, Type: str, **kwargs
      ) -> WwitsResponse:
          url = self.get_url(
              user_id, session, prefix="TechSkills", suffix=f"{Code}/{Type}"
          )
          params = self.remove_empty(kwargs)
          return self.make_response(
              QueryCSRSkillSchema, url, params=params, results_key="CsrSkills"
          )
  
      def QuerySkill(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="Skills")
          params = self.remove_empty(kwargs)
          return self.make_response(
              QuerySkillSchema, url, params=params, results_key="Skill"
          )
  
      def UpdateSkill(
          self,
          user_id: str,
          session: int,
          RecType: str,
          Mode: str,
          SkillCode: str,
          **kwargs,
      ) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          url = self.get_url(
              user_id, session, prefix="Skills", suffix=f"{RecType}/{Mode}/{SkillCode}"
          )
          return self.make_response(
              UpdateSkillSchema, url, request_type="put", params=params
          )
  
      def UpdateCSRSkill(
          self,
          user_id: str,
          session: int,
          Mode: str,
          CsrCode: str,
          Skill: str,
          InactiveFlag: bool,
          **kwargs,
      ) -> WwitsResponse:
          params = self.remove_empty(kwargs)
          url = self.get_url(
              user_id,
              session,
              prefix="TechSkills",
              suffix=f"{Mode}/{CsrCode}/{Skill}/{InactiveFlag}",
          )
          return self.make_response(
              UpdateCSRSkillSchema, url, request_type="put", params=params
          )
  
  
  class GTTerritory(BaseGroup):
      @property
      def base_url(self):
          return rest_url("Territory")
  
      def QueryCSRTerritory(
          self, user_id: str, session: int, territory: str, **kwargs
      ) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="TechTerritory")
          return self.make_response(
              QueryCSRSchema,
              url,
              params=kwargs,
              json=territory,  # type: ignore [arg-type]
              results_key="CSRTerrChanges",
          )
  
      def UpdateCSRTerritory(
          self, user_id: str, session: int, Commands: str
      ) -> WwitsResponse:
          Commands = strings.encode_special_characters(Commands)
          url = self.get_url(user_id, session, prefix="TechTerritory")
          return self.make_response(
              UpdateCSRSchema,
              url,
              json=Commands,  # type: ignore [arg-type]
              request_type="put",
          )
  
  
  class GTServiceSetUp(BaseGroup):
      @property
      def base_url(self):
          return rest_url("ServiceSetup")
  
      def GetCannedSpecialInstructions(
          self, user_id: str, session: int, cust_code: str, **kwargs
      ) -> WwitsResponse:
          cust_code = strings.encode_special_characters(cust_code)
          url = self.get_url(
              user_id, session, prefix="CannedSpecialInstructions", suffix=cust_code
          )
          return self.make_response(
              CannedSpecialInstructionDataSchema,
              url,
              params=kwargs,
              results_key="CanSpInstData",
          )
  
      def GetProductReference(
          self, user_id: str, session: int, cust_code: str, mode: str, **kwargs
      ) -> WwitsResponse:
  
          url = self.get_url(
              user_id,
              session,
              prefix="ProductReference",
              suffix=f"ProductRef/{cust_code}/{mode}",
          )
          return self.make_response(
              ProductRefSchema,
              url,
              params=kwargs,
              results_key="ProductRef",
          )
  
      def GetEntitlements(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
  
          url = self.get_url(user_id, session, prefix="Entitlements")
          return self.make_response(
              EntitlementsSchema, url, params=kwargs, results_key="Entitlements"
          )
  
      def UpdateCannedSpecialInstructions(
          self, user_id: str, session: int, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(
              [
                  "Entity",
                  "EntityRecID",
                  "EntityCount",
                  "Mode",
                  "CustCode",
              ],
              kwargs,
          )
          url = self.get_url(user_id, session, prefix="/CannedSpecialInstructions")
          return self.make_response(
              UpdateCannedSpecialInstructionsSchema,
              url,
              request_type="PUT",
              json={"Parms": kwargs},
          )
  
      def QueryTechClass(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="/TechClass")
          return self.make_response(
              QueryTechClassSchema, url, params=kwargs, results_key="TechClassData"
          )
  
      def UpdateTechClass(self, user_id: str, session: int, **kwargs) -> WwitsResponse:
          url = self.get_url(user_id, session, prefix="/TechClass")
          return self.make_response(
              UpdateTechClassSchema,
              url,
              json={"Parms": kwargs},
              request_type="put",
              results_key="TechClassData",
          )
  
  
  class GTServiceAction(BaseGroup):
      @property
      def base_url(self):
          return rest_url("ServiceActions")
  
      def AssignWOCSR(
          self, user_id: str, session: int, order_no: str, mode: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(["CsrCode", "PageFlag"], kwargs)
          url = self.get_url(
              user_id, session, prefix="WO", suffix=f"{mode}/{order_no}/Assign"
          )
          return self.make_response(
              WOAssignSchema, url, request_type="put", params=kwargs
          )
  
      def ReopenWO(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(["ReOpenReason"], kwargs)
          url = self.get_url(user_id, session, prefix="WO", suffix=f"{order_no}/ReOpen")
          return self.make_response(
              WOReOpenSchema, url, request_type="put", params=kwargs
          )
  
      def CloseCall(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(
              [
                  "Entity",
                  "EntityRecID",
                  "EntityCount",
                  "EquipSerial",
                  "FixDesc",
                  "CloseDateTime",
                  "CSR",
                  "Problem",
                  "Cause",
                  "Repair",
              ],
              kwargs,
          )
          url = self.get_url(user_id, session, prefix="WO", suffix=f"{order_no}/Close")
          return self.make_response(WOCloseSchema, url, request_type="put", params=kwargs)
  
      def ETA(self, user_id: str, session: int, order_no: str, **kwargs) -> WwitsResponse:
          self.check_required_params(["CSRCode", "ETA_DateTime"], kwargs)
          url = self.get_url(user_id, session, prefix="WO", suffix=f"{order_no}/ETA")
          return self.make_response(WOEtaSchema, url, request_type="put", params=kwargs)
  
      def ExtAPI_SCH(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(
              ["SCH_ST_DTM", "SCH_EN_DTM", "Miles", "ETA_DateTime"], kwargs
          )
          url = self.get_url(user_id, session, prefix="WO", suffix=f"{order_no}/Sched")
          return self.make_response(
              WOScheduleSchema, url, request_type="put", params=kwargs
          )
  
      def ActualTravel(
          self, user_id: str, session: int, order_no: str, **kwargs
      ) -> WwitsResponse:
          self.check_required_params(["CSR", "DistanceTo"], kwargs)
          url = self.get_url(
              user_id, session, prefix="WO", suffix=f"{order_no}/ActualTravel"
          )
          return self.make_response(
              WOActualTravelSchema, url, request_type="put", params=kwargs
          )
  