Send a new invoice data from Books to local certified solution via API json due local compliance

Send a new invoice data from Books to local certified solution via API json due local compliance

Greetings,  
I hope you are doing well and staying safe.  

Due to local compliance regulations, I am required to issue invoices exclusively using locally certified software, which Zoho Books is not. However, we would like to continue using Zoho Books, so we need to send invoice data to an external certified solution each time a new invoice is issued. This external system should automatically generate a corresponding invoice, essentially mirroring the one created in Zoho Books.  

I have access to the API documentation for the external certified solution and have attempted to create a custom function to extract invoice data, format it in JSON, and send it to the external system. However, due to my limited knowledge, I have been unable to save the custom function successfully, as the Deluge editor consistently flags syntax errors.  

The API documentation for the external solution can be found here: https://api.factplus.co.ao/documentation/  

Below are some of the approaches I have attempted:  

===
void EnviarFctraParaFctpls( Map invoice, Map organization, Map user )
{
    // A função já recebe os detalhes da fatura e organização como 'invoice' e 'organization'
    // Não precisamos usar zoho.books.getRecordsByID para os dados básicos da fatura.
    // Usaremos 'invoice' diretamente.

    // 1. Extrair Detalhes da Fatura (diretamente do 'invoice' Map)
    invoiceData = invoice; // 'invoice' já é o mapa com os dados da fatura
    organizationId = organization.get("organization_id"); // ID da sua organização no Zoho Books

    invoiceNumber = invoiceData.get("invoice_number");
    invoiceDate = invoiceData.get("date"); // Formato 'YYYY-MM-DD'
    dueDate = invoiceData.get("due_date"); // Formato 'YYYY-MM-DD'
    reference = invoiceData.get("reference_number"); // Pode usar o número de referência do Zoho Books
    currency = invoiceData.get("currency_code");
    // observation = invoiceData.get("notes"); // Supondo que 'notes' seja para observações
    
    // ATENÇÃO: Verifique na documentação do Factplus como lidar com 'retention'.
    // Se o Zoho Books não tiver um campo direto para 'retention', você pode precisar de lógica extra
    // ou definir como "0" se não for aplicável no seu caso.
    retention_value = "0"; 
    
    // Dados do Cliente
    customerData = invoiceData.get("customer_details");
    clientName = customerData.get("customer_name");
    clientNIF = customerData.get("vat_reg_no"); // Assumindo que NIF seja o VAT Registration Number
    clientEmail = customerData.get("email");
    clientCity = customerData.get("city");
    clientAddress = customerData.get("billing_address").get("address"); // Endereço de fatura
    clientPostalCode = customerData.get("billing_address").get("zip"); // CEP de fatura
    clientCountry = customerData.get("billing_address").get("country"); // País de fatura

    // Itens da Fatura
    lineItems = invoiceData.get("line_items");
    factplusItems = collection(); // Coleção para armazenar os itens formatados para o Factplus

    for each item in lineItems
    {
        // Para itemcode, é ideal usar um ID que seja único e identificável no Factplus.
        // item.get("item_id") é o ID interno do Zoho Books, o que pode não ser ideal se o Factplus
        // espera um código de item de produto/serviço. Considere usar item.get("name") ou um campo personalizado.
        itemCode = item.get("item_id"); 
        description = item.get("description");
        price = item.get("rate");
        quantity = item.get("quantity");
        taxRate = item.get("tax_percentage"); // Taxa de imposto
        discount = item.get("discount"); // Desconto por linha de item
        
        // ATENÇÃO: exemption_code e retention por item precisam ser verificados na API do Factplus.
        exemptionCode = ""; // Valor padrão, ajuste se tiver campo correspondente
        itemRetention = "0"; // Valor padrão, ajuste se tiver campo correspondente

        factplusItem = Map();
        factplusItem.put("itemcode", itemCode);
        factplusItem.put("description", description);
        factplusItem.put("price", price);
        factplusItem.put("quantity", quantity);
        factplusItem.put("tax", taxRate);
        factplusItem.put("discount", discount);
        factplusItem.put("exemption_code", exemptionCode);
        factplusItem.put("retention", itemRetention);
        
        factplusItems.add(factplusItem);
    }
    
    // 2. Construir o Objeto JSON para a API do Factplus
    // ATENÇÃO: SUBSTITUA 'SUA_CHAVE_API_AQUI' PELA SUA CHAVE DE 32 DÍGITOS DO FACTPLUS
    factplusPayload = Map();
    factplusPayload.put("apicall", "CREATE");
    factplusPayload.put("apikey", "SUA_CHAVE_API_AQUI"); // <-- SUA CHAVE API DO FACTPLUS AQUI!

    documentMap = Map();
    documentMap.put("type", "factura"); // Tipo de documento, confirme se "factura" é o correto
    documentMap.put("date", invoiceDate);
    documentMap.put("duedate", dueDate);
    documentMap.put("vref", invoiceNumber); // Usando o número da fatura como referência. Verifique se o Factplus aceita este formato.
    // A "serie" é crucial. O exemplo do Factplus mostra "2020". Você precisa definir uma série apropriada.
    // Se o Zoho Books não tiver um campo para série, pode ser um valor fixo ou derivado.
    documentMap.put("serie", "2024"); // <-- ATENÇÃO: Defina a série correta para o Factplus (ex: "2024", "FS_A")
    documentMap.put("currency", currency);
    documentMap.put("exchange_rate", "0"); // Ajuste se houver taxa de câmbio
    // documentMap.put("observation", invoiceData.get("notes")); // Se usar campo de notas
    documentMap.put("retention", retention_value);

    clientMap = Map();
    clientMap.put("name", clientName);
    clientMap.put("nif", clientNIF);
    clientMap.put("email", clientEmail);
    clientMap.put("city", clientCity);
    clientMap.put("address", clientAddress);
    clientMap.put("postalcode", clientPostalCode);
    clientMap.put("country", clientCountry);
    
    factplusPayload.put("document", documentMap);
    factplusPayload.put("client", clientMap);
    factplusPayload.put("items", factplusItems);

    // Converter o mapa Deluge para string JSON
    jsonString = factplusPayload.toString();

    // 3. Fazer a Chamada HTTP POST para a API do Factplus
    // ATENÇÃO: Você PRECISA substituir "https://api.factplus.co.ao" pelo ENDPOINT COMPLETO
    // da API do Factplus para a criação de faturas.
    // Ex: "https://api.factplus.co.ao/v1/invoices" ou similar.
    factplusAPI_URL = "https://api.factplus.co.ao"; // <-- SUBSTITUIR PELO ENDPOINT ESPECÍFICO DE CRIAÇÃO DE FATURA

    // Cabeçalhos (Content-Type é essencial para JSON)
    headers = Map();
    headers.put("Content-Type", "application/json");

    // Executar a chamada API
    apiResponse = invokeurl
    [
        url : factplusAPI_URL
        type : POST
        headers: headers
        content : jsonString
    ];

    // 4. Tratar a Resposta da API
    info "Request sent to Factplus: " + jsonString; // Para depuração, mostre o que foi enviado
    info "Factplus API Response: " + apiResponse;

    // Adicione lógica para verificar a resposta aqui.
    // Ex: if (apiResponse.get("status") == "success") { ... }
    // ou if (apiResponse.get("code") == 200) { ... }
    // Logar erros se a resposta indicar falha e talvez enviar um email de alerta.
    if (apiResponse.get("status") == "success") // Supondo que a API retorne um campo 'status'
    {
        info "Fatura enviada com sucesso para o Factplus!";
        // Opcional: Atualizar a fatura no Zoho Books com um campo de status "Enviado para Factplus"
        // Ou armazenar o ID de retorno do Factplus.
    }
    else
    {
        error "Erro ao enviar fatura para o Factplus: " + apiResponse.get("message"); // Supondo campo 'message'
        // Opcional: Enviar email de erro para o cliente ou para o administrador
    }
}
===

And

===
// Função para enviar fatura do Zoho Books para o Factplus
// Parâmetro: invoice_id (ID da fatura criada)
invoice_id = input.invoice_id;

// Obter detalhes da fatura do Zoho Books
invoice = zoho.books.getRecordsByID("Invoices", organization_id, invoice_id);
invoice_data = invoice.get("invoice");

// Mapear dados do cliente
customer_id = invoice_data.get("customer_id");
customer = zoho.books.getRecordsByID("Contacts", organization_id, customer_id);
customer_data = customer.get("contact");
client_map = Map();
client_map.put("name", customer_data.get("contact_name"));
client_map.put("nif", customer_data.get("tax_reg_no", ""));
client_map.put("email", customer_data.get("email", ""));
client_map.put("city", customer_data.get("billing_address").get("city", ""));
client_map.put("address", customer_data.get("billing_address").get("address", ""));
client_map.put("postalcode", customer_data.get("billing_address").get("zip", ""));
client_map.put("country", customer_data.get("billing_address").get("country", "Angola"));

// Mapear itens da fatura
items_list = List();
for each item in invoice_data.get("line_items")
{
    item_map = Map();
    item_map.put("itemcode", item.get("item_id", "ITEM" + item.get("line_item_id")));
    item_map.put("description", item.get("name"));
    item_map.put("price", item.get("rate").toString());
    item_map.put("quantity", item.get("quantity").toString());
    item_map.put("tax", "14"); // Ajuste conforme a tributação aplicável
    item_map.put("discount", item.get("discount", "0").toString());
    item_map.put("exemption_code", "");
    item_map.put("retention", "");
    item_map.put("unit", "Unidade");
    items_list.add(item_map);
}

// Construir o corpo da requisição para o Factplus
payload = Map();
payload.put("apicall", "CREATE");
payload.put("apikey", "SUA_CHAVE_API_FACTPLUS"); // Substitua pela sua chave de API
document_map = Map();
document_map.put("type", "factura");
document_map.put("date", invoice_data.get("date"));
document_map.put("duedate", invoice_data.get("due_date"));
document_map.put("vref", invoice_data.get("invoice_number"));
document_map.put("serie", invoice_data.get("date").left(4)); // Ano da fatura
document_map.put("currency", "AOA");
document_map.put("exchange_rate", "0");
document_map.put("observation", "");
document_map.put("retention", "0");
payload.put("document", document_map);
payload.put("client", client_map);
payload.put("items", items_list);

// Enviar requisição para o Factplus
headers = Map();
headers.put("Content-Type", "application/json");
response = invokeurl
[
    type: POST,
    parameters: payload.toString(),
    headers: headers,
    connection: "FactplusAPI"
];

// Logar a resposta para depuração
info response;
===

Any help?
Thanks in advance.

    Nederlandse Hulpbronnen


      • Recent Topics

      • What happens to my current site SEO if i opt for zoho creator?

        I have an existing website and I need to use Zoho creators for the rapid creation of my webpage creation. Currently, my IT team is creating the web pages, but I am concerned about the SEO of my current website if I shift to zoho will i loose it all?
      • Automatic Portal invite

        We have numerous customers we move through a blueprint in deals, when they get to a certain point we need to give them portal access, how can this be done through deluge or a workflow?
      • Preview Emails with Merge Fields before sending

        Hello, Are there plans to preview an email with merge fields before sending out? Currently, all you see in the preview are the merge field values, but before I send out the email I want to make sure the merge is working. Also, the saved emails only show
      • User Filter not selecting All Items

        We are encountering 2 issues when using the user filter. When users are trying to search using the filter option, the OK button is grayed out. Users have to unselect or make a change before it filters properly. 2. When filtering and the OK button works,
      • Support Nested JavaScript Variables in PageSense Pop-up Targeting

        Hello Zoho PageSense Team, I hope you're doing well. I’d like to request a feature enhancement for the PageSense pop-up targeting functionality. Current Limitation: Currently, PageSense pop-ups can be triggered using simple JavaScript variables. However,
      • Cannot Invert Axis for Rankings

        Hi there I want to be able to create a ranking graph in Analytics/BI, with 1 at the top of the Y axis, but I am unable to invert the axis. Super simple example in Excel below. Higher rankings need to be higher up on the graph to give the correct visual
      • How to copy value from a single line field into a picklist field within a module's subform?

        Hello there, I have a single line field in a module's subform. I would like the value in the field to automatically update a picklist field within the same subform (both have items with the same names). Is this possible via function? Unfortunately, workflows
      • Committed Stock and To Be Received Stock via API?

        Is it possible to retrieve Committed Stock and/or To Be Received Stock for an Item via the API? I want to use this information for calculating the amount of inventory needed to be purchased.
      • Creating Email template that attaches file uploaded in specific field.

        If there's a way to do this using Zoho CRM's built-in features, then this has eluded me! I'm looking to create a workflow that automatically sends an email upon execution, and that email includes an attachment uploaded in a specific field. Email templates
      • Marketer’s Space - Automate a Personalized Holiday Workflow with Zoho Campaigns

        Hello marketers, Welcome back to another post in Marketer’s Space! From Thanksgiving through Christmas, you have a flurry of opportunities to connect with your audience. In this post, we’ll see how you can plan an entire month-long automated workflow
      • Zoho Inventory Custom Field Update

        Hello All, In this post I am describing how can we Update the Custom Field Value in Zoho Inventory. // Get Org ID orgid = organization.get("organization_id"); // Field Value resvp = ifnull(item.get("purchase_rate"),null); // Record ID iid = item.get("item_id");
      • Sorting columns in Zoho Projects

        Hi, In project management best practice, sorting columns (ascending, descending) is an important tool. Sorting dates to see the order of tasks starting, sorting on priority or even on planned hours is a must for an efficient project control. Currently,
      • Zoho CRM - Calendar Cards View - Let Users Decide What Is Displayed On Calendar Entries

        Imagine planning your week of face-to-face meetings across three counties. You’re trying to group appointments by location to make the best use of your time, but Zoho CRM’s calendar doesn’t show where each meeting is happening. You’re left trying to remember
      • Explore the Redesigned Quotes Module in Zoho Billing

        Dear users, We’re excited to introduce a refreshed look for the Quotes details page in Zoho Billing! This update brings you a more efficient user interface experience without changing your existing workflow. We've enhanced layouts with organized tabs,
      • Updating custom fields in Zoho Projects

        Hi I am wondering if anyone has experience with custom fields in Zoho Projects. I am struggling to update the field using either deluge or the api endpoint. My code is: //custom_Map = map(); custom_Map = {"UDF_DOUBLE_1":"0.27"}; update_Map = map(); update_Map.put("custom_fields",custom_Map.toList());
      • Zoho Inventory - How to pay a supplier up front then receive multiple deliveries

        How do we manage situations where we pay a supplier up front, then the receive the products in increments? Example Workflow: Create Purchase Order > Receive Bill for full amount > Receive Items 2 or more deliveries. Currently, once a Bill is created against
      • How can I add or change the active customer in Zoho Projects?

        I'm trying to change the customer in an active Zoho project. Is it possible to add or change the customer?
      • Almacenamiento

        Hola, Quisiera saber como podría hacer para bajar el almacenamiento de 5gb a mis usuarios, en otras palabras los quiero ir limitando de la cuota real, y luego ir agregando poco a poco la cantidad hasta llegar a los 5gb que me dan en el plan free. 
      • What happens when someone clicks 'unsubscribe' in a zoho CRM email

        Hello, As per, i am going round in circles trying to find an answer to these 2 question. I have an email template that has an unsubscribe link in the footer in zoho CRM. First, what happens when someone clicks it - where does the contact get unsubscribed
      • Nimble enhancements to WhatsApp for Business integration in Zoho CRM: Enjoy context and clarity in business messaging

        Dear Customers, We hope you're well! WhatsApp for business is a renowned business messaging platform that takes your business closer to your customers; it gives your business the power of personalized outreach. Using the WhatsApp for Business integration
      • Zoho CRM - Scheduled Reports Which Contain Chart

        Hi Zoho CRM Team, I'm requesting that the Report Export and Scheduling feature be enhanced to include a chart, if one has been created on a report. At the moment I have a report which shows Sales This Week by Deal Owner and a pie chart at the top of the
      • Can I add Conditional merge tags on my Templates?

        Hi I was wondering if I can use Conditional Mail Merge tags inside my Email templates/Quotes etc within the CRM? In spanish and in our business we use gender and academic degree salutations , ie: Dr., Dra., Sr., Srta., so the beginning of an email / letter
      • Cadences

        I have just started using Cadences for follow-up up email pipeline. Is it just me or do you find the functionality very basic? For example, it will tell me (if I go looking for it) if someone has replied to a follow-up and been unenrolled; but it won't
      • Canvas View in Zoho Recruit

        Is it possible or would it be possible to have the new 'Canvas View' in Zoho Recruit?
      • Zoho Inventory - Move Orders

        Quick question about Move Orders... Why is there no status to say something like "Draft", "In Progress" and "Completed", similar to Transfer Orders? I'm assuming that when something needs to be moved it should be planned in Inventory, executed and then
      • Kaizen #215 - Workflow APIs - Part 3 - Create and Update Workflow Rules

        Welcome back to another week of Kaizen! Over the last couple of weeks, we’ve joined Zylker Cloud Services as they review and improve their workflows. In Part 1, we discovered and audited their sprawling workflow landscape. In Part 2, we learned how to
      • DataPrep Bigquery Connection failed

        Hello everybody, I want to create a connnection beetwen Bigquery and Dataprep but when I try to connect my project I got this error Loading tables has failed. Table list fetched from the data source expired.
      • Issue in Zoho People Regularization – Incorrect Hour Calculation

        I have noticed that when applying attendance regularization in Zoho People for previous dates, the total working hours are not calculated correctly. For example, even if the check-in is 10:00 AM and check-out is 6:00 PM, the system shows an incorrect
      • Free Webinar : Unlock AI driven business insights with Zoho Inventory + Zoho Analytics

        Are you tired of switching between apps and exporting data to build customized reports? Say hello to smarter & streamlined insights! Join us for this exclusive webinar where we explore the power of the Zoho Inventory–Zoho Analytics integration. Learn
      • Allow Multiple usage units to items while adding them to sales/purchase transactions

        The usage unit of items added in zoho books are static right now and can not be changed. But certain items are received or sold in multiple usage units. One example is fabric. It can be bought in Meters, inches, kgs or other units. Another example would
      • PO receive quantities

        At last, Zoho has finally got around to allowing us to receive a larger qty than recorded in the PO :-) Saves us all from editing the PO's before receiving larger quantities ( usual for us ) ! It's still in "beta" but available upon request, I've tested
      • Invalid URL error when embedded sending url into iframe for my website when using in another region

        Hi team, My site is currently working on integrating your signature feature as part of the system functionality, it's working great but recently there's been a problem like this: After successfully creating the document, i will embed a sending url into
      • Analytics : How to share to an external client ?

        We have a use case where a client wants a portal so that several of his users can view dashboards that we have created for them in Zoho Analytics. They are not part of our company or Zoho One account. The clients want the ability to have user specific,
      • Reference Deal Categories in Deluge

        Hello, Is there a way to reference Deal Category in deluge functions? So for our Deals, we have several different WON stages in a pipeline.  Rather than type each stage into our functions, we'd like to be able to reference the Deal Category.  Similar
      • Payroll In Canada

        Hi, When can we expect to have payroll in Canada with books 
      • Users Name & Email in Reports

        Hi, I would like to show the Users Name from their Zoho Acount in All Entries/Reports as well as the current Account Email. Thanks Dan
      • Presenting ABM for Zoho CRM: Expand and retain your customers with precision

        Picture this scenario: You're a growing SaaS company ready to launch a powerful business suite, and are looking to gain traction and momentum. But as a business with a tight budget, you know acquiring new customers is slow, expensive, and often delivers
      • Whatsapp Limitation Questions

        Good day, I would like to find out about the functionality or possibility of all the below points within the Zoho/WhatsApp integration. Will WhatsApp buttons ever be possible in the future? Will WhatsApp Re-directs to different users be possible based
      • Empowered Custom Views: Cross-Module Criteria Now Supported in Zoho CRM

        Hello everyone, We’re excited to introduce cross-module criteria support in custom views! Custom views provide personalized perspectives on your data and that you can save for future use. You can share these views with all users or specific individuals
      • Workflow Creation with Zia gets stuck

        It gets stuck here:
      • Next Page