Establish a many-to-many relationship in Prisma where one of the fields is sourced from a separate table

I'm currently working with a Prisma schema that includes products, orders, and a many-to-many relationship between them. My goal is to store the product price in the relation table so that I can capture the price of the product at the time of sale, regardless of any future price changes. Is there a way to achieve this in Prisma without having to retrieve the current prices of all products?

Below is the schema for reference:

model Product {
  id          String            @id @default(cuid())
  name        String
  // todo add check stock can't be less than zero
  stock       Int
  // todo add check price can't be less than zero
  buyPrice    Float
  sellPrice   Float
  image       String
  createdAt   DateTime          @default(now())
  createdBy   User              @relation(fields: [createdById], references: [id])
  createdById String
  category    Category          @relation(fields: [categoryId], references: [id])
  categoryId  String
  orders      ProductsOnOrder[]
}

model Order {
  id          String            @id @default(cuid())
  // guess it's suppose to be computed value
  total       Float
  paymentType PaymentType       @default(CASH)
  createdAt   DateTime          @default(now())
  createdById String
  createdBy   User              @relation(fields: [createdById], references: [id])
  products    ProductsOnOrder[]
}

model ProductsOnOrder {
  productId String
  Product   Product @relation(fields: [productId], references: [id])
  orderId   String
  order     Order   @relation(fields: [orderId], references: [id])
  quantity  Int     @default(1)
  price     Float // Price of the product at the time of the order

  @@id([productId, orderId])
}

Answer №1

When you initiate an order within your application code, ensure to manually retrieve the current price of the item and incorporate it into the generation of the ProductsOnOrder entry.

const generateOrderWithProducts = async(customerId, orderInformation) => {
  const {
    transactionType,
    productsOrdered
  } = orderInformation; // productsOrdered is an array specifying { productCode, quantity }

  return prisma.$transaction(
    productsOrdered.map(async(productEntry) => {
      const locatedProduct = await prisma.product.findUnique({
        where: {
          id: product.productId
        },
      });

      return prisma.productsOnOrder.create({
        data: {
          quantity: product.quantity,
          price: locatedProduct.sellPrice,
          Product: {
            connect: {
              id: product.productId
            },
          },
          Order: {
            create: {
              total: locatedProduct.sellPrice * product.quantity, 
              transactionType,
              initiatedBy: {
                connect: {
                  id: customerId
                },
              },
            },
          },
        },
      });
    })
  );
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize a variable function in AngularJS

Within my app.js file, I have declared functions in the following manner: var func1 = function(v1,v2,v3) { . . } var func2 = function(v1,v2,v3) { . . } Moving on to my controller.js file: var action = ""; if(..) { action = 'func1';} ...

Could we bypass the parent component somehow?

Just starting out with angular and decided to work on a small project. As I was setting up my routing, I encountered a problem. Here is the routing setup I have: const routes: Routes = [ {path: '', redirectTo: '/home', pathMatch: &a ...

Receiving a Javascript Promise from a $.ajax request

Trying to convert a $.ajax() statement into an es6 Promise and return it as an es6 promise. The goal is to have an application layer with Create, Update, Delete calls to the Microsoft Dynamics Web API that return an es6 Promise for reuse across multiple pa ...

A software piece producing a JSX element that generates a single function

Is it possible to create a JSX element or component that returns a single function as its child? For instance: interface ComponentChildrenProps { someProp: string; } const Component: React.FC<ComponentProps> = ({ children }): JSX.Element => { ...

Node.js and MongoDB Login Form Integration with Mongoose

I am relatively new to web development and currently working on a simple web page for user login authentication. My goal is to verify user credentials (username & password) on the LoginPage from a mongoose database, and if they are correct, redirect them t ...

Despite successfully connecting to my webservice, the ajax function encounters an error

<script type='text/javascript'> $(document).ready(function () { $("#submit").click(function (e) { e.preventDefault(); var userName = $("#username").val(); var pwd = $("#password").val(); authenticate(use ...

Issues with jQuery AJAX functionality

I am in the process of incorporating some ajax functionality into my php website. I have a good understanding of jQuery, but for some reason, the value returned is always empty when I try to alert() it. Below is the code snippet that I am using: PHP: if( ...

Utilize Javascript to extract and showcase JSON data fetched from a RESTful API

I'm attempting to use JavaScript to pull JSON data from a REST API and display it on a webpage. The REST call is functioning correctly in the Firefox console. function gethosts() { var xhttp = new XMLHttpRequest(); xhttp.open("GET", "https://10 ...

Encountering difficulties reaching $refs within component method

Trying to access a ref defined within a template when an element is clicked. Here's the HTML: <!DOCTYPE html> <html lang="en"> <head> <script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protectio ...

Placing the template code underneath the existing code within the Handlebars layout.hbs file

I'm currently working on a project using Express Handlebars. I have a template called foo.hbs that contains some JavaScript code which I need to insert below the script tags in the layout.hbs file: <!DOCTYPE html> <html> <head> ...

What is the reason behind taps in TypeScript only registering the first tap event?

One issue I am encountering is that only the first tap works when clicked, and subsequent taps result in an error message: Uncaught TypeError: Cannot read properties of undefined (reading 'classList') Here is the code I am using: https://codepen ...

Implement Sorting Functionality in Angular Using FormArray

Hello, I am a beginner in Angular and need some help with implementing sorting functionality. I have an input class called Foo which contains a list of books with properties like Id, Title, and Description. These books are displayed in a table where users ...

Unable to bring in an exported class from a TypeScript file

I have a TypeScript file named foo.ts that contains an exported class called "Foo" export default class Foo{ } I am attempting to import this class into another file within the same directory import {Foo} from './foo'; However, I am encounter ...

What is the best method for storing objects in Firebase in order to easily rearrange them at a later time?

My list looks something like this: {"ids": [ { "id1": { "name": "name1", "lastname": "lastname1" } }, { "id2": { "name": "name2", "lastname": "lastname2" } }, { "id3": { "name": "name3", "l ...

New example of how to use the "useSession" syntax in Next Auth

Currently, I am delving into the next-auth documentation and feeling perplexed by the syntax used in the useSession hook. The way it's showcased in the documentation is as follows: const { data: session, status } = useSession() My confusion stems f ...

How can I incorporate a new user interface button into Here Maps?

I have set up a default interactive map using Nokia Here Maps v3. The map contains multiple markers grouped together. Now, I am looking to add a button or some other UI element to the map that, when clicked, will call a function to zoom in as tightly as p ...

Generating Graphql types for React using graphql-codegen when Apollo Server is in production mode: A step-by-step guide

Everything functions perfectly when backend mode is set to NODE_ENV: development, but in production mode I encounter an error with graphql-codegen: Error on local web server: Apollo Server does not allow GraphQL introspection, but the query contains _sc ...

Will the async pipe activate onPush change detection in Angular?

I have searched various sources for the question above, but I am finding conflicting answers. For example, on Angular University's website, it is mentioned that change detection is triggered when the async pipe receives a new observable value. However ...

Asynchronous operations in Node.js with Express

Hey, I'm still pretty new to using async functions and I could really use some help understanding how to pass callbacks in async.each for each item to the next level (middleware). Here's the logic: I want to iterate through all items, and if an ...

Issue with capturing mouse position in canvas when hovering over <h1> element above it

I am working on a project using React Three Fiber to animate a 3D model that follows the mouse cursor. However, I have noticed that when the mouse hovers over some divs or headings on top of the canvas element, the animation freezes and becomes choppy unti ...