Changeset 057453c for src/sections/invoice/invoice-new-edit-form.tsx
- Timestamp:
- 02/26/25 10:05:32 (5 weeks ago)
- Branches:
- main
- Children:
- 299af01
- Parents:
- 5d6f37a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sections/invoice/invoice-new-edit-form.tsx
r5d6f37a r057453c 11 11 import { useRouter } from 'src/routes/hooks'; 12 12 // types 13 import { Invoice } from 'mvpmasters-shared';13 import { CreateInvoice, Invoice } from 'src/schemas'; 14 14 // hooks 15 15 import { useBoolean } from 'src/hooks/use-boolean'; … … 20 20 import uploadToFirebaseStorage from 'src/utils/upload-to-firebase-storage'; 21 21 import { pdf } from '@react-pdf/renderer'; 22 import { useGetSettings } from 'src/api/settings'; 23 import { 24 collections, 25 documents, 26 firestoreBatch, 27 generateId, 28 updateDocument, 29 } from 'src/lib/firestore'; 22 import { useGetTenant } from 'src/api/tenant'; 23 import { collections, generateId, updateDocument } from 'src/lib/firestore'; 30 24 import { useGetServices } from 'src/api/service'; 31 25 import { mutate } from 'swr'; 32 import { Timestamp } from 'firebase/firestore';33 26 import InvoiceNewEditStatusDate from './invoice-new-edit-status-date'; 34 27 import InvoiceNewEditAddress from './invoice-new-edit-address'; 35 28 import InvoiceNewEditDetails from './invoice-new-edit-details'; 36 29 import InvoicePDF from './invoice-pdf'; 30 import { createInvoice, updateInvoice } from 'src/api/invoice'; 37 31 38 32 // ---------------------------------------------------------------------- … … 58 52 ]; 59 53 54 interface InvoiceItem { 55 service: string | null; 56 title: string; 57 price: number; 58 total: number; 59 quantity: number; 60 description: string; 61 } 62 60 63 export default function InvoiceNewEditForm({ isCopy, currentInvoice }: Props) { 61 64 const router = useRouter(); … … 69 72 description: Yup.string().required('Description is required'), 70 73 service: Yup.string().nullable(), 71 quantity: Yup.number().required('Quantity is required').min(0.5, 'Quantity must be at least 1'), 74 quantity: Yup.number() 75 .required('Quantity is required') 76 .min(0.5, 'Quantity must be at least 0.5'), 72 77 price: Yup.number().required('Price is required').min(0, 'Price must be at least 0'), 73 78 total: Yup.number().required('Total is required').min(0, 'Total must be at least 0'), … … 91 96 .required('Quantity type is required'), 92 97 month: Yup.string().oneOf(monthNames).required('Month is required'), 93 status: Yup.string(). required(),98 status: Yup.string().oneOf(['draft', 'processing', 'pending', 'overdue', 'paid']).required(), 94 99 totalAmount: Yup.number().required(), 95 100 // not required … … 103 108 104 109 const { services: invoiceServices } = useGetServices(); 105 const { settings, settingsEmpty, settingsLoading } = useGetSettings(); 110 console.log('invoiceServices', invoiceServices); 111 const { settings: tenant, settingsEmpty, settingsLoading } = useGetTenant(); 106 112 107 113 const defaultValues = useMemo( … … 110 116 !isCopy && currentInvoice?.invoiceNumber 111 117 ? currentInvoice?.invoiceNumber 112 : incrementInvoiceNumber(settings?.invoice?.lastInvoiceNumber), 113 createDate: currentInvoice?.createDate?.toDate() || new Date(), 114 dueDate: currentInvoice?.dueDate?.toDate() || null, 118 : incrementInvoiceNumber(tenant?.lastInvoiceNumber), 119 createDate: currentInvoice?.createDate ? new Date(currentInvoice.createDate) : new Date(), 120 dueDate: currentInvoice?.dueDate 121 ? new Date(currentInvoice.dueDate) 122 : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), 115 123 invoiceFrom: currentInvoice?.invoiceFrom || null, 116 124 invoiceTo: currentInvoice?.invoiceTo || null, … … 138 146 totalAmount: currentInvoice?.totalAmount || 0, 139 147 }), 140 [currentInvoice, isCopy, settings]148 [currentInvoice, isCopy, tenant] 141 149 ); 142 150 … … 164 172 165 173 try { 166 // generate collection id167 174 const id = generateId(collections.invoice); 175 176 // Ensure dates are valid Date objects 177 const createDate = 178 data.createDate instanceof Date ? data.createDate : new Date(data.createDate); 179 const dueDate = data.dueDate instanceof Date ? data.dueDate : new Date(data.dueDate); 180 181 const currentTime = new Date(); 182 createDate.setHours( 183 currentTime.getHours(), 184 currentTime.getMinutes(), 185 currentTime.getSeconds() 186 ); 168 187 169 188 // attach serivce details … … 173 192 })); 174 193 175 const currentTime = new Date();176 const createDateWithCurrentTime = new Date(data.createDate); // This creates a date object using the date from data.createDate177 // Set the time of createDateWithCurrentTime to the current hour, minutes, and seconds178 createDateWithCurrentTime.setHours(179 currentTime.getHours(),180 currentTime.getMinutes(),181 currentTime.getSeconds()182 );183 184 194 // transform data 185 const writeData = {195 const writeData: CreateInvoice = { 186 196 ...data, 187 invoiceNumber: incrementInvoiceNumber( settings?.invoice.lastInvoiceNumber),197 invoiceNumber: incrementInvoiceNumber(tenant?.lastInvoiceNumber), 188 198 status: 'draft', 189 createDate: Timestamp.fromDate(createDateWithCurrentTime), 190 dueDate: Timestamp.fromDate(new Date(data.dueDate)), 191 items, 199 createDate, 200 dueDate, 201 items: items.filter((item) => item.service !== null) as CreateInvoice['items'], 202 subTotal: data.totalAmount - (data.taxes || 0) - (data.discount || 0), 203 month: data.month as Invoice['month'], 204 invoiceFrom: data.invoiceFrom!, 205 invoiceTo: data.invoiceTo!, 192 206 }; 193 207 … … 199 213 200 214 // write to DB 201 await firestoreBatch([ 202 { 203 docPath: `${collections.invoice}/${id}`, 204 type: 'set', 205 data: { 206 ...writeData, 207 pdfRef: storagePath, 208 }, 209 }, 210 { 211 docPath: `${collections.settings}/${documents.settingsInvoice}`, 212 type: 'set', 213 data: { lastInvoiceNumber: writeData.invoiceNumber }, 214 }, 215 ]); 215 // await firestoreBatch([ 216 // { 217 // docPath: `${collections.invoice}/${id}`, 218 // type: 'set', 219 // data: { 220 // ...writeData, 221 // pdfRef: storagePath, 222 // }, 223 // }, 224 // { 225 // docPath: `${collections.settings}/${documents.settingsInvoice}`, 226 // type: 'set', 227 // data: { lastInvoiceNumber: writeData.invoiceNumber }, 228 // }, 229 // ]); 230 231 await createInvoice({ ...writeData, pdfRef: storagePath }); 216 232 217 233 loadingSave.onFalse(); … … 229 245 try { 230 246 if (currentInvoice) { 247 // Ensure dates are valid Date objects 248 const createDate = 249 data.createDate instanceof Date ? data.createDate : new Date(data.createDate); 250 const dueDate = data.dueDate instanceof Date ? data.dueDate : new Date(data.dueDate); 251 231 252 // attach serivce details 232 253 const items = data.items.map((item) => ({ … … 238 259 const writeData = { 239 260 ...data, 240 createDate : Timestamp.fromDate(new Date(data.createDate)),241 dueDate : Timestamp.fromDate(new Date(data.dueDate)),261 createDate, 262 dueDate, 242 263 items, 264 invoiceFrom: data.invoiceFrom!, 265 invoiceTo: data.invoiceTo!, 243 266 }; 244 267 … … 250 273 251 274 // update DB 252 await updateDocument(collections.invoice, currentInvoice.id, { 275 // await updateDocument(collections.invoice, currentInvoice.id, { 276 // ...writeData, 277 // pdfRef: storagePath, 278 // }); 279 280 await updateInvoice(currentInvoice.id, { 253 281 ...writeData, 254 282 pdfRef: storagePath, 283 status: data.status as 'draft' | 'processing' | 'pending' | 'overdue' | 'paid', 284 month: data.month as 285 | 'January' 286 | 'February' 287 | 'March' 288 | 'April' 289 | 'May' 290 | 'June' 291 | 'July' 292 | 'August' 293 | 'September' 294 | 'October' 295 | 'November' 296 | 'December', 297 items: items.filter((item) => item.service !== null) as { 298 service: { id: string; month: number; name: string; sprint: number; hour: number }; 299 title: string; 300 price: number; 301 total: number; 302 quantity: number; 303 description: string; 304 }[], 255 305 }); 256 306 257 307 // mutate current data 258 mutate([collections.invoice, currentInvoice.id]);308 // mutate([collections.invoice, currentInvoice.id]); 259 309 } else { 260 310 // generate collection id 261 311 const id = generateId(collections.invoice); 312 313 // Ensure dates are valid Date objects 314 const createDate = 315 data.createDate instanceof Date ? data.createDate : new Date(data.createDate); 316 const dueDate = data.dueDate instanceof Date ? data.dueDate : new Date(data.dueDate); 262 317 263 318 // attach serivce details … … 270 325 const writeData = { 271 326 ...data, 272 createDate : Timestamp.fromDate(new Date(data.createDate)),273 dueDate : Timestamp.fromDate(new Date(data.dueDate)),327 createDate, 328 dueDate, 274 329 items, 330 invoiceFrom: data.invoiceFrom!, 331 invoiceTo: data.invoiceTo!, 275 332 }; 276 333 … … 282 339 283 340 // write to DB 284 await firestoreBatch([ 285 { 286 docPath: `${collections.invoice}/${id}`, 287 type: 'set', 288 data: { 289 ...writeData, 290 pdfRef: storagePath, 291 }, 292 }, 293 { 294 docPath: `${collections.settings}/${documents.settingsInvoice}`, 295 type: 'set', 296 data: { lastInvoiceNumber: writeData.invoiceNumber }, 297 }, 298 ]); 341 // await firestoreBatch([ 342 // { 343 // docPath: `${collections.invoice}/${id}`, 344 // type: 'set', 345 // data: { 346 // ...writeData, 347 // pdfRef: storagePath, 348 // }, 349 // }, 350 // { 351 // docPath: `${collections.settings}/${documents.settingsInvoice}`, 352 // type: 'set', 353 // data: { lastInvoiceNumber: writeData.invoiceNumber }, 354 // }, 355 // ]); 356 await createInvoice({ ...writeData, pdfRef: storagePath }); 299 357 300 358 reset(); … … 314 372 <FormProvider methods={methods}> 315 373 <Card> 316 { settings?.company&& <InvoiceNewEditAddress />}374 {!!tenant && <InvoiceNewEditAddress />} 317 375 318 376 <InvoiceNewEditStatusDate isCopy={isCopy} />
Note:
See TracChangeset
for help on using the changeset viewer.