from django.db import transaction, models from engine.data import get_data_set_for, remove_recommendations, insert_recommendations from engine.data.util import matrix_str from engine.data.format import get_reason from engine.data.remote.conf import OBJECTS from engine.data.remote.util import get_timezone_for from web.models import Recommendation, Account from .tsp import TravellingSalesman, create_context from app.util import env, boolean, MINUTE import datetime as dt import logging ENABLE = { 'account': env('REC_ACCOUNT', True, boolean), 'opportunity': env('REC_OPPORTUNITY', True, boolean), 'lead': env('REC_LEAD', True, boolean), 'contact': env('REC_CONTACT', True, boolean) } logger = logging.getLogger(__name__) def refresh_recommendations_for_all(ctxs): for ctx in set(ctxs): refresh_recommendations_for(ctx) def refresh_recommendations_for(ctx): with transaction.atomic(): recs, solution = get_recommendations_for(ctx) remove_recommendations(ctx)
from ortools.constraint_solver import routing_enums_pb2 from ortools.constraint_solver import pywrapcp from engine.data import get_data_set_for from app.util import env, coalesce import math import logging logger = logging.getLogger(__name__) TIMEOUT = env('TIMEOUT', 10, int) MAX_SLACK = env('MAX_SLACK', None, int) SOLUTION_LIMIT = env('SOLUTION_LIMIT', None, int) OVERRIDE_TRANSIT_TIME = env('OVERRIDE_TRANSIT_TIME', None, int) FIRST_SOLUTION_STRATEGY = env('FIRST_SOLUTION_STRATEGY', 'PATH_CHEAPEST_ARC') class DataError(Exception): pass class TSPContext: def __init__(self, data_set): # Extract relevant data from data set self.data_set = data_set self.stops = data_set.get_stops() self.nodes = [0] + self.stops # Defaults self.num_vehicles = 1 self.depot = 0 self.day_duration = int((data_set.day['end'] - data_set.day['start']).total_seconds()) self.max_slack = coalesce(MAX_SLACK, self.day_duration)
from ortools.constraint_solver import pywrapcp from .util import create_context, create_context_for, get_search_params, set_transit_callback, timestamp, h from app.util import env, boolean import time import logging logger = logging.getLogger(__name__) ENABLE_TIME_DIMENSION = env('ENABLE_TIME_DIMENSION', True, boolean) ENABLE_TIME_WINDOWS = env('ENABLE_TIME_WINDOWS', True, boolean) ENABLE_DISJUNCTIONS = env('ENABLE_DISJUNCTIONS', True, boolean) ENABLE_DROPPING = env('ENABLE_DROPPING', True, boolean) ENABLE_INITIAL_ROUTE = env('ENABLE_INITIAL_ROUTE', True, boolean) D_TIME = 'time' class TravellingSalesman: def __init__(self, context): self.context = context self.manager = manager = pywrapcp.RoutingIndexManager(context.num_nodes, context.num_vehicles, context.depot) self.model = pywrapcp.RoutingModel(manager) self.params = get_search_params() self._setup() logger.debug('Model size: %d', self.model.Size()) def _setup(self): # Set global cost function as cumulative time transit_cb = set_transit_callback(self) if ENABLE_TIME_DIMENSION:
from .conf import OBJECTS from .util import get_locations_related_to_map, get_routes_for_location_ids, get_timezone_for, get_org_id from ..util import init_matrix, map_by, get_deep, find_deep, select from ..common import RecordSet, DataSet from app.util import env, lenv, boolean, clamp, DAY, get_default_date from pytz import timezone from operator import attrgetter from functools import partial import random import datetime as dt import logging import os logger = logging.getLogger(__name__) PENALTY = env('PENALTY', 9 * 60 * 60, int) DAY_START = lenv('DAY_START', '9:0:0', int, sep=':') DAY_END = lenv('DAY_END', '18:0:0', int, sep=':') MORNING = dt.time(*DAY_START) EVENING = dt.time(*DAY_END) DEFAULT_DRIVING_TIME = env('DEFAULT_DRIVING_TIME', 30 * 60, int) OVERRIDE_DRIVING_TIME = env('OVERRIDE_DRIVING_TIME', None, int) ENABLE_EVENTS = env('ENABLE_EVENTS', True, boolean) ENABLE_REMOTE_SERVICES = env('ENABLE_REMOTE_SERVICES', True, boolean) SERVICES = [ { 'type': 'meeting', 'time': 1 * 60 * 60, 'penalty': 1 }, ]
from django.db import models from app.util import env, DAY from functools import partial import datetime as dt import humanize CURRENCY_SYMBOL = env('CURRENCY', '€') NO_MSG = '{field} is not set' ACTIVITY_MSGS = { 'never': "Has never been {verb}", 'past': "Hasn't been {verb} {in}", 'today': "Was {verb} today", 'future': "Is set to be {verb} {in}", } SLA_MSGS = { 'past': "SLA expired {ago}", 'future': "SLA expires {in}", } EMAIL_MSGS = { 'never': "No bounced emails", 'past': "Last bounced email was {ago}", 'today': "Last bounced email was today", 'future': "Last bounced email {in}", } OPP_CLOSE_MSGS = {'past': "Closed {ago}", 'future': "Closes {in}"} UPSELL_MSGS = { 'Yes': 'Has the opportunity to upsell', 'Maybe': 'Maybe has the opportunity to upsell', 'No': 'Has no opportunity to upsell', } ACCOUNT_TYPES = {