add(remaining): add a way to generate contracts only with remaining shipments
All checks were successful
Deploy Amap / deploy (push) Successful in 41s
All checks were successful
Deploy Amap / deploy (push) Successful in 41s
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
"""Router for contract resource"""
|
||||
import datetime
|
||||
import io
|
||||
import zipfile
|
||||
|
||||
import src.contracts.service as service
|
||||
import src.forms.service as form_service
|
||||
import src.shipments.service as shipment_service
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from fastapi.responses import StreamingResponse
|
||||
from sqlmodel import Session
|
||||
@@ -44,10 +46,15 @@ async def create_contract(
|
||||
)
|
||||
)
|
||||
)
|
||||
remaining_shipments = shipment_service.get_remaining_shipments(
|
||||
session,
|
||||
new_contract.form.id,
|
||||
datetime.datetime.today()
|
||||
)
|
||||
prices = service.generate_products_prices(
|
||||
occasionals,
|
||||
recurrents,
|
||||
new_contract.form.shipments
|
||||
remaining_shipments
|
||||
)
|
||||
recurrent_price = prices['recurrent']
|
||||
total_price = prices['total']
|
||||
@@ -111,7 +118,7 @@ async def get_base_contract_template(
|
||||
cheque_payment_method = list(filter(
|
||||
lambda x: x.name == "cheque", form.productor.payment_methods))
|
||||
cheque_number = cheque_payment_method[0].max if len(
|
||||
cheque_payment_method) > 0 else 3
|
||||
cheque_payment_method) > 0 and cheque_payment_method[0].max is not None else 3
|
||||
print(cheque_number, cheque_payment_method)
|
||||
empty_contract = models.ContractPublic(
|
||||
firstname='',
|
||||
|
||||
@@ -49,6 +49,19 @@ def get_one(session: Session, shipment_id: int) -> models.ShipmentPublic:
|
||||
return session.get(models.Shipment, shipment_id)
|
||||
|
||||
|
||||
def get_remaining_shipments(session: Session, form_id: int, date: datetime.date) -> list[models.ShipmentPublic]:
|
||||
statement = (
|
||||
select(models.Shipment)
|
||||
.join(
|
||||
models.Form,
|
||||
models.Shipment.form_id == models.Form.id
|
||||
)
|
||||
.where(models.Form.id == form_id)
|
||||
.where(models.Shipment.date >= date)
|
||||
)
|
||||
return session.exec(statement.order_by(models.Shipment.name)).all()
|
||||
|
||||
|
||||
def create_one(
|
||||
session: Session,
|
||||
shipment: models.ShipmentCreate) -> models.ShipmentPublic:
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"filter by productor": "filter by producer",
|
||||
"filter by season": "filter by season",
|
||||
"filter by type": "filter by type",
|
||||
"for this contract": "for this contract.",
|
||||
"for this contract": "for this contract",
|
||||
"for transfer method contact your referer or productor": "for bank transfer, contact your referent or producer.",
|
||||
"form": "contract form",
|
||||
"form name": "contract form name",
|
||||
@@ -184,6 +184,8 @@
|
||||
"shipment products": "shipment products",
|
||||
"shipment products is necessary only for occasional products (if all products are recurrent leave empty)": "shipment products configuration is only necessary for occasional products (leave empty if all products are recurrent).",
|
||||
"shipments": "shipments",
|
||||
"remaining_shipments_one": "remaining shipment",
|
||||
"remaining_shipments_other": "remaining shipments",
|
||||
"some contracts require a minimum value per shipment, ignore this field if it's not the case": "some contracts require a minimum value per shipment. Ignore this field if it does not apply to your contract.",
|
||||
"start": "start",
|
||||
"start date": "start date",
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"filter by productor": "filtrer par producteur·trice",
|
||||
"filter by season": "filtrer par saisons",
|
||||
"filter by type": "filtrer par type",
|
||||
"for this contract": "pour ce contrat.",
|
||||
"for this contract": "pour ce contrat",
|
||||
"for transfer method contact your referer or productor": "pour mettre en place le virement automatique, contactez votre référent ou le producteur.",
|
||||
"form": "formulaire de contrat",
|
||||
"form name": "nom du formulaire de contrat",
|
||||
@@ -184,6 +184,8 @@
|
||||
"shipment products": "produits pour la livraison",
|
||||
"shipment products is necessary only for occasional products (if all products are recurrent leave empty)": "il est nécessaire de configurer les produits pour la livraison uniquement si il y a des produits occasionnels (laisser vide si tous les produits sont récurents).",
|
||||
"shipments": "livraisons",
|
||||
"remaining_shipments_one": "livraison restante",
|
||||
"remaining_shipments_other": "livraisons restantes",
|
||||
"some contracts require a minimum value per shipment, ignore this field if it's not the case": "certains contrats nécessitent une valeur minimum par livraison. Ce champ peut être ignoré s’il ne s’applique pas à votre contrat.",
|
||||
"start": "début",
|
||||
"start date": "date de début",
|
||||
|
||||
@@ -24,6 +24,7 @@ import { useParams } from "react-router";
|
||||
import { computePrices } from "./price";
|
||||
import { ContractCheque } from "@/components/PaymentMethods/Cheque";
|
||||
import { tranformProducts, type ContractInputs } from "@/services/resources/contracts";
|
||||
import type { Shipment } from "@/services/resources/shipments";
|
||||
|
||||
export function Contract() {
|
||||
const { id } = useParams();
|
||||
@@ -71,12 +72,22 @@ export function Contract() {
|
||||
return form?.productor?.products;
|
||||
}, [form]);
|
||||
|
||||
const remainingShipments = useMemo(() => {
|
||||
const currentDate = new Date();
|
||||
return form?.shipments.reduce((acc, shipment) => {
|
||||
if (new Date(shipment.date) > currentDate) {
|
||||
return [...acc, shipment];
|
||||
}
|
||||
return acc;
|
||||
}, [] as Shipment[])
|
||||
}, [form])
|
||||
|
||||
const price = useMemo(() => {
|
||||
if (!allProducts) {
|
||||
return 0;
|
||||
}
|
||||
const productValues = Object.entries(inputForm.getValues().products);
|
||||
return computePrices(productValues, allProducts, form?.shipments.length);
|
||||
return computePrices(productValues, allProducts, remainingShipments?.length);
|
||||
}, [inputForm, allProducts, form?.shipments]);
|
||||
|
||||
const inputRefs = useRef<Record<string, HTMLInputElement | null>>({
|
||||
@@ -229,7 +240,7 @@ export function Contract() {
|
||||
/>
|
||||
</Group>
|
||||
<Title order={3}>{t("shipments", { capfirst: true })}</Title>
|
||||
<Text>{`${t("there is", { capfirst: true })} ${shipments.length} ${shipments.length > 1 ? t("shipments") : t("shipment")} ${t("for this contract")}`}</Text>
|
||||
<Text>{`${t("there is", { capfirst: true })} ${shipments.length} ${shipments.length > 1 ? t("shipments") : t("shipment")} ${t("for this contract")} :`}</Text>
|
||||
<List>
|
||||
{shipments.map((shipment) => (
|
||||
<List.Item key={shipment.id}>
|
||||
@@ -243,6 +254,20 @@ export function Contract() {
|
||||
</List.Item>
|
||||
))}
|
||||
</List>
|
||||
<Text>{`${t("there is", { capfirst: true })} ${remainingShipments?.length} ${t("remaining_shipments", {count: remainingShipments?.length})} :`}</Text>
|
||||
<List>
|
||||
{remainingShipments?.map((shipment) => (
|
||||
<List.Item key={shipment.id}>
|
||||
{`${shipment.name} :
|
||||
${new Date(shipment.date).toLocaleDateString("fr-FR", {
|
||||
weekday: "long",
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}`}
|
||||
</List.Item>
|
||||
))}
|
||||
</List>
|
||||
{productsRecurent.length > 0 ? (
|
||||
<>
|
||||
<Title order={3}>{t("recurrent products", { capfirst: true })}</Title>
|
||||
@@ -256,12 +281,12 @@ export function Contract() {
|
||||
))}
|
||||
</>
|
||||
) : null}
|
||||
{shipments.some((shipment) => shipment.products.length > 0) ? (
|
||||
{remainingShipments?.some((shipment) => shipment.products.length > 0) ? (
|
||||
<>
|
||||
<Title order={3}>{t("occasional products", { capfirst: true })}</Title>
|
||||
<Text>{t("select products per shipment", { capfirst: true })}</Text>
|
||||
<Accordion defaultValue={"0"}>
|
||||
{shipments.map((shipment, index) => (
|
||||
{remainingShipments?.map((shipment, index) => (
|
||||
<ShipmentForm
|
||||
minimumPrice={form.minimum_shipment_value}
|
||||
shipment={shipment}
|
||||
|
||||
Reference in New Issue
Block a user