Commit 8bc0cbee authored by Roman's avatar Roman

BRCD-1676 feat(Plays) - filter 'Override Product Price', 'Included Products',...

BRCD-1676 feat(Plays) - filter 'Override Product Price', 'Included Products', 'Included Services' searchas by play type
parent ac66c6e3
......@@ -3,7 +3,7 @@ import moment from 'moment';
import { escapeRegExp } from './Util';
// TODO: fix to uniqueget (for now billAoi can't search by 'rates')
export const searchProductsByKeyAndUsagetQuery = (usages, notKeys) => {
export const searchProductsByKeyAndUsagetQuery = (usages, notKeys, plays = '') => {
const usagesToQuery = Array.isArray(usages) ? usages : [usages];
const query = {
key: {
......@@ -11,9 +11,20 @@ export const searchProductsByKeyAndUsagetQuery = (usages, notKeys) => {
},
to: { $gt: moment().toISOString() }, // only active and future
tariff_category: 'retail', // only retail products
$and: [], // for addition conditions
};
if (usagesToQuery[0] !== 'cost') {
query.$or = usagesToQuery.map(usage => ({ [`rates.${usage}`]: { $exists: true } }));
query.$and.push(
{ $or: usagesToQuery.map(usage => ({ [`rates.${usage}`]: { $exists: true } })) },
);
}
if (plays !== '') {
query.$and.push(
{ $or: [
{ play: { $exists: true, $in: [...plays.split(','), '', null] } },
{ play: { $exists: false } },
] },
);
}
const formData = new FormData();
......@@ -355,7 +366,8 @@ export const getPlansQuery = (project = { name: 1 }) => getEntitesQuery('plans',
export const getServicesQuery = (project = { name: 1 }) => getEntitesQuery('services', project);
export const getServicesKeysWithInfoQuery = () => getEntitesQuery('services', { name: 1, description: 1, play: 1, quantitative: 1, balance_period: 1 }, {}, { name: 1 });
export const getPrepaidIncludesQuery = () => getEntitesQuery('prepaidincludes');
export const getProductsKeysQuery = (project = { key: 1, description: 1 }, query = {}) => getEntitesQuery('rates', project, query);
export const getProductsKeysQuery = (project = { key: 1, description: 1, play: 1 }, query = {}, sort = { key: 1 }) =>
getEntitesQuery('rates', project, query, sort);
export const getRetailProductsKeysQuery = (project = { key: 1, description: 1 }) => {
const query = { tariff_category: 'retail' };
return getEntitesQuery('rates', project, query);
......@@ -365,7 +377,7 @@ export const getRetailProductsWithRatesQuery = () =>
export const getProductsWithRatesQuery = () =>
getProductsKeysQuery({ key: 1, description: 1, rates: 1 });
export const getServicesKeysQuery = () => getEntitesQuery('services', { name: 1 });
export const getIncludedServicesKeysQuery = () => getEntitesQuery('services', { name: 1 }, {
export const getIncludedServicesKeysQuery = () => getEntitesQuery('services', { name: 1, play: 1 }, {
quantitative: { $ne: true },
balance_period: { $exists: false },
});
......
......@@ -17,12 +17,14 @@ class PlanIncludedServicesTab extends Component {
services: PropTypes.instanceOf(List),
dispatch: PropTypes.func.isRequired,
onChangeFieldValue: PropTypes.func.isRequired,
plays: PropTypes.instanceOf(List),
};
static defaultProps = {
includedServices: List(),
mode: 'create',
services: List(),
plays: List(),
};
componentWillMount() {
......@@ -34,9 +36,19 @@ class PlanIncludedServicesTab extends Component {
this.props.onChangeFieldValue(['include', 'services'], List(servicesList));
}
filterByPlay = (option) => {
const { plays } = this.props;
const servicePlays = option.get('play', List());
if (plays && !plays.isEmpty() && !servicePlays.isEmpty()) {
return !plays.filter(entityPlay => servicePlays.includes(entityPlay)).isEmpty();
}
return true;
}
getServicesOptions = () => {
const { services } = this.props;
return services
.filter(this.filterByPlay)
.map(service => ({
value: service.get('name', ''),
label: service.get('name', ''),
......
......@@ -36,6 +36,7 @@ class PlanIncludesTab extends Component {
mode: PropTypes.string,
dispatch: PropTypes.func.isRequired,
type: PropTypes.string,
plays: PropTypes.string,
}
static defaultProps = {
......@@ -45,6 +46,7 @@ class PlanIncludesTab extends Component {
propertyTypes: Immutable.List(),
mode: 'create',
type: '',
plays: '',
};
constructor(props) {
......@@ -117,6 +119,7 @@ class PlanIncludesTab extends Component {
}
return includeGroups.map((include, groupName) => {
const { plays } = this.props;
const shared = include.get('account_shared', false);
const pooled = include.get('account_pool', false);
const quantityAffected = include.get('quantity_affected', false);
......@@ -146,6 +149,7 @@ class PlanIncludesTab extends Component {
usaget={usaget}
usageTypes={usageTypes}
type={this.props.type}
plays={plays}
/>
);
}).toArray();
......@@ -166,7 +170,7 @@ class PlanIncludesTab extends Component {
);
render() {
const { mode } = this.props;
const { mode, plays } = this.props;
const { existingGroups, usedProducts } = this.state;
const allowCreate = mode !== 'view';
......@@ -190,6 +194,7 @@ class PlanIncludesTab extends Component {
usedProducts={usedProducts}
addGroup={this.onGroupAdd}
type={this.props.type}
plays={plays}
/>
}
</Col>
......
......@@ -40,6 +40,7 @@ class PlanProductsPriceTab extends Component {
planRates: PropTypes.instanceOf(Immutable.Map),
usageTypesData: PropTypes.instanceOf(Immutable.List),
propertyTypes: PropTypes.instanceOf(Immutable.List),
plays: PropTypes.string,
mode: PropTypes.string,
originalRates: PropTypes.instanceOf(Immutable.Map),
products: PropTypes.instanceOf(Immutable.List),
......@@ -52,6 +53,7 @@ class PlanProductsPriceTab extends Component {
planRates: Immutable.Map(),
usageTypesData: Immutable.List(),
propertyTypes: Immutable.List(),
plays: '',
mode: 'create',
originalRates: Immutable.Map(),
products: Immutable.List(),
......@@ -228,6 +230,14 @@ class PlanProductsPriceTab extends Component {
.toArray();
}
filterByPlay = (option) => {
const { plays } = this.props;
if (plays !== '' && option.play) {
return plays.split(',').includes(option.play);
}
return true;
}
render() {
const { planRates, mode } = this.props;
const editable = (mode !== 'view');
......@@ -243,7 +253,10 @@ class PlanProductsPriceTab extends Component {
<Panel header={panelTitle}>
<ProductSearch
onSelectProduct={this.onSelectProduct}
searchFunction={getProductsKeysQuery()}
searchFunction={getProductsKeysQuery(
{ key: 1, description: 1, play: 1 },
)}
filterFunction={this.filterByPlay}
/>
</Panel>
}
......
......@@ -217,6 +217,7 @@ class PlanSetup extends Component {
const planRates = item.get('rates', Immutable.Map());
const includedServices = item.getIn(['include', 'services'], Immutable.List());
const includeGroups = item.getIn(['include', 'groups'], Immutable.Map());
const plays = item.get('play', Immutable.List());
return (
<div className="PlanSetup">
......@@ -255,6 +256,7 @@ class PlanSetup extends Component {
mode={mode}
planRates={planRates}
onChangeFieldValue={this.onChangeFieldValue}
plays={plays.join(',')}
/>
</Panel>
</Tab>
......@@ -263,6 +265,7 @@ class PlanSetup extends Component {
<Panel style={{ borderTop: 'none' }}>
<PlanIncludesTab
mode={mode}
plays={plays.join(',')}
includeGroups={includeGroups}
onChangeFieldValue={this.onChangeFieldValue}
onGroupAdd={this.onGroupAdd}
......@@ -275,6 +278,7 @@ class PlanSetup extends Component {
<Panel style={{ borderTop: 'none' }}>
<PlanIncludedServicesTab
mode={mode}
plays={plays}
includedServices={includedServices}
onChangeFieldValue={this.onChangeFieldValue}
/>
......
......@@ -78,7 +78,7 @@ export default class Plan extends Component {
onChangePlays = (plays) => {
const playsToSave = plays === '' ? [] : plays.split(',');
this.props.onChangeFieldValue(['play'], playsToSave);
this.props.onChangeFieldValue(['play'], Immutable.List(playsToSave));
}
onChangePlanEach = (e) => {
......
......@@ -32,6 +32,7 @@ class PlanIncludeGroupCreate extends Component {
usageTypesData: PropTypes.instanceOf(Immutable.List),
propertyTypes: PropTypes.instanceOf(Immutable.List),
type: PropTypes.string,
plays: PropTypes.string,
}
static defaultProps = {
......@@ -43,6 +44,7 @@ class PlanIncludeGroupCreate extends Component {
usageTypesData: Immutable.List(),
propertyTypes: Immutable.List(),
type: '',
plays: '',
};
defaultState = {
......@@ -332,7 +334,7 @@ class PlanIncludeGroupCreate extends Component {
}
getStepContent = (stepIndex) => {
const { usedProducts, currency, propertyTypes, usageTypesData, type } = this.props;
const { usedProducts, currency, propertyTypes, usageTypesData, type, plays } = this.props;
const {
name,
products,
......@@ -480,6 +482,7 @@ class PlanIncludeGroupCreate extends Component {
usages={usages}
onChangeGroupRates={this.onChangeGroupRates}
existingProducts={existingProductsKeys}
plays={plays}
/>
</div>
{ error.length > 0 && <HelpBlock>{error}</HelpBlock>}
......
......@@ -30,6 +30,7 @@ export default class PlanIncludeGroupEdit extends Component {
onChangeFieldValue: PropTypes.func.isRequired,
onChangeGroupProducts: PropTypes.func.isRequired,
mode: PropTypes.string,
plays: PropTypes.string,
onGroupRemove: PropTypes.func.isRequired,
unit: PropTypes.string,
usaget: PropTypes.string,
......@@ -44,6 +45,7 @@ export default class PlanIncludeGroupEdit extends Component {
pooled: false,
quantityAffected: false,
mode: 'create',
plays: '',
unit: '',
usaget: '',
usageTypes: Immutable.List(),
......@@ -171,7 +173,7 @@ export default class PlanIncludeGroupEdit extends Component {
)
renderEdit = () => {
const { name, value, usages, shared, pooled, quantityAffected, products, usedProducts, usaget, unit, type } = this.props;
const { name, value, usages, shared, pooled, quantityAffected, products, usedProducts, usaget, unit, type, plays } = this.props;
const { isEditMode, errorInclude, errorUoM } = this.state;
return (
<Modal show={isEditMode}>
......@@ -231,6 +233,7 @@ export default class PlanIncludeGroupEdit extends Component {
usages={usages}
existingProducts={usedProducts.toList()}
onChangeGroupRates={this.onChangeGroupRates}
plays={plays}
/>
</div>
</Col>
......
......@@ -9,14 +9,19 @@ export default class ProductSearch extends Component {
static propTypes = {
onSelectProduct: PropTypes.func.isRequired,
searchFunction: PropTypes.object,
filterFunction: PropTypes.func,
}
static defaultProps = {
searchFunction: getProductsKeysQuery({ key: 1, description: 1 }),
filterFunction: () => true,
};
state = { val: '' }
state = {
val: '',
rates: [],
}
onSelectProduct = (productKey) => {
if (productKey) {
......@@ -25,24 +30,32 @@ export default class ProductSearch extends Component {
this.setState({ val: '' });
}
componentDidMount() {
this.getProducts();
}
getProducts = () => apiBillRun(this.props.searchFunction)
.then(success => ({
options: success.data[0].data.details.map(option => ({
.then((success) => {
const options = success.data[0].data.details
.map(option => ({
value: option.key,
label: `${option.key} (${option.description})`,
})),
complete: true,
}))
.catch(() => ({ options: [] }));
play: option.play,
}));
this.setState({ rates: options });
})
.catch(() => {
this.setState({ options: [] });
});
render() {
const { val } = this.state;
const { val, rates } = this.state;
const ratesOptions = rates.filter(this.props.filterFunction);
return (
<Select
value={val}
options={ratesOptions}
onChange={this.onSelectProduct}
asyncOptions={this.getProducts}
autoload={true}
searchable={true}
placeholder="Search by product key or title..."
noResultsText="No products found, please try another key"
......
......@@ -12,6 +12,7 @@ export default class ProductSearchByUsagetype extends Component {
existingProducts: Immutable.List(),
products: Immutable.List(),
usages: Immutable.List(),
plays: '',
}
static propTypes = {
......@@ -20,6 +21,7 @@ export default class ProductSearchByUsagetype extends Component {
disabled: React.PropTypes.bool,
existingProducts: React.PropTypes.instanceOf(Immutable.List),
products: React.PropTypes.instanceOf(Immutable.List),
plays: React.PropTypes.string,
}
shouldComponentUpdate(nextProps) {
......@@ -37,9 +39,9 @@ export default class ProductSearchByUsagetype extends Component {
}
findGroupRates = () => {
const { usages, existingProducts } = this.props;
const { usages, existingProducts, plays } = this.props;
const notKeys = existingProducts.toArray();
const query = searchProductsByKeyAndUsagetQuery(usages.toArray(), notKeys);
const query = searchProductsByKeyAndUsagetQuery(usages.toArray(), notKeys, plays);
return apiBillRun(query)
.then((success) => {
const uniqueKeys = [...new Set(success.data[0].data.details.map(option => option.key))];
......
......@@ -73,7 +73,7 @@ export default class ServiceDetails extends Component {
onChangePlays = (plays) => {
const playsToSave = plays === '' ? [] : plays.split(',');
this.props.updateItem(['play'], playsToSave);
this.props.updateItem(['play'], Immutable.List(playsToSave));
}
onChangeDescription = (e) => {
......
......@@ -184,6 +184,7 @@ class ServiceSetup extends Component {
const allowEdit = mode !== 'view';
const includeGroups = item.getIn(['include', 'groups'], Immutable.Map());
const planRates = item.get('rates', Immutable.Map());
const plays = item.get('play', Immutable.List());
return (
<div className="ServiceSetup">
<Panel>
......@@ -215,6 +216,7 @@ class ServiceSetup extends Component {
mode={mode}
planRates={planRates}
onChangeFieldValue={this.onUpdateItem}
plays={plays.join(',')}
/>
</Panel>
</Tab>
......@@ -228,6 +230,7 @@ class ServiceSetup extends Component {
onGroupRemove={this.onGroupRemove}
mode={mode}
type={'service'}
plays={plays.join(',')}
/>
</Panel>
</Tab>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment