<commit_before>import React, { useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import filter from 'lodash/filter';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import map from 'lodash/map';
import noop from 'lodash/noop';
import { Flex, Box } from 'rebass/styled-components';
import { Label, Switch } from '@rebass/forms/styled-components';
import moment from 'moment-timezone';

import Accordion from './elements/Accordion';
import Button from './elements/Button';
import DateRangePicker from './elements/DateRangePicker';
import {
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
} from './elements/Dialog';
import { MediumTitle, Caption, Body1 } from './elements/FontStyles';
import i18next from '../core/language';

const t = i18next.t.bind(i18next);

export const PrintDateRangeModal = (props) => {
  const {
    maxDays,
    mostRecentDatumDates,
    onClose,
    onClickPrint,
    onDatesChange,
    open,
    processing,
    timePrefs: { timezoneName = 'UTC' },
    trackMetric,
  } = props;

  const endOfToday = useMemo(() => moment.utc().tz(timezoneName).endOf('day').subtract(1, 'ms'), [open]);

  // We want the set dates to start at the floor of the start date and the ceiling of the end date
  // to ensure we are selecting full days of data.
  const setDateRangeToExtents = ({ startDate, endDate }) => ({
    startDate: startDate ? moment.utc(startDate).tz(timezoneName).startOf('day') : null,
    endDate: endDate ? moment.utc(endDate).tz(timezoneName).endOf('day').subtract(1, 'ms') : null,
  });

  const getLastNDays = (days, chartType) => {
    const endDate = get(mostRecentDatumDates, chartType)
      ? moment.utc(mostRecentDatumDates[chartType])
      : endOfToday;

    return setDateRangeToExtents({
      startDate: moment.utc(endDate).tz(timezoneName).subtract(days - 1, 'days'),
      endDate,
    });
  };

  const basicsDaysOptions = [14, 21, 30];
  const bgLogDaysOptions = [14, 21,30];
  const dailyDaysOptions = [14, 21, 30];

  const defaultDates = () => ({
    basics: getLastNDays(basicsDaysOptions[0], 'basics'),
    bgLog: getLastNDays(bgLogDaysOptions[2], 'bgLog'),
    daily: getLastNDays(dailyDaysOptions[0], 'daily'),
  });

  const defaults = useMemo(() => ({
    datePickerOpen: false,
    dates: defaultDates(),
    enabled: {
      basics: true,
      bgLog: true,
      daily: true,
      settings: true,
    },
    errors: {
      basics: false,
      bgLog: false,
      daily: false,
      general: false,
    },
    expandedPanel: 'basics',
    submitted: false,
  }), [mostRecentDatumDates]);

  const [dates, setDates] = useState(defaults.dates);
  const [enabled, setEnabled] = useState(defaults.enabled);
  const [errors, setErrors] = useState(defaults.errors);
  const [expandedPanel, setExpandedPanel] = React.useState(defaults.expandedPanel);
  const [submitted, setSubmitted] = useState(defaults.submitted);
  const [datePickerOpen, setDatePickerOpen] = useState(defaults.datePickerOpen);

  const presetDateRanges = {
    basics: useMemo(() => map(basicsDaysOptions, days => getLastNDays(days, 'basics')), [open]),
    bgLog: useMemo(() => map(bgLogDaysOptions, days => getLastNDays(days, 'bgLog')), [open]),
    daily: useMemo(() => map(dailyDaysOptions, days => getLastNDays(days, 'daily')), [open]),
  };

  const datesMatchPreset = (dates, presetDates) => {
    return moment(dates.startDate).isSame(presetDates.startDate) && moment(dates.endDate).isSame(presetDates.endDate);
  };

  const validateDatesSet = dates => (!moment.isMoment(dates.startDate) || !moment.isMoment(dates.endDate)
    ? t('Please select a date range')
    : false
  );

  const validateDates = ({ basics, bgLog, daily }) => {
    const validationErrors = {
      basics: enabled.basics && validateDatesSet(basics),
      bgLog: enabled.bgLog && validateDatesSet(bgLog),
      daily: enabled.daily && validateDatesSet(daily),
    };

    return validationErrors;
  };

  const validateChartEnabled = () => {
    const validationErrors = {
      general: (!enabled.basics && !enabled.bgLog && !enabled.daily && !enabled.settings)
        ? t('Please enable at least one chart to print')
        : false,
    };

    return validationErrors;
  }

  // Accordion Panels
  const handleAccordionChange = key => (event, isExpanded) => {
    setExpandedPanel(key);
  };

  const accordionProps = (chartType, header) => ({
    label: chartType,
    key: chartType,
    expanded: expandedPanel === chartType,
    onChange: handleAccordionChange(chartType),
    themeProps: {
      wrapper: {
        width: '100%',
      },
      panel: {
        width: '100%',
        px: 5,
        pt: 1,
        pb: 3,
      },
      header: {
        width: '100%',
        color: errors[chartType] ? 'feedback.danger' : undefined,
      },
    },
    header,
  });

  const panels = [
    {
      daysOptions: basicsDaysOptions,
      header: t('Basics Chart'),
      key: 'basics',
    },
    {
      daysOptions: dailyDaysOptions,
      header: t('Daily Charts'),
      key: 'daily',
    },
    {
      daysOptions: bgLogDaysOptions,
      header: t('BG Log Chart'),
      key: 'bgLog',
    },
    {
      header: t('Device Settings'),
      key: 'settings',
    },
  ];

  const formatDateEndpoints = dates => ([
    dates.startDate.valueOf(),
    moment.utc(dates.endDate).tz(timezoneName).add(1, 'day').startOf('day').valueOf(),
  ]);

  // Handlers
  const handleSubmit = () => {
    setSubmitted(true);

    const validationErrors = {
      ...validateDates(dates),
      ...validateChartEnabled(),
    };

    setErrors(validationErrors);

    if (!isEqual(validationErrors, defaults.errors)) return;

    const printOpts = {
      basics: { endpoints: formatDateEndpoints(dates.basics), disabled: !enabled.basics },
      bgLog: { endpoints: formatDateEndpoints(dates.bgLog), disabled: !enabled.bgLog },
      daily: { endpoints: formatDateEndpoints(dates.daily), disabled: !enabled.daily },
      settings: { disabled: !enabled.settings },
    };

    const getDateRangeMetric = (presets, chartType) => {
      const matches = filter(
        presets,
        (days, i) => datesMatchPreset(dates[chartType], presetDateRanges[chartType][i])
      );

      return get(map(matches, days => `${days} days`), [0], 'custom range');
    };

    const metrics = {
      basics: printOpts.basics.disabled ? 'disabled' : getDateRangeMetric(basicsDaysOptions, 'basics'),
      bgLog: printOpts.bgLog.disabled ? 'disabled' : getDateRangeMetric(bgLogDaysOptions, 'bgLog'),
      daily: printOpts.daily.disabled ? 'disabled' : getDateRangeMetric(dailyDaysOptions, 'daily'),
      settings: printOpts.settings.disabled ? 'disabled' : 'enabled',
    };

    trackMetric('Submitted Print Options', metrics);
    onClickPrint(printOpts);
  };

  const handleClose = () => {
    onClose();
  };

  // Set to default state when dialog is newly opened
  useEffect(() => {
    if (open) {
      setDatePickerOpen(defaults.datePickerOpen);
      setDates(defaults.dates);
      setEnabled(defaults.enabled);
      setErrors(defaults.errors);
      setExpandedPanel(defaults.expandedPanel);
      setSubmitted(defaults.submitted);
    }
  }, [open]);

  // Call `onDatesChange` prop method when dates change
  useEffect(() => {
    onDatesChange(dates);
  }, [dates]);

  // Validate dates and enabled statuses if submitted
  useEffect(() => {
    if (submitted) setErrors({ ...validateDates(dates), ...validateChartEnabled()});
  }, [enabled, dates]);

  return (
    <Dialog id="printDateRangePicker" maxWidth="md" open={open} onClose={handleClose}>
      <DialogTitle divider={false} onClose={handleClose}>
        <MediumTitle>{t('Print Report')}</MediumTitle>
      </DialogTitle>
      <DialogContent divider={false} minWidth="644px" p={0}>
        {map(panels, panel => (
          <Accordion {...accordionProps(panel.key, panel.header)}>
            <Box width="100%">
              <Flex mb={4}>
                <Label htmlFor={`enabled-${panel.key}`}>
                  <Body1 alignSelf="center">Include {panel.header}</Body1>
                  <Switch
                    name={`enabled-${panel.key}`}
                    ml={4}
                    checked={enabled[panel.key]}
                    onClick={() => setEnabled({ ...enabled, [panel.key]: !enabled[panel.key] })}
                  />
                </Label>
              </Flex>

              {enabled[panel.key] && panel.daysOptions && (
                <Box>
                  <Box mb={5}>
                    <Body1 mb={2}>{t('Number of days (most recent)')}</Body1>
                    <Flex id={`days-${panel.key}`}>
                      {map(panel.daysOptions, (days, i) => (
                        <Button
                          mr={2}
                          variant="chip"
                          id={`days-${panel.key}-${i}`}
                          name={`days-${panel.key}-${i}`}
                          key={`days-${panel.key}-${i}`}
                          value={days}
                          selected={datesMatchPreset(dates[panel.key], presetDateRanges[panel.key][i])}
                          onClick={() => setDates({ ...dates, [panel.key]: getLastNDays(days, panel.key) })}
                        >
                          {days} days
                        </Button>
                      ))}
                    </Flex>
                  </Box>
                  <Box mb={3}>
                    <Body1 mb={2}>{t('Or select a custom date range ({{maxDays}} days max)', { maxDays })}</Body1>
                    <DateRangePicker
                      startDate={dates[panel.key].startDate}
                      startDateId={`${[panel.key]}-start-date`}
                      endDate={dates[panel.key].endDate}
                      endDateId={`${[panel.key]}-end-date`}
                      onDatesChange={newDates => setDates({ ...dates, [panel.key]: setDateRangeToExtents(newDates) })}
                      isOutsideRange={day => (
                        endOfToday.diff(day) < 0 ||
                        (moment.isMoment(dates[panel.key].endDate) && dates[panel.key].endDate.diff(day, 'days') >= maxDays) ||
                        (moment.isMoment(dates[panel.key].startDate) && dates[panel.key].startDate.diff(day, 'days') <= -maxDays)
                      )}
                      onFocusChange={input => setDatePickerOpen(!!input)}
                      themeProps={{
                        minHeight: datePickerOpen ? '300px' : undefined,
                      }}
                    />
                  </Box>
                </Box>
              )}
            </Box>
            {errors[panel.key] && (
              <Caption mt={2} color="feedback.danger" id={`${panel.key}-error`}>
                {errors[panel.key]}
              </Caption>
            )}
          </Accordion>
        ))}
        {errors.general && (
          <Caption mx={5} mt={2} color="feedback.danger" id="general-print-error">
            {errors.general}
          </Caption>
        )}
      </DialogContent>
      <DialogActions justifyContent="space-between" py={2}>
        <Button variant="textSecondary" className="print-cancel" onClick={handleClose}>
          {t('Cancel')}
        </Button>
        <Button variant="textPrimary" className="print-submit" disabled={!isEqual(errors, defaults.errors)} processing={processing} onClick={handleSubmit}>
          {t('Print')}
        </Button>
      </DialogActions>
    </Dialog>
  );
};

PrintDateRangeModal.propTypes = {
  maxDays: PropTypes.number.isRequired,
  mostRecentDatumDates: PropTypes.shape({
    basics: PropTypes.number.isRequired,
    bgLog: PropTypes.number.isRequired,
    daily: PropTypes.number.isRequired,
  }),
  onClickPrint: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired,
  onDatesChange: PropTypes.func.isRequired,
  open: PropTypes.bool,
  processing: PropTypes.bool,
  timePrefs: PropTypes.shape({
    timezoneAware: PropTypes.bool,
    timezoneName: PropTypes.string.isRequired,
  }).isRequired,
  trackMetric: PropTypes.func.isRequired,
};

PrintDateRangeModal.defaultProps = {
  maxDays: 90,
  onClickPrint: noop,
  onClose: noop,
  onDatesChange: noop,
  trackMetric: noop,
};

export default PrintDateRangeModal;
<commit_msg>[RELEASE-1] Fix for print form submission when empty dates submitted for disabled chart<commit_after>import React, { useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import filter from 'lodash/filter';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import map from 'lodash/map';
import noop from 'lodash/noop';
import { Flex, Box } from 'rebass/styled-components';
import { Label, Switch } from '@rebass/forms/styled-components';
import moment from 'moment-timezone';

import Accordion from './elements/Accordion';
import Button from './elements/Button';
import DateRangePicker from './elements/DateRangePicker';
import {
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
} from './elements/Dialog';
import { MediumTitle, Caption, Body1 } from './elements/FontStyles';
import i18next from '../core/language';

const t = i18next.t.bind(i18next);

export const PrintDateRangeModal = (props) => {
  const {
    maxDays,
    mostRecentDatumDates,
    onClose,
    onClickPrint,
    onDatesChange,
    open,
    processing,
    timePrefs: { timezoneName = 'UTC' },
    trackMetric,
  } = props;

  const endOfToday = useMemo(() => moment.utc().tz(timezoneName).endOf('day').subtract(1, 'ms'), [open]);

  // We want the set dates to start at the floor of the start date and the ceiling of the end date
  // to ensure we are selecting full days of data.
  const setDateRangeToExtents = ({ startDate, endDate }) => ({
    startDate: startDate ? moment.utc(startDate).tz(timezoneName).startOf('day') : null,
    endDate: endDate ? moment.utc(endDate).tz(timezoneName).endOf('day').subtract(1, 'ms') : null,
  });

  const getLastNDays = (days, chartType) => {
    const endDate = get(mostRecentDatumDates, chartType)
      ? moment.utc(mostRecentDatumDates[chartType])
      : endOfToday;

    return setDateRangeToExtents({
      startDate: moment.utc(endDate).tz(timezoneName).subtract(days - 1, 'days'),
      endDate,
    });
  };

  const basicsDaysOptions = [14, 21, 30];
  const bgLogDaysOptions = [14, 21,30];
  const dailyDaysOptions = [14, 21, 30];

  const defaultDates = () => ({
    basics: getLastNDays(basicsDaysOptions[0], 'basics'),
    bgLog: getLastNDays(bgLogDaysOptions[2], 'bgLog'),
    daily: getLastNDays(dailyDaysOptions[0], 'daily'),
  });

  const defaults = useMemo(() => ({
    datePickerOpen: false,
    dates: defaultDates(),
    enabled: {
      basics: true,
      bgLog: true,
      daily: true,
      settings: true,
    },
    errors: {
      basics: false,
      bgLog: false,
      daily: false,
      general: false,
    },
    expandedPanel: 'basics',
    submitted: false,
  }), [mostRecentDatumDates]);

  const [dates, setDates] = useState(defaults.dates);
  const [enabled, setEnabled] = useState(defaults.enabled);
  const [errors, setErrors] = useState(defaults.errors);
  const [expandedPanel, setExpandedPanel] = React.useState(defaults.expandedPanel);
  const [submitted, setSubmitted] = useState(defaults.submitted);
  const [datePickerOpen, setDatePickerOpen] = useState(defaults.datePickerOpen);

  const presetDateRanges = {
    basics: useMemo(() => map(basicsDaysOptions, days => getLastNDays(days, 'basics')), [open]),
    bgLog: useMemo(() => map(bgLogDaysOptions, days => getLastNDays(days, 'bgLog')), [open]),
    daily: useMemo(() => map(dailyDaysOptions, days => getLastNDays(days, 'daily')), [open]),
  };

  const datesMatchPreset = (dates, presetDates) => {
    return moment(dates.startDate).isSame(presetDates.startDate) && moment(dates.endDate).isSame(presetDates.endDate);
  };

  const validateDatesSet = dates => (!moment.isMoment(dates.startDate) || !moment.isMoment(dates.endDate)
    ? t('Please select a date range')
    : false
  );

  const validateDates = ({ basics, bgLog, daily }) => {
    const validationErrors = {
      basics: enabled.basics && validateDatesSet(basics),
      bgLog: enabled.bgLog && validateDatesSet(bgLog),
      daily: enabled.daily && validateDatesSet(daily),
    };

    return validationErrors;
  };

  const validateChartEnabled = () => {
    const validationErrors = {
      general: (!enabled.basics && !enabled.bgLog && !enabled.daily && !enabled.settings)
        ? t('Please enable at least one chart to print')
        : false,
    };

    return validationErrors;
  }

  // Accordion Panels
  const handleAccordionChange = key => (event, isExpanded) => {
    setExpandedPanel(key);
  };

  const accordionProps = (chartType, header) => ({
    label: chartType,
    key: chartType,
    expanded: expandedPanel === chartType,
    onChange: handleAccordionChange(chartType),
    themeProps: {
      wrapper: {
        width: '100%',
      },
      panel: {
        width: '100%',
        px: 5,
        pt: 1,
        pb: 3,
      },
      header: {
        width: '100%',
        color: errors[chartType] ? 'feedback.danger' : undefined,
      },
    },
    header,
  });

  const panels = [
    {
      daysOptions: basicsDaysOptions,
      header: t('Basics Chart'),
      key: 'basics',
    },
    {
      daysOptions: dailyDaysOptions,
      header: t('Daily Charts'),
      key: 'daily',
    },
    {
      daysOptions: bgLogDaysOptions,
      header: t('BG Log Chart'),
      key: 'bgLog',
    },
    {
      header: t('Device Settings'),
      key: 'settings',
    },
  ];

  const formatDateEndpoints = ({ startDate, endDate }) => (startDate && endDate ? [
    startDate.valueOf(),
    moment.utc(dates.endDate).tz(timezoneName).add(1, 'day').startOf('day').valueOf(),
  ] : []);

  // Handlers
  const handleSubmit = () => {
    setSubmitted(true);

    const validationErrors = {
      ...validateDates(dates),
      ...validateChartEnabled(),
    };

    setErrors(validationErrors);

    if (!isEqual(validationErrors, defaults.errors)) return;

    const printOpts = {
      basics: { endpoints: formatDateEndpoints(dates.basics), disabled: !enabled.basics },
      bgLog: { endpoints: formatDateEndpoints(dates.bgLog), disabled: !enabled.bgLog },
      daily: { endpoints: formatDateEndpoints(dates.daily), disabled: !enabled.daily },
      settings: { disabled: !enabled.settings },
    };

    const getDateRangeMetric = (presets, chartType) => {
      const matches = filter(
        presets,
        (days, i) => datesMatchPreset(dates[chartType], presetDateRanges[chartType][i])
      );

      return get(map(matches, days => `${days} days`), [0], 'custom range');
    };

    const metrics = {
      basics: printOpts.basics.disabled ? 'disabled' : getDateRangeMetric(basicsDaysOptions, 'basics'),
      bgLog: printOpts.bgLog.disabled ? 'disabled' : getDateRangeMetric(bgLogDaysOptions, 'bgLog'),
      daily: printOpts.daily.disabled ? 'disabled' : getDateRangeMetric(dailyDaysOptions, 'daily'),
      settings: printOpts.settings.disabled ? 'disabled' : 'enabled',
    };

    trackMetric('Submitted Print Options', metrics);
    onClickPrint(printOpts);
  };

  const handleClose = () => {
    onClose();
  };

  // Set to default state when dialog is newly opened
  useEffect(() => {
    if (open) {
      setDatePickerOpen(defaults.datePickerOpen);
      setDates(defaults.dates);
      setEnabled(defaults.enabled);
      setErrors(defaults.errors);
      setExpandedPanel(defaults.expandedPanel);
      setSubmitted(defaults.submitted);
    }
  }, [open]);

  // Call `onDatesChange` prop method when dates change
  useEffect(() => {
    onDatesChange(dates);
  }, [dates]);

  // Validate dates and enabled statuses if submitted
  useEffect(() => {
    if (submitted) setErrors({ ...validateDates(dates), ...validateChartEnabled()});
  }, [enabled, dates]);

  return (
    <Dialog id="printDateRangePicker" maxWidth="md" open={open} onClose={handleClose}>
      <DialogTitle divider={false} onClose={handleClose}>
        <MediumTitle>{t('Print Report')}</MediumTitle>
      </DialogTitle>
      <DialogContent divider={false} minWidth="644px" p={0}>
        {map(panels, panel => (
          <Accordion {...accordionProps(panel.key, panel.header)}>
            <Box width="100%">
              <Flex mb={4}>
                <Label htmlFor={`enabled-${panel.key}`}>
                  <Body1 alignSelf="center">Include {panel.header}</Body1>
                  <Switch
                    name={`enabled-${panel.key}`}
                    ml={4}
                    checked={enabled[panel.key]}
                    onClick={() => setEnabled({ ...enabled, [panel.key]: !enabled[panel.key] })}
                  />
                </Label>
              </Flex>

              {enabled[panel.key] && panel.daysOptions && (
                <Box>
                  <Box mb={5}>
                    <Body1 mb={2}>{t('Number of days (most recent)')}</Body1>
                    <Flex id={`days-${panel.key}`}>
                      {map(panel.daysOptions, (days, i) => (
                        <Button
                          mr={2}
                          variant="chip"
                          id={`days-${panel.key}-${i}`}
                          name={`days-${panel.key}-${i}`}
                          key={`days-${panel.key}-${i}`}
                          value={days}
                          selected={datesMatchPreset(dates[panel.key], presetDateRanges[panel.key][i])}
                          onClick={() => setDates({ ...dates, [panel.key]: getLastNDays(days, panel.key) })}
                        >
                          {days} days
                        </Button>
                      ))}
                    </Flex>
                  </Box>
                  <Box mb={3}>
                    <Body1 mb={2}>{t('Or select a custom date range ({{maxDays}} days max)', { maxDays })}</Body1>
                    <DateRangePicker
                      startDate={dates[panel.key].startDate}
                      startDateId={`${[panel.key]}-start-date`}
                      endDate={dates[panel.key].endDate}
                      endDateId={`${[panel.key]}-end-date`}
                      onDatesChange={newDates => setDates({ ...dates, [panel.key]: setDateRangeToExtents(newDates) })}
                      isOutsideRange={day => (
                        endOfToday.diff(day) < 0 ||
                        (moment.isMoment(dates[panel.key].endDate) && dates[panel.key].endDate.diff(day, 'days') >= maxDays) ||
                        (moment.isMoment(dates[panel.key].startDate) && dates[panel.key].startDate.diff(day, 'days') <= -maxDays)
                      )}
                      onFocusChange={input => setDatePickerOpen(!!input)}
                      themeProps={{
                        minHeight: datePickerOpen ? '300px' : undefined,
                      }}
                    />
                  </Box>
                </Box>
              )}
            </Box>
            {errors[panel.key] && (
              <Caption mt={2} color="feedback.danger" id={`${panel.key}-error`}>
                {errors[panel.key]}
              </Caption>
            )}
          </Accordion>
        ))}
        {errors.general && (
          <Caption mx={5} mt={2} color="feedback.danger" id="general-print-error">
            {errors.general}
          </Caption>
        )}
      </DialogContent>
      <DialogActions justifyContent="space-between" py={2}>
        <Button variant="textSecondary" className="print-cancel" onClick={handleClose}>
          {t('Cancel')}
        </Button>
        <Button variant="textPrimary" className="print-submit" disabled={!isEqual(errors, defaults.errors)} processing={processing} onClick={handleSubmit}>
          {t('Print')}
        </Button>
      </DialogActions>
    </Dialog>
  );
};

PrintDateRangeModal.propTypes = {
  maxDays: PropTypes.number.isRequired,
  mostRecentDatumDates: PropTypes.shape({
    basics: PropTypes.number.isRequired,
    bgLog: PropTypes.number.isRequired,
    daily: PropTypes.number.isRequired,
  }),
  onClickPrint: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired,
  onDatesChange: PropTypes.func.isRequired,
  open: PropTypes.bool,
  processing: PropTypes.bool,
  timePrefs: PropTypes.shape({
    timezoneAware: PropTypes.bool,
    timezoneName: PropTypes.string.isRequired,
  }).isRequired,
  trackMetric: PropTypes.func.isRequired,
};

PrintDateRangeModal.defaultProps = {
  maxDays: 90,
  onClickPrint: noop,
  onClose: noop,
  onDatesChange: noop,
  trackMetric: noop,
};

export default PrintDateRangeModal;
<|endoftext|>


<commit_before>/**
*
* SocialButtons
*
*/

import {
  ShareButtons,
  generateShareIcon,
} from 'react-share';

const {
  FacebookShareButton,
  TwitterShareButton,
} = ShareButtons;

import React from 'react';
// import messages from './messages';

import styles from './styles.scss';

const FacebookIcon = generateShareIcon('facebook');
const TwitterIcon = generateShareIcon('twitter');

function SocialButtons() {
  return (

        Let's vote. Together.

        <FacebookShareButton
          url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAQxxq8RSEVWAQWJEt58Ura_KSXYKShhzhYHy-gI8Xgwn0lxkwfxrpY2mY"
          title="a cute cat"
          className={styles.social}
        >
          <FacebookIcon
            size={32}
            round
          />
        </FacebookShareButton>
        <TwitterShareButton
          url="http://www.tpevent.com/wp-content/uploads/2016/01/cute-cat-images-tpevent-5.jpg"
          title="twitter cute cat"
          className={styles.social}
        >
          <TwitterIcon
            size={32}
            round
          />
        </TwitterShareButton>

  );
}

export default SocialButtons;
<commit_msg>More sensible social buttons<commit_after>/**
*
* SocialButtons
*
*/

import {
  ShareButtons,
  generateShareIcon,
} from 'react-share';

const {
  FacebookShareButton,
  TwitterShareButton,
} = ShareButtons;

import React from 'react';
// import messages from './messages';

import styles from './styles.scss';

const FacebookIcon = generateShareIcon('facebook');
const TwitterIcon = generateShareIcon('twitter');

function SocialButtons() {
  return (

        Let's vote. Together.

        <FacebookShareButton
          url="votemate.us"
          title="VoteMate - Let's Vote. Together."
          className={styles.social}
        >
          <FacebookIcon
            size={32}
            round
          />
        </FacebookShareButton>
        <TwitterShareButton
          url="votemate.us"
          title="Are you registered to vote?"
          className={styles.social}
        >
          <TwitterIcon
            size={32}
            round
          />
        </TwitterShareButton>

  );
}

export default SocialButtons;
<|endoftext|>


<commit_before>import React from 'react';
import { spy } from 'sinon';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';

import Main from '../';
import { MainModel, setInitialState } from '../models';
import configureStore from 'shared/../store/ConfigureStore';

describe('Container', () => {

  describe('<Main />', () => {

    it('Should init Correctly', () => {

      spy(Main.prototype, 'componentDidMount');

      const store = configureStore([]);
      const component = mount(
        <Provider store={ store }>
            <Main />
        </Provider>
      );

      expect(Main.prototype.componentDidMount.calledOnce).to.equal(true);

    });

    it('Should have Logo & LinkButton', () => {

      setInitialState({});
      const fakeStore = {};
      fakeStore.Main = new MainModel({ id: 2222, src:'fakePath', alt:'aaaalt!', width:650 });
      const store = configureStore([], fakeStore);
      const component = mount(
        <Provider store={ store }>
            <Main />
        </Provider>
      );

      expect(component.find('LinkButton')).to.have.lengthOf(1);
      //TODO Improve ajax testing
      setTimeout(() => {
        expect(component.find('Logo')).to.have.lengthOf(1);
        done();
      }, 1000)
    });

  });
});
<commit_msg>bug fix test main container<commit_after>import React from 'react';
import { spy } from 'sinon';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';

import Main from '../';
import { MainModel, setInitialState } from '../models';
import configureStore from 'shared/../store/ConfigureStore';

describe('Container', () => {

  describe('<Main />', () => {

    it('Should init Correctly', () => {

      spy(Main.prototype, 'componentDidMount');

      const store = configureStore([]);
      const component = mount(
        <Provider store={ store }>
            <Main />
        </Provider>
      );

      expect(Main.prototype.componentDidMount.calledOnce).to.equal(true);

    });

    it('Should have Logo & LinkButton', () => {

      setInitialState({});
      const fakeStore = {};
      fakeStore.Main = new MainModel({ id: 2222, src:'fakePath', alt:'aaaalt!', width:650 });
      const store = configureStore([], fakeStore);
      const component = mount(
        <Provider store={ store }>
            <Main />
        </Provider>
      );

      expect(component.find('LinkButton')).to.have.lengthOf(2);
      //TODO Improve ajax testing
      setTimeout(() => {
        expect(component.find('Logo')).to.have.lengthOf(1);
        done();
      }, 1000)
    });

  });
});
<|endoftext|>


<commit_before>const handoverUtils = require('../utils/handoverUtils');
const officeUtils = require('../utils/officeUtils');
const claimantUtils = require('../utils/claimantUtils');
const userUtils = require('../utils/userUtils');
const sIDU = require('../utils/setInitialDataUtils');
const dateUtils = require('../utils/dateUtils');
const commonUtils = require('../utils/commonUtils');

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/*                                        Handover Controllers
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/

function viewHandoverPage(req, res) {

    let users = req.session.user ? req.session.user : sIDU.setInitialUsersData();
    let user = req.session.user ? req.session.user : users[0];
    let handoversList = req.session.handovers ? req.session.handovers : sIDU.setInitialBenefitsAndHandoversData().initialHandovers;
    let handover;
    let handoverNotes = [];

    if (req.query.id === null) {
        handover = req.session.handover ? req.session.handover : handoversList[0];
    } else {
        handover = handoverUtils.getHandoverByIdFromListOfHandovers(handoversList, req.query.id);
    }

    let handoverTextDetails = handoverUtils.getHandoverDetails(handover);
    let claimants = req.session.claimants ? req.session.claimants : sIDU.setInitialClaimantsData();
    let claimant;
    if (req.query.nino === null) {
        claimant= req.session.claimant ? req.session.claimant : claimants[0];
    } else {
        claimant = claimantUtils.getClaimantByNinoFromListOfClaimants(claimants, req.query.nino);
    }
    let officesList = sIDU.setInitialOfficesData();
    let officeId = claimant.claimantOfficeId || "3";
    let officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, officeId);
    let officeTypes = sIDU.setInitialOfficeTypesData();
    let officeTypesIndex = commonUtils.findPositionOfObjectInArray(officeDetails.officeTypeId, officeTypes);
    let officeTypeId = officeTypes[officeTypesIndex].id;
    let officeTypeName = officeTypes[officeTypesIndex].officeType;
    let officeType = {
        id : officeTypeId,
        officeType : officeTypeName
    }
    user.officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, user.owningOfficeId);
    let userOfficeTypeIndex = commonUtils.findPositionOfObjectInArray(user.officeDetails.officeTypeId, officeTypes);
    user.officeDetails.officeType = officeTypes[userOfficeTypeIndex].officeType;

    if (handover.notes === null) {
        handoverNotes = null;
    } else {
        let handNoteLen = handover.notes.length;
        for (let i=0; i < handNoteLen; i++) {
            let handoverNote = {
                id: handover.notes[i].id,
                dateNoteAdded: dateUtils.formatDateAndTimeForDisplay(handover.notes[i].dateNoteAdded),
                userWhoAddedNote: userUtils.getUserByStaffIdFromListOfUsers(users, handover.notes[i].userWhoAddedNote),
                noteContent: handover.notes[i].noteContent
            }
            handoverNotes.push(handoverNote);
        }
    }
    req.session.claimant = claimant;
    req.session.handovers = handoversList;
    req.session.handover = handover;
    req.session.officeDetails = officeDetails;

    res.render('handover', {
        benefitName : handoverTextDetails.benefitName,
        handoverType : handoverTextDetails.handoverType,
        handoverReason : handoverTextDetails.handoverReason,
        handoverNotes : handoverNotes,
        officeDetails : officeDetails,
        officeTypes : officeTypes,
        officeType : officeType,
        claimant : claimant,
        handover : handover,
        user : user,
    });

}

function viewHandoverPageAction(req, res) {

    let handover = req.session.handover;
    let claimantNino = req.session.claimant && req.session.claimant.nino || console.log("No claimant in session, or no nino in claimant");
    let handoverClaimant = req.session.claimant;

    req.session.claimant = handoverClaimant;
    req.session.handover = handover;

    res.redirect('/handover/edit?nino=' + claimantNino);

}

function createHandoverPage(req, res) {
    let editOrCreate = 'create';
    let initialData = sIDU.setInitialBenefitsAndHandoversData();
    let users = req.session.user ? req.session.user : sIDU.setInitialUsersData();
    let user = req.session.user ? req.session.user : users[0];
    let benefitsList = initialData.initialBenefits;
    let handoverTypesList = initialData.initialHandoverTypes;
    let handoverReasonsList = initialData.initialHandoverReasons;
    let handovers = req.session.handovers ? req.session.handovers : initialData.initialHandovers;
    let claimants = req.session.claimants ? req.session.claimants : sIDU.setInitialClaimantsData();
    let claimant = claimantUtils.getClaimantByNinoFromListOfClaimants(claimants, req.query.nino);
    let officesList = sIDU.setInitialOfficesData();
    let officeTypes = sIDU.setInitialOfficeTypesData();
    let officeId = 3;  // Change to let officeId = handover.raisedOnBehalfOfOfficeId || "3" once got different offices sorted
    let officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, officeId);

    user.officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, user.owningOfficeId);
    let userOfficeTypeIndex = commonUtils.findPositionOfObjectInArray(user.officeDetails.officeTypeId, officeTypes);
    user.officeDetails.officeType = officeTypes[userOfficeTypeIndex].officeType;

    req.session.claimant = claimant;
    req.session.handovers = handovers;
    req.session.claimants = claimants;

    res.render('handover-edit', {
        benList : benefitsList,
        handTypesList : handoverTypesList,
        handReasonsList : handoverReasonsList,
        claimant : claimant,
        user : user,
        officeDetails : officeDetails,
        officesList : officesList,
        officeTypes : officeTypes,
        editOrCreate : editOrCreate
    });

}

function createHandoverPageAction(req, res) {

    let newHandover = new Object();
    let handoversList = req.session.handovers ? req.session.handovers : sIDU.setInitialBenefitsAndHandoversData();
    let newDate = new Date();
    let newHandoversList = handoversList;
    let handoverNote = req.body['handover-note'];
    let claimant = req.session.claimant;
    let newId = handoversList.length + 1;

    newHandover.id = newId;
    newHandover.nino = claimant.nino;
    newHandover.staffId = '40001001';
    newHandover.raisedOnBehalfOfOfficeId = req.body['office-id'];
    newHandover.benefitId = req.body['benefit'];

    if (newHandover.benefitId === "5") {
        newHandover.benSubType = req.body['benefit-sub'];
    } else {
        newHandover.benSubType = null;
    }
    newHandover.typeId = req.body['handover-type'];;
    newHandover.reasonId = req.body['handover-reason'];
    newHandover.callback = req.body['callback-req'];
    newHandover.priority = req.body['handover-priority'];
    newHandover.status = "Not allocated";
    newHandover.dateAndTimeRaised = newDate;
    newHandover.targetDateAndTime = newDate;
    newHandover.notes = [];

    if (newHandover.callback === 'Yes') {
        newHandover.targetDateAndTime.setHours(newHandover.dateAndTimeRaised.getHours() + 3);
    }

    newHandover.dateAndTimeRaisedForDisplay = dateUtils.formatDateAndTimeForDisplay(newHandover.dateAndTimeRaised);
    newHandover.targetDateAndTimeForDisplay = dateUtils.formatDateAndTimeForDisplay(newHandover.targetDateAndTime);

    if (handoverNote === "" || handoverNote === null) {
        // Do nothing
    } else {
        let newHandoverNote = new Object();
        newHandoverNote.id = '1';
        newHandoverNote.handoverId = newHandover.id;
        newHandoverNote.dateNoteAdded = newDate;
        newHandoverNote.userWhoAddedNote = newHandover.staffId;
        newHandoverNote.noteContent = handoverNote;
        newHandover.notes.push(newHandoverNote);
    }

    newHandoversList.push(newHandover);
    req.session.handover = newHandover;
    req.session.handovers = newHandoversList;
    req.session.claimant = claimant;

    res.redirect('/handover/view?id=' + newId);

}

function editHandoverPage(req, res) {

    let editOrCreate = 'edit';
    let initialData = sIDU.setInitialBenefitsAndHandoversData();
    let users = req.session.user ? req.session.user : sIDU.setInitialUsersData();
    let user = req.session.user ? req.session.user : users[0];
    let benefitsList = initialData.initialBenefits;
    let handoverTypesList = initialData.initialHandoverTypes;
    let handoverReasonsList = initialData.initialHandoverReasons;
    let handovers = req.session.handovers ? req.session.handovers : initialData.initialHandovers;
    let handover = req.session.handover ? req.session.handover : handoverUtils.getHandoverByIdFromListOfHandovers(handovers, req.query.id);
    let handoverNotes = [];
    let claimants = req.session.claimants ? req.session.claimants : sIDU.setInitialClaimantsData();
    let claimant = claimantUtils.getClaimantByNinoFromListOfClaimants(claimants, req.query.nino);
    let officesList = sIDU.setInitialOfficesData();
    let officeId = handover.raisedOnBehalfOfOfficeId || "3";
    let officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, officeId);
    let officeTypes = sIDU.setInitialOfficeTypesData();
    let officeTypesIndex = commonUtils.findPositionOfObjectInArray(officeDetails.officeTypeId, officeTypes);
    let officeTypeId = officeTypes[officeTypesIndex].id;
    let officeTypeName = officeTypes[officeTypesIndex].officeType;
    let officeType = {
        officeTypeId : officeTypeId,
        officeTypeName : officeTypeName
    }
    user.officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, user.owningOfficeId);
    let userOfficeTypeIndex = commonUtils.findPositionOfObjectInArray(user.officeDetails.officeTypeId, officeTypes);
    user.officeDetails.officeType = officeTypes[userOfficeTypeIndex].officeType;

    if (handover.notes === null) {
        handoverNotes = null
    } else {
        for (let i=0; i < handover.notes.length; i++) {
            let handoverNote = {
                id: handover.notes[i].id,
                dateNoteAdded: dateUtils.formatDateAndTimeForDisplay(handover.notes[i].dateNoteAdded),
                userWhoAddedNote: userUtils.getUserByStaffIdFromListOfUsers(users, handover.notes[i].userWhoAddedNote),
                noteContent: handover.notes[i].noteContent
            }
            handoverNotes.push(handoverNote);
        }
    }
    req.session.claimant = claimant;
    req.session.handover = handover;
    req.session.handovers = handovers;
    req.session.claimants = claimants;

    res.render('handover-edit', {
        benList : benefitsList,
        handTypesList : handoverTypesList,
        handReasonsList : handoverReasonsList,
        handoverNotes : handoverNotes,
        claimant : claimant,
        handover : handover,
        user: user,
        officesList : officesList,
        officeDetails : officeDetails,
        officeType : officeType,
        officeTypes : officeTypes,
        editOrCreate : editOrCreate
    });
}

function editHandoverPageAction(req, res) {

    let handoversList = req.session.handovers ? req.session.handovers : sIDU.setInitialBenefitsAndHandoversData();
    let handover = req.session.handover ? req.session.handover : handoverUtils.getHandoverByIdFromListOfHandovers(handoversList, req.query.id);
    let editedHandover = new Object();
    let newHandoverNotes = [];
    let handoverNote = req.body['handover-note'];
    let editedHandoverNote = new Object();
    let dateAndTimeRaised = new Date(handover.dateAndTimeRaised);
    let targetDateAndTime = new Date(handover.targetDateAndTime);
    let claimant = req.session.claimant;
    let handoverIndex = commonUtils.findPositionOfObjectInArray(handover.id, handoversList);
    let callback = req.body['callback-req'];
    let editedDate = new Date();
    if (callback === 'Yes') {
        targetDateAndTime.setHours(targetDateAndTime.getHours() + 3);
    }

    editedHandover.id = handover.id
    editedHandover.nino = claimant.nino;
    editedHandover.staffId = handover.staffId;
    editedHandover.owningOfficeId = req.body['office'];
    editedHandover.benefitId = req.body['benefit'];

    if (editedHandover.benefitId === "5") {
        editedHandover.benSubType = req.body['benefit-sub'];
    } else {
        editedHandover.benSubType = null;
    }

    editedHandover.typeId = req.body['handover-type'];;
    editedHandover.reasonId = req.body['handover-reason'];
    editedHandover.callback = callback;
    editedHandover.priority = req.body['handover-priority'];
    editedHandover.status = handover.status;
    // editedHandover.status = req.body['handover-status'];
    editedHandover.dateAndTimeRaised = dateAndTimeRaised;
    editedHandover.targetDateAndTime = targetDateAndTime;

    if (editedHandover.callback === 'Yes') {
        editedHandover.targetDateAndTime.setHours(editedHandover.dateAndTimeRaised.getHours() + 3);
    }

    editedHandover.dateAndTimeRaisedForDisplay = dateUtils.formatDateAndTimeForDisplay(dateAndTimeRaised);
    editedHandover.targetDateAndTimeForDisplay = dateUtils.formatDateAndTimeForDisplay(targetDateAndTime);

    if (handoverNote === "" || handoverNote === null) {
        // Do nothing
    } else {
        editedHandoverNote.handoverId = handover.id;
        editedHandoverNote.dateNoteAdded = editedDate;
        editedHandoverNote.userWhoAddedNote = editedHandover.staffId;
        editedHandoverNote.noteContent = handoverNote;
        if (handover.notes === null) {
            editedHandoverNote.id = "1";
            newHandoverNotes.push(editedHandoverNote);
        } else {
            editedHandoverNote.id = handover.notes.length + 1;
            newHandoverNotes = handover.notes;
            newHandoverNotes.unshift(editedHandoverNote);
        }
        editedHandover.notes = newHandoverNotes;

    }

    handoversList[handoverIndex] = editedHandover;

    req.session.handovers = handoversList;
    req.session.handover = editedHandover;
    req.session.claimant = claimant;

    res.redirect('/handover/view?id=' + editedHandover.id);

}

module.exports.viewHandoverPage = viewHandoverPage;
module.exports.viewHandoverPageAction = viewHandoverPageAction;
module.exports.createHandoverPage = createHandoverPage;
module.exports.createHandoverPageAction = createHandoverPageAction;
module.exports.editHandoverPage = editHandoverPage;
module.exports.editHandoverPageAction = editHandoverPageAction;
<commit_msg>Fixed bug that occurred when editing handover without adding new note<commit_after>const handoverUtils = require('../utils/handoverUtils');
const officeUtils = require('../utils/officeUtils');
const claimantUtils = require('../utils/claimantUtils');
const userUtils = require('../utils/userUtils');
const sIDU = require('../utils/setInitialDataUtils');
const dateUtils = require('../utils/dateUtils');
const commonUtils = require('../utils/commonUtils');

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/*                                        Handover Controllers
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/

function viewHandoverPage(req, res) {

    let users = req.session.user ? req.session.user : sIDU.setInitialUsersData();
    let user = req.session.user ? req.session.user : users[0];
    let handoversList = req.session.handovers ? req.session.handovers : sIDU.setInitialBenefitsAndHandoversData().initialHandovers;
    let handover;
    let handoverNotes = [];

    if (req.query.id === null) {
        handover = req.session.handover ? req.session.handover : handoversList[0];
    } else {
        handover = handoverUtils.getHandoverByIdFromListOfHandovers(handoversList, req.query.id);
    }

    let handoverTextDetails = handoverUtils.getHandoverDetails(handover);
    let claimants = req.session.claimants ? req.session.claimants : sIDU.setInitialClaimantsData();
    let claimant;
    if (req.query.nino === null) {
        claimant= req.session.claimant ? req.session.claimant : claimants[0];
    } else {
        claimant = claimantUtils.getClaimantByNinoFromListOfClaimants(claimants, req.query.nino);
    }
    let officesList = sIDU.setInitialOfficesData();
    let officeId = claimant.claimantOfficeId || "3";
    let officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, officeId);
    let officeTypes = sIDU.setInitialOfficeTypesData();
    let officeTypesIndex = commonUtils.findPositionOfObjectInArray(officeDetails.officeTypeId, officeTypes);
    let officeTypeId = officeTypes[officeTypesIndex].id;
    let officeTypeName = officeTypes[officeTypesIndex].officeType;
    let officeType = {
        id : officeTypeId,
        officeType : officeTypeName
    }
    user.officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, user.owningOfficeId);
    let userOfficeTypeIndex = commonUtils.findPositionOfObjectInArray(user.officeDetails.officeTypeId, officeTypes);
    user.officeDetails.officeType = officeTypes[userOfficeTypeIndex].officeType;

    if (handover.notes === null) {
        handoverNotes = null;
    } else {
        let handNoteLen = handover.notes.length;
        for (let i=0; i < handNoteLen; i++) {
            let handoverNote = {
                id: handover.notes[i].id,
                dateNoteAdded: dateUtils.formatDateAndTimeForDisplay(handover.notes[i].dateNoteAdded),
                userWhoAddedNote: userUtils.getUserByStaffIdFromListOfUsers(users, handover.notes[i].userWhoAddedNote),
                noteContent: handover.notes[i].noteContent
            }
            handoverNotes.push(handoverNote);
        }
    }
    req.session.claimant = claimant;
    req.session.handovers = handoversList;
    req.session.handover = handover;
    req.session.officeDetails = officeDetails;

    res.render('handover', {
        benefitName : handoverTextDetails.benefitName,
        handoverType : handoverTextDetails.handoverType,
        handoverReason : handoverTextDetails.handoverReason,
        handoverNotes : handoverNotes,
        officeDetails : officeDetails,
        officeTypes : officeTypes,
        officeType : officeType,
        claimant : claimant,
        handover : handover,
        user : user,
    });

}

function viewHandoverPageAction(req, res) {

    let handover = req.session.handover;
    let claimantNino = req.session.claimant && req.session.claimant.nino || console.log("No claimant in session, or no nino in claimant");
    let handoverClaimant = req.session.claimant;

    req.session.claimant = handoverClaimant;
    req.session.handover = handover;

    res.redirect('/handover/edit?nino=' + claimantNino);

}

function createHandoverPage(req, res) {
    let editOrCreate = 'create';
    let initialData = sIDU.setInitialBenefitsAndHandoversData();
    let users = req.session.user ? req.session.user : sIDU.setInitialUsersData();
    let user = req.session.user ? req.session.user : users[0];
    let benefitsList = initialData.initialBenefits;
    let handoverTypesList = initialData.initialHandoverTypes;
    let handoverReasonsList = initialData.initialHandoverReasons;
    let handovers = req.session.handovers ? req.session.handovers : initialData.initialHandovers;
    let claimants = req.session.claimants ? req.session.claimants : sIDU.setInitialClaimantsData();
    let claimant = claimantUtils.getClaimantByNinoFromListOfClaimants(claimants, req.query.nino);
    let officesList = sIDU.setInitialOfficesData();
    let officeTypes = sIDU.setInitialOfficeTypesData();
    let officeId = 3;  // Change to let officeId = handover.raisedOnBehalfOfOfficeId || "3" once got different offices sorted
    let officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, officeId);

    user.officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, user.owningOfficeId);
    let userOfficeTypeIndex = commonUtils.findPositionOfObjectInArray(user.officeDetails.officeTypeId, officeTypes);
    user.officeDetails.officeType = officeTypes[userOfficeTypeIndex].officeType;

    req.session.claimant = claimant;
    req.session.handovers = handovers;
    req.session.claimants = claimants;

    res.render('handover-edit', {
        benList : benefitsList,
        handTypesList : handoverTypesList,
        handReasonsList : handoverReasonsList,
        claimant : claimant,
        user : user,
        officeDetails : officeDetails,
        officesList : officesList,
        officeTypes : officeTypes,
        editOrCreate : editOrCreate
    });

}

function createHandoverPageAction(req, res) {

    let newHandover = new Object();
    let handoversList = req.session.handovers ? req.session.handovers : sIDU.setInitialBenefitsAndHandoversData();
    let newDate = new Date();
    let newHandoversList = handoversList;
    let handoverNote = req.body['handover-note'];
    let claimant = req.session.claimant;
    let newId = handoversList.length + 1;

    newHandover.id = newId;
    newHandover.nino = claimant.nino;
    newHandover.staffId = '40001001';
    newHandover.raisedOnBehalfOfOfficeId = req.body['office-id'];
    newHandover.benefitId = req.body['benefit'];

    if (newHandover.benefitId === "5") {
        newHandover.benSubType = req.body['benefit-sub'];
    } else {
        newHandover.benSubType = null;
    }
    newHandover.typeId = req.body['handover-type'];;
    newHandover.reasonId = req.body['handover-reason'];
    newHandover.callback = req.body['callback-req'];
    newHandover.priority = req.body['handover-priority'];
    newHandover.status = "Not allocated";
    newHandover.dateAndTimeRaised = newDate;
    newHandover.targetDateAndTime = newDate;
    newHandover.notes = [];

    if (newHandover.callback === 'Yes') {
        newHandover.targetDateAndTime.setHours(newHandover.dateAndTimeRaised.getHours() + 3);
    }

    newHandover.dateAndTimeRaisedForDisplay = dateUtils.formatDateAndTimeForDisplay(newHandover.dateAndTimeRaised);
    newHandover.targetDateAndTimeForDisplay = dateUtils.formatDateAndTimeForDisplay(newHandover.targetDateAndTime);

    if (handoverNote === "" || handoverNote === null) {
        // Do nothing
    } else {
        let newHandoverNote = new Object();
        newHandoverNote.id = '1';
        newHandoverNote.handoverId = newHandover.id;
        newHandoverNote.dateNoteAdded = newDate;
        newHandoverNote.userWhoAddedNote = newHandover.staffId;
        newHandoverNote.noteContent = handoverNote;
        newHandover.notes.push(newHandoverNote);
    }

    newHandoversList.push(newHandover);
    req.session.handover = newHandover;
    req.session.handovers = newHandoversList;
    req.session.claimant = claimant;

    res.redirect('/handover/view?id=' + newId);

}

function editHandoverPage(req, res) {

    let editOrCreate = 'edit';
    let initialData = sIDU.setInitialBenefitsAndHandoversData();
    let users = req.session.user ? req.session.user : sIDU.setInitialUsersData();
    let user = req.session.user ? req.session.user : users[0];
    let benefitsList = initialData.initialBenefits;
    let handoverTypesList = initialData.initialHandoverTypes;
    let handoverReasonsList = initialData.initialHandoverReasons;
    let handovers = req.session.handovers ? req.session.handovers : initialData.initialHandovers;
    let handover = req.session.handover ? req.session.handover : handoverUtils.getHandoverByIdFromListOfHandovers(handovers, req.query.id);
    let handoverNotes = [];
    let claimants = req.session.claimants ? req.session.claimants : sIDU.setInitialClaimantsData();
    let claimant = claimantUtils.getClaimantByNinoFromListOfClaimants(claimants, req.query.nino);
    let officesList = sIDU.setInitialOfficesData();
    let officeId = handover.raisedOnBehalfOfOfficeId || "3";
    let officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, officeId);
    let officeTypes = sIDU.setInitialOfficeTypesData();
    let officeTypesIndex = commonUtils.findPositionOfObjectInArray(officeDetails.officeTypeId, officeTypes);
    let officeTypeId = officeTypes[officeTypesIndex].id;
    let officeTypeName = officeTypes[officeTypesIndex].officeType;
    let officeType = {
        officeTypeId : officeTypeId,
        officeTypeName : officeTypeName
    }
    user.officeDetails = officeUtils.getOfficeByIdFromListOfOffices(officesList, user.owningOfficeId);
    let userOfficeTypeIndex = commonUtils.findPositionOfObjectInArray(user.officeDetails.officeTypeId, officeTypes);
    user.officeDetails.officeType = officeTypes[userOfficeTypeIndex].officeType;

    if (handover.notes === null) {
        handoverNotes = null
    } else {
        for (let i=0; i < handover.notes.length; i++) {
            let handoverNote = {
                id: handover.notes[i].id,
                dateNoteAdded: dateUtils.formatDateAndTimeForDisplay(handover.notes[i].dateNoteAdded),
                userWhoAddedNote: userUtils.getUserByStaffIdFromListOfUsers(users, handover.notes[i].userWhoAddedNote),
                noteContent: handover.notes[i].noteContent
            }
            handoverNotes.push(handoverNote);
        }
    }
    req.session.claimant = claimant;
    req.session.handover = handover;
    req.session.handovers = handovers;
    req.session.claimants = claimants;

    res.render('handover-edit', {
        benList : benefitsList,
        handTypesList : handoverTypesList,
        handReasonsList : handoverReasonsList,
        handoverNotes : handoverNotes,
        claimant : claimant,
        handover : handover,
        user: user,
        officesList : officesList,
        officeDetails : officeDetails,
        officeType : officeType,
        officeTypes : officeTypes,
        editOrCreate : editOrCreate
    });
}

function editHandoverPageAction(req, res) {

    let handoversList = req.session.handovers ? req.session.handovers : sIDU.setInitialBenefitsAndHandoversData();
    let handover = req.session.handover ? req.session.handover : handoverUtils.getHandoverByIdFromListOfHandovers(handoversList, req.query.id);
    let editedHandover = new Object();
    let newHandoverNotes = [];
    let handoverNote = req.body['handover-note'];
    let editedHandoverNote = new Object();
    let dateAndTimeRaised = new Date(handover.dateAndTimeRaised);
    let targetDateAndTime = new Date(handover.targetDateAndTime);
    let claimant = req.session.claimant;
    let handoverIndex = commonUtils.findPositionOfObjectInArray(handover.id, handoversList);
    let callback = req.body['callback-req'];
    let editedDate = new Date();
    if (callback === 'Yes') {
        targetDateAndTime.setHours(targetDateAndTime.getHours() + 3);
    }

    editedHandover.id = handover.id
    editedHandover.nino = claimant.nino;
    editedHandover.staffId = handover.staffId;
    editedHandover.owningOfficeId = req.body['office'];
    editedHandover.benefitId = req.body['benefit'];

    if (editedHandover.benefitId === "5") {
        editedHandover.benSubType = req.body['benefit-sub'];
    } else {
        editedHandover.benSubType = null;
    }

    editedHandover.typeId = req.body['handover-type'];;
    editedHandover.reasonId = req.body['handover-reason'];
    editedHandover.callback = callback;
    editedHandover.priority = req.body['handover-priority'];
    editedHandover.status = handover.status;
    // editedHandover.status = req.body['handover-status'];
    editedHandover.dateAndTimeRaised = dateAndTimeRaised;
    editedHandover.targetDateAndTime = targetDateAndTime;

    if (editedHandover.callback === 'Yes') {
        editedHandover.targetDateAndTime.setHours(editedHandover.dateAndTimeRaised.getHours() + 3);
    }

    editedHandover.dateAndTimeRaisedForDisplay = dateUtils.formatDateAndTimeForDisplay(dateAndTimeRaised);
    editedHandover.targetDateAndTimeForDisplay = dateUtils.formatDateAndTimeForDisplay(targetDateAndTime);

    if (handoverNote === "" || handoverNote === null) {
        newHandoverNotes = handover.notes;
    } else {
        editedHandoverNote.handoverId = handover.id;
        editedHandoverNote.dateNoteAdded = editedDate;
        editedHandoverNote.userWhoAddedNote = editedHandover.staffId;
        editedHandoverNote.noteContent = handoverNote;
        if (handover.notes === null) {
            editedHandoverNote.id = "1";
            newHandoverNotes.push(editedHandoverNote);
        } else {
            editedHandoverNote.id = handover.notes.length + 1;
            newHandoverNotes = handover.notes;
            newHandoverNotes.unshift(editedHandoverNote);
        }
    }
    editedHandover.notes = newHandoverNotes;

    handoversList[handoverIndex] = editedHandover;

    req.session.handovers = handoversList;
    req.session.handover = editedHandover;
    req.session.claimant = claimant;

    res.redirect('/handover/view?id=' + editedHandover.id);

}

module.exports.viewHandoverPage = viewHandoverPage;
module.exports.viewHandoverPageAction = viewHandoverPageAction;
module.exports.createHandoverPage = createHandoverPage;
module.exports.createHandoverPageAction = createHandoverPageAction;
module.exports.editHandoverPage = editHandoverPage;
module.exports.editHandoverPageAction = editHandoverPageAction;
<|endoftext|>


<commit_before>Alloy.Globals.extendsBaseViewController($, arguments[0]);

$.makeContextMenu = function(e, isSelectMode, sourceModel) {
	var menuSection = Ti.UI.createTableViewSection();
	menuSection.add($.createContextMenuItem("新增项目", function() {
		Alloy.Globals.openWindow("project/projectForm", {$model : "Project", saveableMode : "add", data : { parentProject : sourceModel }});
	}));
	return menuSection;
}

$.titleBar.bindXTable($.myProjectsTable);

var sharedWithMeTableCollection = Alloy.createCollection("Project").xSearchInDb({ownerUserId : Alloy.Models.User.id,projectSharedById : "NOT NULL"});
    sharedWithMeTableCollection = sharedWithMeTableCollection.xSetFilter({ownerUser : Alloy.Models.User,projectSharedBy : "NOT NULL"});
var myProjectsTableCollection = Alloy.Models.User.xGet("projects").xCreateFilter({parentProject : null,projectSharedBy : null});
// var sharedWithMeTableCollection = Alloy.Models.User.xGet("projects").xCreateFilter({projectSharedBy : "NOT NULL"});
var sharedWithHerTableCollection = Alloy.Models.User.xGet("projects").xCreateFilter({projectShareAuthorizations : "NOT NULL"});
$.myProjectsTable.addCollection(myProjectsTableCollection);
$.sharedWithMeTable.addCollection(sharedWithMeTableCollection);
$.sharedWithHerTable.addCollection(sharedWithHerTableCollection);

<commit_msg>projectAll<commit_after>Alloy.Globals.extendsBaseViewController($, arguments[0]);

$.makeContextMenu = function(e, isSelectMode, sourceModel) {
	var menuSection = Ti.UI.createTableViewSection();
	menuSection.add($.createContextMenuItem("新增项目", function() {
		Alloy.Globals.openWindow("project/projectForm", {$model : "Project", saveableMode : "add", data : { parentProject : sourceModel }});
	}));
	return menuSection;
}

$.titleBar.bindXTable($.myProjectsTable);

// var sharedWithMeTableCollection = Alloy.createCollection("Project").xSearchInDb({ownerUserId : Alloy.Models.User.id,projectSharedById : "NOT NULL"});
    // sharedWithMeTableCollection = sharedWithMeTableCollection.xSetFilter(function(model){
    	// var parentProject = null;
    	// if(!model.xGet("projectSharedBy").xGet("project").xGet("parentProject")){
    		// return true;
    	// }
	   	// return false;
	// });
//
// var sharedWithHerTableCollection = Alloy.createCollection("Project").xSearchInDb({ownerUserId : Alloy.Models.User.id,projectSharedById : null});
    // sharedWithHerTableCollection = sharedWithHerTableCollection.xSetFilter(function(model){
    	// if(model.xGet("projectShareAuthorizations").length > 0
    	// && (model.xGet("projectProject").xGet("projectShareAuthorizations").length === 0 || model.xGet("projectProject").xGet("id") === null)){
    		// return true;
    	// }
	   	// return false;
	// });

var myProjectsTableCollection = Alloy.Models.User.xGet("projects").xCreateFilter({parentProject : null,projectSharedBy : null});
var sharedWithMeTableCollection = Alloy.Models.User.xGet("projects").xCreateFilter({projectSharedBy : "NOT NULL"});
var sharedWithHerTableCollection = Alloy.Models.User.xGet("projects").xCreateFilter({projectShareAuthorizations : "NOT NULL"});
$.myProjectsTable.addCollection(myProjectsTableCollection);
$.sharedWithMeTable.addCollection(sharedWithMeTableCollection);
$.sharedWithHerTable.addCollection(sharedWithHerTableCollection);

<|endoftext|>


<commit_before>/*jshint esversion: 6 */
'use strict'
const AWS = require("aws-sdk");
const dynamodb = new AWS.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {

};
<commit_msg>Add table scanning<commit_after>/*jshint esversion: 6 */
'use strict';
const AWS = require("aws-sdk");
const dynamodb = new AWS.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {
    const today = new Date();
    var yyyy = today.getFullYear();
    var mm = today.getMonth();
    var dd = today.getDate();
    const todayEpoch = new Date(yyyy, mm, dd).getTime() / 1000;
    console.log(todayEpoch);
    // 21600

    let startTime = todayEpoch - 21600;

    if (event.lastupdated) {
        startTime = event.lastupdated;
    }

    var params = {
    TableName: "impact-map",
    ProjectionExpression: "Coordinates, #b",
    FilterExpression: "#a > :start",
    ExpressionAttributeNames: {
        "#a": "Added",
        "#b": "Action"
    },
    ExpressionAttributeValues: {
         ":start": todayEpoch
    }
    };

    console.log("Scanning table.");
    dynamodb.scan(params, onScan);

    function onScan(err, data) {
        if (err) {
            console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
        } else {
            // print all items
            console.log("Scan succeeded.");
            data.Items.forEach(function(item) {
               console.log(item.Coordinates);
               console.log(item.Action);
            });

            // continue scanning if we have more items, because
            // scan can retrieve a maximum of 1MB of data
            if (typeof data.LastEvaluatedKey != "undefined") {
                console.log("Scanning for more...");
                params.ExclusiveStartKey = data.LastEvaluatedKey;
                dynamodb.scan(params, onScan);
            }
        }
    }
};<|endoftext|>


<commit_before>/*************************************************************************
 * Description: 友盟PUSH组件
 * Author: raojia
 * Mail: raojia@le.com
 * Created Time: 2017-01-06
 * Modified Time: 2017-01-10
 ************************************************************************/
'use strict';

import React, {
    NativeModules,
    NativeEventEmitter,
    Platform,
    AppState,
} from 'react-native';

const UmengPush = NativeModules.UmengPushModule;
const myNativeEvt = new NativeEventEmitter(UmengPush);  //创建自定义事件接口

var receiveMessageSubscript, openMessageSubscription;

var listeners = {};

var id = 0;
var META_1 = '__recv_notify_listener_id';
var META_2 = '__open_notify_listener_id';

function getKey(listener, META) {
    if (!listener.hasOwnProperty(META)) {
        if (!Object.isExtensible(listener)) {
            return 'F';
        }
        Object.defineProperty(listener, META, {
            value: 'L' + ++id,
        });
    }
    return listener[META];
};

module.exports = {

    isPushEnabled() {
        return UmengPush.isPushEnabled();
    },

    switchPush(enable) {
        return UmengPush.switchPush(enable ? 1 : 0);
    },

    addReceiveMessageListener(handler: Function) {
        var key = getKey(handler, META_1);
        listeners[key] = myNativeEvt.addListener(UmengPush.EVENT_UMENG_RECV_MESSAGE, message => {
            //处于后台时，拦截收到的消息
            if (AppState.currentState === 'background') {
                return;
            }
            handler(message);
        });
    },

    removeReceiveMessageListener(handler: Function) {
        var key = getKey(handler, META_1);
        if (!listeners[key]) {
            return;
        }
        listeners[key].remove();
        listeners[key] = null;
    },

    addOpenMessageListener(handler: Function) {
        var key = getKey(handler, META_2);
        listeners[key] = myNativeEvt.addListener(UmengPush.EVENT_UMENG_OPEN_MESSAGE,
            message => {
                handler(message);
            });
        // openMessageSubscription = myNativeEvt.addListener(UmengPush.EVENT_UMENG_OPEN_MESSAGE, handler);
    },

    removeOpenMessageListener(handler: Function) {
        var key = getKey(handler, META_2);
        if (!listeners[key]) {
            return;
        }
        listeners[key].remove();
        listeners[key] = null;
    },

    // addEventListener(eventName: string, handler: Function) {
    //     if (Platform.OS === 'android') {
    //         return DeviceEventEmitter.addListener(eventName, (event) => {
    //             handler(event);
    //         });
    //     }
    //     else {
    //         return NativeAppEventEmitter.addListener(
    //             eventName, (userInfo) => {
    //                 handler(userInfo);
    //             });
    //     }
    // },

};
<commit_msg>update<commit_after>/*************************************************************************
 * Description: 友盟PUSH组件
 * Author: raojia
 * Mail: raojia@le.com
 * Created Time: 2017-01-06
 * Modified Time: 2017-04-09
 ************************************************************************/
'use strict';

import React, {
    NativeModules,
    NativeEventEmitter,
    Platform,
    AppState,
} from 'react-native';

const UmengPush = NativeModules.UmengPushModule;
const myNativeEvt = new NativeEventEmitter(UmengPush);  //创建自定义事件接口

var receiveMessageSubscript, openMessageSubscription;

var listeners = {};

var id = 0;
var META_1 = '__recv_notify_listener_id';
var META_2 = '__open_notify_listener_id';

function getKey(listener, META) {
    if (!listener.hasOwnProperty(META)) {
        if (!Object.isExtensible(listener)) {
            return 'F';
        }
        Object.defineProperty(listener, META, {
            value: 'L' + ++id,
        });
    }
    return listener[META];
};

module.exports = {

    isPushEnabled() {
        return UmengPush.isPushEnabled();
    },

    switchPush(enable) {
        return UmengPush.switchPush(enable ? 1 : 0);
    },

    addReceiveMessageListener(handler: Function) {
        var key = getKey(handler, META_1);
        listeners[key] = myNativeEvt.addListener(UmengPush.EVENT_UMENG_RECV_MESSAGE, message => {
            //处于后台时，拦截收到的消息
            if (AppState.currentState === 'background') {
                return;
            }
            handler(message);
        });
    },

    removeReceiveMessageListener(handler: Function) {
        var key = getKey(handler, META_1);
        if (!listeners[key]) {
            return;
        }
        listeners[key].remove();
        listeners[key] = null;
    },

    addOpenMessageListener(handler: Function) {
        var key = getKey(handler, META_2);
        listeners[key] = myNativeEvt.addListener(UmengPush.EVENT_UMENG_OPEN_MESSAGE,
            message => {
                handler(message);
            });
        // openMessageSubscription = myNativeEvt.addListener(UmengPush.EVENT_UMENG_OPEN_MESSAGE, handler);
    },

    removeOpenMessageListener(handler: Function) {
        var key = getKey(handler, META_2);
        if (!listeners[key]) {
            return;
        }
        listeners[key].remove();
        listeners[key] = null;
    },

    // addEventListener(eventName: string, handler: Function) {
    //     if (Platform.OS === 'android') {
    //         return DeviceEventEmitter.addListener(eventName, (event) => {
    //             handler(event);
    //         });
    //     }
    //     else {
    //         return NativeAppEventEmitter.addListener(
    //             eventName, (userInfo) => {
    //                 handler(userInfo);
    //             });
    //     }
    // },

};
<|endoftext|>


<commit_before>/* eslint-disable */

const crypto = require('crypto')
const request = require('request')

function rest (key, secret, opts = {}) {
  this.url = 'https://api.bitfinex.com'
  this.version = 'v1'
  this.key = key
  this.secret = secret
  this.nonce = Date.now()
  this.generateNonce = (typeof opts.nonceGenerator === 'function')
      ? opts.nonceGenerator
      : () => ++this.nonce
}

rest.prototype.make_request = function (path, params, cb) {
  var headers, key, nonce, path, payload, signature, url, value
  if (!this.key || !this.secret) {
    return cb(new Error('missing api key or secret'))
  }
  url = `${this.url}/${this.version}/${path}`
  nonce = JSON.stringify(this.generateNonce())
  payload = {
    request: `/${this.version}/${path}`,
    nonce
  }
  for (key in params) {
    value = params[key]
    payload[key] = value
  }
  payload = new Buffer(JSON.stringify(payload)).toString('base64')
  signature = crypto.createHmac('sha384', this.secret).update(payload).digest('hex')
  headers = {
    'X-BFX-APIKEY': this.key,
    'X-BFX-PAYLOAD': payload,
    'X-BFX-SIGNATURE': signature
  }
  return request({
    url,
    method: 'POST',
    headers,
    timeout: 15000
  }, (err, response, body) => {
    let error, result
    if (err || (response.statusCode !== 200 && response.statusCode !== 400)) {
      return cb(new Error(err != null ? err : response.statusCode))
    }
    try {
      result = JSON.parse(body)
    } catch (error1) {
      error = error1
      return cb(null, {
        message: body.toString()
      })
    }
    if (result.message != null) {
      if (/Nonce is too small/.test(result.message)) {
        result.message = result.message +
        ' See https://github.com/bitfinexcom/bitfinex-api-node/blob/master/README.md#nonce-too-small for help'
      }

      return cb(new Error(result.message))
    }
    return cb(null, result)
  })
}

rest.prototype.make_public_request = function (path, cb) {
  const url = `${this.url}/${this.version}/${path}`
  return request({
    url,
    method: 'GET',
    timeout: 15000
  }, (err, response, body) => {
    let error, result
    if (err || (response.statusCode !== 200 && response.statusCode !== 400)) {
      return cb(new Error(err != null ? err : response.statusCode))
    }
    try {
      result = JSON.parse(body)
    } catch (error1) {
      error = error1
      return cb(null, {
        message: body.toString()
      })
    }
    if (result.message != null) {
      return cb(new Error(result.message))
    }
    return cb(null, result)
  })
}

rest.prototype.ticker = function (symbol, cb) {
  if (arguments.length == 0) {
    symbol = 'BTCUSD'
    cb = function (error, data) { console.log(data) }
  }
  return this.make_public_request('pubticker/' + symbol, cb)
}

rest.prototype.today = function (symbol, cb) {
  return this.make_public_request('today/' + symbol, cb)
}

rest.prototype.stats = function (symbol, cb) {
  return this.make_public_request('stats/' + symbol, cb)
}

// rest.prototype.candles = function (symbol, cb) {
//    return this.make_public_request('candles/' + symbol, cb);
// };

rest.prototype.fundingbook = function (currency, options, cb) {
  let err, index, option, query_string, uri, value
  index = 0
  uri = 'lendbook/' + currency
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        if (index++ > 0) {
          query_string += '&' + option + '=' + value
        } else {
          query_string = '/?' + option + '=' + value
        }
      }
      if (index > 0) {
        uri += query_string
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_public_request(uri, cb)
}

rest.prototype.orderbook = function (symbol, options, cb) {
  let err, index, option, query_string, uri, value
  index = 0
  uri = 'book/' + symbol
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        if (index++ > 0) {
          query_string += '&' + option + '=' + value
        } else {
          query_string = '/?' + option + '=' + value
        }
      }
      if (index > 0) {
        uri += query_string
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_public_request(uri, cb)
}
rest.prototype.trades = function (symbol, cb) {
  return this.make_public_request('trades/' + symbol, cb)
}

rest.prototype.lends = function (currency, cb) {
  return this.make_public_request('lends/' + currency, cb)
}

rest.prototype.get_symbols = function (cb) {
  return this.make_public_request('symbols', cb)
}

rest.prototype.symbols_details = function (cb) {
  return this.make_public_request('symbols_details', cb)
}

rest.prototype.new_order = function (symbol, amount, price, exchange, side, type, is_hidden, postOnly, cb) {
  if (typeof is_hidden === 'function') {
    cb = is_hidden
    is_hidden = false
  }

  if (typeof postOnly === 'function') {
    cb = postOnly
    postOnly = false
  }

  const params = {
    symbol,
    amount,
    price,
    exchange,
    side,
    type
  }

  if (postOnly) {
    params['post_only'] = true
  }
  if (is_hidden) {
    params['is_hidden'] = true
  }
  return this.make_request('order/new', params, cb)
}

rest.prototype.multiple_new_orders = function (orders, cb) {
  const params = {
    orders
  }
  return this.make_request('order/new/multi', params, cb)
}

rest.prototype.cancel_order = function (order_id, cb) {
  const params = {
    order_id: parseInt(order_id)
  }
  return this.make_request('order/cancel', params, cb)
}

rest.prototype.cancel_all_orders = function (cb) {
  return this.make_request('order/cancel/all', {}, cb)
}

rest.prototype.cancel_multiple_orders = function (order_ids, cb) {
  const params = {
    order_ids: order_ids.map((id) => parseInt(id))
  }
  return this.make_request('order/cancel/multi', params, cb)
}

rest.prototype.replace_order = function (order_id, symbol, amount, price, exchange, side, type, cb) {
  const params = {
    order_id: parseInt(order_id),
    symbol,
    amount,
    price,
    exchange,
    side,
    type
  }
  return this.make_request('order/cancel/replace', params, cb)
}

rest.prototype.order_status = function (order_id, cb) {
  const params = {
    order_id
  }
  return this.make_request('order/status', params, cb)
}

rest.prototype.active_orders = function (cb) {
  return this.make_request('orders', {}, cb)
}

rest.prototype.orders_history = function (cb) {
  return this.make_request('orders/hist', {}, cb)
}

rest.prototype.active_positions = function (cb) {
  return this.make_request('positions', {}, cb)
}

rest.prototype.claim_position = function (position_id, amount, cb) {
  const params = {
    position_id: parseInt(position_id),
    amount: amount
  }
  return this.make_request('position/claim', params, cb)
}

rest.prototype.balance_history = function (currency, options, cb) {
  let err, option, value
  const params = {
    currency
  }
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        params[option] = value
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_request('history', params, cb)
}

rest.prototype.movements = function (currency, options, cb) {
  let err, option, value
  const params = {
    currency
  }
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        params[option] = value
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_request('history/movements', params, cb)
}

rest.prototype.past_trades = function (symbol, options, cb) {
  let err, option, value
  const params = {
    symbol
  }
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        params[option] = value
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_request('mytrades', params, cb)
}

rest.prototype.new_deposit = function (currency, method, wallet_name, cb) {
  const params = {
    currency,
    method,
    wallet_name
  }
  return this.make_request('deposit/new', params, cb)
}

rest.prototype.new_offer = function (currency, amount, rate, period, direction, cb) {
  const params = {
    currency,
    amount,
    rate,
    period,
    direction
  }
  return this.make_request('offer/new', params, cb)
}

rest.prototype.cancel_offer = function (offer_id, cb) {
  const params = {
    offer_id
  }
  return this.make_request('offer/cancel', params, cb)
}

rest.prototype.offer_status = function (offer_id, cb) {
  const params = {
    offer_id
  }
  return this.make_request('offer/status', params, cb)
}

rest.prototype.active_offers = function (cb) {
  return this.make_request('offers', {}, cb)
}

rest.prototype.active_credits = function (cb) {
  return this.make_request('credits', {}, cb)
}

rest.prototype.wallet_balances = function (cb) {
  return this.make_request('balances', {}, cb)
}

rest.prototype.taken_swaps = function (cb) {
  return this.make_request('taken_funds', {}, cb)
}

rest.prototype.total_taken_swaps = function (cb) {
  return this.make_request('total_taken_funds', {}, cb)
}

rest.prototype.close_swap = function (swap_id, cb) {
  return this.make_request('swap/close', {
    swap_id
  }, cb)
}

rest.prototype.account_infos = function (cb) {
  return this.make_request('account_infos', {}, cb)
}

rest.prototype.margin_infos = function (cb) {
  return this.make_request('margin_infos', {}, cb)
}

/*
 POST /v1/withdraw

 Parameters:
 'withdraw_type' :string (can be "bitcoin", "litecoin" or "darkcoin" or "mastercoin")
 'walletselected' :string (the origin of the wallet to withdraw from, can be "trading", "exchange", or "deposit")
 'amount' :decimal (amount to withdraw)
 'address' :address (destination address for withdrawal)
 */

rest.prototype.withdraw = function (withdraw_type, walletselected, amount, address, cb) {
  const params = {
    withdraw_type,
    walletselected,
    amount,
    address
  }
  return this.make_request('withdraw', params, cb)
}

/*
 POST /v1/transfer

 Parameters:
 ‘amount’: decimal (amount to transfer)
 ‘currency’: string, currency of funds to transfer
 ‘walletfrom’: string. Wallet to transfer from
 ‘walletto’: string. Wallet to transfer to
 */

rest.prototype.transfer = function (amount, currency, walletfrom, walletto, cb) {
  const params = {
    amount,
    currency,
    walletfrom,
    walletto
  }
  return this.make_request('transfer', params, cb)
}

module.exports = rest
<commit_msg>(fix) parseInt on all Ids in rest v1<commit_after>/* eslint-disable */

const crypto = require('crypto')
const request = require('request')

function rest (key, secret, opts = {}) {
  this.url = 'https://api.bitfinex.com'
  this.version = 'v1'
  this.key = key
  this.secret = secret
  this.nonce = Date.now()
  this.generateNonce = (typeof opts.nonceGenerator === 'function')
      ? opts.nonceGenerator
      : () => ++this.nonce
}

rest.prototype.make_request = function (path, params, cb) {
  var headers, key, nonce, path, payload, signature, url, value
  if (!this.key || !this.secret) {
    return cb(new Error('missing api key or secret'))
  }
  url = `${this.url}/${this.version}/${path}`
  nonce = JSON.stringify(this.generateNonce())
  payload = {
    request: `/${this.version}/${path}`,
    nonce
  }
  for (key in params) {
    value = params[key]
    payload[key] = value
  }
  payload = new Buffer(JSON.stringify(payload)).toString('base64')
  signature = crypto.createHmac('sha384', this.secret).update(payload).digest('hex')
  headers = {
    'X-BFX-APIKEY': this.key,
    'X-BFX-PAYLOAD': payload,
    'X-BFX-SIGNATURE': signature
  }
  return request({
    url,
    method: 'POST',
    headers,
    timeout: 15000
  }, (err, response, body) => {
    let error, result
    if (err || (response.statusCode !== 200 && response.statusCode !== 400)) {
      return cb(new Error(err != null ? err : response.statusCode))
    }
    try {
      result = JSON.parse(body)
    } catch (error1) {
      error = error1
      return cb(null, {
        message: body.toString()
      })
    }
    if (result.message != null) {
      if (/Nonce is too small/.test(result.message)) {
        result.message = result.message +
        ' See https://github.com/bitfinexcom/bitfinex-api-node/blob/master/README.md#nonce-too-small for help'
      }

      return cb(new Error(result.message))
    }
    return cb(null, result)
  })
}

rest.prototype.make_public_request = function (path, cb) {
  const url = `${this.url}/${this.version}/${path}`
  return request({
    url,
    method: 'GET',
    timeout: 15000
  }, (err, response, body) => {
    let error, result
    if (err || (response.statusCode !== 200 && response.statusCode !== 400)) {
      return cb(new Error(err != null ? err : response.statusCode))
    }
    try {
      result = JSON.parse(body)
    } catch (error1) {
      error = error1
      return cb(null, {
        message: body.toString()
      })
    }
    if (result.message != null) {
      return cb(new Error(result.message))
    }
    return cb(null, result)
  })
}

rest.prototype.ticker = function (symbol, cb) {
  if (arguments.length == 0) {
    symbol = 'BTCUSD'
    cb = function (error, data) { console.log(data) }
  }
  return this.make_public_request('pubticker/' + symbol, cb)
}

rest.prototype.today = function (symbol, cb) {
  return this.make_public_request('today/' + symbol, cb)
}

rest.prototype.stats = function (symbol, cb) {
  return this.make_public_request('stats/' + symbol, cb)
}

// rest.prototype.candles = function (symbol, cb) {
//    return this.make_public_request('candles/' + symbol, cb);
// };

rest.prototype.fundingbook = function (currency, options, cb) {
  let err, index, option, query_string, uri, value
  index = 0
  uri = 'lendbook/' + currency
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        if (index++ > 0) {
          query_string += '&' + option + '=' + value
        } else {
          query_string = '/?' + option + '=' + value
        }
      }
      if (index > 0) {
        uri += query_string
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_public_request(uri, cb)
}

rest.prototype.orderbook = function (symbol, options, cb) {
  let err, index, option, query_string, uri, value
  index = 0
  uri = 'book/' + symbol
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        if (index++ > 0) {
          query_string += '&' + option + '=' + value
        } else {
          query_string = '/?' + option + '=' + value
        }
      }
      if (index > 0) {
        uri += query_string
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_public_request(uri, cb)
}
rest.prototype.trades = function (symbol, cb) {
  return this.make_public_request('trades/' + symbol, cb)
}

rest.prototype.lends = function (currency, cb) {
  return this.make_public_request('lends/' + currency, cb)
}

rest.prototype.get_symbols = function (cb) {
  return this.make_public_request('symbols', cb)
}

rest.prototype.symbols_details = function (cb) {
  return this.make_public_request('symbols_details', cb)
}

rest.prototype.new_order = function (symbol, amount, price, exchange, side, type, is_hidden, postOnly, cb) {
  if (typeof is_hidden === 'function') {
    cb = is_hidden
    is_hidden = false
  }

  if (typeof postOnly === 'function') {
    cb = postOnly
    postOnly = false
  }

  const params = {
    symbol,
    amount,
    price,
    exchange,
    side,
    type
  }

  if (postOnly) {
    params['post_only'] = true
  }
  if (is_hidden) {
    params['is_hidden'] = true
  }
  return this.make_request('order/new', params, cb)
}

rest.prototype.multiple_new_orders = function (orders, cb) {
  const params = {
    orders
  }
  return this.make_request('order/new/multi', params, cb)
}

rest.prototype.cancel_order = function (order_id, cb) {
  const params = {
    order_id: parseInt(order_id)
  }
  return this.make_request('order/cancel', params, cb)
}

rest.prototype.cancel_all_orders = function (cb) {
  return this.make_request('order/cancel/all', {}, cb)
}

rest.prototype.cancel_multiple_orders = function (order_ids, cb) {
  const params = {
    order_ids: order_ids.map((id) => parseInt(id))
  }
  return this.make_request('order/cancel/multi', params, cb)
}

rest.prototype.replace_order = function (order_id, symbol, amount, price, exchange, side, type, cb) {
  const params = {
    order_id: parseInt(order_id),
    symbol,
    amount,
    price,
    exchange,
    side,
    type
  }, cb)
}

// TODO: Why is order_id not parsed here as above? Also applies to further
//       instances below
rest.prototype.order_status = function (order_id, cb) {
  return this.make_request('order/status', {
    order_id: parseInt(order_id)
  }, cb)
}

rest.prototype.active_orders = function (cb) {
  return this.make_request('orders', {}, cb)
}

rest.prototype.orders_history = function (cb) {
  return this.make_request('orders/hist', {}, cb)
}

rest.prototype.active_positions = function (cb) {
  return this.make_request('positions', {}, cb)
}

rest.prototype.claim_position = function (position_id, amount, cb) {
  const params = {
    position_id: parseInt(position_id),
    amount: amount
  }
  return this.make_request('position/claim', params, cb)
}

rest.prototype.balance_history = function (currency, options, cb) {
  let err, option, value
  const params = {
    currency
  }
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        params[option] = value
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_request('history', params, cb)
}

rest.prototype.movements = function (currency, options, cb) {
  let err, option, value
  const params = {
    currency
  }
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        params[option] = value
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_request('history/movements', params, cb)
}

rest.prototype.past_trades = function (symbol, options, cb) {
  let err, option, value
  const params = {
    symbol
  }
  if (typeof options === 'function') {
    cb = options
  } else {
    try {
      for (option in options) {
        value = options[option]
        params[option] = value
      }
    } catch (error1) {
      err = error1
      return cb(err)
    }
  }
  return this.make_request('mytrades', params, cb)
}

rest.prototype.new_deposit = function (currency, method, wallet_name, cb) {
  const params = {
    currency,
    method,
    wallet_name
  }
  return this.make_request('deposit/new', params, cb)
}

rest.prototype.new_offer = function (currency, amount, rate, period, direction, cb) {
  const params = {
    currency,
    amount,
    rate,
    period,
    direction
  }
  return this.make_request('offer/new', params, cb)
}

rest.prototype.cancel_offer = function (offer_id, cb) {
  return this.make_request('offer/cancel', {
    offer_id: parseInt(offer_id)
  }, cb)
}

rest.prototype.offer_status = function (offer_id, cb) {
  return this.make_request('offer/status', {
    offer_id: parseInt(offer_id)
  }, cb)
}

rest.prototype.active_offers = function (cb) {
  return this.make_request('offers', {}, cb)
}

rest.prototype.active_credits = function (cb) {
  return this.make_request('credits', {}, cb)
}

rest.prototype.wallet_balances = function (cb) {
  return this.make_request('balances', {}, cb)
}

rest.prototype.taken_swaps = function (cb) {
  return this.make_request('taken_funds', {}, cb)
}

rest.prototype.total_taken_swaps = function (cb) {
  return this.make_request('total_taken_funds', {}, cb)
}

rest.prototype.close_swap = function (swap_id, cb) {
  return this.make_request('swap/close', {
    swap_id: parseInt(swap_id)
  }, cb)
}

rest.prototype.account_infos = function (cb) {
  return this.make_request('account_infos', {}, cb)
}

rest.prototype.margin_infos = function (cb) {
  return this.make_request('margin_infos', {}, cb)
}

/*
 POST /v1/withdraw

 Parameters:
 'withdraw_type' :string (can be "bitcoin", "litecoin" or "darkcoin" or "mastercoin")
 'walletselected' :string (the origin of the wallet to withdraw from, can be "trading", "exchange", or "deposit")
 'amount' :decimal (amount to withdraw)
 'address' :address (destination address for withdrawal)
 */

rest.prototype.withdraw = function (withdraw_type, walletselected, amount, address, cb) {
  const params = {
    withdraw_type,
    walletselected,
    amount,
    address
  }
  return this.make_request('withdraw', params, cb)
}

/*
 POST /v1/transfer

 Parameters:
 ‘amount’: decimal (amount to transfer)
 ‘currency’: string, currency of funds to transfer
 ‘walletfrom’: string. Wallet to transfer from
 ‘walletto’: string. Wallet to transfer to
 */

rest.prototype.transfer = function (amount, currency, walletfrom, walletto, cb) {
  const params = {
    amount,
    currency,
    walletfrom,
    walletto
  }
  return this.make_request('transfer', params, cb)
}

module.exports = rest
<|endoftext|>


<commit_before>import Config from '../config/environment';

export function initialize(instance) {
  if (Config.mixpanel.enabled) {
    var router = instance.lookup('router:main');
    router.on('didTransition', function() {
      instance.lookup('service:mixpanel').trackPageView(this.get('url'));
    });
  }
}

export default {
  name: 'mixpanel',
  initialize: initialize
};
<commit_msg>Make lookup accessible for 1.13.x and 2.x<commit_after>import Config from '../config/environment';

export function initialize(appInstance) {
  if (Config.mixpanel.enabled) {
    if (typeof(appInstance.lookup) === 'undefined') {
      appInstance = appInstance.container;
    }
    let router = appInstance.lookup('router:main');
    router.on('didTransition', function() {
      appInstance.lookup('service:mixpanel').trackPageView(this.get('url'));
    });
  }
}

export default {
  name: 'mixpanel',
  initialize: initialize
};
<|endoftext|>