Skip to content

Commit

Permalink
backend + frontend : create order and load salesn persistency ok
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminpochat committed Mar 10, 2024
1 parent d22c4be commit fb31b9c
Show file tree
Hide file tree
Showing 17 changed files with 147 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import eu.viandeendirect.repository.OrderItemRepository;
import eu.viandeendirect.repository.PackageLotRepository;
import eu.viandeendirect.repository.SaleRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -16,6 +17,7 @@
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_METHOD;

Expand Down Expand Up @@ -55,6 +57,7 @@ void createOrder_should_persist_order_in_database() {
item.setUnitPrice(16f);
item.setPackageLot(packageLot);
order.setItems(List.of(item));
int quantitySoldBeforeOrderCreation = packageLot.getQuantitySold();

// when
Order orderCreated = orderService.createOrder(order).getBody();
Expand All @@ -64,6 +67,29 @@ void createOrder_should_persist_order_in_database() {
assertThat(orderCreated.getId()).isNotNull();
List<OrderItem> itemsCreated = orderItemRepository.findByOrder(orderCreated);
assertThat(itemsCreated).hasSize(1);
assertThat(packageLot.getQuantitySold()).isEqualTo(quantitySoldBeforeOrderCreation + 1);
}

@Test
void createOrder_should_raise_an_exception_if_not_enough_quantity_to_sell() {
// given
Sale sale = saleRepository.findById(1000).get();
Customer customer = customerRepository.findById(3000).get();
PackageLot packageLot = packageLotRepository.findById(10001).get();
Order order = new Order();
order.setCustomer(customer);
order.setSale(sale);
OrderItem item = new OrderItem();
item.setQuantity(100);
item.setUnitPrice(16f);
item.setPackageLot(packageLot);
order.setItems(List.of(item));
int quantitySoldBeforeOrderCreation = packageLot.getQuantitySold();

// when / then
assertThatThrownBy(() -> orderService.createOrder(order))
.isNotNull();
assertThat(packageLot.getQuantitySold()).isEqualTo(quantitySoldBeforeOrderCreation);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.net.URI;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import eu.viandeendirect.model.Customer;
Expand Down Expand Up @@ -63,8 +65,8 @@ public Order id(Integer id) {
*
* @return id
*/
@NotNull
@Schema(name = "id", description = "", required = true)

@Schema(name = "id", description = "", required = false)
public Integer getId() {
return id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.net.URI;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import eu.viandeendirect.model.Order;
Expand Down Expand Up @@ -38,6 +40,7 @@ public class OrderItem {

@JsonProperty("order")
@ManyToOne
@JsonIgnore
private Order order;

@JsonProperty("packageLot")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class Producer {
private List<Production> productions = null;

@JsonProperty("sales")
@JsonIgnore
@JsonManagedReference("salesSeller")
@jakarta.persistence.OneToMany(mappedBy = "seller")
@Valid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class Sale {
@JsonProperty("orders")
@jakarta.persistence.OneToMany(mappedBy = "sale")
@Valid
@JsonIgnore
private List<Order> orders = null;

@JsonProperty("deliveryStart")
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/src/domains/customer/CustomerController.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from 'react'
import CustomersList from './views/CustomersList.tsx'

export default function CustomerController() {
export default function CustomerController({producer: producer}) {

const NONE = 'NONE'

Expand Down
31 changes: 17 additions & 14 deletions frontend/app/src/domains/customer/views/CustomersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,34 @@ import { DataGrid, GridRowsProp, GridColDef, GridToolbar } from '@mui/x-data-gri

import { useKeycloak } from '@react-keycloak/web'
import { ApiBuilder } from '../../../api/ApiBuilder.ts'
import { ApiInvoker } from '../../../api/ApiInvoker.ts';

export default function CustomersList() {

const [customers, setCustomers] = useState([])
const { keycloak, initialized } = useKeycloak()
const apiBuilder = new ApiBuilder()

const apiInvoker = new ApiInvoker()

useEffect(() => {
loadCustomers()
}, [keycloak])

function loadCustomers() {
apiBuilder.getAuthenticatedApi(keycloak).then(api => {
apiBuilder.invokeAuthenticatedApi(() => {
api.getProducerCustomers((error, data, response) => {
if (error) {
console.error(error)
} else {
console.log('api.getProducerCustomers called successfully. Returned data: ' + data)
setCustomers(data)
}
})
}, keycloak)
})

apiInvoker.callApiAuthenticatedly(keycloak, api => api.getProducerCustomers, null, setCustomers, console.error)

// apiBuilder.getAuthenticatedApi(keycloak).then(api => {
// apiBuilder.invokeAuthenticatedApi(() => {
// api.getProducerCustomers((error, data, response) => {
// if (error) {
// console.error(error)
// } else {
// console.log('api.getProducerCustomers called successfully. Returned data: ' + data)
// setCustomers(data)
// }
// })
// }, keycloak)
// })
}

const rows: GridRowsProp = customers.map(customer => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageLotsCreator from './views/PackageLotsCreator.tsx'
import ProductionsList from './views/ProductionsList.tsx'
import BeefProductionView from './views/beefProduction/BeefProductionView.tsx'

export default function ProductionController() {
export default function ProductionController({producer: producer}) {

const BEEF_PRODUCTION_CREATION = 'BEEF_PRODUCTION_CREATION'
const BEEF_PRODUCTION_VIEW = 'BEEF_PRODUCTION_VIEW'
Expand Down
6 changes: 3 additions & 3 deletions frontend/app/src/domains/sale/SaleController.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react'
import { useState } from 'react'
import { useState, useEffect } from 'react'

import SalesList from './views/SalesList.tsx'
import SaleForm from './views/SaleForm.tsx'
import OrdersList from './views/OrdersList.tsx'
import Sale from 'viandeendirect_eu/dist/model/Sale'
import Order from 'viandeendirect_eu/dist/model/Order'
import OrderView from './views/OrderView.tsx'
import OrderForm from './views/OrderForm.tsx'
import ProducerOrderForm from './views/ProducerOrderForm.tsx'

export default function SaleController({producer: producer}) {

Expand All @@ -28,7 +28,7 @@ export default function SaleController({producer: producer}) {
case SALE_CREATION_VIEW: return <SaleForm producer={producer} returnCallback={displaySalesList}></SaleForm>
case ORDERS_LIST_VIEW: return <OrdersList sale={context} returnCallback={displaySalesList} viewOrderCallback={displayOrder} createOrderCallback={() => createOrder(context)}/>
case ORDER_VIEW: return <OrderView order={context.order} sale={context.sale} returnCallback={displayOrdersList}/>
case ORDER_CREATION_VIEW: return <OrderForm sale={context} returnCallback={displayOrdersList}/>
case ORDER_CREATION_VIEW: return <ProducerOrderForm producer={producer} sale={context} returnCallback={displayOrdersList}/>
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { useState } from 'react'

import { Switch, Autocomplete, TextField, Button } from "@mui/material"
import { Switch, Button } from "@mui/material"
import { AutocompleteElement, FormContainer, TextFieldElement } from 'react-hook-form-mui'

import Customer from "viandeendirect_eu/dist/model/Customer"
Expand Down
28 changes: 23 additions & 5 deletions frontend/app/src/domains/sale/components/SaleCard.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
import React from 'react'
import React, { useEffect, useState } from 'react'

import { Button, ButtonGroup, Card, CardActions, CardContent, Typography } from "@mui/material"
import dayjs from 'dayjs'
import SaleCardBeefProduction from './SaleCardBeefProduction.js';
import { ApiInvoker } from '../../../api/ApiInvoker.ts';
import { useKeycloak } from '@react-keycloak/web';
import Order from 'viandeendirect_eu/dist/model/Order'
import Production from 'viandeendirect_eu/dist/model/Production'


export default function SaleCard({ sale: sale, manageOrdersCallback: manageOrdersCallback}) {

const apiInvoker = new ApiInvoker()
const [orders, setOrders] = useState<Array<Order>>([])
const [productions, setProductions] = useState<Array<Production>>([])
const {keycloak} = useKeycloak()

useEffect(() => {
apiInvoker.callApiAuthenticatedly(keycloak, api => api.getSaleOrders, sale.id, setOrders, console.error)
}, [keycloak, sale])

useEffect(() => {
apiInvoker.callApiAuthenticatedly(keycloak, api => api.getSaleProductions, sale.id, setProductions, console.error)
}, [keycloak, sale])

return (
<Card>
<CardContent>
Expand All @@ -29,7 +47,7 @@ export default function SaleCard({ sale: sale, manageOrdersCallback: manageOrder
Commandes
</Typography>
<Typography>
{sale.orders.length} commandes client
{orders.length} commandes client
</Typography>
<Typography>
{getQuantitySold()} kg commandés
Expand All @@ -44,7 +62,7 @@ export default function SaleCard({ sale: sale, manageOrdersCallback: manageOrder
<Typography color="text.secondary">
Productions mises en vente
</Typography>
{sale.productions.map(getProduction)}
{productions.map(getProduction)}
</div>
</div>
</CardContent>
Expand All @@ -69,14 +87,14 @@ export default function SaleCard({ sale: sale, manageOrdersCallback: manageOrder
}

function getQuantitySold() {
return sale.orders
return orders
.flatMap(order => order.items)
.map(item => item.packageLot.netWeight * item.quantity)
.reduce((totalQuantity, orderItemQuantity) => totalQuantity + orderItemQuantity, 0)
}

function getAmountSold() {
return sale.orders
return orders
.flatMap(order => order.items)
.map(item => item.unitPrice * item.quantity)
.reduce((totalAmout, orderItemAmout) => totalAmout + orderItemAmout, 0)
Expand Down
31 changes: 10 additions & 21 deletions frontend/app/src/domains/sale/components/SaleCardBeefProduction.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
import { useEffect, useState } from 'react';
import { useKeycloak } from '@react-keycloak/web'
import { Typography } from "@mui/material"
import { ApiBuilder } from '../../../api/ApiBuilder.ts'
import { ApiInvoker } from '../../../api/ApiInvoker.ts'
import { AnimalTypeUtils } from '../../../enum/AnimalType.ts';
import PieChart from '../../commons/components/PieChart.tsx'
import styles from './SaleCard.css'

export default function SaleCardBeefProduction({production: production}) {

const [productionPercentageSold, setProductionPercentageSold] = useState([])
const { keycloak, initialized } = useKeycloak()
const apiBuilder = new ApiBuilder()
const { keycloak } = useKeycloak()
const apiInvoker = new ApiInvoker()

useEffect(() => {
loadProductionPercentageSold()
}, [keycloak])


function loadProductionPercentageSold() {
apiBuilder.getAuthenticatedApi(keycloak).then(api => {
apiBuilder.invokeAuthenticatedApi(() => {
api.getProductionPercentageSold(production.id, (error, data, response) => {
if (error) {
console.error(error)
} else {
console.log('api.getProductionPercentageSold called successfully. Returned data: ' + data)
setProductionPercentageSold(data)
}
})
}, keycloak)
})
}
apiInvoker.callApiAuthenticatedly(
keycloak,
api => api.getProductionPercentageSold,
production.id,
setProductionPercentageSold,
console.error)
}, [keycloak, production])

return <>
<div className='sale-card-production'>
Expand Down
Loading

0 comments on commit fb31b9c

Please sign in to comment.