Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
This commit is contained in:
commit
d5cf57fbb1
|
@ -1 +0,0 @@
|
||||||
UPDATE salix.ACL t SET t.principalId = 'employee' WHERE t.id = 269;
|
|
|
@ -1,9 +1,10 @@
|
||||||
<div ng-if="$ctrl.model.moreRows">
|
<div ng-if="$ctrl.model.moreRows" class="vn-py-md">
|
||||||
<vn-button
|
<div
|
||||||
ng-if="!$ctrl.model.isPaging"
|
ng-if="!$ctrl.model.isPaging"
|
||||||
label="Load more results"
|
|
||||||
ng-click="$ctrl.onLoadClick()">
|
ng-click="$ctrl.onLoadClick()">
|
||||||
</vn-button>
|
<vn-button label="Load more results"></vn-button>
|
||||||
|
<vn-icon icon="arrow_drop_down"/>
|
||||||
|
</div>
|
||||||
<vn-spinner
|
<vn-spinner
|
||||||
ng-if="$ctrl.model.isPaging"
|
ng-if="$ctrl.model.isPaging"
|
||||||
enable="::true">
|
enable="::true">
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
vn-pagination {
|
vn-pagination {
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: $color-primary;
|
||||||
|
|
||||||
|
vn-button, vn-icon {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
& > div > vn-icon-button {
|
& > div > vn-icon-button {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
|
|
|
@ -129,54 +129,20 @@ module.exports = Self => {
|
||||||
|
|
||||||
const where = buildFilter(ctx.args, (param, value) => {
|
const where = buildFilter(ctx.args, (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
|
||||||
return /^\d+$/.test(value)
|
|
||||||
? {'t.id': {inq: value}}
|
|
||||||
: {'t.nickname': {like: `%${value}%`}};
|
|
||||||
case 'from':
|
case 'from':
|
||||||
return {'t.shipped': {gte: value}};
|
return {'t.shipped': {gte: value}};
|
||||||
case 'to':
|
case 'to':
|
||||||
return {'t.shipped': {lte: value}};
|
return {'t.shipped': {lte: value}};
|
||||||
case 'nickname':
|
|
||||||
return {'t.nickname': {like: `%${value}%`}};
|
|
||||||
case 'refFk':
|
|
||||||
return {'t.refFk': value};
|
|
||||||
case 'salesPersonFk':
|
case 'salesPersonFk':
|
||||||
return {'c.salesPersonFk': value};
|
return {'c.salesPersonFk': value};
|
||||||
case 'provinceFk':
|
|
||||||
return {'a.provinceFk': value};
|
|
||||||
case 'stateFk':
|
|
||||||
return {'ts.stateFk': value};
|
|
||||||
case 'mine':
|
case 'mine':
|
||||||
case 'myTeam':
|
case 'myTeam':
|
||||||
if (value)
|
if (value)
|
||||||
return {'c.salesPersonFk': {inq: teamMembersId}};
|
return {'c.salesPersonFk': {inq: teamMembersId}};
|
||||||
else
|
else
|
||||||
return {'c.salesPersonFk': {nin: teamMembersId}};
|
return {'c.salesPersonFk': {nin: teamMembersId}};
|
||||||
|
|
||||||
case 'alertLevel':
|
|
||||||
return {'ts.alertLevel': value};
|
|
||||||
case 'pending':
|
|
||||||
if (value) {
|
|
||||||
return {and: [
|
|
||||||
{'st.alertLevel': 0},
|
|
||||||
{'st.code': {nin: [
|
|
||||||
'OK',
|
|
||||||
'BOARDING',
|
|
||||||
'PRINTED',
|
|
||||||
'PRINTED_AUTO',
|
|
||||||
'PICKER_DESIGNED'
|
|
||||||
]}}
|
|
||||||
]};
|
|
||||||
} else {
|
|
||||||
return {and: [
|
|
||||||
{'st.alertLevel': {gt: 0}}
|
|
||||||
]};
|
|
||||||
}
|
|
||||||
case 'id':
|
case 'id':
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
case 'agencyModeFk':
|
|
||||||
case 'warehouseFk':
|
|
||||||
param = `t.${param}`;
|
param = `t.${param}`;
|
||||||
return {[param]: value};
|
return {[param]: value};
|
||||||
}
|
}
|
||||||
|
@ -216,6 +182,7 @@ module.exports = Self => {
|
||||||
ts.code AS alertLevelCode,
|
ts.code AS alertLevelCode,
|
||||||
u.name AS userName,
|
u.name AS userName,
|
||||||
c.salesPersonFk,
|
c.salesPersonFk,
|
||||||
|
c.credit,
|
||||||
z.hour AS zoneLanding,
|
z.hour AS zoneLanding,
|
||||||
z.name AS zoneName,
|
z.name AS zoneName,
|
||||||
z.id AS zoneFk,
|
z.id AS zoneFk,
|
||||||
|
@ -246,6 +213,47 @@ module.exports = Self => {
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
// Get client debt balance
|
||||||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt');
|
||||||
|
stmts.push(`
|
||||||
|
CREATE TEMPORARY TABLE tmp.clientGetDebt
|
||||||
|
(INDEX (clientFk))
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT DISTINCT clientFk FROM tmp.filter`);
|
||||||
|
|
||||||
|
stmt = new ParameterizedSQL('CALL clientGetDebt(?)', [args.to]);
|
||||||
|
stmts.push(stmt);
|
||||||
|
stmts.push('DROP TEMPORARY TABLE tmp.clientGetDebt');
|
||||||
|
|
||||||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.tickets');
|
||||||
|
stmt = new ParameterizedSQL(`
|
||||||
|
CREATE TEMPORARY TABLE tmp.tickets
|
||||||
|
(INDEX (id))
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT f.*, r.risk AS debt
|
||||||
|
FROM tmp.filter f
|
||||||
|
LEFT JOIN tmp.risk r ON f.clientFk = r.clientFk`);
|
||||||
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
// Sum risk to future
|
||||||
|
stmts.push(`SET @client:= 0`);
|
||||||
|
stmts.push('SET @risk := 0');
|
||||||
|
stmts.push(`
|
||||||
|
UPDATE tmp.tickets
|
||||||
|
SET debt = IF(@client <> @client:= clientFk,
|
||||||
|
-totalWithVat + @risk:= - debt + totalWithVat,
|
||||||
|
-totalWithVat + @risk:= @risk + totalWithVat
|
||||||
|
)
|
||||||
|
ORDER BY clientFk, shipped DESC
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Remove positive risks
|
||||||
|
stmts.push(`
|
||||||
|
UPDATE tmp.tickets t
|
||||||
|
SET debt = 0
|
||||||
|
WHERE t.debt + t.credit >= 0
|
||||||
|
`);
|
||||||
|
|
||||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems');
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems');
|
||||||
stmts.push(`
|
stmts.push(`
|
||||||
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
CREATE TEMPORARY TABLE tmp.sale_getProblems
|
||||||
|
@ -258,27 +266,39 @@ module.exports = Self => {
|
||||||
AND f.shipped >= CURDATE()`);
|
AND f.shipped >= CURDATE()`);
|
||||||
stmts.push('CALL ticket_getProblems(FALSE)');
|
stmts.push('CALL ticket_getProblems(FALSE)');
|
||||||
|
|
||||||
|
stmts.push(`
|
||||||
|
INSERT INTO tmp.ticket_problems (ticketFk, risk, totalProblems)
|
||||||
|
SELECT t.id, t.debt + t.credit AS risk, 1
|
||||||
|
FROM tmp.tickets t
|
||||||
|
WHERE (t.debt + t.credit) < 0
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
risk = t.debt + t.credit, totalProblems = totalProblems + 1
|
||||||
|
`);
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(`
|
stmt = new ParameterizedSQL(`
|
||||||
SELECT f.*, tp.*
|
SELECT t.*, tp.*,
|
||||||
FROM tmp.filter f
|
((tp.risk) + cc.riskTolerance < 0) AS hasHighRisk
|
||||||
LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id`);
|
FROM tmp.tickets t
|
||||||
|
LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = t.id
|
||||||
|
JOIN clientConfig cc`);
|
||||||
|
|
||||||
const hasProblems = args.problems;
|
const hasProblems = args.problems;
|
||||||
if (hasProblems != undefined && (!args.from && !args.to))
|
if (hasProblems != undefined && (!args.from && !args.to))
|
||||||
throw new UserError('Choose a date range or days forward');
|
throw new UserError('Choose a date range or days forward');
|
||||||
|
|
||||||
let problemsFilter;
|
let finalFilter = {};
|
||||||
|
let whereProblems;
|
||||||
if (hasProblems === true) {
|
if (hasProblems === true) {
|
||||||
problemsFilter = {or: [
|
whereProblems = {or: [
|
||||||
{'tp.isFreezed': true},
|
{'tp.isFreezed': true},
|
||||||
{'tp.risk': {gt: 0}},
|
{'tp.risk': {lt: 0}},
|
||||||
{'tp.hasTicketRequest': true},
|
{'tp.hasTicketRequest': true},
|
||||||
{'tp.hasComponentLack': true},
|
{'tp.hasComponentLack': true},
|
||||||
{'tp.isTaxDataChecked': false},
|
{'tp.isTaxDataChecked': false},
|
||||||
{'tp.isAvailable': false}
|
{'tp.isAvailable': false}
|
||||||
]};
|
]};
|
||||||
} else if (hasProblems === false) {
|
} else if (hasProblems === false) {
|
||||||
problemsFilter = {and: [
|
whereProblems = {and: [
|
||||||
{'tp.isFreezed': false},
|
{'tp.isFreezed': false},
|
||||||
{'tp.risk': 0},
|
{'tp.risk': 0},
|
||||||
{'tp.hasTicketRequest': false},
|
{'tp.hasTicketRequest': false},
|
||||||
|
@ -288,8 +308,53 @@ module.exports = Self => {
|
||||||
]};
|
]};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (problemsFilter)
|
if (whereProblems) finalFilter.where = whereProblems;
|
||||||
stmt.merge(conn.makeWhere(problemsFilter));
|
|
||||||
|
const myWhere = buildFilter(ctx.args, (param, value) => {
|
||||||
|
switch (param) {
|
||||||
|
case 'search':
|
||||||
|
return /^\d+$/.test(value)
|
||||||
|
? {'t.id': {inq: value}}
|
||||||
|
: {'t.nickname': {like: `%${value}%`}};
|
||||||
|
|
||||||
|
case 'nickname':
|
||||||
|
return {'t.nickname': {like: `%${value}%`}};
|
||||||
|
case 'refFk':
|
||||||
|
return {'t.refFk': value};
|
||||||
|
|
||||||
|
case 'provinceFk':
|
||||||
|
return {'t.provinceFk': value};
|
||||||
|
case 'stateFk':
|
||||||
|
return {'t.stateFk': value};
|
||||||
|
case 'alertLevel':
|
||||||
|
return {'t.alertLevel': value};
|
||||||
|
case 'pending':
|
||||||
|
if (value) {
|
||||||
|
return {and: [
|
||||||
|
{'t.alertLevel': 0},
|
||||||
|
{'t.alertLevelCode': {nin: [
|
||||||
|
'OK',
|
||||||
|
'BOARDING',
|
||||||
|
'PRINTED',
|
||||||
|
'PRINTED_AUTO',
|
||||||
|
'PICKER_DESIGNED'
|
||||||
|
]}}
|
||||||
|
]};
|
||||||
|
} else {
|
||||||
|
return {and: [
|
||||||
|
{'t.alertLevel': {gt: 0}}
|
||||||
|
]};
|
||||||
|
}
|
||||||
|
case 'agencyModeFk':
|
||||||
|
case 'warehouseFk':
|
||||||
|
param = `t.${param}`;
|
||||||
|
return {[param]: value};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
finalFilter = mergeFilters(finalFilter, {where: myWhere});
|
||||||
|
if (finalFilter.where)
|
||||||
|
stmt.merge(conn.makeWhere(finalFilter.where));
|
||||||
|
|
||||||
stmt.merge(conn.makeOrderBy(filter.order));
|
stmt.merge(conn.makeOrderBy(filter.order));
|
||||||
stmt.merge(conn.makeLimit(filter));
|
stmt.merge(conn.makeLimit(filter));
|
||||||
|
@ -298,7 +363,9 @@ module.exports = Self => {
|
||||||
stmts.push(
|
stmts.push(
|
||||||
`DROP TEMPORARY TABLE
|
`DROP TEMPORARY TABLE
|
||||||
tmp.filter,
|
tmp.filter,
|
||||||
tmp.ticket_problems`);
|
tmp.ticket_problems,
|
||||||
|
tmp.sale_getProblems,
|
||||||
|
tmp.risk`);
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
let result = await conn.executeStmt(sql);
|
let result = await conn.executeStmt(sql);
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe('SalesMonitor salesFilter()', () => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
const result = await app.models.SalesMonitor.salesFilter(ctx, filter);
|
||||||
|
|
||||||
expect(result.length).toEqual(9);
|
expect(result.length).toEqual(13);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the tickets matching the problems on false', async() => {
|
it('should return the tickets matching the problems on false', async() => {
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
data="$ctrl.groupedStates"
|
data="$ctrl.groupedStates"
|
||||||
label="Grouped States"
|
label="Grouped States"
|
||||||
value-field="alertLevel"
|
value-field="id"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
ng-model="filter.alertLevel">
|
ng-model="filter.alertLevel">
|
||||||
<tpl-item>
|
<tpl-item>
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Controller extends SearchPanel {
|
||||||
this.$http.get('AlertLevels').then(res => {
|
this.$http.get('AlertLevels').then(res => {
|
||||||
for (let state of res.data) {
|
for (let state of res.data) {
|
||||||
groupedStates.push({
|
groupedStates.push({
|
||||||
alertLevel: state.alertLevel,
|
id: state.id,
|
||||||
code: state.code,
|
code: state.code,
|
||||||
name: this.$t(state.code)
|
name: this.$t(state.code)
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('Monitor Component vnMonitorSalesSearchPanel', () => {
|
||||||
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
|
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
alertLevel: 9999,
|
id: 9999,
|
||||||
code: 'myCode'
|
code: 'myCode'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -27,7 +27,7 @@ describe('Monitor Component vnMonitorSalesSearchPanel', () => {
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
expect(controller.groupedStates).toEqual([{
|
expect(controller.groupedStates).toEqual([{
|
||||||
alertLevel: 9999,
|
id: 9999,
|
||||||
code: 'myCode',
|
code: 'myCode',
|
||||||
name: 'miCodigo'
|
name: 'miCodigo'
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
<a ng-repeat="ticket in model.data"
|
<a ng-repeat="ticket in model.data"
|
||||||
class="clickable vn-tr search-result"
|
class="clickable vn-tr search-result"
|
||||||
ui-sref="ticket.card.summary({id: {{::ticket.id}}})" target="_blank">
|
ui-sref="ticket.card.summary({id: {{::ticket.id}}})" target="_blank">
|
||||||
<vn-td class="icon-field">
|
<vn-td expand>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-show="::ticket.isTaxDataChecked === 0"
|
ng-show="::ticket.isTaxDataChecked === 0"
|
||||||
translate-attr="{title: 'No verified data'}"
|
translate-attr="{title: 'No verified data'}"
|
||||||
|
|
|
@ -119,7 +119,7 @@ module.exports = Self => {
|
||||||
case 'sourceApp':
|
case 'sourceApp':
|
||||||
return {'o.source_app': value};
|
return {'o.source_app': value};
|
||||||
case 'ticketFk':
|
case 'ticketFk':
|
||||||
return {'ort.ticketFk': value};
|
return {'ot.ticketFk': value};
|
||||||
case 'isConfirmed':
|
case 'isConfirmed':
|
||||||
return {'o.confirmed': value ? 1 : 0};
|
return {'o.confirmed': value ? 1 : 0};
|
||||||
case 'myTeam':
|
case 'myTeam':
|
||||||
|
@ -137,7 +137,10 @@ module.exports = Self => {
|
||||||
let stmt;
|
let stmt;
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
stmt = new ParameterizedSQL(
|
||||||
`SELECT
|
`CREATE TEMPORARY TABLE tmp.filter
|
||||||
|
(INDEX (id))
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT
|
||||||
o.id,
|
o.id,
|
||||||
o.total,
|
o.total,
|
||||||
o.date_send landed,
|
o.date_send landed,
|
||||||
|
@ -168,20 +171,20 @@ module.exports = Self => {
|
||||||
LEFT JOIN ticket t ON t.id = ot.ticketFk
|
LEFT JOIN ticket t ON t.id = ot.ticketFk
|
||||||
LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`);
|
LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`);
|
||||||
|
|
||||||
if (args && args.ticketFk) {
|
|
||||||
stmt.merge({
|
|
||||||
sql: `LEFT JOIN orderTicket ort ON ort.orderFk = o.id`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
stmt.merge(`GROUP BY o.id`);
|
|
||||||
stmt.merge(conn.makePagination(filter));
|
stmt.merge(conn.makePagination(filter));
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
stmt = new ParameterizedSQL(`SELECT * FROM tmp.filter`);
|
||||||
|
stmt.merge(`GROUP BY id`);
|
||||||
|
stmt.merge(conn.makeOrderBy(filter.order));
|
||||||
|
const ordersIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
|
stmts.push(`DROP TEMPORARY TABLE tmp.filter`);
|
||||||
|
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
const result = await conn.executeStmt(sql);
|
const result = await conn.executeStmt(sql);
|
||||||
|
|
||||||
return result;
|
return result[ordersIndex];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<vn-th field="landed" shrink-date>Landed</vn-th>
|
<vn-th field="landed" shrink-date>Landed</vn-th>
|
||||||
<vn-th field="created" center>Hour</vn-th>
|
<vn-th field="created" center>Hour</vn-th>
|
||||||
<vn-th field="agencyName" center>Agency</vn-th>
|
<vn-th field="agencyName" center>Agency</vn-th>
|
||||||
<vn-th center>Total</vn-th>
|
<vn-th field="total" center>Total</vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
data="$ctrl.groupedStates"
|
data="$ctrl.groupedStates"
|
||||||
label="Grouped States"
|
label="Grouped States"
|
||||||
value-field="alertLevel"
|
value-field="id"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
ng-model="filter.alertLevel">
|
ng-model="filter.alertLevel">
|
||||||
<tpl-item>
|
<tpl-item>
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Controller extends SearchPanel {
|
||||||
this.$http.get('AlertLevels').then(res => {
|
this.$http.get('AlertLevels').then(res => {
|
||||||
for (let state of res.data) {
|
for (let state of res.data) {
|
||||||
groupedStates.push({
|
groupedStates.push({
|
||||||
alertLevel: state.alertLevel,
|
id: state.id,
|
||||||
code: state.code,
|
code: state.code,
|
||||||
name: this.$t(state.code)
|
name: this.$t(state.code)
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('Ticket Component vnTicketSearchPanel', () => {
|
||||||
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
|
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
alertLevel: 9999,
|
id: 9999,
|
||||||
code: 'myCode'
|
code: 'myCode'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -27,7 +27,7 @@ describe('Ticket Component vnTicketSearchPanel', () => {
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
expect(controller.groupedStates).toEqual([{
|
expect(controller.groupedStates).toEqual([{
|
||||||
alertLevel: 9999,
|
id: 9999,
|
||||||
code: 'myCode',
|
code: 'myCode',
|
||||||
name: 'miCodigo'
|
name: 'miCodigo'
|
||||||
}]);
|
}]);
|
||||||
|
|
Loading…
Reference in New Issue