feat: add vendor optional fields and configuration hooks
- Implemented VendorOptionalFields component to handle optional vendor details (mobile, email, address) with validation. - Created useCustomerConfig hook to load optional customer field settings from Sales configuration. - Developed useProcurementConfig hook to manage Procurement configuration flags. - Introduced accessConfigApi for managing access configuration settings. - Added openingBalancesApi for handling opening balances operations. - Created procurementConfigApi for managing procurement configuration settings. - Implemented nav-routes for permission-based routing. - Developed PDF generation for purchase orders with dynamic vendor and item details. - Added purchase-order tax helpers for tax calculations and formatting. - Defined types for opening balances and related operations.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { useCustomerConfig } from "@/hooks/use-customer-config"
|
||||
import { customersApi } from "@/lib/api/customers"
|
||||
import { errorMessage, fieldErrors } from "@/lib/error-map"
|
||||
import { Customer, CustomerType } from "@/types/customers"
|
||||
@@ -28,6 +29,8 @@ export function EditCustomerDialog({
|
||||
onClose: () => void
|
||||
onSaved: (customer: Customer) => void
|
||||
}) {
|
||||
// A field switched off in Sales Configuration is hidden; its stored value is sent back unchanged.
|
||||
const { fields } = useCustomerConfig()
|
||||
const [customer, setCustomer] = useState<Customer | null>(null)
|
||||
const [etag, setEtag] = useState<string | null>(null)
|
||||
const [loadError, setLoadError] = useState<string | null>(null)
|
||||
@@ -194,48 +197,70 @@ export function EditCustomerDialog({
|
||||
</Select>
|
||||
</Field>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-phone">Phone (optional)</FieldLabel>
|
||||
<Input id="ec-phone" value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="0771234567" />
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-email">Email (optional)</FieldLabel>
|
||||
<Input id="ec-email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="customer@example.com" />
|
||||
</Field>
|
||||
</div>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-addr1">Address line 1 (optional)</FieldLabel>
|
||||
<Input id="ec-addr1" value={addressLine1} onChange={(e) => setAddressLine1(e.target.value)} />
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-addr2">Address line 2 (optional)</FieldLabel>
|
||||
<Input id="ec-addr2" value={addressLine2} onChange={(e) => setAddressLine2(e.target.value)} />
|
||||
</Field>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-city">City (optional)</FieldLabel>
|
||||
<Input id="ec-city" value={city} onChange={(e) => setCity(e.target.value)} />
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-country">Country (optional)</FieldLabel>
|
||||
<Input id="ec-country" value={country} onChange={(e) => setCountry(e.target.value)} />
|
||||
</Field>
|
||||
</div>
|
||||
{(fields.phone || fields.email) && (
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{fields.phone && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-phone">Phone (optional)</FieldLabel>
|
||||
<Input id="ec-phone" value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="0771234567" />
|
||||
</Field>
|
||||
)}
|
||||
{fields.email && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-email">Email (optional)</FieldLabel>
|
||||
<Input id="ec-email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="customer@example.com" />
|
||||
</Field>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{fields.address && (
|
||||
<>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-addr1">Address line 1 (optional)</FieldLabel>
|
||||
<Input id="ec-addr1" value={addressLine1} onChange={(e) => setAddressLine1(e.target.value)} />
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-addr2">Address line 2 (optional)</FieldLabel>
|
||||
<Input id="ec-addr2" value={addressLine2} onChange={(e) => setAddressLine2(e.target.value)} />
|
||||
</Field>
|
||||
</>
|
||||
)}
|
||||
{(fields.city || fields.country) && (
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{fields.city && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-city">City (optional)</FieldLabel>
|
||||
<Input id="ec-city" value={city} onChange={(e) => setCity(e.target.value)} />
|
||||
</Field>
|
||||
)}
|
||||
{fields.country && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-country">Country (optional)</FieldLabel>
|
||||
<Input id="ec-country" value={country} onChange={(e) => setCountry(e.target.value)} />
|
||||
</Field>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-tax">Tax registration (optional)</FieldLabel>
|
||||
<Input id="ec-tax" value={taxRegistrationNo} onChange={(e) => setTaxRegistrationNo(e.target.value)} />
|
||||
</Field>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-credit-limit">Credit limit (LKR)</FieldLabel>
|
||||
<Input id="ec-credit-limit" type="number" min="0" step="0.01" placeholder="0" value={creditLimit} onChange={(e) => setCreditLimit(e.target.value)} />
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-credit-days">Credit days</FieldLabel>
|
||||
<Input id="ec-credit-days" type="number" min="0" step="1" placeholder="0" value={creditDays} onChange={(e) => setCreditDays(e.target.value)} />
|
||||
</Field>
|
||||
</div>
|
||||
{(fields.creditLimit || fields.creditDays) && (
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{fields.creditLimit && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-credit-limit">Credit limit (LKR)</FieldLabel>
|
||||
<Input id="ec-credit-limit" type="number" min="0" step="0.01" placeholder="0" value={creditLimit} onChange={(e) => setCreditLimit(e.target.value)} />
|
||||
</Field>
|
||||
)}
|
||||
{fields.creditDays && (
|
||||
<Field>
|
||||
<FieldLabel htmlFor="ec-credit-days">Credit days</FieldLabel>
|
||||
<Input id="ec-credit-days" type="number" min="0" step="1" placeholder="0" value={creditDays} onChange={(e) => setCreditDays(e.target.value)} />
|
||||
</Field>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</FieldGroup>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user