Ignore:
Timestamp:
02/26/25 10:05:32 (5 weeks ago)
Author:
Naum Shapkarovski <naumshapkarovski@…>
Branches:
main
Children:
299af01
Parents:
5d6f37a
Message:

feat: implement employees

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sections/invoice/invoice-new-edit-form.tsx

    r5d6f37a r057453c  
    1111import { useRouter } from 'src/routes/hooks';
    1212// types
    13 import { Invoice } from 'mvpmasters-shared';
     13import { CreateInvoice, Invoice } from 'src/schemas';
    1414// hooks
    1515import { useBoolean } from 'src/hooks/use-boolean';
     
    2020import uploadToFirebaseStorage from 'src/utils/upload-to-firebase-storage';
    2121import { 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';
     22import { useGetTenant } from 'src/api/tenant';
     23import { collections, generateId, updateDocument } from 'src/lib/firestore';
    3024import { useGetServices } from 'src/api/service';
    3125import { mutate } from 'swr';
    32 import { Timestamp } from 'firebase/firestore';
    3326import InvoiceNewEditStatusDate from './invoice-new-edit-status-date';
    3427import InvoiceNewEditAddress from './invoice-new-edit-address';
    3528import InvoiceNewEditDetails from './invoice-new-edit-details';
    3629import InvoicePDF from './invoice-pdf';
     30import { createInvoice, updateInvoice } from 'src/api/invoice';
    3731
    3832// ----------------------------------------------------------------------
     
    5852];
    5953
     54interface InvoiceItem {
     55  service: string | null;
     56  title: string;
     57  price: number;
     58  total: number;
     59  quantity: number;
     60  description: string;
     61}
     62
    6063export default function InvoiceNewEditForm({ isCopy, currentInvoice }: Props) {
    6164  const router = useRouter();
     
    6972    description: Yup.string().required('Description is required'),
    7073    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'),
    7277    price: Yup.number().required('Price is required').min(0, 'Price must be at least 0'),
    7378    total: Yup.number().required('Total is required').min(0, 'Total must be at least 0'),
     
    9196      .required('Quantity type is required'),
    9297    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(),
    9499    totalAmount: Yup.number().required(),
    95100    // not required
     
    103108
    104109  const { services: invoiceServices } = useGetServices();
    105   const { settings, settingsEmpty, settingsLoading } = useGetSettings();
     110  console.log('invoiceServices', invoiceServices);
     111  const { settings: tenant, settingsEmpty, settingsLoading } = useGetTenant();
    106112
    107113  const defaultValues = useMemo(
     
    110116        !isCopy && currentInvoice?.invoiceNumber
    111117          ? 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),
    115123      invoiceFrom: currentInvoice?.invoiceFrom || null,
    116124      invoiceTo: currentInvoice?.invoiceTo || null,
     
    138146      totalAmount: currentInvoice?.totalAmount || 0,
    139147    }),
    140     [currentInvoice, isCopy, settings]
     148    [currentInvoice, isCopy, tenant]
    141149  );
    142150
     
    164172
    165173    try {
    166       // generate collection id
    167174      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      );
    168187
    169188      // attach serivce details
     
    173192      }));
    174193
    175       const currentTime = new Date();
    176       const createDateWithCurrentTime = new Date(data.createDate); // This creates a date object using the date from data.createDate
    177       // Set the time of createDateWithCurrentTime to the current hour, minutes, and seconds
    178       createDateWithCurrentTime.setHours(
    179         currentTime.getHours(),
    180         currentTime.getMinutes(),
    181         currentTime.getSeconds()
    182       );
    183 
    184194      // transform data
    185       const writeData = {
     195      const writeData: CreateInvoice = {
    186196        ...data,
    187         invoiceNumber: incrementInvoiceNumber(settings?.invoice.lastInvoiceNumber),
     197        invoiceNumber: incrementInvoiceNumber(tenant?.lastInvoiceNumber),
    188198        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!,
    192206      };
    193207
     
    199213
    200214      // 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 });
    216232
    217233      loadingSave.onFalse();
     
    229245    try {
    230246      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
    231252        // attach serivce details
    232253        const items = data.items.map((item) => ({
     
    238259        const writeData = {
    239260          ...data,
    240           createDate: Timestamp.fromDate(new Date(data.createDate)),
    241           dueDate: Timestamp.fromDate(new Date(data.dueDate)),
     261          createDate,
     262          dueDate,
    242263          items,
     264          invoiceFrom: data.invoiceFrom!,
     265          invoiceTo: data.invoiceTo!,
    243266        };
    244267
     
    250273
    251274        // 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, {
    253281          ...writeData,
    254282          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          }[],
    255305        });
    256306
    257307        // mutate current data
    258         mutate([collections.invoice, currentInvoice.id]);
     308        // mutate([collections.invoice, currentInvoice.id]);
    259309      } else {
    260310        // generate collection id
    261311        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);
    262317
    263318        // attach serivce details
     
    270325        const writeData = {
    271326          ...data,
    272           createDate: Timestamp.fromDate(new Date(data.createDate)),
    273           dueDate: Timestamp.fromDate(new Date(data.dueDate)),
     327          createDate,
     328          dueDate,
    274329          items,
     330          invoiceFrom: data.invoiceFrom!,
     331          invoiceTo: data.invoiceTo!,
    275332        };
    276333
     
    282339
    283340        // 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 });
    299357
    300358        reset();
     
    314372    <FormProvider methods={methods}>
    315373      <Card>
    316         {settings?.company && <InvoiceNewEditAddress />}
     374        {!!tenant && <InvoiceNewEditAddress />}
    317375
    318376        <InvoiceNewEditStatusDate isCopy={isCopy} />
Note: See TracChangeset for help on using the changeset viewer.