Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date Time Issue In Batch Request #5100

Open
rpathak-max opened this issue Oct 18, 2024 · 9 comments
Open

Date Time Issue In Batch Request #5100

rpathak-max opened this issue Oct 18, 2024 · 9 comments
Labels
question Further information is requested

Comments

@rpathak-max
Copy link

rpathak-max commented Oct 18, 2024

Describe the bug I'm encountering an issue with the SAP Cloud SDK when generating a batch request in Node.js. The error occurs specifically when trying to handle a Date field (orderDate) during batch processing. The error message is:

Error during batch request: TypeError: momentInstance.unix is not a function
The issue seems to arise from the use of date handling and serialization, as shown in the error trace:

serializeFromMoment (/home/vcap/app/node_modules/@sap-cloud-sdk/odata-v2/dist/de-serializers/converters.js:62:38)
To Reproduce Steps to reproduce the behavior:

Set up a Node.js project using the SAP Cloud SDK for OData V2.
Create a batch request with a Date field formatted using a custom function like formatToTimestampDate.
Send the request to an OData service using the SAP Cloud SDK.
Observe the error when processing the orderDate field.
Expected behavior The orderDate should be correctly serialized and processed without throwing the momentInstance.unix error, and the batch request should execute successfully.

Screenshots N/A

Used Versions:

Node.js version: v16.13.0
npm version: 8.1.0
SAP Cloud SDK version: 1.59.0
Code Examples The code snippet below is where the error is triggered. The error occurs when setting the orderDate field in the batch request.

const formatToTimestampDate = (date) => {
    const dateObj = new Date(date);
    const timestamp = dateObj.getTime();
    return `\/Date(${timestamp})\/`;
};

const createOrderRequestBuilder = zcssc_C_Order_HeaderApi.requestBuilder().create(
    zcssc_C_Order_HeaderApi.entityBuilder().fromJson({
        orderDate: formatToTimestampDate(req.data.createdAt),
        currency: req.data.currency,
        customerName: req.data.customerName,
        grossValue: req.data.grossValue.toString(),
        guid: req.data.guid,
        itemsAddedOnline: req.data.itemsAddedOnline,
        orderType: req.data.orderType,
        orderTypeDescr: req.data.orderTypeDescription,
        salesOrg: req.data.salesOrg,
        plant: req.data.storeId
    })
);

Log file Here’s the relevant part of the error stack trace:

Error during batch request: TypeError: momentInstance.unix is not a function
    at serializeFromMoment (/home/vcap/app/node_modules/@sap-cloud-sdk/odata-v2/dist/de-serializers/converters.js:62:38)
    at /home/vcap/app/node_modules/@sap-cloud-sdk/odata-common/dist/de-serializers/default-de-serializers.js:103:20
    at /home/vcap/app/node_modules/@sap-cloud-sdk/odata-common/dist/de-serializers/de-serializers.js:28:28

Impact / Priority

Affected development phase: Development
Impact: Blocked
Timeline: Go-Live is in 1 weeks.

Additional context The issue appears to stem from how the SDK handles the Date field (orderDate). I’ve attempted various methods to format the date, including using the /Date()/ format as shown in the code, but it consistently leads to this issue.

@rpathak-max rpathak-max added the bug Something isn't working label Oct 18, 2024
@rpathak-max
Copy link
Author

this is complete code

const { zgwCsscSrv } = require('../services/ZGW_CSSC_SRV');
const { changeset, batch } = require('../services/ZGW_CSSC_SRV/BatchRequest');

const formatToTimestampDate = (date) => {
const dateObj = new Date(date);
const timestamp = dateObj.getTime();
return \/Date(${timestamp})\/;
};

module.exports = async (req) => {
try {
console.log("Starting batch request process...");

   // const service = await cds.connect.to('ZGW_CSSC_SRV');
    const { zcssc_C_Order_HeaderApi, zcssc_I_Order_ItemApi, zcssc_I_Pay_SplitApi } = zgwCsscSrv();

    // Create the header request
    const createOrderRequestBuilder = zcssc_C_Order_HeaderApi.requestBuilder().create(
        zcssc_C_Order_HeaderApi.entityBuilder().fromJson({
            orderDate: formatToTimestampDate(req.data.createdAt),
            currency: req.data.currency,
            customerName: req.data.customerName,
            grossValue: req.data.grossValue.toString(),
            guid: req.data.guid,
            itemsAddedOnline: req.data.itemsAddedOnline,
            orderType: req.data.orderType,
            orderTypeDescr: req.data.orderTypeDescription,
            salesOrg: req.data.salesOrg,
            plant: req.data.storeId
        })
    );

    // Create the order item requests dynamically
    const createOrderItemRequests = req.data.orderItems.map((item, i) => 
        zcssc_I_Order_ItemApi.requestBuilder().create(
            zcssc_I_Order_ItemApi.entityBuilder().fromJson({
                material: item.articleNumber,
                discountValue: item.discountValue,
                forced: item.forced,
                giftIndicator: item.isGift,
                itemId: (i + 1).toString(),
                netValue: item.netValue,
                saId: item.salesAssociateId,
                saName: item.salesAssociateName,
                saNumber: item.salesAssociateNumber
            })
        )
    );

    // Create the payment split requests dynamically
    const createPaymentSplitRequests = (req.data.paymentSplits || []).map(payment => 
        zcssc_I_Pay_SplitApi.requestBuilder().create(
            zcssc_I_Pay_SplitApi.entityBuilder().fromJson({
                amount: payment.amount,
                paymentCode: payment.paymentCode,
                paymentDesc: payment.paymentDescription,
                saleType: payment.saleType
            })
        )
    );

    // Combine the header, order items, and payment splits into a changeset
    const batchRequest = batch(
        changeset(createOrderRequestBuilder, ...createOrderItemRequests, ...createPaymentSplitRequests)
    );

    const token = req.headers.authorization?.split(' ')[1];
    const batchResponse = await batchRequest.execute({ destinationName: 'DRGUP_2', jwt: token });

    console.log("Batch request executed successfully:", batchResponse);
    return batchResponse;

} catch (error) {
    console.error("Error during batch request:", error);
    return req.error({
        code: 'BATCH_EXCEPTION',
        message: error.message || 'An error occurred while processing the batch request.',
        status: 400
    });
}

};

@marikaner
Copy link
Contributor

Hey @rpathak-max, I think you are using the wrong assumptions on how fromJson works. The docs are not very exact on that, but I think what you want is rather deserialization. Otherwise you would have to pass an instance of moment instead.

Let me know if that helps.

@rpathak-max
Copy link
Author

rpathak-max commented Oct 18, 2024

Hi @marikaner, thank you for your reply. can you please guide me with any docs and any sample how can i pass instance of moment because i have tried with moment library but still facing that error. may be you can share some example of it if its possible.

@marikaner
Copy link
Contributor

Sure:

const moment = require('moment');

const createOrderRequestBuilder = zcssc_C_Order_HeaderApi.requestBuilder().create(
    zcssc_C_Order_HeaderApi.entityBuilder().fromJson({
        orderDate: moment(),
        // ...
    })
);

Is this what you tried?

@rpathak-max
Copy link
Author

No i have to pass the order date which i mentioned as request payload so first i passed that date to the moment and then assigned it i a variable then passed it to the orderDate can you please share the example of that like passing the parameter from postman and convert it into the instance. this is the format i am passing from postman "/Date(1603843200000)/"

@marikaner
Copy link
Contributor

As I pointed out before, you have two options:

  1. Use our deserializer for this. I think this is the preferred option in your case.
  2. Parse the date according to your needs: https://momentjs.com/docs/#/parsing/string-format/ and https://momentjs.com/docs/#/parsing/date/ might be helpful. Please note that the native JS Date object does not have timezone information so it can get lost.

@rpathak-max
Copy link
Author

Ok let me try this solution then i will let you know thank you for your support

@marikaner marikaner added question Further information is requested and removed bug Something isn't working labels Oct 21, 2024
@deekshas8
Copy link
Contributor

Hi @rpathak-max , were you able to resolve your issue using @marikaner 's suggestion?

@rpathak-max
Copy link
Author

Hello @deekshas8,

I apologize for the delayed response, and I wanted to express my sincere gratitude for your support. I’m pleased to inform you that the issue has been resolved, thanks to your invaluable assistance. I greatly appreciate your patience and guidance throughout this process.

Thank you once again for your support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants