pattanshetti / src /pages /Invoice.tsx
triflix's picture
Upload 99 files
4be2b2b verified
import { useState } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { ArrowLeft, Save, Printer } from "lucide-react";
import { Link } from "react-router-dom";
import { useToast } from "@/hooks/use-toast";
const Invoice = () => {
const { toast } = useToast();
const [formData, setFormData] = useState({
partyName: "",
date: new Date().toISOString().split('T')[0],
serialNumber: "",
particular: "",
lotNumber: "",
bags: "",
grossWeight: "40",
rate: "",
});
const [charges, setCharges] = useState({
bardhana: true,
hamali: false,
adhath: 0,
cess: 2,
gaadiBharni: "",
});
const calculateNetWeight = () => {
const bags = parseFloat(formData.bags) || 0;
const grossPerBag = parseFloat(formData.grossWeight) || 40;
return bags * (grossPerBag - 1);
};
const calculateBasicAmount = () => {
const netWeight = calculateNetWeight();
const rate = parseFloat(formData.rate) || 0;
return netWeight * rate;
};
const calculateCharges = () => {
const bags = parseFloat(formData.bags) || 0;
const basicAmount = calculateBasicAmount();
let total = basicAmount;
const breakdown = {
bardhana: charges.bardhana ? bags * 18 : 0,
hamali: charges.hamali ? bags * 6 : 0,
adhath: (charges.adhath / 100) * basicAmount,
cess: (charges.cess / 100) * basicAmount,
gaadiBharni: parseFloat(charges.gaadiBharni) || 0,
};
total += breakdown.bardhana + breakdown.hamali + breakdown.adhath + breakdown.cess + breakdown.gaadiBharni;
return { breakdown, total };
};
const handleSave = () => {
toast({
title: "Invoice Saved",
description: "Invoice has been saved successfully.",
});
};
const handlePrint = () => {
window.print();
};
const { breakdown, total } = calculateCharges();
return (
<div className="min-h-screen bg-background">
{/* Header */}
<header className="border-b bg-card print:hidden">
<div className="container mx-auto px-4 py-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Link to="/">
<Button variant="ghost" size="icon">
<ArrowLeft className="h-5 w-5" />
</Button>
</Link>
<div>
<h1 className="text-2xl font-bold text-foreground">New Invoice</h1>
<p className="text-sm text-muted-foreground">Create sales invoice</p>
</div>
</div>
<div className="flex gap-2">
<Button variant="outline" onClick={handlePrint}>
<Printer className="h-4 w-4 mr-2" />
Print
</Button>
<Button onClick={handleSave}>
<Save className="h-4 w-4 mr-2" />
Save
</Button>
</div>
</div>
</div>
</header>
{/* Main Content */}
<main className="container mx-auto px-4 py-8">
<div className="grid gap-6 lg:grid-cols-3">
{/* Invoice Form */}
<div className="lg:col-span-2">
<Card>
<CardHeader>
<CardTitle>Invoice Details</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Basic Info */}
<div className="grid gap-4 md:grid-cols-3">
<div className="space-y-2">
<Label htmlFor="serialNumber">Serial Number</Label>
<Input
id="serialNumber"
value={formData.serialNumber}
onChange={(e) => setFormData({ ...formData, serialNumber: e.target.value })}
placeholder="INV-001"
/>
</div>
<div className="space-y-2">
<Label htmlFor="date">Date</Label>
<Input
id="date"
type="date"
value={formData.date}
onChange={(e) => setFormData({ ...formData, date: e.target.value })}
/>
</div>
<div className="space-y-2">
<Label htmlFor="lotNumber">Lot Number</Label>
<Input
id="lotNumber"
value={formData.lotNumber}
onChange={(e) => setFormData({ ...formData, lotNumber: e.target.value })}
placeholder="LOT-123"
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="partyName">Party Name</Label>
<Input
id="partyName"
value={formData.partyName}
onChange={(e) => setFormData({ ...formData, partyName: e.target.value })}
placeholder="Enter party name"
/>
</div>
<Separator />
{/* Product Details */}
<div className="space-y-4">
<h3 className="font-semibold">Product Details</h3>
<div className="grid gap-4 md:grid-cols-2">
<div className="space-y-2">
<Label htmlFor="particular">Variety</Label>
<Select
value={formData.particular}
onValueChange={(value) => setFormData({ ...formData, particular: value })}
>
<SelectTrigger id="particular">
<SelectValue placeholder="Select variety" />
</SelectTrigger>
<SelectContent>
<SelectItem value="teja">Teja</SelectItem>
<SelectItem value="garuda">Garuda</SelectItem>
<SelectItem value="341">341</SelectItem>
<SelectItem value="other">Other</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="bags">Number of Bags</Label>
<Input
id="bags"
type="number"
value={formData.bags}
onChange={(e) => setFormData({ ...formData, bags: e.target.value })}
placeholder="10"
/>
</div>
</div>
<div className="grid gap-4 md:grid-cols-3">
<div className="space-y-2">
<Label htmlFor="grossWeight">Gross Weight (kg/bag)</Label>
<Input
id="grossWeight"
type="number"
value={formData.grossWeight}
onChange={(e) => setFormData({ ...formData, grossWeight: e.target.value })}
placeholder="40"
/>
</div>
<div className="space-y-2">
<Label>Net Weight (kg/bag)</Label>
<Input
value={(parseFloat(formData.grossWeight) || 40) - 1}
disabled
className="bg-muted"
/>
</div>
<div className="space-y-2">
<Label htmlFor="rate">Rate (₹/kg)</Label>
<Input
id="rate"
type="number"
value={formData.rate}
onChange={(e) => setFormData({ ...formData, rate: e.target.value })}
placeholder="200"
/>
</div>
</div>
</div>
<Separator />
{/* Additional Charges */}
<div className="space-y-4">
<h3 className="font-semibold">Additional Charges</h3>
<div className="space-y-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<input
type="checkbox"
id="bardhana"
checked={charges.bardhana}
onChange={(e) => setCharges({ ...charges, bardhana: e.target.checked })}
className="h-4 w-4"
/>
<Label htmlFor="bardhana">Bardhana (₹18/bag)</Label>
</div>
<span className="text-sm text-muted-foreground">₹{breakdown.bardhana.toFixed(2)}</span>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<input
type="checkbox"
id="hamali"
checked={charges.hamali}
onChange={(e) => setCharges({ ...charges, hamali: e.target.checked })}
className="h-4 w-4"
/>
<Label htmlFor="hamali">Hamali (₹6/bag)</Label>
</div>
<span className="text-sm text-muted-foreground">₹{breakdown.hamali.toFixed(2)}</span>
</div>
<div className="flex items-center justify-between gap-4">
<Label htmlFor="adhath">Adhath (%)</Label>
<div className="flex items-center gap-2">
<Input
id="adhath"
type="number"
value={charges.adhath}
onChange={(e) => setCharges({ ...charges, adhath: parseFloat(e.target.value) || 0 })}
className="w-20"
min="0"
max="6"
/>
<span className="text-sm text-muted-foreground">₹{breakdown.adhath.toFixed(2)}</span>
</div>
</div>
<div className="flex items-center justify-between gap-4">
<Label htmlFor="cess">Cess (%)</Label>
<div className="flex items-center gap-2">
<Input
id="cess"
type="number"
value={charges.cess}
onChange={(e) => setCharges({ ...charges, cess: parseFloat(e.target.value) || 0 })}
className="w-20"
min="0"
max="6"
/>
<span className="text-sm text-muted-foreground">₹{breakdown.cess.toFixed(2)}</span>
</div>
</div>
<div className="flex items-center justify-between gap-4">
<Label htmlFor="gaadiBharni">Gaadi Bharni</Label>
<div className="flex items-center gap-2">
<Input
id="gaadiBharni"
type="number"
value={charges.gaadiBharni}
onChange={(e) => setCharges({ ...charges, gaadiBharni: e.target.value })}
className="w-20"
placeholder="0"
/>
<span className="text-sm text-muted-foreground">₹{breakdown.gaadiBharni.toFixed(2)}</span>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
{/* Invoice Summary */}
<div className="lg:col-span-1">
<Card className="sticky top-4">
<CardHeader>
<CardTitle>Summary</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-muted-foreground">Bags:</span>
<span className="font-medium">{formData.bags || 0}</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Gross Weight:</span>
<span className="font-medium">
{(parseFloat(formData.bags) || 0) * (parseFloat(formData.grossWeight) || 40)} kg
</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Net Weight:</span>
<span className="font-medium">{calculateNetWeight()} kg</span>
</div>
<Separator />
<div className="flex justify-between text-base">
<span className="font-medium">Basic Amount:</span>
<span className="font-bold">₹{calculateBasicAmount().toFixed(2)}</span>
</div>
<Separator />
<div className="flex justify-between text-lg font-bold text-primary">
<span>Total Amount:</span>
<span>₹{total.toFixed(2)}</span>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
</main>
</div>
);
};
export default Invoice;