def dispatch_job(start_day, end_day, team_code, dispatch_days): """Shows all available plugins""" print("Dispatch started...") from dispatch.team import service as team_service from sqlalchemy.orm import sessionmaker sl = sessionmaker(bind=engine) session = sl() team_obj = team_service.get_by_code(db_session=session, code=team_code) if not team_obj: print(f"Failed to find team by team_code = {team_code }, aborted.") return from dispatch.plugins.kandbox_planner.data_generator.veo_data_generator import ( dispatch_jobs_batch_optimizer, ) dispatch_jobs_batch_optimizer( { "service_url": "http://localhost:8000/api/v1", "start_day": start_day, "end_day": end_day, "dispatch_days": dispatch_days, "team_id": team_obj.id, } )
def create(*, db_session, worker_in: WorkerCreate) -> Worker: """Creates an worker.""" flag, msg = _check_business_hour(worker_in.business_hour) if flag: log.error(f"{worker_in.code} , {msg}") raise HTTPException(status_code=400, detail=f"{worker_in.code} , {msg}") team = team_service.get_by_code(db_session=db_session, code=worker_in.team.code) if worker_in.location is not None: worker_in.location.org_id = worker_in.org_id location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=worker_in.location) else: location_obj = None if worker_in.dispatch_user: u = auth_service.get_by_email(db_session=db_session, email=worker_in.dispatch_user.email) else: u = None contact = Worker(**worker_in.dict( exclude={"flex_form_data", "team", "location", "dispatch_user"}), team=team, location=location_obj, dispatch_user=u, flex_form_data=worker_in.flex_form_data) db_session.add(contact) db_session.commit() return contact
def update( *, db_session, worker: Worker, worker_in: WorkerUpdate, ) -> Worker: worker_data = jsonable_encoder(worker_in) update_data = worker_in.dict( skip_defaults=True, exclude={"flex_form_data", "team", "location"}, ) team = team_service.get_by_code(db_session=db_session, code=worker_in.team.code) location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=worker_in.location) for field in worker_data: if field in update_data: setattr(worker, field, update_data[field]) worker.flex_form_data = worker_in.flex_form_data worker.team = team worker.location = location_obj db_session.add(worker) db_session.commit() return worker
def create(*, db_session, worker_in: WorkerCreate) -> Worker: """Creates an worker.""" team = team_service.get_by_code(db_session=db_session, code=worker_in.team.code) if worker_in.location is not None: location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=worker_in.location) else: location_obj = None contact = Worker(**worker_in.dict( exclude={"flex_form_data", "team", "location"}), team=team, location=location_obj, flex_form_data=worker_in.flex_form_data) db_session.add(contact) db_session.commit() return contact
def run_batch_optimizer_view( request_in: ResetPlanningWindowInput, team_code: str = Query("1", alias="team_code"), current_user: DispatchUser = Depends(get_current_user), db_session: Session = Depends(get_db), ): org_code = current_user.org_code team = team_service.get_by_code(db_session=db_session, code=request_in.team_code) if team is None: raise HTTPException( status_code=400, detail=f"The team code you requested is not in your organization.", ) if team.org_id != current_user.org_id: raise HTTPException( status_code=400, detail=f"The team code you requested is not in your organization...", ) result_info = run_batch_optimizer( org_code=org_code, team_id=team.id,) return JSONResponse(result_info)
def update( *, db_session, worker: Worker, worker_in: WorkerUpdate, ) -> Worker: flag, msg = _check_business_hour(worker_in.business_hour) if flag: log.error(f"{worker_in.code} , {msg}") raise HTTPException(status_code=400, detail=f"{worker_in.code} , {msg}") update_data = worker_in.dict( exclude={"flex_form_data", "team", "location", "dispatch_user"}, ) if worker.team.code != worker_in.team.code: team = team_service.get_by_code(db_session=db_session, code=worker_in.team.code) worker.team = team if worker_in.location and (not worker.location or worker_in.location.location_code != worker.location.location_code): location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=worker_in.location) worker.location = location_obj if worker_in.dispatch_user and ( (worker.dispatch_user is None) or (worker.dispatch_user.email != worker_in.dispatch_user.email)): u = auth_service.get_by_email(db_session=db_session, email=worker_in.dispatch_user.email) worker.dispatch_user = u for field, field_value in update_data.items(): setattr(worker, field, field_value) worker.flex_form_data = worker_in.flex_form_data db_session.add(worker) db_session.commit() return worker
def create(*, db_session, location_in: LocationCreate) -> Location: location = location_in if type(location_in) != Location: if location_in.team is not None: team = get_by_code(db_session=db_session, code=location_in.team.code) else: team = None if location_in.dispatch_user is not None: user = auth_service.get_by_email( db_session=db_session, email=location_in.dispatch_user.email) else: user = None location = Location(**location_in.dict( exclude={"team", "dispatch_user"}), team=team, dispatch_user=user) db_session.add(location) db_session.commit() return location
def update(*, db_session, job: Job, job_in: JobUpdate, org_code: str) -> Job: tags = [] for t in job_in.tags: tags.append(tag_service.get_or_create(db_session=db_session, tag_in=TagUpdate(**t))) scheduled_secondary_workers = [] if job_in.scheduled_secondary_workers: for w in job_in.scheduled_secondary_workers: scheduled_secondary_workers.append( worker_service.get_by_code(db_session=db_session, code=w.code)) if job_in.team and job_in.team.code != job.team.code: team_obj = team_service.get_by_code(db_session=db_session, code=job_in.team.code) job.team = team_obj if job_in.location and job_in.location.location_code and job_in.location.location_code != job.location.location_code: location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=job_in.location) job.location = location_obj update_data = job_in.dict( skip_defaults=True, exclude={ "tags", "scheduled_secondary_workers", "requested_primary_worker", "scheduled_primary_worker", "team", "location", }, ) for field in update_data.keys(): setattr(job, field, update_data[field]) job.scheduled_secondary_workers = scheduled_secondary_workers job.tags = tags if job_in.scheduled_primary_worker is not None: job.scheduled_primary_worker = worker_service.get_by_code( db_session=db_session, code=job_in.scheduled_primary_worker.code) if job_in.requested_primary_worker is not None: job.requested_primary_worker = worker_service.get_by_code( db_session=db_session, code=job_in.requested_primary_worker.code) db_session.add(job) db_session.commit() event_service.log( db_session=db_session, source="Dispatch Core App", description=f"Job ({job_in.code}) is updated {job_in.flex_form_data}", job_id=job.id, ) print(f"\033[37;46m\t1: job update succeed {job.code}\033[0m") post_job_to_kafka(job=job, message_type=KafkaMessageType.UPDATE_JOB, db_session=db_session, org_code=org_code) print(f"\033[37;46m\t2: job psot kafka in succeed {job.code}\033[0m") # zulip send message if job.planning_status != JobPlanningStatus.UNPLANNED: zulip_dict = get_zulip_client_by_org_id(job.org_id) if zulip_dict: zulip_core = zulip_dict['client'] zulip_core.update_job_send_message( job, [job.scheduled_primary_worker] + job.scheduled_secondary_workers) return job
def create( *, db_session, # job_priority: str = None, # job_type: str, code: str, job_type: str = "visit", org_id: str = None, org_code: str = None, name: str = None, planning_status: str, tags: List[dict] = [], description: str = None, team: TeamCreate, location: LocationCreate, flex_form_data: dict = None, requested_primary_worker: WorkerCreate = None, requested_start_datetime: datetime = None, requested_duration_minutes: float = None, scheduled_primary_worker: WorkerCreate = None, scheduled_secondary_workers: List[WorkerCreate] = [], scheduled_start_datetime: datetime = None, scheduled_duration_minutes: float = None, auto_planning: bool = True, requested_skills: List[str] = [], requested_items: List[str] = [], life_cycle_status: JobLifeCycleUpdate = None ) -> Job: """Creates a new job.""" tag_objs = [] for t in tags: tag_objs.append(tag_service.get_or_create(db_session=db_session, tag_in=TagCreate(**t))) team_obj = team_service.get_by_code(db_session=db_session, code=team["code"]) location_obj = location_service.get_by_location_code( db_session=db_session, location_code=location["location_code"]) if location_obj is None: loc_to_create = LocationCreate(**location) loc_to_create.org_id = org_id if loc_to_create.geo_address_text and not loc_to_create.geo_latitude: try: nid = SHORTUUID.random(length=9) location_config = { "url": config.LOCATION_SERVICE_URL, "token": config.LOCATION_SERVICE_TOKEN, "request_method": config.LOCATION_SERVICE_REQUEST_METHOD, } payload = {"address_id": nid, "input_address": loc_to_create.geo_address_text } # get location service location_plug = service_plugin_service.get_by_service_id_and_type( db_session=db_session, service_id=team_obj.service_id, service_plugin_type=KandboxPlannerPluginType.kandbox_location_service, ).all() if location_plug: location_plugin = plugins.get(location_plug[0].plugin.slug) location_adapter_service = location_plugin(config=location_config) status, _location_ret, msg = location_adapter_service.get_pldt_location(payload) if status: if isinstance(_location_ret['latitude'], float): if _check_location(_location_ret, team_obj.flex_form_data): loc_to_create.geo_latitude = _location_ret['latitude'] loc_to_create.geo_longitude = _location_ret['longitude'] loc_to_create.id = _location_ret['location_id'] loc_to_create.location_code = _location_ret['location_code'] else: logService.create(db_session=db_session, log_in=LogCreate( title='Location Response Data OutSide', category='Location', content=f"location outside,job code:{code},input_address:{payload['input_address']}, msg:{str(_location_ret)}", org_id=int(org_id), team_id=team_obj.id)) log.error( f"Location Response Data OutSide ,{msg} :{payload['input_address']}") else: logService.create(db_session=db_session, log_in=LogCreate( title='Location Response Data NUll', category='Location', content=f"job code:{code},input_address:{payload['input_address']},msg:{str(_location_ret)}", org_id=int(org_id), team_id=team_obj.id)) log.error( f"Location Response Data NUll ,{msg} :{payload['input_address']}") else: logService.create(db_session=db_session, log_in=LogCreate( title=msg['type'], category='Location', content=f"job code:{code},input_address:{payload['input_address']},msg:{str(msg['msg'])}", org_id=int(org_id), team_id=team_obj.id)) log.error( f"Location Response failed ,{msg} :{payload['input_address']}") else: log.error( f"not find location plug,service:{team_obj.service_id},{KandboxPlannerPluginType.kandbox_location_service}") except Exception as e: print(traceback.format_exc()) log.error(f"address request error:{loc_to_create.geo_address_text},{ e} ") location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=loc_to_create) # if location_obj.geo_longitude < 1: # location_obj.geo_longitude = loc_to_create.geo_longitude # location_obj.geo_latitude = loc_to_create.geo_latitude db_session.add(location_obj) # location_obj = location_service.update( # db_session=db_session, location=location_obj, location_in=LocationUpdate(**location) # ) if requested_primary_worker: requested_primary_worker = worker_service.get_by_code( db_session=db_session, code=requested_primary_worker["code"]) if scheduled_primary_worker: scheduled_primary_worker = worker_service.get_by_code( db_session=db_session, code=scheduled_primary_worker["code"]) scheduled_secondary_workers_list = [] if scheduled_secondary_workers is not None: for w in scheduled_secondary_workers: scheduled_secondary_workers_list.append( worker_service.get_by_code(db_session=db_session, code=w['code'])) # We create the job if requested_skills: flex_form_data['requested_skills'] = requested_skills if requested_items: flex_form_data['requested_items'] = requested_items job = Job( code=code, name=name, org_id=org_id, job_type=job_type, description=description, planning_status=planning_status, tags=tag_objs, flex_form_data=flex_form_data, location=location_obj, team=team_obj, requested_start_datetime=requested_start_datetime, requested_duration_minutes=requested_duration_minutes, requested_primary_worker=requested_primary_worker, scheduled_start_datetime=scheduled_start_datetime, scheduled_duration_minutes=scheduled_duration_minutes, scheduled_primary_worker=scheduled_primary_worker, scheduled_secondary_workers=scheduled_secondary_workers_list, auto_planning=auto_planning, requested_skills=requested_skills, requested_items=requested_items, ) db_session.add(job) if job.job_type == JobType.REPLENISH: depot_code = flex_form_data["depot_code"] depot = depot_service.get_by_code(db_session=db_session, code=depot_code) for item_str in flex_form_data["requested_items"]: item_list = parse_item_str(item_str) item = item_service.get_by_code(db_session=db_session, code=item_list[0]) inv = inventory_service.get_by_item_depot( db_session=db_session, item_id=item.id, depot_id=depot.id, org_id=team_obj.org_id ).one_or_none() inv.curr_qty -= item_list[1] inv.allocated_qty += item_list[1] if inv.curr_qty < 0: log.error( f" Not enough inventory for item: {item_list[0]}, depot: {depot_code}, org.id: {team_obj.org_id}") continue db_session.add(inv) inventory_event_service.log( db_session=db_session, source="Env_Replenish", description=f"Allocated {item_list[1]} {item_list[0]} from depot: {depot_code}", item_code=item_list[0], depot_code=depot_code, item_id=item.id, depot_id=depot.id ) db_session.commit() print(f"\033[37;46m\t1:add job succeed,{code}\033[0m") log.info(f"1:add job succeed,{code}") event_service.log( db_session=db_session, source="Dispatch Core App", description=f"Job ({code}) is created, planning_status={planning_status}, requested_start_datetime={requested_start_datetime}", job_id=job.id, ) post_job_to_kafka(job=job, message_type=KafkaMessageType.CREATE_JOB, db_session=db_session, org_code=org_code) print(f"\033[37;46m\t2:job post kafka in succeed,{code}\033[0m") log.info(f"2:job post kafka in succeed,{code}") # zulip send message if job.planning_status != JobPlanningStatus.UNPLANNED: zulip_dict = get_zulip_client_by_org_id(job.org_id) if zulip_dict: zulip_core = zulip_dict['client'] zulip_core.update_job_send_message( job, [job.scheduled_primary_worker] + job.scheduled_secondary_workers) return job
def create( *, db_session, # job_priority: str = None, # job_type: str, code: str, name: str = None, planning_status: str, tags: List[dict], description: str = None, team: TeamCreate, location: LocationCreate, flex_form_data: dict = None, requested_primary_worker: WorkerCreate = None, requested_start_datetime: datetime = None, requested_duration_minutes: float = None, scheduled_primary_worker: WorkerCreate = None, scheduled_secondary_workers: List[WorkerCreate], scheduled_start_datetime: datetime = None, scheduled_duration_minutes: float = None, auto_planning: bool = True, ) -> Job: """Creates a new job.""" tag_objs = [] for t in tags: tag_objs.append( tag_service.get_or_create(db_session=db_session, tag_in=TagCreate(**t))) team_obj = team_service.get_by_code(db_session=db_session, code=team["code"]) loc_to_create = LocationCreate(**location) location_obj = location_service.get_or_create_by_code( db_session=db_session, location_in=loc_to_create) # if location_obj.geo_longitude < 1: # location_obj.geo_longitude = loc_to_create.geo_longitude # location_obj.geo_latitude = loc_to_create.geo_latitude db_session.add(location_obj) # location_obj = location_service.update( # db_session=db_session, location=location_obj, location_in=LocationUpdate(**location) # ) if requested_primary_worker: requested_primary_worker = worker_service.get_by_code( db_session=db_session, code=requested_primary_worker["code"]) if scheduled_primary_worker: scheduled_primary_worker = worker_service.get_by_code( db_session=db_session, code=scheduled_primary_worker["code"]) if scheduled_secondary_workers is None: scheduled_secondary_workers = [] # We create the job job = Job( code=code, name=name, description=description, planning_status=planning_status, tags=tag_objs, flex_form_data=flex_form_data, location=location_obj, team=team_obj, requested_start_datetime=requested_start_datetime, requested_duration_minutes=requested_duration_minutes, requested_primary_worker=requested_primary_worker, scheduled_start_datetime=scheduled_start_datetime, scheduled_duration_minutes=scheduled_duration_minutes, scheduled_primary_worker=scheduled_primary_worker, scheduled_secondary_workers=scheduled_secondary_workers, auto_planning=auto_planning, ) db_session.add(job) db_session.commit() event_service.log( db_session=db_session, source="Dispatch Core App", description= f"Job ({code}) is created, planning_status={planning_status}, scheduled_start_datetime={scheduled_start_datetime}", job_id=job.id, ) post_job_to_kafka(job=job, message_type=KafkaMessageType.CREATE_JOB, db_session=db_session) return job
def create_worker(*, db_session: Session = Depends(get_db), worker_in: WorkerCreate, current_user: DispatchUser = Depends(get_current_user)): """ Create a new worker contact. """ # limit max org_data = orgService.get(db_session=db_session, org_code=current_user.org_code) if not org_data: raise HTTPException(status_code=400, detail="org not exists") max_nbr_worker = org_data.max_nbr_workers if worker_in.skills: worker_in.flex_form_data['skills'] = worker_in.skills if worker_in.loaded_items: worker_in.flex_form_data['loaded_items'] = worker_in.loaded_items job_all_count = get_by_org_id_count(db_session=db_session, org_id=current_user.org_id) if job_all_count >= max_nbr_worker: raise HTTPException(status_code=400, detail="Worker Reached the upper limit") worker_in.org_id = current_user.org_id worker = get_by_code_org_id(db_session=db_session, code=worker_in.code, org_id=current_user.org_id) team = team_service.get_by_code(db_session=db_session, code=worker_in.team.code) # use zulip zulip_user_id = worker_in.flex_form_data.get("zulip_user_id", None) result = None zulip_dict = get_zulip_client_by_org_id(current_user.org_id) if zulip_dict and zulip_user_id and worker_in.team.flex_form_data.get( 'use_zulip', False): flag, worker_code = check_zulip_user_id(db_session=db_session, zulip_user_id=zulip_user_id, team_id=team.id) if not flag: raise HTTPException( status_code=400, detail= f"The worker zulip_user_id already exists in {worker_code}") zulip_core = zulip_dict['client'] result = zulip_core.update_add_subscribe_user_group( worker_in, org_code=current_user.org_code, team_code=team.code, flag=True) if result and result['result'] != 'success': raise HTTPException(status_code=400, detail=f"{result['msg']}") # add worker if worker: raise HTTPException(status_code=400, detail="The worker with this code already exists.") worker = create(db_session=db_session, worker_in=worker_in) # change to env if current_user.org_code and team.id: message_dict = transfrom_worker_data(worker, team) post_worker_to_env(message_dict, current_user.org_code, team.id, False) return worker
def update_worker_by_code( *, db_session: Session = Depends(get_db), worker_code: str, worker_in: WorkerUpdate, current_user: DispatchUser = Depends(get_current_user)): """ Update a worker contact. """ worker_in.org_id = current_user.org_id worker = get_by_code(db_session=db_session, code=worker_code) code_change = False if worker_in.code != worker.code: code_change = True change_active = False if worker_in.is_active != worker.is_active: change_active = True count = get_count_by_active(db_session=db_session, is_active=True) if count < 2 and not worker_in.is_active: raise HTTPException(status_code=404, detail="There must be a normal worker.") if not worker: raise HTTPException(status_code=404, detail="The worker with this id does not exist.") if worker_in.requested_skills: worker_in.flex_form_data[ 'requested_skills'] = worker_in.requested_skills team = team_service.get_by_code(db_session=db_session, code=worker_in.team.code) # use zulip zulip_user_id = worker_in.flex_form_data.get("zulip_user_id", None) old_user_id = worker.flex_form_data.get("zulip_user_id", None) result = None zulip_dict = get_zulip_client_by_org_id(current_user.org_id) if zulip_dict and zulip_user_id and zulip_user_id != old_user_id and worker_in.team.flex_form_data.get( 'use_zulip', False): flag, worker_code = check_zulip_user_id(db_session=db_session, zulip_user_id=zulip_user_id, team_id=team.id) if not flag: raise HTTPException( status_code=400, detail= f"The worker zulip_user_id already exists in {worker_code}") zulip_core = zulip_dict['client'] result = zulip_core.update_add_subscribe_user_group( worker_in, org_code=current_user.org_code, team_code=team.code, flag=True) if result and result['result'] != 'success': raise HTTPException(status_code=400, detail=f"{result['msg']}") worker = update( db_session=db_session, worker=worker, worker_in=worker_in, ) if current_user.org_code and team.id: message_dict = transfrom_worker_data(worker, team) post_worker_to_env(message_dict, current_user.org_code, team.id, any([code_change, change_active])) return worker