2016-11-03 2 views
0

Я пытаюсь создать простое приложение для продажи/продажи в JavaScript с помощью Dexie.js. Я не уверен, как вернуться к возврату суммы Total Sales без написания ужасного рекурсивного кода, который выполняет запрос несколько раз только для общей суммы продаж одного продукта.Как рассчитать общий объем продаж из нескольких таблиц в базе данных IndexedDB?

Моя схема несколько, как это:

clients: "++id, name, phone", 
order: "++id, clientId, daate", 
order_content: "orderId, productId, qty", 
product: "++id, name, mu, mk_cost, sa_cost, prod_cost", 
stock: "++id, date, productId, qty, lot" 

хранить типы продуктов в «Продукт» с ценами и другими деталями. Когда размещается заказ, я храню clientId в порядке, затем я использую «order_content» для хранения элементов там, используя orderId в качестве ключа для сортировки.

В основном я хочу сделать итог для каждого элемента и суммы, которая вверх.

Я попытался выполнить код ниже в цикле db.product.each(), но похоже, что я усложняю себя.

var product1Total = 0; 
function calculateTotal(productId, price){ 
db.order_content 
.where("productID") 
.equals(productId) 
.each(function(item){ 
product1Total += (price * qty) 
}) 
} 

Спасибо!

ответ

2

Если ваша цель состоит в том, чтобы получить общую цену для конкретного заказа в одном запросе, и prod_cost является стоимость вашего продукта, и вы хотите, общее на определенном порядке, вы должны сделать это что-то вроде следующего:

function calculateTotal (orderId) { 
    return db.order_content 
     .where('orderId').equals(orderId).toArray() 
    .then(orderContents => { 
     return Promise.all(
      orderContents.map(oc => db.product.get(oc.productId)) 
     ).then (products => { 
      return orderContents.reduce (
       (total, oc, i) => total + oc.qty * producs[i].prod_cost, 0); 
     }); 
    }); 
} 

Или с асинхронными функциями:

async function calculateTotal (orderId) { 
    let orderContents = await db.order_content 
     .where('orderId').equals(orderId).toArray(); 

    let products = await Promise.all(orderContents.map(oc => 
     db.product.get(oc.productId)); 

    return orderContents.reduce (
     (total, oc, i) => total + oc.qty * producs[i].prod_cost, 0); 
} 

Или с ванильным ES5 JavaScript:

function calculateTotal (orderId) { 
    return db.order_content 
     .where('orderId').equals(orderId).toArray() 
    .then(function (orderContents) { 
     return Dexie.Promise.all(
      orderContents.map(function (oc) { 
       return db.product.get(oc.productId); 
      }) 
     ).then (function (products) { 
      return orderContents.reduce (
       function (total, oc, i) { 
        return total + oc.qty * producs[i].prod_cost; 
       }, 0); 
     }); 
    }); 
} 
+0

Да, это именно то, что я хотел. Извините за неопределенное сообщение. Можно ли это сделать и в ванильном JS? –

+0

Я просто использую функции стрелок в первом примере. Замените "orderContents => {...}" на "function (orderContents) {...}" и "oc => ..." с "function (oc) {return ...}" –

1

В вашем запросе нет ничего плохого, но вы должны инкапсулировать его в функцию возврата обещаний. Это легко осуществить, объединив обещание, возвращенное из коллекции Dexie Collection.each().

function calculateTotal(productId, price) { 
    var total = 0; 
    return db.order_content 
     .where("productID") 
     .equals(productId) 
     .each(function(item){ 
      total += (price * item.qty) 
     }).then (function() { 
      return total; 
     }); 
} 

Или в ES7:

async function calculateTotal (productId, price) { 
    var total = 0; 

    await db.order_content 
     .where("productID") 
     .equals(productId) 
     .each (item => total += (price * item.qty)); 

    return total; 
} 
Смежные вопросы