tango-app-api-store-builder 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/controllers/fixtureTemplate.controller.js +1 -0
- package/src/controllers/managePlano.controller.js +275 -33
- package/src/controllers/script.controller.js +110 -0
- package/src/controllers/storeBuilder.controller.js +982 -185
- package/src/routes/fixtureTemplate.routes.js +17 -17
- package/src/routes/managePlano.routes.js +21 -21
- package/src/routes/script.routes.js +2 -0
- package/src/routes/storeBuilder.routes.js +4 -3
- package/src/service/planoRevision.service.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tango-app-api-store-builder",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "storeBuilder",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"path": "^0.12.7",
|
|
33
33
|
"selenium-webdriver": "^4.31.0",
|
|
34
34
|
"sharp": "^0.34.1",
|
|
35
|
-
"tango-api-schema": "^2.5.
|
|
35
|
+
"tango-api-schema": "^2.5.13",
|
|
36
36
|
"tango-app-api-middleware": "3.1.48",
|
|
37
37
|
"url": "^0.11.4",
|
|
38
38
|
"winston": "^3.17.0",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as floorService from '../service/storeBuilder.service.js';
|
|
2
|
-
import { logger, insertOpenSearchData, getOpenSearchData } from 'tango-app-api-middleware';
|
|
2
|
+
import { logger, insertOpenSearchData, getOpenSearchData, updateOpenSearchData, getOpenSearchById } from 'tango-app-api-middleware';
|
|
3
3
|
// import * as storeService from '../service/store.service.js';
|
|
4
4
|
import * as planoService from '../service/planogram.service.js';
|
|
5
5
|
import * as storeFixtureService from '../service/storeFixture.service.js';
|
|
6
6
|
import * as fixtureShelfService from '../service/fixtureShelf.service.js';
|
|
7
|
+
import * as storeBuilderService from '../service/storeBuilder.service.js';
|
|
7
8
|
// import * as planoProductService from '../service/planoProduct.service.js';
|
|
8
9
|
import * as planoVmService from '../service/planoVm.service.js';
|
|
9
10
|
// import * as planoMappingService from '../service/planoMapping.service.js';
|
|
@@ -18,6 +19,9 @@ import mongoose from 'mongoose';
|
|
|
18
19
|
import * as planoRevisionService from '../service/planoRevision.service.js';
|
|
19
20
|
import * as planoVmDuplicateService from '../service/planoVmDuplicate.service.js';
|
|
20
21
|
import * as vmTypeService from '../service/vmType.service.js';
|
|
22
|
+
import * as planoMappingService from '../service/planoMapping.service.js';
|
|
23
|
+
import * as planoComplianceService from '../service/planoCompliance.service.js';
|
|
24
|
+
import dayjs from 'dayjs';
|
|
21
25
|
export async function getplanoFeedback( req, res ) {
|
|
22
26
|
try {
|
|
23
27
|
const taskTypes = req.body.filterByTask && req.body.filterByTask.length > 0 ? req.body.filterByTask : [ 'layout', 'fixture', 'vm' ];
|
|
@@ -115,6 +119,7 @@ export async function getplanoFeedback( req, res ) {
|
|
|
115
119
|
let data = {};
|
|
116
120
|
if ( aiDetails?.body?.hits?.hits.length ) {
|
|
117
121
|
data = aiDetails?.body?.hits?.hits?.[0]?._source;
|
|
122
|
+
console.log( data, 'data' );
|
|
118
123
|
delete data.isEmpty;
|
|
119
124
|
delete data.fixtureFound;
|
|
120
125
|
}
|
|
@@ -281,6 +286,18 @@ function buildPipelineByType( type, planoId, floorId, filterByStatus, filterByAp
|
|
|
281
286
|
'FixtureData.shelfConfig': '$Fixtureshelves',
|
|
282
287
|
},
|
|
283
288
|
},
|
|
289
|
+
|
|
290
|
+
{
|
|
291
|
+
$set: {
|
|
292
|
+
'FixtureData.shelfConfig': {
|
|
293
|
+
$sortArray: {
|
|
294
|
+
input: '$FixtureData.shelfConfig',
|
|
295
|
+
sortBy: { shelfNumber: 1 },
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
|
|
284
301
|
];
|
|
285
302
|
|
|
286
303
|
const vmStages = [ 'vm', 'vmRollout' ].includes( type ) ? [
|
|
@@ -1022,7 +1039,10 @@ export async function updateFixtureStatus( req, res ) {
|
|
|
1022
1039
|
await planoTaskService.updateOnefilters(
|
|
1023
1040
|
{ _id: new mongoose.Types.ObjectId( req.body._id ) },
|
|
1024
1041
|
{
|
|
1025
|
-
$set: {
|
|
1042
|
+
$set: {
|
|
1043
|
+
'answers.$[ans].status': req.body.type,
|
|
1044
|
+
'answers.$[ans].userAction': req.body.userAction,
|
|
1045
|
+
},
|
|
1026
1046
|
},
|
|
1027
1047
|
[
|
|
1028
1048
|
{ 'ans._id': new mongoose.Types.ObjectId( req.body.answerId ) },
|
|
@@ -1287,7 +1307,7 @@ export async function updateStoreFixture( req, res ) {
|
|
|
1287
1307
|
|
|
1288
1308
|
const currentFixture = await storeFixtureService.findOne( { _id: new mongoose.Types.ObjectId( fixtureId ) } );
|
|
1289
1309
|
let currentFixtureDoc = currentFixture.toObject();
|
|
1290
|
-
if (
|
|
1310
|
+
if ( data?.userAction === 'editWithAi' || data?.userAction === 'acceptAi' ) {
|
|
1291
1311
|
let shelfDetails = await fixtureShelfService.find( { fixtureId: fixtureId } );
|
|
1292
1312
|
data.shelfConfig.forEach( ( ele ) => {
|
|
1293
1313
|
let findShelfProduct = shelfDetails.find( ( shelf ) => shelf.shelfNumber == ele.shelfNumber );
|
|
@@ -1523,7 +1543,8 @@ export async function updateStoreFixture( req, res ) {
|
|
|
1523
1543
|
} );
|
|
1524
1544
|
}
|
|
1525
1545
|
await planoService.updateOne( { _id: currentFixtureDoc?.planoId }, { $set: { updatedAt: new Date() } } );
|
|
1526
|
-
|
|
1546
|
+
|
|
1547
|
+
if ( data?.userAction === 'editWithAi' || data?.userAction === 'editWithPlano' ) {
|
|
1527
1548
|
let comments = {
|
|
1528
1549
|
userId: req.user._id,
|
|
1529
1550
|
userName: req.user.userName,
|
|
@@ -1531,7 +1552,8 @@ export async function updateStoreFixture( req, res ) {
|
|
|
1531
1552
|
responsetype: 'agree',
|
|
1532
1553
|
comment: '',
|
|
1533
1554
|
};
|
|
1534
|
-
await planoTaskService.updateOne( { planoId: currentFixture.planoId, floorId: currentFixture.floorId, fixtureId: currentFixture._id }, { 'answers.0.status': 'agree', 'approvalStatus': 'approved' } );
|
|
1555
|
+
await planoTaskService.updateOne( { planoId: currentFixture.planoId, floorId: currentFixture.floorId, fixtureId: currentFixture._id }, { 'answers.0.status': 'agree', 'approvalStatus': 'approved', 'answers.0.userAction': data.userAction } );
|
|
1556
|
+
|
|
1535
1557
|
await planoTaskService.updateOnefilters(
|
|
1536
1558
|
{ planoId: new mongoose.Types.ObjectId( currentFixture.planoId ), floorId: new mongoose.Types.ObjectId( currentFixture.floorId ), fixtureId: new mongoose.Types.ObjectId( currentFixture._id ) },
|
|
1537
1559
|
{
|
|
@@ -1539,9 +1561,15 @@ export async function updateStoreFixture( req, res ) {
|
|
|
1539
1561
|
},
|
|
1540
1562
|
);
|
|
1541
1563
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1564
|
+
|
|
1565
|
+
if ( data?.userAction === 'editWithAi' || data?.userAction === 'acceptAi' ) {
|
|
1566
|
+
const op_id = `${data?.storeName}_${data?.storeDate}_${data?._id}`;
|
|
1567
|
+
await updateAIFeedbackInOpenSearch( data, op_id );
|
|
1544
1568
|
}
|
|
1569
|
+
|
|
1570
|
+
// if ( req.body?.editMode ) {
|
|
1571
|
+
// await floorService.updateOne( { _id: new mongoose.Types.ObjectId( currentFixture.floorId ) }, { isEdited: true } );
|
|
1572
|
+
// }
|
|
1545
1573
|
res.sendSuccess( { message: 'Updated Successfully', ...( configId && { id: configId } ) } );
|
|
1546
1574
|
} catch ( e ) {
|
|
1547
1575
|
logger.error( { functionName: 'updateStoreFixture', error: e } );
|
|
@@ -1549,6 +1577,62 @@ export async function updateStoreFixture( req, res ) {
|
|
|
1549
1577
|
}
|
|
1550
1578
|
}
|
|
1551
1579
|
|
|
1580
|
+
const updateAIFeedbackInOpenSearch = async ( fixtureData, id ) => {
|
|
1581
|
+
try {
|
|
1582
|
+
let openSearchDetails = await getOpenSearchById( JSON.parse( process.env.OPENSEARCH ).planoAIValidation, id );
|
|
1583
|
+
if ( openSearchDetails && openSearchDetails.statusCode == 200 && openSearchDetails?.body?._source ) {
|
|
1584
|
+
const doc = {
|
|
1585
|
+
'fixtureId': fixtureData._id,
|
|
1586
|
+
'fixtureCapacity': fixtureData.fixtureCapacity,
|
|
1587
|
+
'fixtureType': fixtureData.fixtureType,
|
|
1588
|
+
'fixtureCategory': fixtureData.fixtureCategory,
|
|
1589
|
+
'header': {
|
|
1590
|
+
'label': fixtureData.header.label,
|
|
1591
|
+
},
|
|
1592
|
+
'vmConfig': fixtureData?.vmConfig.map( ( vm ) => {
|
|
1593
|
+
return {
|
|
1594
|
+
'vmType': vm.vmType,
|
|
1595
|
+
'startYPosition': vm.startYPosition,
|
|
1596
|
+
'endYPosition': vm.endYPosition,
|
|
1597
|
+
'xZone': vm.xZone,
|
|
1598
|
+
'yZone': vm.yZone,
|
|
1599
|
+
'vmImage': vm.vmImage,
|
|
1600
|
+
'vmName': vm.vmName,
|
|
1601
|
+
};
|
|
1602
|
+
} ) ?? [
|
|
1603
|
+
|
|
1604
|
+
],
|
|
1605
|
+
'shelfConfig': fixtureData?.shelfConfig.map( ( s ) => {
|
|
1606
|
+
return {
|
|
1607
|
+
'shelfNumber': s.shelfNumber,
|
|
1608
|
+
'shelfType': s.shelfType,
|
|
1609
|
+
'productPerShelf': s.productPerShelf,
|
|
1610
|
+
'trayRows': s.trayRows,
|
|
1611
|
+
};
|
|
1612
|
+
} ) ?? [],
|
|
1613
|
+
'fixtureImage': fixtureData.fixtureImage,
|
|
1614
|
+
'storeDate': fixtureData.storeDate,
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1617
|
+
const document = {
|
|
1618
|
+
doc: doc,
|
|
1619
|
+
};
|
|
1620
|
+
|
|
1621
|
+
let updateResult = await updateOpenSearchData( JSON.parse( process.env.OPENSEARCH ).planoAIValidation, id, document );
|
|
1622
|
+
|
|
1623
|
+
if ( updateResult?.statusCode == 200 ) {
|
|
1624
|
+
return true;
|
|
1625
|
+
}
|
|
1626
|
+
return false;
|
|
1627
|
+
} else {
|
|
1628
|
+
return false;
|
|
1629
|
+
}
|
|
1630
|
+
} catch ( e ) {
|
|
1631
|
+
logger.error( { error: e, function: 'updateAIFeedbackInOpenSearch' } );
|
|
1632
|
+
return false;
|
|
1633
|
+
}
|
|
1634
|
+
};
|
|
1635
|
+
|
|
1552
1636
|
export async function updateredostatus( req, res ) {
|
|
1553
1637
|
try {
|
|
1554
1638
|
if ( req.body.type === 'layout' ) {
|
|
@@ -1609,6 +1693,7 @@ export async function updateGlobalComment( req, res ) {
|
|
|
1609
1693
|
return res.sendError( e, 500 );
|
|
1610
1694
|
}
|
|
1611
1695
|
}
|
|
1696
|
+
|
|
1612
1697
|
export async function getGlobalComment( req, res ) {
|
|
1613
1698
|
try {
|
|
1614
1699
|
// let layoutComment = await planoGlobalCommentService.find( {
|
|
@@ -1642,19 +1727,36 @@ export async function getGlobalComment( req, res ) {
|
|
|
1642
1727
|
|
|
1643
1728
|
export async function getAllPlanoRevisions( req, res ) {
|
|
1644
1729
|
try {
|
|
1645
|
-
const {
|
|
1730
|
+
const { planoId, floorId, storeId } = req.body;
|
|
1646
1731
|
|
|
1647
|
-
if ( !
|
|
1648
|
-
return res.sendError( '
|
|
1732
|
+
if ( !storeId || !planoId || !floorId ) {
|
|
1733
|
+
return res.sendError( 'Required field is missing', 400 );
|
|
1649
1734
|
}
|
|
1650
1735
|
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1736
|
+
let query = [
|
|
1737
|
+
{
|
|
1738
|
+
$match: {
|
|
1739
|
+
storeId: storeId,
|
|
1740
|
+
planoId: new mongoose.Types.ObjectId( planoId ),
|
|
1741
|
+
floorId: new mongoose.Types.ObjectId( floorId ),
|
|
1742
|
+
},
|
|
1743
|
+
},
|
|
1744
|
+
{
|
|
1745
|
+
$sort: { _id: -1 },
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
$limit: 5,
|
|
1749
|
+
},
|
|
1750
|
+
{
|
|
1751
|
+
$sort: { _id: 1 },
|
|
1752
|
+
},
|
|
1753
|
+
];
|
|
1754
|
+
|
|
1755
|
+
const revisions = await planoRevisionService.aggregate( query );
|
|
1655
1756
|
|
|
1656
1757
|
res.sendSuccess( revisions );
|
|
1657
1758
|
} catch ( e ) {
|
|
1759
|
+
console.log( e );
|
|
1658
1760
|
logger.error( { functionName: 'getAllPlanoRevisions', error: e } );
|
|
1659
1761
|
res.sendError( 'Failed to fetch plano revisions', 500 );
|
|
1660
1762
|
}
|
|
@@ -1662,22 +1764,44 @@ export async function getAllPlanoRevisions( req, res ) {
|
|
|
1662
1764
|
|
|
1663
1765
|
export async function createPlanoRevision( req, res ) {
|
|
1664
1766
|
try {
|
|
1665
|
-
|
|
1767
|
+
let { storeName, storeId, clientId, planoId, floorId, floorData } = req.body;
|
|
1666
1768
|
|
|
1667
1769
|
if ( !storeName || !storeId || !clientId || !planoId || !floorId || !floorData ) {
|
|
1668
1770
|
return res.sendError( 'Missing required fields', 400 );
|
|
1669
1771
|
}
|
|
1772
|
+
let planoProductCount = 0;
|
|
1773
|
+
floorData.layoutPolygon.forEach( ( poly ) => {
|
|
1774
|
+
poly.fixtures.forEach( ( fixt ) => {
|
|
1775
|
+
planoProductCount += fixt.fixtureCapacity;
|
|
1776
|
+
} );
|
|
1777
|
+
} );
|
|
1670
1778
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
storeId,
|
|
1674
|
-
clientId,
|
|
1675
|
-
planoId,
|
|
1676
|
-
floorId,
|
|
1677
|
-
floorData,
|
|
1779
|
+
floorData.centerFixture.forEach( ( fixt ) => {
|
|
1780
|
+
planoProductCount += fixt.fixtureCapacity;
|
|
1678
1781
|
} );
|
|
1679
1782
|
|
|
1680
|
-
|
|
1783
|
+
floorData = { ...floorData, planoProductCount };
|
|
1784
|
+
|
|
1785
|
+
const data = {
|
|
1786
|
+
storeName: storeName,
|
|
1787
|
+
storeId: storeId,
|
|
1788
|
+
clientId: clientId,
|
|
1789
|
+
planoId: planoId,
|
|
1790
|
+
productResolutionLevel: req.body.productResolutionLevel,
|
|
1791
|
+
scanType: req.body.scanType,
|
|
1792
|
+
createdByName: req.user.userName,
|
|
1793
|
+
createdByEmail: req.user.email,
|
|
1794
|
+
createdBy: req.user._id,
|
|
1795
|
+
layoutName: req.body.layoutName,
|
|
1796
|
+
floorId: floorId,
|
|
1797
|
+
floorData: floorData,
|
|
1798
|
+
};
|
|
1799
|
+
|
|
1800
|
+
await planoRevisionService.create( data );
|
|
1801
|
+
|
|
1802
|
+
await storeBuilderService.updateOne( { _id: floorId }, { ...( req.body.type == 'rollout' ) ? { rolloutStatus: true } : { verificationStatus: true } } );
|
|
1803
|
+
|
|
1804
|
+
res.sendSuccess( 'Plano published successfully' );
|
|
1681
1805
|
} catch ( e ) {
|
|
1682
1806
|
logger.error( { functionName: 'createPlanoRevision', error: e } );
|
|
1683
1807
|
res.sendError( 'Failed to create plano revision', 500 );
|
|
@@ -1686,26 +1810,144 @@ export async function createPlanoRevision( req, res ) {
|
|
|
1686
1810
|
|
|
1687
1811
|
export async function getPlanoRevisionById( req, res ) {
|
|
1688
1812
|
try {
|
|
1689
|
-
|
|
1813
|
+
let { clientId, planoId } = req.body;
|
|
1690
1814
|
|
|
1691
|
-
if (
|
|
1692
|
-
|
|
1815
|
+
if ( req.body?.id ) {
|
|
1816
|
+
const planoDetails = await planoService.findOne( { ...( !mongoose.Types.ObjectId.isValid( req.body?.id ) && { storeId: req.body.id } ), ...( mongoose.Types.ObjectId.isValid( req.body?.id ) && { _id: req.body.id } ) }, { _id: 1, clientId: 1 } );
|
|
1817
|
+
if ( !planoDetails ) {
|
|
1818
|
+
return res.sendError( 'No data found', 204 );
|
|
1819
|
+
}
|
|
1820
|
+
planoId = planoDetails._id;
|
|
1821
|
+
clientId = planoDetails.clientId;
|
|
1693
1822
|
}
|
|
1694
1823
|
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1824
|
+
if ( !clientId || !planoId ) {
|
|
1825
|
+
return res.sendError( 'Required field is missing', 400 );
|
|
1826
|
+
}
|
|
1698
1827
|
|
|
1699
|
-
|
|
1700
|
-
|
|
1828
|
+
let query = [
|
|
1829
|
+
{
|
|
1830
|
+
$match: {
|
|
1831
|
+
planoId: new mongoose.Types.ObjectId( planoId ),
|
|
1832
|
+
clientId: clientId,
|
|
1833
|
+
},
|
|
1834
|
+
},
|
|
1835
|
+
{
|
|
1836
|
+
$sort: { _id: -1 },
|
|
1837
|
+
},
|
|
1838
|
+
{
|
|
1839
|
+
$group: {
|
|
1840
|
+
_id: { plano: '$planoId', floor: '$floorId' },
|
|
1841
|
+
storeName: { $first: '$storeName' },
|
|
1842
|
+
storeId: { $first: '$storeId' },
|
|
1843
|
+
productResolutionLevel: { $first: '$productResolutionLevel' },
|
|
1844
|
+
scanType: { $first: '$scanType' },
|
|
1845
|
+
layoutName: { $first: '$layoutName' },
|
|
1846
|
+
floorData: { $first: '$floorData' },
|
|
1847
|
+
floorData: { $first: '$floorData' },
|
|
1848
|
+
revisionId: { $first: '$_id' },
|
|
1849
|
+
},
|
|
1850
|
+
},
|
|
1851
|
+
{
|
|
1852
|
+
$group: {
|
|
1853
|
+
_id: '$_id.plano',
|
|
1854
|
+
storeName: { $first: '$storeName' },
|
|
1855
|
+
storeId: { $first: '$storeId' },
|
|
1856
|
+
productResolutionLevel: { $first: '$productResolutionLevel' },
|
|
1857
|
+
scanType: { $first: '$scanType' },
|
|
1858
|
+
layoutName: { $first: '$layoutName' },
|
|
1859
|
+
floors: { $push: '$floorData' },
|
|
1860
|
+
revisionId: { $first: '$revisionId' },
|
|
1861
|
+
},
|
|
1862
|
+
},
|
|
1863
|
+
{
|
|
1864
|
+
$limit: 1,
|
|
1865
|
+
},
|
|
1866
|
+
];
|
|
1867
|
+
|
|
1868
|
+
let revisions = await planoRevisionService.aggregate( query );
|
|
1869
|
+
if ( !revisions.length ) {
|
|
1870
|
+
return res.sendError( 'No data found', 204 );
|
|
1701
1871
|
}
|
|
1872
|
+
let currentDate = new Date( dayjs().format( 'YYYY-MM-DD' ) );
|
|
1873
|
+
revisions[0].floors = await Promise.all( revisions?.[0]?.floors.map( async ( floor ) => {
|
|
1874
|
+
floor.layoutPolygon = await Promise.all( floor.layoutPolygon.map( async ( poly ) => {
|
|
1875
|
+
poly.fixtures = await Promise.all( poly.fixtures.map( async ( fixture ) => {
|
|
1876
|
+
fixture.shelfConfig = await Promise.all( fixture.shelfConfig.map( async ( shelf ) => {
|
|
1877
|
+
const productDetails = await planoMappingService.find( { fixtureId: fixture._id, shelfId: shelf._id, type: 'product' }, { _id: 1 } );
|
|
1878
|
+
let productIdList = productDetails.map( ( ele ) => ele._id );
|
|
1879
|
+
let complianceQuery = [
|
|
1880
|
+
{
|
|
1881
|
+
$match: {
|
|
1882
|
+
fixtureId: fixture._id,
|
|
1883
|
+
shelfId: shelf._id,
|
|
1884
|
+
date: currentDate,
|
|
1885
|
+
planoMappingId: { $in: productIdList },
|
|
1886
|
+
},
|
|
1887
|
+
},
|
|
1888
|
+
{
|
|
1889
|
+
$group: {
|
|
1890
|
+
_id: '$createdAt',
|
|
1891
|
+
status: { $push: '$compliance' },
|
|
1892
|
+
},
|
|
1893
|
+
},
|
|
1894
|
+
{
|
|
1895
|
+
$sort: { _id: -1 },
|
|
1896
|
+
},
|
|
1897
|
+
{
|
|
1898
|
+
$limit: 1,
|
|
1899
|
+
},
|
|
1900
|
+
];
|
|
1901
|
+
let complianceStatus = await planoComplianceService.aggregate( complianceQuery );
|
|
1902
|
+
shelf.compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length != shelf.productPerShelf ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
|
|
1903
|
+
return shelf;
|
|
1904
|
+
} ) );
|
|
1905
|
+
return fixture;
|
|
1906
|
+
} ) );
|
|
1907
|
+
return poly;
|
|
1908
|
+
} ) );
|
|
1909
|
+
floor.centerFixture = await Promise.all( floor.centerFixture.map( async ( fixture ) => {
|
|
1910
|
+
fixture.shelfConfig = await Promise.all( fixture.shelfConfig.map( async ( shelf ) => {
|
|
1911
|
+
const productDetails = await planoMappingService.find( { fixtureId: fixture._id, shelfId: shelf._id, type: 'product' }, { _id: 1 } );
|
|
1912
|
+
let productIdList = productDetails.map( ( ele ) => ele._id );
|
|
1913
|
+
let complianceQuery = [
|
|
1914
|
+
{
|
|
1915
|
+
$match: {
|
|
1916
|
+
fixtureId: fixture._id,
|
|
1917
|
+
shelfId: shelf._id,
|
|
1918
|
+
date: currentDate,
|
|
1919
|
+
planoMappingId: { $in: productIdList },
|
|
1920
|
+
},
|
|
1921
|
+
},
|
|
1922
|
+
{
|
|
1923
|
+
$group: {
|
|
1924
|
+
_id: '$createdAt',
|
|
1925
|
+
status: { $push: '$compliance' },
|
|
1926
|
+
},
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
$sort: { _id: -1 },
|
|
1930
|
+
},
|
|
1931
|
+
{
|
|
1932
|
+
$limit: 1,
|
|
1933
|
+
},
|
|
1934
|
+
];
|
|
1935
|
+
let complianceStatus = await planoComplianceService.aggregate( complianceQuery );
|
|
1936
|
+
shelf.compliance = complianceStatus?.[0]?.status.length ? ( ( complianceStatus?.[0]?.status?.length != shelf.productPerShelf ) || complianceStatus?.[0]?.status?.includes( 'misplaced' ) ) ? 'improper' : 'proper' : 'improper';
|
|
1937
|
+
return shelf;
|
|
1938
|
+
} ) );
|
|
1939
|
+
return fixture;
|
|
1940
|
+
} ) );
|
|
1941
|
+
return floor;
|
|
1942
|
+
} ) );
|
|
1702
1943
|
|
|
1703
|
-
res.sendSuccess(
|
|
1944
|
+
res.sendSuccess( revisions );
|
|
1704
1945
|
} catch ( e ) {
|
|
1705
1946
|
logger.error( { functionName: 'getPlanoRevisionById', error: e } );
|
|
1706
|
-
res.sendError( 'Failed to fetch plano
|
|
1947
|
+
res.sendError( 'Failed to fetch plano revisions', 500 );
|
|
1707
1948
|
}
|
|
1708
1949
|
}
|
|
1950
|
+
|
|
1709
1951
|
export async function getRolloutFeedback( req, res ) {
|
|
1710
1952
|
try {
|
|
1711
1953
|
const taskTypes = req.body.filterByTask && req.body.filterByTask.length > 0 ? req.body.filterByTask : [ 'merchRollout', 'vmRollout' ];
|
|
@@ -27,6 +27,7 @@ import fs from 'fs';
|
|
|
27
27
|
import os from 'os';
|
|
28
28
|
import { fileURLToPath } from 'url';
|
|
29
29
|
import path from 'path';
|
|
30
|
+
const ObjectId=mongoose.Types.ObjectId;
|
|
30
31
|
|
|
31
32
|
const __filename = fileURLToPath( import.meta.url );
|
|
32
33
|
const __dirname = path.dirname( __filename );
|
|
@@ -17358,6 +17359,91 @@ async function createUser( data ) {
|
|
|
17358
17359
|
}
|
|
17359
17360
|
}
|
|
17360
17361
|
|
|
17362
|
+
export async function createLayout( req, res ) {
|
|
17363
|
+
try {
|
|
17364
|
+
let storeDetails = await storeService.find( { storeName: { $in: req.body.storeName }, clientId: req.body.clientId, status: 'active' }, { storeName: 1, storeId: 1 } );
|
|
17365
|
+
if ( !storeDetails ) {
|
|
17366
|
+
return res.sendError( 'No data found', 204 );
|
|
17367
|
+
}
|
|
17368
|
+
await Promise.all( storeDetails.map( async ( store ) => {
|
|
17369
|
+
let planoDetails = await storeBuilderService.find( { storeName: store.storeName }, { planoId: 1, _id: 1 } );
|
|
17370
|
+
await Promise.all( planoDetails.map( async ( task ) => {
|
|
17371
|
+
let getLayoutDetails = await processedTaskService.findOne( { storeName: store.storeName, planoType: 'layout' }, { _id: 1 } );
|
|
17372
|
+
if ( !getLayoutDetails ) {
|
|
17373
|
+
let data = {
|
|
17374
|
+
client_id: req.body.clientId,
|
|
17375
|
+
date_iso: new Date( dayjs().format( 'YYYY-MM-DD' ) ),
|
|
17376
|
+
date_string: dayjs().format( 'YYYY-MM-DD' ),
|
|
17377
|
+
sourceCheckList_id: new ObjectId(),
|
|
17378
|
+
checkListName: 'Layout Verification',
|
|
17379
|
+
checkListId: new ObjectId(),
|
|
17380
|
+
scheduleStartTime: dayjs().format( 'hh:mm A' ),
|
|
17381
|
+
scheduleEndTime: dayjs().format( 'hh:mm A' ),
|
|
17382
|
+
scheduleStartTime_iso: dayjs().format(),
|
|
17383
|
+
scheduleEndTime_iso: dayjs().format(),
|
|
17384
|
+
allowedOverTime: false,
|
|
17385
|
+
allowedStoreLocation: false,
|
|
17386
|
+
createdBy: new ObjectId(),
|
|
17387
|
+
createdByName: 'tango',
|
|
17388
|
+
questionAnswers: [],
|
|
17389
|
+
isdeleted: false,
|
|
17390
|
+
questionCount: 0,
|
|
17391
|
+
storeCount: 0,
|
|
17392
|
+
locationCount: 0,
|
|
17393
|
+
checkListType: 'task',
|
|
17394
|
+
country: '',
|
|
17395
|
+
store_id: store.storeId,
|
|
17396
|
+
storeName: store.storeName,
|
|
17397
|
+
userId: new ObjectId(),
|
|
17398
|
+
userName: 'tango',
|
|
17399
|
+
userEmail: 'tango@tangotech.co.in',
|
|
17400
|
+
checklistStatus: 'submit',
|
|
17401
|
+
timeFlagStatus: true,
|
|
17402
|
+
timeFlag: 0,
|
|
17403
|
+
questionFlag: 0,
|
|
17404
|
+
mobileDetectionFlag: 0,
|
|
17405
|
+
storeOpenCloseFlag: 0,
|
|
17406
|
+
reinitiateStatus: false,
|
|
17407
|
+
markasread: false,
|
|
17408
|
+
uniformDetectionFlag: 0,
|
|
17409
|
+
scheduleRepeatedType: 'daily',
|
|
17410
|
+
approvalStatus: false,
|
|
17411
|
+
approvalEnable: false,
|
|
17412
|
+
redoStatus: false,
|
|
17413
|
+
isPlano: true,
|
|
17414
|
+
planoType: 'layout',
|
|
17415
|
+
planoId: task.planoId,
|
|
17416
|
+
floorId: task._id,
|
|
17417
|
+
};
|
|
17418
|
+
|
|
17419
|
+
let taskData = await processedTaskService.create( data );
|
|
17420
|
+
let layoutData = {
|
|
17421
|
+
"date_string": dayjs().format( 'YYYY-MM-DD' ),
|
|
17422
|
+
"floorId": task._id,
|
|
17423
|
+
"fixtureId": null,
|
|
17424
|
+
"planoId": task.planoId,
|
|
17425
|
+
"taskType": "initial",
|
|
17426
|
+
"type": "layout",
|
|
17427
|
+
"taskId": taskData._id,
|
|
17428
|
+
"answers": [],
|
|
17429
|
+
"approvalStatus": "approved",
|
|
17430
|
+
"date_iso": new Date( dayjs().format( 'YYYY-MM-DD' ) ),
|
|
17431
|
+
"status": "complete",
|
|
17432
|
+
"storeId": store.storeId,
|
|
17433
|
+
"storeName": store.storeName,
|
|
17434
|
+
};
|
|
17435
|
+
await planoTaskService.create( layoutData );
|
|
17436
|
+
await storeBuilderService.updateOne( { _id: task._id }, { planoProgress: 50 } );
|
|
17437
|
+
}
|
|
17438
|
+
} ) );
|
|
17439
|
+
} ) );
|
|
17440
|
+
return res.sendSuccess( 'Layout SUbmitted Successfully' );
|
|
17441
|
+
} catch ( e ) {
|
|
17442
|
+
logger.error( { functionName: 'createLayout', error: e } );
|
|
17443
|
+
return res.sendError( e, 500 );
|
|
17444
|
+
}
|
|
17445
|
+
}
|
|
17446
|
+
|
|
17361
17447
|
async function standardizeHeaders() {
|
|
17362
17448
|
const headerMap = {
|
|
17363
17449
|
"Innovation": "Innovation",
|
|
@@ -18537,3 +18623,27 @@ async function updateMellerCollection() {
|
|
|
18537
18623
|
|
|
18538
18624
|
// updateMellerCollection();
|
|
18539
18625
|
|
|
18626
|
+
|
|
18627
|
+
export async function updateProduct( req, res ) {
|
|
18628
|
+
try {
|
|
18629
|
+
let query = [
|
|
18630
|
+
{
|
|
18631
|
+
$group: {
|
|
18632
|
+
_id: '$brandName',
|
|
18633
|
+
id: { $first: '$_id' },
|
|
18634
|
+
},
|
|
18635
|
+
},
|
|
18636
|
+
];
|
|
18637
|
+
let getProducts = await planoProductService.aggregate( query );
|
|
18638
|
+
if ( getProducts.length ) {
|
|
18639
|
+
await Promise.all( getProducts.map( async ( prod, index ) => {
|
|
18640
|
+
await planoProductService.updateOne( { _id: prod.id }, { rfId: req.body.rfId[index] } );
|
|
18641
|
+
} ) );
|
|
18642
|
+
}
|
|
18643
|
+
|
|
18644
|
+
return res.sendSuccess( 'Updated Successfully' );
|
|
18645
|
+
} catch ( e ) {
|
|
18646
|
+
logger.error( { functionName: "updateProduct", error: e } );
|
|
18647
|
+
return res.sendError( e, 500 );
|
|
18648
|
+
}
|
|
18649
|
+
}
|