diff --git a/src/idpay/20_apim_api_data_factory.tf b/src/idpay/20_apim_api_data_factory.tf
new file mode 100644
index 00000000..a4162c71
--- /dev/null
+++ b/src/idpay/20_apim_api_data_factory.tf
@@ -0,0 +1,50 @@
+# #
+# # IDPAY API for internal use from data factory
+# #
+#
+
+resource "azurerm_api_management_api" "idpay_data_factory" {
+ name = "${var.env_short}-idpay-itn-data-factory"
+ api_management_name = data.azurerm_api_management.apim_core.name
+ resource_group_name = data.azurerm_resource_group.apim_rg.name
+
+ revision = "1"
+ display_name = "IDPAY ITN Data Factory"
+ path = "idpay-itn/df"
+ subscription_required = false
+ #service_url = ""
+ protocols = ["https"]
+
+}
+
+resource "azurerm_api_management_api_operation" "idpay_df_report_patch" {
+ operation_id = "idpay-df-report-patch"
+ api_name = azurerm_api_management_api.idpay_data_factory.name
+ api_management_name = data.azurerm_api_management.apim_core.name
+ resource_group_name = data.azurerm_resource_group.apim_rg.name
+ display_name = "IDPAY DF Report Patch"
+ method = "PATCH"
+ url_template = "/initiatives/{initiativeId}/reports/{reportId}"
+ template_parameter {
+ name = "initiativeId"
+ type = "string"
+ required = true
+ }
+ template_parameter {
+ name = "reportId"
+ type = "string"
+ required = true
+ }
+ description = "Endpoint for DF in order to perform a report patch for update the status"
+}
+
+resource "azurerm_api_management_api_operation_policy" "idpay_df_report_patch_policy" {
+ api_name = azurerm_api_management_api_operation.idpay_df_report_patch.api_name
+ api_management_name = azurerm_api_management_api_operation.idpay_df_report_patch.api_management_name
+ resource_group_name = azurerm_api_management_api_operation.idpay_df_report_patch.resource_group_name
+ operation_id = azurerm_api_management_api_operation.idpay_df_report_patch.operation_id
+
+ xml_content = templatefile("./apim/api/idpay_data_factory/patch-report-policy.xml.tpl", {
+ ingress_load_balancer_hostname = local.domain_aks_ingress_hostname
+ })
+}
diff --git a/src/idpay/20_apim_api_portal.tf b/src/idpay/20_apim_api_portal.tf
index d5126030..d511539f 100644
--- a/src/idpay/20_apim_api_portal.tf
+++ b/src/idpay/20_apim_api_portal.tf
@@ -569,6 +569,27 @@ module "idpay_itn_merchant_portal" {
ingress_load_balancer_hostname = local.domain_aks_ingress_hostname
})
},
+ {
+ operation_id = "generateReport"
+
+ xml_content = templatefile("./apim/api/idpay_merchant/post-generate-report-policy.xml.tpl", {
+ ingress_load_balancer_hostname = local.domain_aks_ingress_hostname
+ })
+ },
+ {
+ operation_id = "getMerchantTransactionsReports"
+
+ xml_content = templatefile("./apim/api/idpay_merchant/get-report-list-policy.xml.tpl", {
+ ingress_load_balancer_hostname = local.domain_aks_ingress_hostname
+ })
+ },
+ {
+ operation_id = "downloadTransactionsReport"
+
+ xml_content = templatefile("./apim/api/idpay_merchant/get-report-download-policy.xml.tpl", {
+ ingress_load_balancer_hostname = local.domain_aks_ingress_hostname
+ })
+ },
{
operation_id = "getRewardBatches"
diff --git a/src/idpay/apim/api/idpay_data_factory/patch-report-policy.xml.tpl b/src/idpay/apim/api/idpay_data_factory/patch-report-policy.xml.tpl
new file mode 100644
index 00000000..2865c1ab
--- /dev/null
+++ b/src/idpay/apim/api/idpay_data_factory/patch-report-policy.xml.tpl
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/idpay/apim/api/idpay_merchant/get-report-download-policy.xml.tpl b/src/idpay/apim/api/idpay_merchant/get-report-download-policy.xml.tpl
new file mode 100644
index 00000000..e2247bfd
--- /dev/null
+++ b/src/idpay/apim/api/idpay_merchant/get-report-download-policy.xml.tpl
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/idpay/apim/api/idpay_merchant/get-report-list-policy.xml.tpl b/src/idpay/apim/api/idpay_merchant/get-report-list-policy.xml.tpl
new file mode 100644
index 00000000..463e9bc7
--- /dev/null
+++ b/src/idpay/apim/api/idpay_merchant/get-report-list-policy.xml.tpl
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/idpay/apim/api/idpay_merchant/openapi.merchant.yml b/src/idpay/apim/api/idpay_merchant/openapi.merchant.yml
index 6873d048..e7916f65 100644
--- a/src/idpay/apim/api/idpay_merchant/openapi.merchant.yml
+++ b/src/idpay/apim/api/idpay_merchant/openapi.merchant.yml
@@ -462,6 +462,117 @@ paths:
description: Too many requests
"500":
description: Server error
+ /initiative/{initiativeId}/reports:
+ post:
+ tags:
+ - merchant-report
+ summary: Generates a report with all transactions associated with a merchant and a reference period and returns the data from the created file
+ description: "ENG: Generates a report with all transactions associated with a merchant and a reference period and returns the data from the created file
IT: Genera un report con tutte le transazioni associate ad un esercente e ad un periodo di riferimento e ritorna i dati del file creato"
+ operationId: generateReport
+ parameters:
+ - name: initiativeId
+ in: path
+ description: The initiative ID
+ required: true
+ schema:
+ type: string
+ - name: merchantId
+ in: query
+ description: The merchant ID
+ required: false
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ReportRequest"
+ responses:
+ "200":
+ $ref: "#/components/responses/POST_generate_transactions_report_200_Response"
+ "400":
+ $ref: "#/components/responses/POST_generate_transactions_report_400_Response"
+ "401":
+ $ref: "#/components/responses/POST_generate_transactions_report_401_Response"
+ "404":
+ $ref: "#/components/responses/POST_generate_transactions_report_404_Response"
+ "429":
+ $ref: "#/components/responses/POST_generate_transactions_report_429_Response"
+ "500":
+ $ref: "#/components/responses/POST_generate_transactions_report_500_Response"
+ get:
+ tags:
+ - merchant-report
+ summary: Retrieve the list of generated reports
+ description: "ENG: Retrieves the paginated list of reports generated for a merchant or Invitalia operator, ordered by request creation date descending.
IT: Recupera la lista paginata dei report generati per un merchant o per un operatore Invitalia, ordinata per data di richiesta in ordine decrescente."
+ operationId: getMerchantTransactionsReports
+ parameters:
+ - name: initiativeId
+ in: path
+ description: The initiative ID
+ required: true
+ schema:
+ type: string
+ - name: page
+ in: query
+ required: false
+ schema:
+ type: integer
+ default: 0
+ minimum: 0
+ - name: size
+ in: query
+ required: false
+ schema:
+ type: integer
+ default: 10
+ minimum: 1
+ maximum: 100
+ responses:
+ "200":
+ $ref: "#/components/responses/GET_list_transactions_reports_200_Response"
+ "400":
+ $ref: "#/components/responses/GET_list_transactions_reports_400_Response"
+ "401":
+ $ref: "#/components/responses/GET_list_transactions_reports_401_Response"
+ "404":
+ $ref: "#/components/responses/GET_list_transactions_reports_404_Response"
+ "429":
+ $ref: "#/components/responses/GET_list_transactions_reports_429_Response"
+ "500":
+ $ref: "#/components/responses/GET_list_transactions_reports_500_Response"
+ /initiative/{initiativeId}/reports/{reportId}/download:
+ get:
+ tags:
+ - merchant-report
+ summary: Download the generated transactions report file
+ description: "ENG: This service allows downloading the file associated with a previously generated transactions report.
IT: Questo servizio consente di scaricare il file associato a un report di transazioni precedentemente generato."
+ operationId: downloadTransactionsReport
+ parameters:
+ - name: initiativeId
+ in: path
+ required: true
+ schema:
+ type: string
+ - name: reportId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ $ref: "#/components/responses/GET_download_transactions_report_200_Response"
+ "400":
+ $ref: "#/components/responses/GET_download_transactions_report_400_Response"
+ "401":
+ $ref: "#/components/responses/GET_download_transactions_report_401_Response"
+ "404":
+ $ref: "#/components/responses/GET_download_transactions_report_404_Response"
+ "429":
+ $ref: "#/components/responses/GET_download_transactions_report_429_Response"
+ "500":
+ $ref: "#/components/responses/GET_download_transactions_report_500_Response"
/initiatives/{initiativeId}/reward-batches/{rewardBatchId}/transactions/rejected:
post:
tags:
@@ -1085,6 +1196,276 @@ components:
maxLength: 36
pattern: .*
responses:
+ GET_download_transactions_report_200_Response:
+ description: Ok
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/DownloadReportResponseDTO"
+ GET_download_transactions_report_400_Response:
+ description: Bad request
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_download_transactions_report_401_Response:
+ description: Authentication failed
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_download_transactions_report_404_Response:
+ description: Resource not found
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_download_transactions_report_429_Response:
+ description: Too many requests
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_download_transactions_report_500_Response:
+ description: Server error
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ POST_generate_transactions_report_200_Response:
+ description: Ok
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ReportDTO"
+ POST_generate_transactions_report_400_Response:
+ description: Bad request
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ POST_generate_transactions_report_401_Response:
+ description: Authentication failed
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ POST_generate_transactions_report_404_Response:
+ description: Resource not found
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ POST_generate_transactions_report_429_Response:
+ description: Too many requests
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ POST_generate_transactions_report_500_Response:
+ description: Server error
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_list_transactions_reports_200_Response:
+ description: Ok
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ReportListDTO"
+ GET_list_transactions_reports_400_Response:
+ description: Bad request
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_list_transactions_reports_401_Response:
+ description: Authentication failed
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_list_transactions_reports_404_Response:
+ description: Resource not found
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_list_transactions_reports_429_Response:
+ description: Too many requests
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
+ GET_list_transactions_reports_500_Response:
+ description: Server error
+ headers:
+ Access-Control-Allow-Origin:
+ $ref: "#/components/headers/Access-Control-Allow-Origin"
+ X-RateLimit-Limit:
+ $ref: "#/components/headers/X-RateLimit-Limit"
+ X-RateLimit-Remaining:
+ $ref: "#/components/headers/X-RateLimit-Remaining"
+ X-RateLimit-Reset:
+ $ref: "#/components/headers/X-RateLimit-Reset"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/TransactionErrorDTO"
GET_download_invoice_file_200_Response:
description: Ok
headers:
@@ -2069,6 +2450,61 @@ components:
type: integer
format: int32
description: "ENG: The total number of the pages
IT: Il numero totale delle pagine"
+ ReportDTO:
+ type: object
+ properties:
+ id:
+ type: string
+ description: "ENG: Report ID
IT: ID del report"
+ maxLength: 64
+ pattern: .*
+ initiativeId:
+ type: string
+ description: "ENG: The ID of the initiative
IT: L'ID' dell'iniziativa"
+ reportStatus:
+ type: string
+ enum:
+ - INSERTED
+ - IN_PROGRESS
+ - GENERATED
+ - FAILED
+ description: "ENG: Report status
IT: Stato del report"
+ fileName:
+ type: string
+ description: "ENG: Name of the report
IT: Nome del report"
+ requestDate:
+ type: string
+ format: date-time
+ description: "ENG: Report request date
IT: Data di richiesta del report"
+ elaborationDate:
+ type: string
+ format: date-time
+ description: "ENG: Report processing end date
IT: Data di fine elaborazione del report"
+ startPeriod:
+ type: string
+ format: date-time
+ description: "ENG: Start date of the reference period
IT: Data di inizio del periodo di riferimento"
+ endPeriod:
+ type: string
+ format: date-time
+ description: "ENG: End date of the reference period
IT: Data di fine del periodo di riferimento"
+ merchantId:
+ type: string
+ description: "ENG: Merchant ID
IT: L'ID dell'esercente"
+ businessName:
+ type: string
+ description: "ENG: The name of the merchant
IT: La ragione sociale dell'esercente"
+ operatorLevel:
+ type: string
+ enum:
+ - L1
+ - L2
+ - L3
+ description: "ENG: Invitalia operator level
IT: Livello dell'operatore Invitalia"
+ reportType:
+ type: string
+ enum:
+ - MERCHANT_TRANSACTIONS
PointOfSaleErrorDTO:
type: object
required:
@@ -2098,6 +2534,65 @@ components:
description: "ENG: URL to download the approved batch file - IT: URL per scaricare il file del lotto approvato"
required:
- approvedBatchUrl
+ DownloadReportResponseDTO:
+ type: object
+ properties:
+ reportUrl:
+ type: string
+ maxLength: 10000
+ description: "ENG: URL to download the report file - IT: URL per scaricare il file del report"
+ required:
+ - reportUrl
+ ReportListDTO:
+ type: object
+ description: "ENG: Paginated list of generated transaction reports.
IT: Lista paginata dei report di transazioni generati."
+ properties:
+ content:
+ type: array
+ description: >
+ ENG: List of generated reports for the requested page.
+ IT: Elenco dei report generati per la pagina richiesta.
+ items:
+ $ref: "#/components/schemas/ReportDTO"
+ page:
+ type: integer
+ description: >
+ ENG: Current page number (0-based).
+ IT: Numero della pagina corrente (partendo da 0).
+ size:
+ type: integer
+ description: >
+ ENG: Number of elements per page.
+ IT: Numero di elementi per pagina.
+ totalElements:
+ type: integer
+ description: >
+ ENG: Total number of available reports.
+ IT: Numero totale dei report disponibili.
+ totalPages:
+ type: integer
+ description: >
+ ENG: Total number of available pages.
+ IT: Numero totale delle pagine disponibili.
+ ReportRequest:
+ type: object
+ properties:
+ startPeriod:
+ type: string
+ format: date-time
+ description: "ENG: Start date of the reference period
IT: Data di inizio del periodo di riferimento"
+ endPeriod:
+ type: string
+ format: date-time
+ description: "ENG: End date of the reference period
IT: Data di fine del periodo di riferimento"
+ reportType:
+ type: string
+ enum:
+ - MERCHANT_TRANSACTIONS
+ required:
+ - startPeriod
+ - endPeriod
+ - reportType
securitySchemes:
Bearer:
type: apiKey
diff --git a/src/idpay/apim/api/idpay_merchant/post-generate-report-policy.xml.tpl b/src/idpay/apim/api/idpay_merchant/post-generate-report-policy.xml.tpl
new file mode 100644
index 00000000..f61f524d
--- /dev/null
+++ b/src/idpay/apim/api/idpay_merchant/post-generate-report-policy.xml.tpl
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+ @(context.Request.Url.Query.GetValueOrDefault("merchantId",""))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+