Lineas activas e insertar cada una

This commit is contained in:
2026-03-24 17:27:52 +01:00
parent 5bb3bc554b
commit 28880c4d99
7 changed files with 302 additions and 5 deletions

View File

@@ -0,0 +1,20 @@
CREATE table if not exists objenious_lines (
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
simId BIGINT UNIQUE,
status TEXT,
iccid TEXT NOT NULL,
msisdn TEXT,
imei TEXT,
imeiChangeDate TIMESTAMPTZ,
offerCode TEXT,
status TEXT,
preactivationDate TIMESTAMPTZ, -- No viene con hora
activationDate TIMESTAMPTZ,
commercialStatus TEXT,
commercialStatusDate TIMESTAMPTZ,
billingStatus TEXT,
billingStatusChangeDate TIMESTAMPTZ,
billingActivationDate TIMESTAMPTZ,
createDate TIMESTAMPTZ,
raw JSONB
)

View File

@@ -5,16 +5,16 @@ meta {
}
get {
url: https://api-getway.objenious.com/ws/lines?pageSize=10&identifier.identifierType=ICCID&identifier.identifiers=8933201125065160455
url: https://api-getway.objenious.com/ws/lines?pageSize=1000&simStatus=ACTIVATED
body: formUrlEncoded
auth: bearer
}
params:query {
pageSize: 10
identifier.identifierType: ICCID
identifier.identifiers: 8933201125065160455
~simStatus: ACTIVATED
pageSize: 1000
simStatus: ACTIVATED
~identifier.identifierType: ICCID
~identifier.identifiers: 8933201125065160455
}
auth:bearer {

View File

@@ -0,0 +1,20 @@
/**
* Cliente de postgres para la intranet. Se usa solo porque hace falta para el
* volcado de datos, si se usa en mas partes algo estás haciendo mal.
*/
import { Pool } from 'pg';
import { PgClient } from 'sim-shared/infrastructure/PgClient.js'
import { env } from './env/index.js';
export const pgPoolIntranet = new Pool({
user: env.POSTGRES_USER,
host: env.POSTGRES_HOST,
database: "intranet",
password: env.POSTGRES_PASSWORD,
port: Number(env.POSTGRES_PORT) || 5432,
});
export const postgrClientIntranet = new PgClient({
pool: pgPoolIntranet
})

View File

@@ -0,0 +1,73 @@
import { PoolClient } from "pg";
import { CreateObjeniousLineDTO } from "sim-shared/domain/objeniousLine.js";
import { PgClient } from "sim-shared/infrastructure/PgClient.js";
export class ObjeniousLinesRepository {
constructor(
private pgClient: PgClient
) {
}
public async insertOrUpdate(data: CreateObjeniousLineDTO) {
const query = `
INSERT INTO objenious_lines (
simId, iccid, msisdn, imei, imeiChangeDate,
offerCode, status, preactivationDate, activationDate,
commercialStatus, commercialStatusDate, billingStatus,
billingStatusChangeDate, billingActivationDate, createDate, raw
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16
)
ON CONFLICT (simId)
DO UPDATE SET
iccid = EXCLUDED.iccid,
msisdn = EXCLUDED.msisdn,
imei = EXCLUDED.imei,
imeiChangeDate = EXCLUDED.imeiChangeDate,
offerCode = EXCLUDED.offerCode,
status = EXCLUDED.status,
preactivationDate = EXCLUDED.preactivationDate,
activationDate = EXCLUDED.activationDate,
commercialStatus = EXCLUDED.commercialStatus,
commercialStatusDate = EXCLUDED.commercialStatusDate,
billingStatus = EXCLUDED.billingStatus,
billingStatusChangeDate = EXCLUDED.billingStatusChangeDate,
billingActivationDate = EXCLUDED.billingActivationDate,
raw = EXCLUDED.raw
RETURNING id;
`;
const values = [
data.simId,
data.iccid,
data.msisdn,
data.imei,
data.imeiChangeDate,
data.offerCode,
data.status,
data.preactivationDate,
data.activationDate,
data.commercialStatus,
data.commercialStatusDate,
data.billingStatus,
data.billingStatusChangeDate,
data.billingActivationDate,
data.createDate || new Date(), // Default a ahora si no viene
JSON.stringify(data.raw) // El driver de pg requiere string o el objeto directo para JSONB
];
let client: PoolClient | undefined = undefined;
try {
client = await this.pgClient.connect();
const res = await client.query(query, values);
return res.rows[0].id;
} catch (err) {
console.error('Error en la inserción:', err);
throw err;
} finally {
if (client != undefined) {
client.release()
}
}
}
}

View File

@@ -54,6 +54,7 @@ export class CheckObjeniousRequests {
/**
* Para una lista de operaciones **con mass_action_id** se comprueba si han tenido alguna actualizacion
* Devuelve el numero de operaciones comprobadas.
* TODO: Esto va en un repositorio
*/
private async getMassActionsStatus(requestList: ObjeniousOperation[]) {
if (requestList.length == 0) return 0;

View File

@@ -0,0 +1,68 @@
import { ObjeniousLine, ObjeniousLineResponse } from "sim-shared/domain/objeniousLine.js";
import { tryCatch, Result } from "sim-shared/domain/Result.js";
import { HttpClient } from "sim-shared/infrastructure/HTTPClient.js";
const MAX_PAGE_SIZE = 1000
export class VolcadoLineas {
constructor(
private readonly httpClient: HttpClient
) {
}
/**
* Mover al repo
*/
private async getLinesByStatus(args?: {
pageSize?: number,
pageNumber?: number,
status?: string
}): Promise<Result<string, ObjeniousLine[]>> {
const path = "/lines"
const pageSize = args?.pageSize ?? MAX_PAGE_SIZE;
const status = args?.status ?? null;
let currentPage = args?.pageNumber ?? 0;
let totalPages = 1;
let allLines: ObjeniousLine[] = []
const loadNextLine = async () => {
const nextPage = await tryCatch<ObjeniousLineResponse>(this.httpClient.client.get(path, {
params: {
simStatus: status,
pageSize: pageSize,
pageNumber: currentPage
}
}))
if (nextPage.error != undefined) {
return {
error: nextPage.error.msg.message
}
}
// Se aumenta para la siguiente ejecucion
currentPage = nextPage.data.pageNumber + 1
allLines = [...allLines, ...nextPage.data.content]
totalPages = nextPage.data.totalPages
}
// El inicio se ejecuta siempre
await loadNextLine()
// Copia para evitar bucles infinitos por error de la api
const maxPages = totalPages
for (let i = currentPage; i < maxPages; i++) {
await loadNextLine()
}
return {
data: allLines
}
}
public async loadLines() {
}
}

View File

@@ -0,0 +1,115 @@
export type ObjeniousLineResponse = {
content: ObjeniousLine[],
offset: number,
pageNumber: number,
pageSize: number,
paged: boolean,
totalPages: number,
totalElements: number
}
export type ObjeniousLine = {
identifier: {
simId: number,
iccid: string,
imsi: string,
msisdn: string,
amsisdn?: string,
imei: string
},
simCardType: {
code: string,
description: string
},
device: {
imei: string,
imeiChangeDate: string, //Fecha iso
deviceReference?: string | null,
manufacturer?: string | null,
},
customerAccount: {
code: string,
label: string,
address: {
address1: string,
address2: string,
address3: string,
zipCode: string,
city: string,
country: string,
state?: string | null
}
},
offer: {
code: string,
description: string,
},
party: {
name: string,
code: string,
contractReference: string,
partyType: string,
},
lineCustomFields: {
custom1: {
label: string | null,
value: string | null
},
custom2: {
label: string | null,
value: string | null
},
custom3: {
label: string | null,
value: string | null
},
custom4: {
label: string | null,
value: string | null
},
custom5: {
label: string | null,
value: string | null
},
custom6: {
label: string | null,
value: string | null
}
},
status: {
status: string,
preactivationDate: string | null, //"2026-03-17",
activationDate: string | null, //"2026-03-17T11:04:11.408+00:00",
commercialStatus: string, //"test",
commercialStatusDate: string, //"2026-03-17T11:41:01.493+00:00",
networkStatus: string, // "ACTIVATED",
billingStatus: string, //"TEST",
billingStatusChangeDate: string | null, // "2026-03-17T11:01:00.276+00:00",
billingActivationDate: string | null //,
createdDate: string | null,//"2026-01-30T01:50:02.060+00:00"
},
services: string | null
};
export type ObjeniousLineDb = {
id: number;
simId?: string;
iccid: string;
msisdn?: string;
imei?: string;
imeiChangeDate?: Date;
offerCode?: string;
status?: string;
preactivationDate?: Date;
activationDate?: Date;
commercialStatus?: string;
commercialStatusDate?: Date;
billingStatus?: string;
billingStatusChangeDate?: Date;
billingActivationDate?: Date;
createDate?: Date;
raw: ObjeniousLine;
}
// DTO para inserción (omite el ID autogenerado)
export type CreateObjeniousLineDTO = Omit<ObjeniousLineDb, 'id'>;