Your IP : 216.73.216.91


Current Path : /var/node/inatote/Inatote-Backend/vendors/
Upload File :
Current File : /var/node/inatote/Inatote-Backend/vendors/vendor-list.js

import makeVendor from './vendor.js'
import { UniqueConstraintError } from '../helpers/errors.js'

export default function makevendorList({ database }) {
    return Object.freeze({
        add,
        findByEmail,
        findById,
        getItems,
        remove,
        replace,
        update,
        getVendorByLocation,
        getVendorsWithCategories,
        searchVendors

    })

  async function searchVendors( name ) {
        try{
            const db = await database
            let result = [];
            let vendor_ids = [] 
            
        let category = await db.collection("categories").find({"products.productName" : {$regex : name ,  $options: 'i'}}).toArray();
        category.forEach(element => {
            vendor_ids=[...vendor_ids , db.makeId(element.vendorID) ]
        });
        // let vendors_byids = await db.collection("vendors").find({"_id" : {$in : vendor_ids }}).toArray();
        // result = [...vendors ,...vendors_byids ]
        return vendor_ids
        }catch(err){
            console.log("err", err);
        }
        
    }

    async function getItems({ max = 100, before, after } = {}) {
        const db = await database
        const query = {}
        if (before || after) {
            query._id = {}
            query._id = before ? { ...query._id, $lt: db.makeId(before) } : query._id
            query._id = after ? { ...query._id, $gt: db.makeId(after) } : query._id
        }
        

        return (await db
            .collection('vendors')
            .find(query)
            .limit(Number(max))
            .toArray()).map((x)=>documentTovendor(x , []))
    }

    async function add({ vendorId, ...vendor }) {
        const db = await database
        if (vendorId) {
            vendor._id = db.makeId(vendorId)
        }

        vendor.createdDate = new Date();
        vendor.lastUpdatedDate = new Date();


        const { result, ops } = await db
            .collection('vendors')
            .insertOne(vendor)
            .catch(mongoError => {
                const [errorCode] = mongoError.message.split(' ')
                if (errorCode === 'E11000') {
                    const [_, mongoIndex] = mongoError.message.split(':')[2].split(' ')
                    throw new UniqueConstraintError(
                        mongoIndex === 'vendorEmailIndex' ? 'emailAddress' : 'vendorId'
                    )
                }
                throw mongoError
            })
        return {
            success: result.ok === 1,
            created: documentTovendor(ops[0])
        }
    }

    async function findById({ vendorId }) {
        const db = await database
        const found = await db
            .collection('vendors')
            .findOne({ _id: db.makeId(vendorId) })

        console.log("found" , found ,vendorId);
        if (found) {
            return found 
            // documentTovendor(found)
        }
        return null
    }

    async function getVendorsWithCategories({ id, name , userId }) {
        const db = await database;
        //console.log("name", RegExp(name), id);
        let aggregate = !name ?
            await db.collection("vendors").aggregate([
                { $match: { _id: db.makeId(id) } },
                {
                    $match:{ isEnabled :{ $not: { $eq: false } }}
                },
                {
                    $lookup:
                    {
                        from: "categories",
                        localField: "_id",
                        foreignField: "vendorID",
                        as: "categories"
                    }
                }
            ]).toArray() :
            await db.collection("vendors").aggregate([
                { $match: { _id: db.makeId(id) } },
                  {
                    $match:{ isEnabled :{ $not: { $eq: false } }}
                },
                {   
                    $lookup:
                    {
                        from: "categories",
                        let: { vendor_id: "$_id"},
                        pipeline: [
                            {
                                $match:
                                {
                                    $expr:
                                    {
                                        $and:
                                            [
                                                { $eq: ["$vendorID", "$$vendor_id"] },
                                            ],
                                    },
                                },
                            },
                            // {
                            //     $match: {
                            //         "products.productName": { $regex: name, $options: "i" },
                            //         "products.isEnabled": true,
                            //         "products.inStock": true,
                            //     }
                            // }
                        ],
                        as: "categories"
                    }
                }
            ]).toArray();

            let configrations = (await db
                .collection('configurations')
                .findOne());

        let favourites = await db.collection("favourites").findOne({userId :db.makeId(userId) })
        //console.log(favourites ,"favourites", userId);
        let fav_products = favourites && favourites.product && favourites.product.length > 0 ? favourites.product : [] ;
        //console.log("aggregate", aggregate);
        for (let j = 0; j < aggregate.length; j++) 
        {
                //console.log("x" , aggregate[j]["categories"]);
                let category = aggregate[j]["categories"];
              
                for (let i = 0; i < category.length; i++) {
                    let u_products = []
                    let products = category[i].products;
                
                    for (let l = 0; l < products.length; l++) {
                       if(products[l].isEnabled && products[l].inStock){
                           
                        //    products[l]["productMarkup"] = configrations["productMarkup"] ? configrations["productMarkup"] : 0 
                           products[l]["totalPrice"] =  parseInt(products[l]["unitPrice"]);
                           products[l]["favourite"] = fav_products.includes(`${products[l]["productId"]}`);
                            

                            u_products = [...u_products , products[l]]
                       }
                    }
                    category[i]["products"] = u_products;
                }
                aggregate[j]["categories"] = category
            }
        //console.log("aggregate", aggregate);
       
        return aggregate 
    }

    async function findByEmail({ emailAddress }) {
        const db = await database
        const results = await db
            .collection('vendors')
            .find({ emailAddress })
            .toArray()
        return results.map((x)=>documentTovendor(x , []))
    }

    async function remove(vendorId) {
        const db = await database
      
        const { result } = await db.collection('vendors').updateOne({
            _id: db.makeId(vendorId)
        }, {$set : {
            id_deleted : true
        }}, {})
        return result.n
    }

    // todo:
    async function replace(vendor) { }

    // todo:
    async function update({ vendorId, vendor }) {
        const db = await database
        //console.log(vendorId)
        //console.log(vendor)
        let { vendorID} = vendor;
        vendor.lastUpdatedDate = new Date();
        vendor.isEnabled = 'true' === vendor.isEnabled;
        vendor.is_deleted = 'true' === vendor.is_deleted;
        vendor.isOpened = 'true' === vendor.isOpened;
        console.log("VENDOR", vendor);
        

        var q = {};

        for (var item in vendor) {
            console.log(item)
            if(item == 'location'){
                q[item] = vendor[item]
        
            }
            else{
                q[item] = vendor[item]
        
            }
        }

        const query = {
            $set: q
        }

        console.log(query)

        const { result } = await db.collection('vendors').updateOne({
            _id: db.makeId(vendorId)
        }, query, {})

        //console.log(result)

        if (result.nModified != 1) {
            return {
                success: false,
                error: "Something went wrong when performing this operation."
            }
        }

        return {
            success: true,
            vendor: vendor
        };
    }

    async function getVendorByLocation({ latitude, longitude, max = 10 , userId  , name} = {}) {
       
        try {
            //console.log("latitude", latitude, longitude, parseFloat(latitude), Number(latitude));
            const db = await database
            let vendorIds = [];
            let configrations = (await db
                .collection('configurations')
                .findOne());
            let query = { isEnabled : true , is_deleted: false , location: { $near: { $geometry: { type: "Point", coordinates: [Number(latitude), Number(longitude)] }, $maxDistance: Number(configrations.nearbyArea) } } };
            // let query = {}
            if(name){
                vendorIds = await searchVendors(name);
                console.log("vendorIds" ,vendorIds);
                if(vendorIds && vendorIds.length > 0){
                    query = {...query , "_id" : {$in : vendorIds }}        
                }
                query = {...query , "vendorName" : {$regex : name ,  $options: 'i'} }
            }

            console.log("QUERY" , query);
            //console.log("configrations", configrations);
            // const query =  {
            //     location:
            //       { $near:
            //          {
            //            $geometry: { type: "Point",  coordinates: [ Number(latitude),Number(longitude)] },
            //         //    $minDistance: 1000,
            //            $maxDistance: 10000
            //          }
            //       }
            //   }

            // return (await db
            //     .collection('vendors')
            //     .find(query)
            //     .limit(Number(max))
            //     .toArray()).map(documentTovendor)
            // return (await db.collection("vendors").aggregate( [
            //     {
            //        $geoNear: {
            //           near: { type: "Point", coordinates: [ Number(latitude), Number(longitude)] },
            //           spherical: true,
            //         //   query: { category: "Parks" },
            //           distanceField: "location"
            //        }
            //     }
            //  ] ))
            // return (await db.collection("vendors").aggregate([ {$geoNear: { near :{type: "Point", coordinates:[77.6174,12.9226]}, distanceField: "distance", spherical: true } } ]).toArray())
            //console.log("userId" , userId);
            
            let favourites = await db.collection("favourites").findOne({userId :db.makeId(userId) })
            //console.log(favourites ,"favourites");
            let index = (await db.collection("vendors").ensureIndex({ location: "2dsphere" }))
            console.log("index", index);
            return (await db.collection("vendors").find(query).toArray()).map((x)=>documentTovendor(x , favourites && favourites.vendor ? favourites.vendor  : []))
            // return (await db.collection("vendors").aggregate([ {$geoNear: { near :{type: "Point", coordinates:[77.6174,12.9226]}, distanceField: "distance", spherical: true } } ]).toArray())

        } catch (err) {
            console.log("err", err);
        }

        // db.restaurants.find( { location: { $geoWithin: { $geometry: neighborhood.geometry } } } ).count()
        // )
    }

    function documentTovendor({ _id: vendorId, featured , ...doc } , array = []) {
    //console.log("vendor" , array);
        let favourite = false ;
        //console.log("vendorId" ,array.includes(`${vendorId}`) , vendorId);
        if (array && array.includes(`${vendorId}`)){
            //console.log("includes" , vendorId);
            favourite = true
        }
        return makeVendor({ vendorId, ...doc, favourite })
    }

    // function documentToproduct({ _id: productId, ...doc } , markup) {
    //     doc["productMarkup"] = markup;
    //     doc["totalPrice"] = parseInt(doc["productMarkup"])  + parseInt(doc["unitPrice"])
    //     return makeproduct({ productId, ...doc })
    // }
}