add contract pdf generation
This commit is contained in:
@@ -5,6 +5,9 @@ import type { Shipment, ShipmentCreate, ShipmentEditPayload } from "@/services/r
|
||||
import type { Productor, ProductorCreate, ProductorEditPayload } from "@/services/resources/productors";
|
||||
import type { User, UserCreate, UserEditPayload } from "@/services/resources/users";
|
||||
import type { Product, ProductCreate, ProductEditPayload } from "./resources/products";
|
||||
import type { ContractCreate } from "./resources/contracts";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { t } from "@/config/i18n";
|
||||
|
||||
export function getShipments(filters?: URLSearchParams): UseQueryResult<Shipment[], Error> {
|
||||
const queryString = filters?.toString()
|
||||
@@ -43,7 +46,18 @@ export function createShipment() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully created shipment", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['shipments'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing shipment`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -62,7 +76,18 @@ export function editShipment() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully edited shipment", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['shipments'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing shipment`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -79,7 +104,18 @@ export function deleteShipment() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully deleted shipment", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['shipments'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error deleting shipment`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -121,7 +157,18 @@ export function createProductor() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully created productor", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['productors'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing productor`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -140,7 +187,18 @@ export function editProductor() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully edited productor", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['productors'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing productor`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -157,7 +215,18 @@ export function deleteProductor() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully deleted productor", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['productors'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error deleting productor`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -216,7 +285,18 @@ export function deleteForm() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully deleted form", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['forms'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error deleting form`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -235,7 +315,18 @@ export function editForm() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully edited form", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['forms'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing form`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -277,7 +368,18 @@ export function createProduct() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully created product", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['products'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing product`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -294,7 +396,18 @@ export function deleteProduct() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully deleted product", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['products'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error deleting product`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -313,7 +426,18 @@ export function editProduct() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully edited product", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['products'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing product`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -355,7 +479,18 @@ export function createUser() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully created user", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['users'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing user`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -372,7 +507,18 @@ export function deleteUser() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully deleted user", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['users'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error deleting user`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -391,7 +537,44 @@ export function editUser() {
|
||||
}).then((res) => res.json());
|
||||
},
|
||||
onSuccess: async () => {
|
||||
notifications.show({
|
||||
title: t("success", {capfirst: true}),
|
||||
message: t("successfully edited user", {capfirst: true}),
|
||||
});
|
||||
await queryClient.invalidateQueries({ queryKey: ['users'] })
|
||||
},
|
||||
onError: (error: any) => {
|
||||
notifications.show({
|
||||
title: t("error", {capfirst: true}),
|
||||
message: error?.message || t(`error editing user`, {capfirst: true}),
|
||||
color: "red"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function createContract() {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (newContract: ContractCreate) => {
|
||||
return fetch(`${Config.backend_uri}/contracts`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(newContract),
|
||||
}).then(async (res) => await res.blob());
|
||||
},
|
||||
onSuccess: async (pdfBlob) => {
|
||||
const url = URL.createObjectURL(pdfBlob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = `contract.pdf`;
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
await queryClient.invalidateQueries({ queryKey: ["contracts"] });
|
||||
}
|
||||
});
|
||||
}
|
||||
4
frontend/src/services/resources/contracts.ts
Normal file
4
frontend/src/services/resources/contracts.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export type ContractCreate = {
|
||||
form_id: number;
|
||||
contract: Record<string, string | number | null>;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Productor } from "@/services/resources/productors";
|
||||
import type { Shipment, ShipmentInputs } from "@/services/resources/shipments";
|
||||
import type { Shipment } from "@/services/resources/shipments";
|
||||
import type { User } from "@/services/resources/users";
|
||||
|
||||
export type Form = {
|
||||
@@ -11,6 +11,7 @@ export type Form = {
|
||||
productor: Productor;
|
||||
referer: User;
|
||||
shipments: Shipment[];
|
||||
minimum_shipment_value: number | null;
|
||||
}
|
||||
|
||||
export type FormCreate = {
|
||||
@@ -20,6 +21,7 @@ export type FormCreate = {
|
||||
end: string;
|
||||
productor_id: number;
|
||||
referer_id: number;
|
||||
minimum_shipment_value: number | null;
|
||||
}
|
||||
|
||||
export type FormEdit = {
|
||||
@@ -29,6 +31,7 @@ export type FormEdit = {
|
||||
end?: string | null;
|
||||
productor_id?: number | null;
|
||||
referer_id?: number | null;
|
||||
minimum_shipment_value: number | null;
|
||||
}
|
||||
|
||||
export type FormEditPayload = {
|
||||
@@ -43,4 +46,5 @@ export type FormInputs = {
|
||||
end: string | null;
|
||||
productor_id: string;
|
||||
referer_id: string;
|
||||
minimum_shipment_value: number | string | null;
|
||||
}
|
||||
@@ -1,10 +1,21 @@
|
||||
import { t } from "@/config/i18n";
|
||||
import type { Product } from "./products";
|
||||
|
||||
export const PaymentMethods = [
|
||||
{value: "cheque", label: t("cheque", {capfirst: true})},
|
||||
{value: "transfer", label: t("transfer", {capfirst: true})},
|
||||
]
|
||||
|
||||
export type PaymentMethod = {
|
||||
name: string;
|
||||
details: string;
|
||||
}
|
||||
|
||||
export type Productor = {
|
||||
id: number;
|
||||
name: string;
|
||||
address: string;
|
||||
payment: string;
|
||||
payment_methods: PaymentMethod[];
|
||||
type: string;
|
||||
products: Product[]
|
||||
}
|
||||
@@ -12,22 +23,22 @@ export type Productor = {
|
||||
export type ProductorCreate = {
|
||||
name: string;
|
||||
address: string;
|
||||
payment: string;
|
||||
payment_methods: PaymentMethod[];
|
||||
type: string;
|
||||
}
|
||||
|
||||
export type ProductorEdit = {
|
||||
name: string | null;
|
||||
address: string | null;
|
||||
payment: string | null;
|
||||
payment_methods: PaymentMethod[];
|
||||
type: string | null;
|
||||
}
|
||||
|
||||
export type ProductorInputs = {
|
||||
name: string;
|
||||
address: string;
|
||||
payment: string;
|
||||
type: string;
|
||||
payment_methods: PaymentMethod[];
|
||||
}
|
||||
|
||||
export type ProductorEditPayload = {
|
||||
|
||||
@@ -61,9 +61,9 @@ export type ProductInputs = {
|
||||
productor_id: string | null;
|
||||
name: string;
|
||||
unit: string | null;
|
||||
price: number | null;
|
||||
price_kg: number | null;
|
||||
quantity: number | null;
|
||||
price: number | string | null;
|
||||
price_kg: number | string | null;
|
||||
quantity: number | string | null;
|
||||
quantity_unit: string | null;
|
||||
type: string | null;
|
||||
}
|
||||
@@ -91,9 +91,9 @@ export function productCreateFromProductInputs(productInput: ProductInputs): Pro
|
||||
productor_id: Number(productInput.productor_id)!,
|
||||
name: productInput.name,
|
||||
unit: productInput.unit!,
|
||||
price: productInput.price!,
|
||||
price_kg: productInput.price_kg,
|
||||
quantity: productInput.quantity,
|
||||
price: productInput.price === "" || !productInput.price ? null : Number(productInput.price),
|
||||
price_kg: productInput.price_kg === "" || !productInput.price_kg ? null : Number(productInput.price_kg),
|
||||
quantity: productInput.quantity === "" || !productInput.quantity ? null : Number(productInput.quantity),
|
||||
quantity_unit: productInput.quantity_unit,
|
||||
type: productInput.type!,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user