SELECT CASE WHEN nombre = 'FEDERICO DE LEON' THEN 'Jefe de Transformacion y Personas' ELSE PUENOM END AS PUENOM, AVG(SUELDO) AS Promedio_Sueldo_Anual, AVG(PRODUCTIVIDAD) AS Promedio_Productividad, AVG([COMISIONES VARIABLES]) AS Promedio_Comisiones_Variables_Anual, AVG(GRATIFICACION) AS Promedio_Gratificacion FROM ( SELECT RTRIM(primer_nombre) + ' ' + RTRIM(primer_apellido) AS nombre, PUENOM, [PREMIOS] AS PRODUCTIVIDAD, [COMISIONES VARIABLES] AS [COMISIONES VARIABLES], [SUELDO] AS SUELDO, [GRATIFICACION] FROM ( SELECT vista_completa.primer_nombre, vista_completa.primer_apellido, PUESTOS.PUENOM, vista_completa.DEPARTAMENTO_NOMBRE, VISTA_GENEXCEL.FECHA_INGRESO, vista_genexcel.mes_y_anio, vista_genexcel.importe, vista_completa.fecha_de_egreso, CASE WHEN vista_genexcel.CONCEPTO IN (45, 40, 46) THEN 'COMISIONES VARIABLES' ELSE vista_genexcel.concepto_nombre END AS concepto_nombre FROM sueldosprod.dbo.fundef FUNDEF, sueldosprod.dbo.puestos PUESTOS, sueldosprod.dbo.vista_genexcel VISTA_GENEXCEL INNER JOIN sueldosprod.dbo.vista_completa VISTA_COMPLETA ON vista_genexcel.funcionario = vista_completa.ci WHERE ((( vista_genexcel.mes_y_anio >= {ts '2024-08-01 00:00:00'} ) and ( vista_genexcel.mes_y_anio < {ts '2024-09-01 00:00:00'} )) or ( vista_genexcel.mes_y_anio >= {ts '2024-01-01 00:00:00'} and VISTA_GENEXCEL.CONCEPTO=2000)) AND fundef.deffuncod = vista_completa.funcionario_codigo AND puestos.empcod = fundef.empcod AND puestos.puecod = fundef.puecod AND vista_genexcel.CONCEPTO IN (1, 44, 20, 45, 40, 46, 2000) ) AS SourceTable PIVOT ( SUM(importe) FOR concepto_nombre IN ([PREMIOS], [COMISIONES VARIABLES], [SUELDO],[GRATIFICACION]) ) AS PivotTable WHERE fecha_de_egreso IS NULL ) AS ResultTable where PUENOM != 'SIN DEFINIR' GROUP BY CASE WHEN nombre = 'FEDERICO DE LEON' THEN 'Jefe de Transformacion y Personas' ELSE PUENOM END
create procedure generate_range(startvalue integer, endvalue integer) returns (seq integer) as begin seq = startvalue; suspend; while (seq < endvalue) do begin seq = seq + 1; suspend; end end; /* Ex: select seq from generate_range(1, 100); */
A interoperabilidade no sistema bancário em Moçambique é uma realidade, tendo a SIMO como ponto central de gestão do sistema integrado de transações. Os bancos passaram a receber um conjunto de dados (em ficheiros de texto) transacionados nos seus terminais como POSs (compras) e ATMs (levantamentos/pagamentos) por meios de cartões. Por forma a garantir o melhor controle e rentabilidade (pelo menos uma transação) dos cartões. Considere a estrutura do ficheiro de transações de clientes (Clientes Ativos - 1 transação dentro de 90 dias, Clientes inativos - Transações acima de 90 dias) recebido abaixo: Estrutura da tabela a considerar: | Data | Transacao_ID | Terminal_ID | Tipo_Terminal | Valor | Cliente | Idade | Tipo_Cartao | Provincia | Distrito | |---|---|---|---|---|---|---|---|---|---| 1. Crie um modelo normalizado e os devidos relacionamentos de acordo com a tabela. 2. Com base nas tabelas normalizadas escreva uma query que indique todos os clientes inactivos da província de Gaza, com mais levantamentos. 3. Tendo em consideração que para o banco uma “boa” rentabilidade é ter transações acima de MZN 1000. Indique a província do cliente menos rentável e com mais transações. 4. Ainda sobre a “boa rentabilidade”, indique a província com maior número de clientes activos e menos rentáveis. 5. Continuando sobre a “boa rentabilidade”, indique o cliente ativo mais velho, que realizou mais pagamentos no dia da independência. -- 1. Criação do modelo normalizado CREATE TABLE Cliente ( ClienteID INT PRIMARY KEY, Nome VARCHAR(100), Idade INT ); CREATE TABLE Cartao ( CartaoID INT PRIMARY KEY, ClienteID INT, Tipo_Cartao VARCHAR(50), FOREIGN KEY (ClienteID) REFERENCES Cliente(ClienteID) ); CREATE TABLE Localizacao ( LocalizacaoID INT PRIMARY KEY, Provincia VARCHAR(50), Distrito VARCHAR(50) ); CREATE TABLE Terminal ( TerminalID VARCHAR(50) PRIMARY KEY, Tipo_Terminal VARCHAR(20), LocalizacaoID INT, FOREIGN KEY (LocalizacaoID) REFERENCES Localizacao(LocalizacaoID) ); CREATE TABLE Transacao ( TransacaoID VARCHAR(50) PRIMARY KEY, Data DATE, Valor DECIMAL(10,2), CartaoID INT, TerminalID VARCHAR(50), FOREIGN KEY (CartaoID) REFERENCES Cartao(CartaoID), FOREIGN KEY (TerminalID) REFERENCES Terminal(TerminalID) ); -- Inserção de dados de exemplo (opcional, para teste) -- Inserção de dados de exemplo -- Clientes INSERT INTO Cliente (ClienteID, Nome, Idade) VALUES (1, 'João Silva', 35), (2, 'Maria Santos', 28), (3, 'Pedro Nunes', 45), (4, 'Ana Oliveira', 50), (5, 'Edson Famanda', 29), (6, 'Luísa Costa', 42), (7, 'António Mendes', 55), (8, 'Sofia Rodrigues', 30), (9, 'Miguel Almeida', 38), (10, 'Beatriz Sousa', 47); -- Cartões INSERT INTO Cartao (CartaoID, ClienteID, Tipo_Cartao) VALUES (101, 1, 'Débito'), (102, 2, 'Crédito'), (103, 3, 'Débito'), (104, 4, 'Crédito'), (105, 5, 'Débito'), (106, 6, 'Crédito'), (107, 7, 'Débito'), (108, 8, 'Crédito'), (109, 9, 'Débito'), (110, 10, 'Crédito'); -- Localizações INSERT INTO Localizacao (LocalizacaoID, Provincia, Distrito) VALUES (201, 'Gaza', 'Xai-Xai'), (202, 'Maputo', 'Matola'), (203, 'Sofala', 'Beira'), (204, 'Nampula', 'Nampula'), (205, 'Gaza', 'Chibuto'), (206, 'Inhambane', 'Inhambane'), (207, 'Tete', 'Tete'), (208, 'Zambézia', 'Quelimane'), (209, 'Cabo Delgado', 'Pemba'), (210, 'Niassa', 'Lichinga'); -- Terminais INSERT INTO Terminal (TerminalID, Tipo_Terminal, LocalizacaoID) VALUES ('T001', 'ATM', 201), ('T002', 'POS', 202), ('T003', 'ATM', 203), ('T004', 'POS', 204), ('T005', 'ATM', 205), ('T006', 'POS', 206), ('T007', 'ATM', 207), ('T008', 'POS', 208), ('T009', 'ATM', 209), ('T010', 'POS', 210); -- Transações (50 transações) INSERT INTO Transacao (TransacaoID, Data, Valor, CartaoID, TerminalID) VALUES ('TR001', '2024-06-25', 500.00, 101, 'T001'), ('TR002', '2024-06-25', 1200.00, 102, 'T002'), ('TR003', '2024-05-15', 800.00, 103, 'T003'), ('TR004', '2024-06-25', 1500.00, 104, 'T004'), ('TR005', '2024-03-01', 300.00, 105, 'T005'), ('TR006', '2024-06-25', 2000.00, 106, 'T006'), ('TR007', '2024-06-01', 100.00, 107, 'T007'), ('TR008', '2024-06-10', 950.00, 108, 'T008'), ('TR009', '2024-06-15', 1100.00, 109, 'T009'), ('TR010', '2024-06-20', 750.00, 110, 'T010'), ('TR011', '2024-06-25', 600.00, 101, 'T001'), ('TR012', '2024-05-30', 1800.00, 102, 'T002'), ('TR013', '2024-04-22', 400.00, 103, 'T003'), ('TR014', '2024-06-25', 2500.00, 104, 'T004'), ('TR015', '2024-02-15', 200.00, 105, 'T005'), ('TR016', '2024-06-25', 3000.00, 106, 'T006'), ('TR017', '2024-05-18', 150.00, 107, 'T007'), ('TR018', '2024-06-05', 1050.00, 108, 'T008'), ('TR019', '2024-06-12', 900.00, 109, 'T009'), ('TR020', '2024-06-19', 1250.00, 110, 'T010'), ('TR021', '2024-06-25', 700.00, 101, 'T001'), ('TR022', '2024-06-02', 1600.00, 102, 'T002'), ('TR023', '2024-05-10', 550.00, 103, 'T003'), ('TR024', '2024-06-25', 2200.00, 104, 'T004'), ('TR025', '2024-01-20', 350.00, 105, 'T005'), ('TR026', '2024-06-25', 2800.00, 106, 'T006'), ('TR027', '2024-04-30', 180.00, 107, 'T007'), ('TR028', '2024-06-08', 1150.00, 108, 'T008'), ('TR029', '2024-06-14', 980.00, 109, 'T009'), ('TR030', '2024-06-22', 1450.00, 110, 'T010'), ('TR031', '2024-06-25', 850.00, 101, 'T001'), ('TR032', '2024-05-28', 2100.00, 102, 'T002'), ('TR033', '2024-04-18', 480.00, 103, 'T003'), ('TR034', '2024-06-25', 3200.00, 104, 'T004'), ('TR035', '2024-02-10', 280.00, 105, 'T005'), ('TR036', '2024-06-25', 3500.00, 106, 'T006'), ('TR037', '2024-05-22', 220.00, 107, 'T007'), ('TR038', '2024-06-03', 1350.00, 108, 'T008'), ('TR039', '2024-06-11', 1020.00, 109, 'T009'), ('TR040', '2024-06-18', 1650.00, 110, 'T010'), ('TR041', '2024-06-25', 920.00, 101, 'T001'), ('TR042', '2024-06-01', 2400.00, 102, 'T002'), ('TR043', '2024-05-08', 630.00, 103, 'T003'), ('TR044', '2024-06-25', 2900.00, 104, 'T004'), ('TR045', '2024-01-15', 380.00, 105, 'T005'), ('TR046', '2024-06-25', 3800.00, 106, 'T006'), ('TR047', '2024-04-25', 250.00, 107, 'T007'), ('TR048', '2024-06-07', 1550.00, 108, 'T008'), ('TR049', '2024-06-13', 1080.00, 109, 'T009'), ('TR050', '2024-06-21', 1850.00, 110, 'T010'); -- 2. Query para clientes inativos da província de Gaza, com mais levantamentos SELECT c.ClienteID, c.Nome, COUNT(*) as NumLevantamentos FROM Cliente c JOIN Cartao ca ON c.ClienteID = ca.ClienteID JOIN Transacao t ON ca.CartaoID = t.CartaoID JOIN Terminal te ON t.TerminalID = te.TerminalID JOIN Localizacao l ON te.LocalizacaoID = l.LocalizacaoID WHERE l.Provincia = 'Gaza' AND te.Tipo_Terminal = 'ATM' AND t.Data < DATE_SUB(CURDATE(), INTERVAL 90 DAY) GROUP BY c.ClienteID, c.Nome ORDER BY NumLevantamentos DESC; -- 3. Província do cliente menos rentável e com mais transações SELECT l.Provincia FROM Cliente c JOIN Cartao ca ON c.ClienteID = ca.ClienteID JOIN Transacao t ON ca.CartaoID = t.CartaoID JOIN Terminal te ON t.TerminalID = te.TerminalID JOIN Localizacao l ON te.LocalizacaoID = l.LocalizacaoID GROUP BY l.Provincia ORDER BY SUM(CASE WHEN t.Valor > 1000 THEN 1 ELSE 0 END) ASC, COUNT(*) DESC LIMIT 1; -- 4. Província com maior número de clientes ativos e menos rentáveis SELECT l.Provincia FROM Cliente c JOIN Cartao ca ON c.ClienteID = ca.ClienteID JOIN Transacao t ON ca.CartaoID = t.CartaoID JOIN Terminal te ON t.TerminalID = te.TerminalID JOIN Localizacao l ON te.LocalizacaoID = l.LocalizacaoID WHERE t.Data >= DATE_SUB(CURDATE(), INTERVAL 90 DAY) GROUP BY l.Provincia ORDER BY COUNT(DISTINCT c.ClienteID) DESC, SUM(CASE WHEN t.Valor <= 1000 THEN 1 ELSE 0 END) DESC LIMIT 1; -- 5. Cliente ativo mais velho, com mais pagamentos no dia da independência SELECT c.ClienteID, c.Nome, c.Idade, COUNT(*) as NumPagamentos FROM Cliente c JOIN Cartao ca ON c.ClienteID = ca.ClienteID JOIN Transacao t ON ca.CartaoID = t.CartaoID JOIN Terminal te ON t.TerminalID = te.TerminalID WHERE te.Tipo_Terminal = 'POS' AND DAY(t.Data) = 25 AND MONTH(t.Data) = 6 AND t.Data >= DATE_SUB(CURDATE(), INTERVAL 90 DAY) GROUP BY c.ClienteID, c.Nome, c.Idade ORDER BY c.Idade DESC, NumPagamentos DESC LIMIT 1;
Create Schema demo; CREATE TABLE demo.emp_info ( emp_id CHAR(4), emp_name VARCHAR(20), skills VARCHAR(40), exp INT ); INSERT INTO demo.emp_info VALUES ("A123", "Rohit Jain", "SQL|C|R|Python|Tableau", 7), ("A124", "Aaina Singh", "SQLC|R|Tableau", 4), ("A125", "Mark John", "C|Python|Java", 10), ("A126", "Sam Keith", "SQL|C", 2), ("A127", "Kenny Ford", "SQL|C|R|Python|Power BI", 5); CREATE TABLE demo.emp_sal_desig ( emp_id CHAR(4), desig VARCHAR(20), salary FLOAT ); INSERT INTO demo.emp_sal_desig VALUES ("A123", "L3", 4500), ("A126", "L1", 2500), ("A121", "L2", 3500), ("A122", "L5", 9500);
1. Find the product id and unit list price of products belonging to the 'Yoghurt' category. SELECT product_id, unit_list_price FROM products WHERE product_category = 'yoghurt'; ----------- 2. Find all the information (i.e., all columns) of the managers with null values in their first name. SELECT * FROM managers WHERE first_name IS NULL; ----------- 3. Find the sales ID and sales date where quantity sold on that date is greater than or equal to 2100. SELECT sales_id, sales_date, quantity_sold FROM sales WHERE quantity_sold >= 2100; ----------- 4. Find the manager ID and the sum of quantity sold for all products (except those with ID 7001001) for each of the managers in the sales table and sort the output by manager ID in descending order. SELECT sales_manager_id, SUM(quantity_sold) AS quant_sold FROM sales WHERE product_id <> 7001001 GROUP BY sales_manager_id ORDER BY sales_manager_id DESC; ----------- 5. Find the product ID, product name, and unit production cost of the products with maximum unit production cost below $1.10 and sort the output by production cost in ascending order (HINT: Use HAVING). SELECT product_id, product_name, MAX(unit_production_cost) AS unit_production_cost FROM products GROUP BY 1 , 2 HAVING MAX(unit_production_cost) < 1.10 ORDER BY unit_production_cost DESC; SELECT product_id, product_name, unit_production_cost FROM products WHERE unit_production_cost < 1.10 ORDER BY unit_production_cost DESC; ----------- 6. Find the product ID and sales date with the highest quantity sold from sales transacted after 30 Oct 2021 (exclusive) except for products with IDs 7001001 and 7001002. SELECT product_id, sales_date, quantity_sold FROM sales WHERE sales_date > '2021-10-30' AND product_id NOT IN (7001001 , 7001002) ORDER BY quantity_sold desc LIMIT 1; SELECT product_id, sales_date, quantity_sold FROM sales WHERE sales_date > '2021-10-30';
SELECT ISNULL(A.[staffpin], '') AS [staffpin], ISNULL(A.[staffname], '') AS [staffname], ISNULL(A.[sex], '') AS [sex], CONVERT(date, A.[dateofbirth]) AS [dateofbirth], DATEDIFF(year,A.[dateofbirth],GETDATE()) AS [age], CONVERT(date, A.[joining_date]) AS [joining_date], DATEDIFF(year,A.[joining_date],GETDATE()) AS [service_length], Case when ISNULL(A.[status], '') = 'C' then 'CONFIRM' else 'NON CONFIRM' end AS [status], ISNULL(A.[jobstatus], '') AS [jobstatus], ISNULL(A.[jobbase], '') AS [jobbase], ISNULL(A.[designation], '') AS [designation], ISNULL(A.[functionaldesignation], '') AS [Role], ISNULL(A.[program_name], '') AS [program_name], ISNULL(A.[project_name], '') AS [project_name], ISNULL(A.[branchname], '') AS [branchname], ISNULL(A.[district_name], '') AS [district_name], ISNULL(A.[thana_name], '') AS [thana_name], ISNULL(A.[division_name], '') AS [division_name], CASE WHEN ISNULL(A.[level], 0) = 99 THEN 0 ELSE ISNULL(A.[level], 0) END AS [Grade], ISNULL(A.[email_address], '') AS [email_address], ISNULL(A.[mobile], '') AS [mobile], ISNULL(slb.slab, 0) AS [slab], ISNULL(A.[BirthDistrict], '') AS [HomeDistrict], ISNULL(A.[LastEducation], '') AS [LastEducation], ISNULL(A.[Last_Pms], '') AS [PMS2022], ISNULL(A.[Second_Last_Pms], '') AS [PMS2021], ISNULL(A.[Third_Last_Pms], '') AS [PMS2020], ISNULL(A.[Last_Promotion_Date], '') AS [Last_Promotion_Date], ISNULL(A.[Action_Taken], '') AS [Action_Taken], ISNULL(A.[LastTransferDate], '') AS [LastTransferDate], FDate [LastSlab] FROM [HRReportDB].[HRReportDB].[dbo].[tblERP_Data] A LEFT JOIN (Select PIN,max(FDate) as FDate from [HRReportDB].[HRPMS].[dbo].[tblSlab] group by PIN) B ON A.[staffpin] = B.[PIN] LEFT JOIN ( SELECT RIGHT('00000000' + pin, 8) AS PIN, ISNULL(slab, 0) AS slab FROM OPENQUERY(payroll_tool, 'SELECT pin, slab FROM payroll_tools.staffs') ) slb ON a.staffPIN = slb.PIN WHERE a.jobstatus = 'Active' AND HRProgramId = '11' AND a.HRProgramId NOT IN ('00', '08', '41', '33', '05', '78', '66', '65', '50', '31') AND a.jobbase IN ('REGULAR', 'SERVICE', 'CONTRACT') UNION SELECT RIGHT(REPLICATE('0', 8) + k.pin,8) AS [staffpin], ISNULL(k.name, '') AS StaffName, ISNULL(A.[sex], '') AS [sex], CONVERT(date, A.[dateofbirth]) AS [dateofbirth], DATEDIFF( year, A.[dateofbirth], GETDATE() ) AS [age], CONVERT(date, A.[joining_date]) AS [joining_date], DATEDIFF(year,A.[joining_date],GETDATE()) AS [service_length], ISNULL(k.job_status, '') AS [status], 'Active' AS [jobstatus], ISNULL(k.employee_type, '') AS [jobbase], ISNULL(k.designation, '') AS [designation], ISNULL(k.designation, '') AS [Role], ISNULL(k.program_name, '') AS [program_name], ISNULL(k.project_name, '') AS [project_name], ISNULL(k.branch_name, '') AS [branchname], ISNULL(Branch.DistrictName, '') AS [district_name], ISNULL(Branch.UpazilaName, '') AS [thana_name], ISNULL(Branch.DivisionName, '') AS [division_name], RIGHT( REPLICATE('0', 3) + CAST( ISNULL(k.grade, 0) AS VARCHAR ), 3 ) AS [Grade], ISNULL(A.[email_address], '') AS [email_address], ISNULL(A.[mobile], '') AS [mobile], RIGHT( REPLICATE('0', 3) + CAST( CASE WHEN ISNULL(k.slab, 0) IN (0, 99, 16) THEN 0 ELSE k.slab END AS VARCHAR ), 3 ) AS [slab], ISNULL(A.[BirthDistrict], '') AS [HomeDistrict], ISNULL(A.[LastEducation], '') AS [LastEducation], ISNULL(A.[Last_Pms], '') AS [PMS2022], ISNULL(A.[Second_Last_Pms], '') AS [PMS2021], ISNULL(A.[Third_Last_Pms], '') AS [PMS2020], ISNULL(A.[Last_Promotion_Date], '') AS [Last_Promotion_Date], ISNULL(A.[Action_Taken], '') AS [Action_Taken], ISNULL(A.[LastTransferDate], '') AS [LastTransferDate], FDate [LastSlab] FROM OPENQUERY( PAYROLL_TOOL, 'SELECT DISTINCT month, pin, name, designation, grade, slab, employee_type, job_status, project_name, project_code, branch_name, branch_code, program_name, program_code, salary_to_be_paid FROM ( SELECT MAX(sa.id) AS id, b.month, pin, sa.name, designation, grade, slab, employee_type, job_status, project_name, project_code, branch_name, branch_code, program_name, program_code, salary_to_be_paid FROM payroll_tools.salary_info_history sa INNER JOIN payroll_tools.batches ba ON ba.id = sa.batch_id INNER JOIN payroll_tools.salary_months b ON b.id = ba.salary_month_id WHERE sa.salary_to_be_paid != ''separation'' AND ba.`type` = ''salary'' and sa.program_code = ''11'' AND b.month IN ( SELECT MAX(month) FROM payroll_tools.batches bb INNER JOIN payroll_tools.salary_months bm ON bm.id = bb.salary_month_id WHERE salary_month_id IS NOT NULL AND status IN (''finalized'',''archived'') ) GROUP BY pin, b.month, sa.name, designation, grade, slab, employee_type, job_status, project_name, project_code, branch_name, branch_code, program_name, program_code, salary_to_be_paid ) s' ) k LEFT JOIN HRReportDb.HRReportDb.dbo.tblERP_Data A ON staffpin = RIGHT(REPLICATE('0', 8) + k.pin,8) LEFT JOIN (Select PIN,max(FDate) as FDate from [HRReportDB].[HRPMS].[dbo].[tblSlab] group by PIN) B ON A.[staffpin] = B.[PIN] LEFT JOIN DataProject.bpm.Branch ON HR_BranchId = branch_code WHERE JobBase NOT IN ('REGULAR', 'SERVICE', 'CONTRACT');
import { DomainEntityService } from '../base/DomainEntityService'; import { Inventory } from './Inventory'; import { Service, Inject } from 'typedi'; import { FindOptions } from '../base/FindOptions'; import { Equal, In } from 'typeorm'; import { ConfigurationService } from '../configuration/ConfigurationService'; import { CustomerService } from '../customer/CustomerService'; import { PartnerService } from '../partner/PartnerService'; import { DynamicAttrsService } from '../attribute/DynamicAttrsService'; import { DataFileService } from '../datafile/DataFileService'; import { SubmissionPeriodService } from '../submission/SubmissionPeriodService'; import { InventoryQuantityService } from './InventoryQuantityService'; import { InventoryPriceService } from './InventoryPriceService'; import { Writer } from '../../writer/Writer'; import { InventoryInput } from './InventoryInput'; import { ServiceError } from '../base/ServiceError'; import { Operator } from '../base/filters/Operator'; import { AppDataSource } from '../../platform/DataSource'; import { InventoryResubmitInput } from './InventoryResubmitInput'; const INVENTORY_RESUBMIT = 'InventoryResubmit'; @Service() export class InventoryService extends DomainEntityService<Inventory> { @Inject() protected configurationService: ConfigurationService; @Inject() protected customerService: CustomerService; @Inject() protected partnerService: PartnerService; @Inject() protected dynamicAttrsService: DynamicAttrsService; @Inject() protected dataFileService: DataFileService; @Inject() protected submissionPeriodService: SubmissionPeriodService; @Inject() protected inventoryQuantityService: InventoryQuantityService; @Inject() protected inventoryPriceService: InventoryPriceService; @Inject('Writer') protected writer: Writer; constructor() { super(Inventory); } getServiceName(): string { return 'Inventory'; } async findInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const config = await this.configurationService.getConfiguration(customerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('ili') .leftJoinAndSelect( 'ili.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'ili.dataFile', 'df', '"df"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'ili.onHandQuantity', 'ili.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'ili.onOrderQuantity', 'ili.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'ili.committedQuantity', 'ili.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'ili.floatQuantity', 'ili.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'ili.backorderedQuantity', 'ili.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'ili.returnedQuantity', 'ili.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'ili.inTransitQuantity', 'ili.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'ili.inStockQuantity', 'ili.inventoryQuantities', 'inStockInvQuantity', '"inStockInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'IN STOCK\')' ) .leftJoinAndMapOne( 'ili.damagedQuantity', 'ili.inventoryQuantities', 'damagedInvQuantity', '"damagedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'DAMAGED\')' ) .leftJoinAndMapOne( 'ili.transferredQuantity', 'ili.inventoryQuantities', 'transferredInvQuantity', '"transferredInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSFERRED\')' ) .leftJoinAndMapOne( 'ili.unitPrice', 'ili.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\')' ) .leftJoinAndMapOne( 'ili.bestFitPrice', 'ili.inventoryPrices', 'bestFitInvPrice', '"bestFitInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'BEST_FIT_PRICE\')' ) .leftJoinAndMapOne( 'ili.invConvertedPrice', 'ili.inventoryPrices', 'invConvertedInvPrice', '"invConvertedInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'INV_CONVERTED\')' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); quantityFiltersMap.set('inStockQuantity', 'inStockInvQuantity'); quantityFiltersMap.set('damagedQuantity', 'damagedInvQuantity'); quantityFiltersMap.set('transferredQuantity', 'transferredInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } this.buildWhere(filters, query); query .andWhere('"ili"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"ili"."CUSTOMER_SID" = ' + customer.sid); // add order by this.addOrderBys(query, sort); if (!PartnerService.isAll(partnerId)) { query.andWhere('"df"."REPORTING_PARTNER_SID" = ' + partner.sid); } const inventory = await query.getMany(); return this.loadIliValidationAggregation(inventory); } protected async loadIliValidationAggregation( inventory: Inventory[] ): Promise<Inventory[]> { if (inventory.length === 0) return inventory; // construct SQL const sql = ' select ' + ' ili.sid, count(iliv.inv_Line_item_sid) validationCodesCount ' + ' from inv_line_item ili ' + ' left join ili_validation iliv on iliv.inv_Line_item_sid = ili.sid ' + ' and iliv.customer_sid = ili.CUSTOMER_SID ' + ' where ili.customer_sid = :customersid and ili.sid in (:iliSids)' + ' group by ili.sid '; // execute SQL var rows = new Map(); for (var i = 0; i < inventory.length; i += 1000) { const iliSids = inventory.slice(i, i + 1000).map((s) => s.sid); //not a param to avoid bind var peaking var inListSql = sql.replace( ':customersid', inventory[0].customerSid.toString() as string ); inListSql = inListSql.replace(':iliSids', iliSids.join(',')); var results = await this.repository.query(inListSql); results.map((r) => { rows.set(r.SID, r.VALIDATIONCODESCOUNT); }); } // map SQL result return inventory.map((inventory) => { inventory.validationCodesCount = rows.get(inventory.sid); return inventory; }); } async findNeedCorrectionInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const config = await this.configurationService.getConfiguration(customerId); const queueName = config.get('needCorrectionInventoryQueueName', 'resign'); const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('inv') .leftJoinAndSelect( 'inv.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'inv.dataFile', 'df', '"df"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'inv.submissionPeriod', 'sp', '"sp"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'sp.submissionSchedule', 'ss', '"sp"."CUSTOMER_SID" = "ss"."CUSTOMER_SID"' ) .leftJoinAndSelect('ss.dataType', 'dt') .leftJoinAndSelect( 'sp.submissionPeriodLineItemView', 'spli', '"sp"."CUSTOMER_SID" = "spli"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .innerJoin( 'PEH_INV_QUEUE', 'piq', '"piq"."CLIENT_SKU" = "inv"."CLIENT_SKU" and "piq"."INV_LINE_ITEM_SID" = "inv"."SID" ' + 'and "piq"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } // add unit price condition const unitPriceFilters = filters['unitPrice']; delete filters['unitPrice']; if (unitPriceFilters) { const unitPriceWhere = this.inventoryPriceService.buildWhereExpression( unitPriceFilters, 'invPrice' ); query.andWhere(unitPriceWhere); } this.buildWhere(filters, query); query .andWhere('"inv"."CUSTOMER_SID" = ' + customer.sid) .andWhere('"inv"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"piq"."QUEUE_NAME" = \'' + queueName + "'") .andWhere({ deleted: Equal(0) }); if (!PartnerService.isAll(partnerId)) { query.andWhere('"inv"."REPORTING_PARTNER_SID" = ' + partner.sid); } // add order by this.addOrderBys(query, sort); return query.getMany(); } async resubmitInventory( customerId: string, partnerId: string, inputs: Partial<InventoryResubmitInput>[] ): Promise<ServiceError[]> { // Check input array size if (inputs.length === 0) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', 'No inventory items provided for resubmission.' ) ]; } //Inventory Item Limit Check if (inputs.length > 1000) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `The number of inventory items exceeds the limit of 1000.` ) ]; } const sids: number[] = inputs.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to inventory items const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `Customer ${customerId} or partner ${partnerId} are invalid.` ) ]; } // Query to fetch inventory items with required joins let inventoryItems: Inventory[] = await this.repository .createQueryBuilder('inv') .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = (SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sids) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: customer.sid }) .getMany(); let inventoryItemMap = new Map( inventoryItems.map((inventoryItem) => [ Number(inventoryItem.sid), inventoryItem ]) ); let inventoryItemsToResubmit = []; errors = await Promise.all( inputs.map(async (inventoryResubmitInput) => { const inventoryItem = inventoryItemMap.get( Number(inventoryResubmitInput.sid) ); if (inventoryItem) { let resubmitInventoryItem = await this.loadResubmitInventoryLineItemRefs( inventoryItem, inventoryResubmitInput ); inventoryItemsToResubmit.push(resubmitInventoryItem); return null; } else { return new ServiceError( 'INVENTORY_ITEM_ERR', `Inventory Item with IID ${inventoryResubmitInput.sid} not found. Please check the input data.` ); } }) ); let reportingPartnerId: string; if(inventoryItemsToResubmit.length != 0) { reportingPartnerId = inventoryItemsToResubmit[0].reportingPartner.id; } // Write to S3 or perform further operations with resubmitted inventory items console.log( `Inventory items to resubmit: ${inventoryItemsToResubmit.length}` ); if (inventoryItemsToResubmit.length > 0) { // Example: Write to a service or perform operations with resubmitted inventory items await this.writer.writeToPartnersFolder( customerId, reportingPartnerId, INVENTORY_RESUBMIT, inventoryItemsToResubmit ); } return errors; } clone(...objs) { return Object.assign({}, ...objs); } async loadResubmitInventoryLineItemRefs( inventoryItem: Inventory, inventoryResubmitInput: Partial<InventoryResubmitInput> ): Promise<Inventory> { let resubmitInventoryLineItem: Inventory = this.clone( inventoryItem, inventoryResubmitInput ); resubmitInventoryLineItem.dynamicAttrs = this.clone( await inventoryItem.dynamicAttrs, inventoryResubmitInput.dynamicAttrs ); resubmitInventoryLineItem.onHandQuantity = this.clone( inventoryItem.onHandQuantity, inventoryResubmitInput.onHandQuantity ); resubmitInventoryLineItem.onOrderQuantity = this.clone( inventoryItem.onOrderQuantity, inventoryResubmitInput.onOrderQuantity ); resubmitInventoryLineItem.committedQuantity = this.clone( inventoryItem.committedQuantity, inventoryResubmitInput.committedQuantity ); resubmitInventoryLineItem.backorderedQuantity = this.clone( inventoryItem.backorderedQuantity, inventoryResubmitInput.backorderedQuantity ); resubmitInventoryLineItem.returnedQuantity = this.clone( inventoryItem.returnedQuantity, inventoryResubmitInput.returnedQuantity ); resubmitInventoryLineItem.inTransitQuantity = this.clone( inventoryItem.inTransitQuantity, inventoryResubmitInput.inTransitQuantity ); resubmitInventoryLineItem.inStockQuantity = this.clone( inventoryItem.inStockQuantity, inventoryResubmitInput.inStockQuantity ); resubmitInventoryLineItem.damagedQuantity = this.clone( inventoryItem.damagedQuantity, inventoryResubmitInput.damagedQuantity ); resubmitInventoryLineItem.transferredQuantity = this.clone( inventoryItem.transferredQuantity, inventoryResubmitInput.transferredQuantity ); resubmitInventoryLineItem.inventoryPrices = this.clone( await inventoryItem.inventoryPrices ); resubmitInventoryLineItem.reportedPrice = this.clone( inventoryItem.reportedPrice, inventoryResubmitInput.reportedPrice ); resubmitInventoryLineItem.reportingPartner = this.clone( await inventoryItem.reportingPartner ); return resubmitInventoryLineItem; } async updateInventory( customerId: string, partnerId: string, data: InventoryInput[] ): Promise<ServiceError[]> { let inventoryToCreate: Inventory[] = []; let sids: number[] = data.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to ili let options: FindOptions = { offset: 0, limit: 1000, filters: { sid: { operator: Operator.IN, values: sids } } }; let inventory: Inventory[] = await this.findNeedCorrectionInventory( customerId, partnerId, options ); let sidsToUpdate: number[] = []; errors = sids.map((sid) => { if (inventory) { let s: Inventory = inventory.find((inv: Inventory) => { return inv.sid.toString() === sid.toString(); }); if (s) { sidsToUpdate.push(sid); return null; } } return new ServiceError( 'INVENTORY_NOT_FOUND', `Inventory line sid : ${sid} not found` ); }); if (inventory && inventory.length > 0) { let invLineItems: Inventory[] = await this.repository .createQueryBuilder('inv') // load partner and gs number .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') // load dynamic attrs .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sidsToUpdate) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: inventory[0].customerSid }) .getMany(); await Promise.all( invLineItems.map(async (invLineItem) => { // load serial numbers let input: InventoryInput = data.find((inv: InventoryInput) => { return inv.sid.toString() === invLineItem.sid.toString(); }); invLineItem = Object.assign({}, invLineItem, input); // add inv line to list to write to S3. inventoryToCreate.push(invLineItem); }) ); console.log(`Inventory to write to S3 : ${inventoryToCreate.length}`); // Write to S3 if (inventoryToCreate.length > 0) { await this.writer.write( customerId, partnerId, this.getServiceName(), inventoryToCreate ); } // It is safe to delete from PEH after writing to S3, just in case if delete fails, // the inv will still be deleted from PEH the json file from S3 is loaded into nucleus. // If we delete first and for some reason the writing to S3 fails, there is no way to roll back the db update. await Promise.all( inventoryToCreate.map(async (invLineItem) => { try { // delete inventory line from PEH await AppDataSource.query( 'delete from peh_inv_queue where inv_line_item_sid = :sid', [invLineItem.sid] ); console.log(`Deleted line item : ${invLineItem.sid} from PEH`); } catch (e) { console.log( `Error while deleting from PEH for inv line : ${JSON.stringify( invLineItem )} for Customer : ${customerId}` ); console.error(e); // eat the error as if delete fails, the only con is User will still be able to see the inv line // until the file on S3 is loaded into nucleus } }) ); } return errors; } }
import { DomainEntityService } from '../base/DomainEntityService'; import { Inventory } from './Inventory'; import { Service, Inject } from 'typedi'; import { FindOptions } from '../base/FindOptions'; import { Equal, In } from 'typeorm'; import { ConfigurationService } from '../configuration/ConfigurationService'; import { CustomerService } from '../customer/CustomerService'; import { PartnerService } from '../partner/PartnerService'; import { DynamicAttrsService } from '../attribute/DynamicAttrsService'; import { DataFileService } from '../datafile/DataFileService'; import { SubmissionPeriodService } from '../submission/SubmissionPeriodService'; import { InventoryQuantityService } from './InventoryQuantityService'; import { InventoryPriceService } from './InventoryPriceService'; import { Writer } from '../../writer/Writer'; import { InventoryInput } from './InventoryInput'; import { ServiceError } from '../base/ServiceError'; import { Operator } from '../base/filters/Operator'; import { AppDataSource } from '../../platform/DataSource'; import { InventoryResubmitInput } from './InventoryResubmitInput'; const INVENTORY_RESUBMIT = 'InventoryResubmit'; @Service() export class InventoryService extends DomainEntityService<Inventory> { @Inject() protected configurationService: ConfigurationService; @Inject() protected customerService: CustomerService; @Inject() protected partnerService: PartnerService; @Inject() protected dynamicAttrsService: DynamicAttrsService; @Inject() protected dataFileService: DataFileService; @Inject() protected submissionPeriodService: SubmissionPeriodService; @Inject() protected inventoryQuantityService: InventoryQuantityService; @Inject() protected inventoryPriceService: InventoryPriceService; @Inject('Writer') protected writer: Writer; constructor() { super(Inventory); } getServiceName(): string { return 'Inventory'; } async findInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const config = await this.configurationService.getConfiguration(customerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('ili') .leftJoinAndSelect( 'ili.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'ili.dataFile', 'df', '"df"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'ili.onHandQuantity', 'ili.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'ili.onOrderQuantity', 'ili.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'ili.committedQuantity', 'ili.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'ili.floatQuantity', 'ili.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'ili.backorderedQuantity', 'ili.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'ili.returnedQuantity', 'ili.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'ili.inTransitQuantity', 'ili.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'ili.inStockQuantity', 'ili.inventoryQuantities', 'inStockInvQuantity', '"inStockInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'IN STOCK\')' ) .leftJoinAndMapOne( 'ili.damagedQuantity', 'ili.inventoryQuantities', 'damagedInvQuantity', '"damagedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'DAMAGED\')' ) .leftJoinAndMapOne( 'ili.transferredQuantity', 'ili.inventoryQuantities', 'transferredInvQuantity', '"transferredInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSFERRED\')' ) .leftJoinAndMapOne( 'ili.unitPrice', 'ili.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\')' ) .leftJoinAndMapOne( 'ili.bestFitPrice', 'ili.inventoryPrices', 'bestFitInvPrice', '"bestFitInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'BEST_FIT_PRICE\')' ) .leftJoinAndMapOne( 'ili.invConvertedPrice', 'ili.inventoryPrices', 'invConvertedInvPrice', '"invConvertedInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'INV_CONVERTED\')' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); quantityFiltersMap.set('inStockQuantity', 'inStockInvQuantity'); quantityFiltersMap.set('damagedQuantity', 'damagedInvQuantity'); quantityFiltersMap.set('transferredQuantity', 'transferredInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } this.buildWhere(filters, query); query .andWhere('"ili"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"ili"."CUSTOMER_SID" = ' + customer.sid); // add order by this.addOrderBys(query, sort); if (!PartnerService.isAll(partnerId)) { query.andWhere('"df"."REPORTING_PARTNER_SID" = ' + partner.sid); } const inventory = await query.getMany(); return this.loadIliValidationAggregation(inventory); } protected async loadIliValidationAggregation( inventory: Inventory[] ): Promise<Inventory[]> { if (inventory.length === 0) return inventory; // construct SQL const sql = ' select ' + ' ili.sid, count(iliv.inv_Line_item_sid) validationCodesCount ' + ' from inv_line_item ili ' + ' left join ili_validation iliv on iliv.inv_Line_item_sid = ili.sid ' + ' and iliv.customer_sid = ili.CUSTOMER_SID ' + ' where ili.customer_sid = :customersid and ili.sid in (:iliSids)' + ' group by ili.sid '; // execute SQL var rows = new Map(); for (var i = 0; i < inventory.length; i += 1000) { const iliSids = inventory.slice(i, i + 1000).map((s) => s.sid); //not a param to avoid bind var peaking var inListSql = sql.replace( ':customersid', inventory[0].customerSid.toString() as string ); inListSql = inListSql.replace(':iliSids', iliSids.join(',')); var results = await this.repository.query(inListSql); results.map((r) => { rows.set(r.SID, r.VALIDATIONCODESCOUNT); }); } // map SQL result return inventory.map((inventory) => { inventory.validationCodesCount = rows.get(inventory.sid); return inventory; }); } async findNeedCorrectionInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const config = await this.configurationService.getConfiguration(customerId); const queueName = config.get('needCorrectionInventoryQueueName', 'resign'); const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('inv') .leftJoinAndSelect( 'inv.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'inv.dataFile', 'df', '"df"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'inv.submissionPeriod', 'sp', '"sp"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'sp.submissionSchedule', 'ss', '"sp"."CUSTOMER_SID" = "ss"."CUSTOMER_SID"' ) .leftJoinAndSelect('ss.dataType', 'dt') .leftJoinAndSelect( 'sp.submissionPeriodLineItemView', 'spli', '"sp"."CUSTOMER_SID" = "spli"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .innerJoin( 'PEH_INV_QUEUE', 'piq', '"piq"."CLIENT_SKU" = "inv"."CLIENT_SKU" and "piq"."INV_LINE_ITEM_SID" = "inv"."SID" ' + 'and "piq"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } // add unit price condition const unitPriceFilters = filters['unitPrice']; delete filters['unitPrice']; if (unitPriceFilters) { const unitPriceWhere = this.inventoryPriceService.buildWhereExpression( unitPriceFilters, 'invPrice' ); query.andWhere(unitPriceWhere); } this.buildWhere(filters, query); query .andWhere('"inv"."CUSTOMER_SID" = ' + customer.sid) .andWhere('"inv"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"piq"."QUEUE_NAME" = \'' + queueName + "'") .andWhere({ deleted: Equal(0) }); if (!PartnerService.isAll(partnerId)) { query.andWhere('"inv"."REPORTING_PARTNER_SID" = ' + partner.sid); } // add order by this.addOrderBys(query, sort); return query.getMany(); } async resubmitInventory( customerId: string, partnerId: string, inputs: Partial<InventoryResubmitInput>[] ): Promise<ServiceError[]> { // Check input array size if (inputs.length === 0) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', 'No inventory items provided for resubmission.' ) ]; } //Inventory Item Limit Check if (inputs.length > 1000) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `The number of inventory items exceeds the limit of 1000.` ) ]; } const sids: number[] = inputs.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to inventory items const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `Customer ${customerId} or partner ${partnerId} are invalid.` ) ]; } // Query to fetch inventory items with required joins let inventoryItems: Inventory[] = await this.repository .createQueryBuilder('inv') .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = (SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sids) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: customer.sid }) .getMany(); let inventoryItemMap = new Map( inventoryItems.map((inventoryItem) => [ Number(inventoryItem.sid), inventoryItem ]) ); let inventoryItemsToResubmit = []; errors = await Promise.all( inputs.map(async (inventoryResubmitInput) => { const inventoryItem = inventoryItemMap.get( Number(inventoryResubmitInput.sid) ); if (inventoryItem) { let resubmitInventoryItem = await this.loadResubmitInventoryLineItemRefs( inventoryItem, inventoryResubmitInput ); inventoryItemsToResubmit.push(resubmitInventoryItem); return null; } else { return new ServiceError( 'INVENTORY_ITEM_ERR', `Inventory Item with IID ${inventoryResubmitInput.sid} not found. Please check the input data.` ); } }) ); let reportingPartnerId: string; // Process each SID errors = await Promise.all( sids.map(async (sid) => { // Log the SID being processed console.log('Processing SID:', sid); // Query the database let partnerIdResult = await this.repository .createQueryBuilder('ili') .innerJoin('ili.reportingPartner', 'rp') .innerJoin('ili.customer', 'c') .where('ili.sid = :sid', { sid }) // Use `sid` directly .andWhere('ili.CUSTOMER_SID = :customerSid', { customerSid: customer.sid }) .select('rp.id') .getRawOne(); // Check query result and handle errors if (partnerIdResult) { reportingPartnerId = String(partnerIdResult['rp_ID']); // Optionally process `reportingPartnerId` if needed return null; // No error } else { console.log('No reporting partner ID found for SID:', sid); return new ServiceError( 'INVENTORY_ITEM_ERR', `Inventory Item with IID ${sid} not found. Please check the input data again.` ); } }) ); // Write to S3 or perform further operations with resubmitted inventory items console.log( `Inventory items to resubmit: ${inventoryItemsToResubmit.length}` ); if (inventoryItemsToResubmit.length > 0) { // Example: Write to a service or perform operations with resubmitted inventory items await this.writer.writeToPartnersFolder( customerId, reportingPartnerId, INVENTORY_RESUBMIT, inventoryItemsToResubmit ); } return errors; } clone(...objs) { return Object.assign({}, ...objs); } async loadResubmitInventoryLineItemRefs( inventoryItem: Inventory, inventoryResubmitInput: Partial<InventoryResubmitInput> ): Promise<Inventory> { let resubmitInventoryLineItem: Inventory = this.clone( inventoryItem, inventoryResubmitInput ); resubmitInventoryLineItem.dynamicAttrs = this.clone( await inventoryItem.dynamicAttrs, inventoryResubmitInput.dynamicAttrs ); resubmitInventoryLineItem.onHandQuantity = this.clone( inventoryItem.onHandQuantity, inventoryResubmitInput.onHandQuantity ); resubmitInventoryLineItem.onOrderQuantity = this.clone( inventoryItem.onOrderQuantity, inventoryResubmitInput.onOrderQuantity ); resubmitInventoryLineItem.committedQuantity = this.clone( inventoryItem.committedQuantity, inventoryResubmitInput.committedQuantity ); resubmitInventoryLineItem.backorderedQuantity = this.clone( inventoryItem.backorderedQuantity, inventoryResubmitInput.backorderedQuantity ); resubmitInventoryLineItem.returnedQuantity = this.clone( inventoryItem.returnedQuantity, inventoryResubmitInput.returnedQuantity ); resubmitInventoryLineItem.inTransitQuantity = this.clone( inventoryItem.inTransitQuantity, inventoryResubmitInput.inTransitQuantity ); resubmitInventoryLineItem.inStockQuantity = this.clone( inventoryItem.inStockQuantity, inventoryResubmitInput.inStockQuantity ); resubmitInventoryLineItem.damagedQuantity = this.clone( inventoryItem.damagedQuantity, inventoryResubmitInput.damagedQuantity ); resubmitInventoryLineItem.transferredQuantity = this.clone( inventoryItem.transferredQuantity, inventoryResubmitInput.transferredQuantity ); resubmitInventoryLineItem.inventoryPrices = this.clone( await inventoryItem.inventoryPrices ); resubmitInventoryLineItem.reportedPrice = this.clone( inventoryItem.reportedPrice, inventoryResubmitInput.reportedPrice ); resubmitInventoryLineItem.reportingPartner = this.clone( await inventoryItem.reportingPartner ); return resubmitInventoryLineItem; } async updateInventory( customerId: string, partnerId: string, data: InventoryInput[] ): Promise<ServiceError[]> { let inventoryToCreate: Inventory[] = []; let sids: number[] = data.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to ili let options: FindOptions = { offset: 0, limit: 1000, filters: { sid: { operator: Operator.IN, values: sids } } }; let inventory: Inventory[] = await this.findNeedCorrectionInventory( customerId, partnerId, options ); let sidsToUpdate: number[] = []; errors = sids.map((sid) => { if (inventory) { let s: Inventory = inventory.find((inv: Inventory) => { return inv.sid.toString() === sid.toString(); }); if (s) { sidsToUpdate.push(sid); return null; } } return new ServiceError( 'INVENTORY_NOT_FOUND', `Inventory line sid : ${sid} not found` ); }); if (inventory && inventory.length > 0) { let invLineItems: Inventory[] = await this.repository .createQueryBuilder('inv') // load partner and gs number .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') // load dynamic attrs .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sidsToUpdate) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: inventory[0].customerSid }) .getMany(); await Promise.all( invLineItems.map(async (invLineItem) => { // load serial numbers let input: InventoryInput = data.find((inv: InventoryInput) => { return inv.sid.toString() === invLineItem.sid.toString(); }); invLineItem = Object.assign({}, invLineItem, input); // add inv line to list to write to S3. inventoryToCreate.push(invLineItem); }) ); console.log(`Inventory to write to S3 : ${inventoryToCreate.length}`); // Write to S3 if (inventoryToCreate.length > 0) { await this.writer.write( customerId, partnerId, this.getServiceName(), inventoryToCreate ); } // It is safe to delete from PEH after writing to S3, just in case if delete fails, // the inv will still be deleted from PEH the json file from S3 is loaded into nucleus. // If we delete first and for some reason the writing to S3 fails, there is no way to roll back the db update. await Promise.all( inventoryToCreate.map(async (invLineItem) => { try { // delete inventory line from PEH await AppDataSource.query( 'delete from peh_inv_queue where inv_line_item_sid = :sid', [invLineItem.sid] ); console.log(`Deleted line item : ${invLineItem.sid} from PEH`); } catch (e) { console.log( `Error while deleting from PEH for inv line : ${JSON.stringify( invLineItem )} for Customer : ${customerId}` ); console.error(e); // eat the error as if delete fails, the only con is User will still be able to see the inv line // until the file on S3 is loaded into nucleus } }) ); } return errors; } }
import { DomainEntityService } from '../base/DomainEntityService'; import { Inventory } from './Inventory'; import { Service, Inject } from 'typedi'; import { FindOptions } from '../base/FindOptions'; import { Equal, In } from 'typeorm'; import { ConfigurationService } from '../configuration/ConfigurationService'; import { CustomerService } from '../customer/CustomerService'; import { PartnerService } from '../partner/PartnerService'; import { DynamicAttrsService } from '../attribute/DynamicAttrsService'; import { DataFileService } from '../datafile/DataFileService'; import { SubmissionPeriodService } from '../submission/SubmissionPeriodService'; import { InventoryQuantityService } from './InventoryQuantityService'; import { InventoryPriceService } from './InventoryPriceService'; import { Writer } from '../../writer/Writer'; import { InventoryInput } from './InventoryInput'; import { ServiceError } from '../base/ServiceError'; import { Operator } from '../base/filters/Operator'; import { AppDataSource } from '../../platform/DataSource'; import { InventoryResubmitInput } from './InventoryResubmitInput'; const INVENTORY_RESUBMIT = 'InventoryResubmit'; @Service() export class InventoryService extends DomainEntityService<Inventory> { @Inject() protected configurationService: ConfigurationService; @Inject() protected customerService: CustomerService; @Inject() protected partnerService: PartnerService; @Inject() protected dynamicAttrsService: DynamicAttrsService; @Inject() protected dataFileService: DataFileService; @Inject() protected submissionPeriodService: SubmissionPeriodService; @Inject() protected inventoryQuantityService: InventoryQuantityService; @Inject() protected inventoryPriceService: InventoryPriceService; @Inject('Writer') protected writer: Writer; constructor() { super(Inventory); } getServiceName(): string { return 'Inventory'; } async findInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const config = await this.configurationService.getConfiguration(customerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('ili') .leftJoinAndSelect( 'ili.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'ili.dataFile', 'df', '"df"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'ili.onHandQuantity', 'ili.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'ili.onOrderQuantity', 'ili.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'ili.committedQuantity', 'ili.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'ili.floatQuantity', 'ili.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'ili.backorderedQuantity', 'ili.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'ili.returnedQuantity', 'ili.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'ili.inTransitQuantity', 'ili.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'ili.inStockQuantity', 'ili.inventoryQuantities', 'inStockInvQuantity', '"inStockInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'IN STOCK\')' ) .leftJoinAndMapOne( 'ili.damagedQuantity', 'ili.inventoryQuantities', 'damagedInvQuantity', '"damagedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'DAMAGED\')' ) .leftJoinAndMapOne( 'ili.transferredQuantity', 'ili.inventoryQuantities', 'transferredInvQuantity', '"transferredInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSFERRED\')' ) .leftJoinAndMapOne( 'ili.unitPrice', 'ili.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\')' ) .leftJoinAndMapOne( 'ili.bestFitPrice', 'ili.inventoryPrices', 'bestFitInvPrice', '"bestFitInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'BEST_FIT_PRICE\')' ) .leftJoinAndMapOne( 'ili.invConvertedPrice', 'ili.inventoryPrices', 'invConvertedInvPrice', '"invConvertedInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'INV_CONVERTED\')' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); quantityFiltersMap.set('inStockQuantity', 'inStockInvQuantity'); quantityFiltersMap.set('damagedQuantity', 'damagedInvQuantity'); quantityFiltersMap.set('transferredQuantity', 'transferredInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } this.buildWhere(filters, query); query .andWhere('"ili"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"ili"."CUSTOMER_SID" = ' + customer.sid); // add order by this.addOrderBys(query, sort); if (!PartnerService.isAll(partnerId)) { query.andWhere('"df"."REPORTING_PARTNER_SID" = ' + partner.sid); } const inventory = await query.getMany(); return this.loadIliValidationAggregation(inventory); } protected async loadIliValidationAggregation( inventory: Inventory[] ): Promise<Inventory[]> { if (inventory.length === 0) return inventory; // construct SQL const sql = ' select ' + ' ili.sid, count(iliv.inv_Line_item_sid) validationCodesCount ' + ' from inv_line_item ili ' + ' left join ili_validation iliv on iliv.inv_Line_item_sid = ili.sid ' + ' and iliv.customer_sid = ili.CUSTOMER_SID ' + ' where ili.customer_sid = :customersid and ili.sid in (:iliSids)' + ' group by ili.sid '; // execute SQL var rows = new Map(); for (var i = 0; i < inventory.length; i += 1000) { const iliSids = inventory.slice(i, i + 1000).map((s) => s.sid); //not a param to avoid bind var peaking var inListSql = sql.replace( ':customersid', inventory[0].customerSid.toString() as string ); inListSql = inListSql.replace(':iliSids', iliSids.join(',')); var results = await this.repository.query(inListSql); results.map((r) => { rows.set(r.SID, r.VALIDATIONCODESCOUNT); }); } // map SQL result return inventory.map((inventory) => { inventory.validationCodesCount = rows.get(inventory.sid); return inventory; }); } async findNeedCorrectionInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const config = await this.configurationService.getConfiguration(customerId); const queueName = config.get('needCorrectionInventoryQueueName', 'resign'); const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('inv') .leftJoinAndSelect( 'inv.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'inv.dataFile', 'df', '"df"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'inv.submissionPeriod', 'sp', '"sp"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'sp.submissionSchedule', 'ss', '"sp"."CUSTOMER_SID" = "ss"."CUSTOMER_SID"' ) .leftJoinAndSelect('ss.dataType', 'dt') .leftJoinAndSelect( 'sp.submissionPeriodLineItemView', 'spli', '"sp"."CUSTOMER_SID" = "spli"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .innerJoin( 'PEH_INV_QUEUE', 'piq', '"piq"."CLIENT_SKU" = "inv"."CLIENT_SKU" and "piq"."INV_LINE_ITEM_SID" = "inv"."SID" ' + 'and "piq"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } // add unit price condition const unitPriceFilters = filters['unitPrice']; delete filters['unitPrice']; if (unitPriceFilters) { const unitPriceWhere = this.inventoryPriceService.buildWhereExpression( unitPriceFilters, 'invPrice' ); query.andWhere(unitPriceWhere); } this.buildWhere(filters, query); query .andWhere('"inv"."CUSTOMER_SID" = ' + customer.sid) .andWhere('"inv"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"piq"."QUEUE_NAME" = \'' + queueName + "'") .andWhere({ deleted: Equal(0) }); if (!PartnerService.isAll(partnerId)) { query.andWhere('"inv"."REPORTING_PARTNER_SID" = ' + partner.sid); } // add order by this.addOrderBys(query, sort); return query.getMany(); } async resubmitInventory( customerId: string, partnerId: string, inputs: Partial<InventoryResubmitInput>[] ): Promise<ServiceError[]> { // Check input array size if (inputs.length === 0) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', 'No inventory items provided for resubmission.' ) ]; } //Inventory Item Limit Check if (inputs.length > 1000) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `The number of inventory items exceeds the limit of 1000.` ) ]; } const sids: number[] = inputs.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to inventory items const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `Customer ${customerId} or partner ${partnerId} are invalid.` ) ]; } // Query to fetch inventory items with required joins let inventoryItems: Inventory[] = await this.repository .createQueryBuilder('inv') .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = (SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sids) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: customer.sid }) .getMany(); let inventoryItemMap = new Map( inventoryItems.map((inventoryItem) => [ Number(inventoryItem.sid), inventoryItem ]) ); let inventoryItemsToResubmit = []; errors = await Promise.all( inputs.map(async (inventoryResubmitInput) => { const inventoryItem = inventoryItemMap.get( Number(inventoryResubmitInput.sid) ); if (inventoryItem) { let resubmitInventoryItem = await this.loadResubmitInventoryLineItemRefs( inventoryItem, inventoryResubmitInput ); inventoryItemsToResubmit.push(resubmitInventoryItem); return null; } else { return new ServiceError( 'INVENTORY_ITEM_ERR', `Inventory Item with IID ${inventoryResubmitInput.sid} not found. Please check the input data.` ); } }) ); console.log(sids) let partnerIdResult = await this.repository .createQueryBuilder('ili') .innerJoin('ili.reportingPartner','rp') .innerJoin('ili.customer', 'c') .where('ili.sid = :sids' , {sids : sids[0]}) .andWhere('ili.CUSTOMER_SID = :customerSid', { customerSid: customer.sid }).select('rp.id').getRawOne(); let reportingPartnerId: string = ''; if (partnerIdResult) { reportingPartnerId = String(partnerIdResult['rp_ID']); } else { console.log('No reporting partner ID found'); errors.push(new ServiceError( 'INVENTORY_ITEM_ERR', `Inventory Item with IID ${sids[0]} not found. Please check the input data.` )); } // Write to S3 or perform further operations with resubmitted inventory items console.log( `Inventory items to resubmit: ${inventoryItemsToResubmit.length}` ); if (inventoryItemsToResubmit.length > 0) { // Example: Write to a service or perform operations with resubmitted inventory items await this.writer.write2( customerId, reportingPartnerId, INVENTORY_RESUBMIT, inventoryItemsToResubmit ); } return errors; } clone(...objs) { return Object.assign({}, ...objs); } async loadResubmitInventoryLineItemRefs( inventoryItem: Inventory, inventoryResubmitInput: Partial<InventoryResubmitInput> ): Promise<Inventory> { let resubmitInventoryLineItem: Inventory = this.clone( inventoryItem, inventoryResubmitInput ); resubmitInventoryLineItem.dynamicAttrs = this.clone( await inventoryItem.dynamicAttrs, inventoryResubmitInput.dynamicAttrs ); resubmitInventoryLineItem.onHandQuantity = this.clone( inventoryItem.onHandQuantity, inventoryResubmitInput.onHandQuantity ); resubmitInventoryLineItem.onOrderQuantity = this.clone( inventoryItem.onOrderQuantity, inventoryResubmitInput.onOrderQuantity ); resubmitInventoryLineItem.committedQuantity = this.clone( inventoryItem.committedQuantity, inventoryResubmitInput.committedQuantity ); resubmitInventoryLineItem.backorderedQuantity = this.clone( inventoryItem.backorderedQuantity, inventoryResubmitInput.backorderedQuantity ); resubmitInventoryLineItem.returnedQuantity = this.clone( inventoryItem.returnedQuantity, inventoryResubmitInput.returnedQuantity ); resubmitInventoryLineItem.inTransitQuantity = this.clone( inventoryItem.inTransitQuantity, inventoryResubmitInput.inTransitQuantity ); resubmitInventoryLineItem.inStockQuantity = this.clone( inventoryItem.inStockQuantity, inventoryResubmitInput.inStockQuantity ); resubmitInventoryLineItem.damagedQuantity = this.clone( inventoryItem.damagedQuantity, inventoryResubmitInput.damagedQuantity ); resubmitInventoryLineItem.transferredQuantity = this.clone( inventoryItem.transferredQuantity, inventoryResubmitInput.transferredQuantity ); resubmitInventoryLineItem.inventoryPrices = this.clone( await inventoryItem.inventoryPrices ); resubmitInventoryLineItem.reportedPrice = this.clone( inventoryItem.reportedPrice, inventoryResubmitInput.reportedPrice ); resubmitInventoryLineItem.reportingPartner = this.clone( await inventoryItem.reportingPartner ); return resubmitInventoryLineItem; } async updateInventory( customerId: string, partnerId: string, data: InventoryInput[] ): Promise<ServiceError[]> { let inventoryToCreate: Inventory[] = []; let sids: number[] = data.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to ili let options: FindOptions = { offset: 0, limit: 1000, filters: { sid: { operator: Operator.IN, values: sids } } }; let inventory: Inventory[] = await this.findNeedCorrectionInventory( customerId, partnerId, options ); let sidsToUpdate: number[] = []; errors = sids.map((sid) => { if (inventory) { let s: Inventory = inventory.find((inv: Inventory) => { return inv.sid.toString() === sid.toString(); }); if (s) { sidsToUpdate.push(sid); return null; } } return new ServiceError( 'INVENTORY_NOT_FOUND', `Inventory line sid : ${sid} not found` ); }); if (inventory && inventory.length > 0) { let invLineItems: Inventory[] = await this.repository .createQueryBuilder('inv') // load partner and gs number .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') // load dynamic attrs .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sidsToUpdate) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: inventory[0].customerSid }) .getMany(); await Promise.all( invLineItems.map(async (invLineItem) => { // load serial numbers let input: InventoryInput = data.find((inv: InventoryInput) => { return inv.sid.toString() === invLineItem.sid.toString(); }); invLineItem = Object.assign({}, invLineItem, input); // add inv line to list to write to S3. inventoryToCreate.push(invLineItem); }) ); console.log(`Inventory to write to S3 : ${inventoryToCreate.length}`); // Write to S3 if (inventoryToCreate.length > 0) { await this.writer.write( customerId, partnerId, this.getServiceName(), inventoryToCreate ); } // It is safe to delete from PEH after writing to S3, just in case if delete fails, // the inv will still be deleted from PEH the json file from S3 is loaded into nucleus. // If we delete first and for some reason the writing to S3 fails, there is no way to roll back the db update. await Promise.all( inventoryToCreate.map(async (invLineItem) => { try { // delete inventory line from PEH await AppDataSource.query( 'delete from peh_inv_queue where inv_line_item_sid = :sid', [invLineItem.sid] ); console.log(`Deleted line item : ${invLineItem.sid} from PEH`); } catch (e) { console.log( `Error while deleting from PEH for inv line : ${JSON.stringify( invLineItem )} for Customer : ${customerId}` ); console.error(e); // eat the error as if delete fails, the only con is User will still be able to see the inv line // until the file on S3 is loaded into nucleus } }) ); } return errors; } }
import { DomainEntityService } from '../base/DomainEntityService'; import { Inventory } from './Inventory'; import { Service, Inject } from 'typedi'; import { FindOptions } from '../base/FindOptions'; import { Equal, In } from 'typeorm'; import { ConfigurationService } from '../configuration/ConfigurationService'; import { CustomerService } from '../customer/CustomerService'; import { PartnerService } from '../partner/PartnerService'; import { DynamicAttrsService } from '../attribute/DynamicAttrsService'; import { DataFileService } from '../datafile/DataFileService'; import { SubmissionPeriodService } from '../submission/SubmissionPeriodService'; import { InventoryQuantityService } from './InventoryQuantityService'; import { InventoryPriceService } from './InventoryPriceService'; import { Writer } from '../../writer/Writer'; import { InventoryInput } from './InventoryInput'; import { ServiceError } from '../base/ServiceError'; import { Operator } from '../base/filters/Operator'; import { AppDataSource } from '../../platform/DataSource'; import { InventoryResubmitInput } from './InventoryResubmitInput'; const INVENTORY_RESUBMIT = 'InventoryResubmit'; @Service() export class InventoryService extends DomainEntityService<Inventory> { @Inject() protected configurationService: ConfigurationService; @Inject() protected customerService: CustomerService; @Inject() protected partnerService: PartnerService; @Inject() protected dynamicAttrsService: DynamicAttrsService; @Inject() protected dataFileService: DataFileService; @Inject() protected submissionPeriodService: SubmissionPeriodService; @Inject() protected inventoryQuantityService: InventoryQuantityService; @Inject() protected inventoryPriceService: InventoryPriceService; @Inject('Writer') protected writer: Writer; constructor() { super(Inventory); } getServiceName(): string { return 'Inventory'; } async findInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const config = await this.configurationService.getConfiguration(customerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('ili') .leftJoinAndSelect( 'ili.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'ili.dataFile', 'df', '"df"."CUSTOMER_SID" = "ili"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'ili.onHandQuantity', 'ili.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'ili.onOrderQuantity', 'ili.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'ili.committedQuantity', 'ili.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'ili.floatQuantity', 'ili.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'ili.backorderedQuantity', 'ili.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'ili.returnedQuantity', 'ili.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'ili.inTransitQuantity', 'ili.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'ili.inStockQuantity', 'ili.inventoryQuantities', 'inStockInvQuantity', '"inStockInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'IN STOCK\')' ) .leftJoinAndMapOne( 'ili.damagedQuantity', 'ili.inventoryQuantities', 'damagedInvQuantity', '"damagedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'DAMAGED\')' ) .leftJoinAndMapOne( 'ili.transferredQuantity', 'ili.inventoryQuantities', 'transferredInvQuantity', '"transferredInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSFERRED\')' ) .leftJoinAndMapOne( 'ili.unitPrice', 'ili.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\')' ) .leftJoinAndMapOne( 'ili.bestFitPrice', 'ili.inventoryPrices', 'bestFitInvPrice', '"bestFitInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'BEST_FIT_PRICE\')' ) .leftJoinAndMapOne( 'ili.invConvertedPrice', 'ili.inventoryPrices', 'invConvertedInvPrice', '"invConvertedInvPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'INV_CONVERTED\')' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); quantityFiltersMap.set('inStockQuantity', 'inStockInvQuantity'); quantityFiltersMap.set('damagedQuantity', 'damagedInvQuantity'); quantityFiltersMap.set('transferredQuantity', 'transferredInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } this.buildWhere(filters, query); query .andWhere('"ili"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"ili"."CUSTOMER_SID" = ' + customer.sid); // add order by this.addOrderBys(query, sort); if (!PartnerService.isAll(partnerId)) { query.andWhere('"df"."REPORTING_PARTNER_SID" = ' + partner.sid); } const inventory = await query.getMany(); return this.loadIliValidationAggregation(inventory); } protected async loadIliValidationAggregation( inventory: Inventory[] ): Promise<Inventory[]> { if (inventory.length === 0) return inventory; // construct SQL const sql = ' select ' + ' ili.sid, count(iliv.inv_Line_item_sid) validationCodesCount ' + ' from inv_line_item ili ' + ' left join ili_validation iliv on iliv.inv_Line_item_sid = ili.sid ' + ' and iliv.customer_sid = ili.CUSTOMER_SID ' + ' where ili.customer_sid = :customersid and ili.sid in (:iliSids)' + ' group by ili.sid '; // execute SQL var rows = new Map(); for (var i = 0; i < inventory.length; i += 1000) { const iliSids = inventory.slice(i, i + 1000).map((s) => s.sid); //not a param to avoid bind var peaking var inListSql = sql.replace( ':customersid', inventory[0].customerSid.toString() as string ); inListSql = inListSql.replace(':iliSids', iliSids.join(',')); var results = await this.repository.query(inListSql); results.map((r) => { rows.set(r.SID, r.VALIDATIONCODESCOUNT); }); } // map SQL result return inventory.map((inventory) => { inventory.validationCodesCount = rows.get(inventory.sid); return inventory; }); } async findNeedCorrectionInventory( customerId: string, partnerId: string, options: FindOptions = new FindOptions() ): Promise<Inventory[]> { const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); const { offset, limit, filters = {}, sort } = options; if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return Promise.resolve([]); } const config = await this.configurationService.getConfiguration(customerId); const queueName = config.get('needCorrectionInventoryQueueName', 'resign'); const maxAge = config.get('nmiMaxAgeInDays', '30'); const query = this.repository .createQueryBuilder('inv') .leftJoinAndSelect( 'inv.dynamicAttrs', 'da', '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .innerJoinAndSelect( 'inv.dataFile', 'df', '"df"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'inv.submissionPeriod', 'sp', '"sp"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .leftJoinAndSelect( 'sp.submissionSchedule', 'ss', '"sp"."CUSTOMER_SID" = "ss"."CUSTOMER_SID"' ) .leftJoinAndSelect('ss.dataType', 'dt') .leftJoinAndSelect( 'sp.submissionPeriodLineItemView', 'spli', '"sp"."CUSTOMER_SID" = "spli"."CUSTOMER_SID"' ) .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' + 'NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .innerJoin( 'PEH_INV_QUEUE', 'piq', '"piq"."CLIENT_SKU" = "inv"."CLIENT_SKU" and "piq"."INV_LINE_ITEM_SID" = "inv"."SID" ' + 'and "piq"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"' ) .offset(offset) .limit(limit); // add filters for quantity filters let quantityFiltersMap = new Map(); quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity'); quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity'); quantityFiltersMap.set('committedQuantity', 'committedInvQuantity'); quantityFiltersMap.set('floatQuantity', 'floatInvQuantity'); quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity'); quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity'); quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity'); for (let [key, value] of quantityFiltersMap) { const quantityFilters = filters[key]; delete filters[key]; if (quantityFilters) { const quantityWhere = this.inventoryQuantityService.buildWhereExpression( quantityFilters, value ); query.andWhere(quantityWhere); } } // add unit price condition const unitPriceFilters = filters['unitPrice']; delete filters['unitPrice']; if (unitPriceFilters) { const unitPriceWhere = this.inventoryPriceService.buildWhereExpression( unitPriceFilters, 'invPrice' ); query.andWhere(unitPriceWhere); } this.buildWhere(filters, query); query .andWhere('"inv"."CUSTOMER_SID" = ' + customer.sid) .andWhere('"inv"."INVENTORY_DATE" >= sysdate - ' + maxAge) .andWhere('"piq"."QUEUE_NAME" = \'' + queueName + "'") .andWhere({ deleted: Equal(0) }); if (!PartnerService.isAll(partnerId)) { query.andWhere('"inv"."REPORTING_PARTNER_SID" = ' + partner.sid); } // add order by this.addOrderBys(query, sort); return query.getMany(); } async resubmitInventory( customerId: string, partnerId: string, inputs: Partial<InventoryResubmitInput>[] ): Promise<ServiceError[]> { // Check input array size if (inputs.length === 0) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', 'No inventory items provided for resubmission.' ) ]; } //Inventory Item Limit Check if (inputs.length > 1000) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `The number of inventory items exceeds the limit of 1000.` ) ]; } const sids: number[] = inputs.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to inventory items const customer = await this.customerService.findOneById(customerId); const partner = await this.partnerService.findOneById(partnerId); if (!customer || (!partner && !PartnerService.isAll(partnerId))) { return [ new ServiceError( 'INVENTORY_ITEM_ERR', `Customer ${customerId} or partner ${partnerId} are invalid.` ) ]; } // Query to fetch inventory items with required joins let inventoryItems: Inventory[] = await this.repository .createQueryBuilder('inv') .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = (SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = (SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sids) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: customer.sid }) .getMany(); let inventoryItemMap = new Map( inventoryItems.map((inventoryItem) => [ Number(inventoryItem.sid), inventoryItem ]) ); let inventoryItemsToResubmit = []; errors = await Promise.all( inputs.map(async (inventoryResubmitInput) => { const inventoryItem = inventoryItemMap.get( Number(inventoryResubmitInput.sid) ); if (inventoryItem) { let resubmitInventoryItem = await this.loadResubmitInventoryLineItemRefs( inventoryItem, inventoryResubmitInput ); inventoryItemsToResubmit.push(resubmitInventoryItem); return null; } else { return new ServiceError( 'INVENTORY_ITEM_ERR', `Inventory Item with IID ${inventoryResubmitInput.sid} not found. Please check the input data.` ); } }) ); let partnerIdResult = await this.repository .createQueryBuilder('ili') .innerJoin('ili.reportingPartner','rp') .innerJoin('ili.customer', 'c') .where('ili.sid = :sids' , {sids : sids[0]}) .andWhere('ili.CUSTOMER_SID = :customerSid', { customerSid: customer.sid }).select('rp.id').getRawOne(); let rpid: string = ''; if (partnerIdResult) { rpid = String(partnerIdResult['rp_ID']); // Convert the ID to a string console.log('rpid as string:', rpid); // Log the string value } else { console.log('No reporting partner ID found'); } // Write to S3 or perform further operations with resubmitted inventory items console.log( `Inventory items to resubmit: ${inventoryItemsToResubmit.length}` ); if (inventoryItemsToResubmit.length > 0) { // Example: Write to a service or perform operations with resubmitted inventory items await this.writer.write2( customerId, rpid, INVENTORY_RESUBMIT, inventoryItemsToResubmit ); } return errors; } clone(...objs) { return Object.assign({}, ...objs); } async loadResubmitInventoryLineItemRefs( inventoryItem: Inventory, inventoryResubmitInput: Partial<InventoryResubmitInput> ): Promise<Inventory> { let resubmitInventoryLineItem: Inventory = this.clone( inventoryItem, inventoryResubmitInput ); resubmitInventoryLineItem.dynamicAttrs = this.clone( await inventoryItem.dynamicAttrs, inventoryResubmitInput.dynamicAttrs ); resubmitInventoryLineItem.onHandQuantity = this.clone( inventoryItem.onHandQuantity, inventoryResubmitInput.onHandQuantity ); resubmitInventoryLineItem.onOrderQuantity = this.clone( inventoryItem.onOrderQuantity, inventoryResubmitInput.onOrderQuantity ); resubmitInventoryLineItem.committedQuantity = this.clone( inventoryItem.committedQuantity, inventoryResubmitInput.committedQuantity ); resubmitInventoryLineItem.backorderedQuantity = this.clone( inventoryItem.backorderedQuantity, inventoryResubmitInput.backorderedQuantity ); resubmitInventoryLineItem.returnedQuantity = this.clone( inventoryItem.returnedQuantity, inventoryResubmitInput.returnedQuantity ); resubmitInventoryLineItem.inTransitQuantity = this.clone( inventoryItem.inTransitQuantity, inventoryResubmitInput.inTransitQuantity ); resubmitInventoryLineItem.inStockQuantity = this.clone( inventoryItem.inStockQuantity, inventoryResubmitInput.inStockQuantity ); resubmitInventoryLineItem.damagedQuantity = this.clone( inventoryItem.damagedQuantity, inventoryResubmitInput.damagedQuantity ); resubmitInventoryLineItem.transferredQuantity = this.clone( inventoryItem.transferredQuantity, inventoryResubmitInput.transferredQuantity ); resubmitInventoryLineItem.inventoryPrices = this.clone( await inventoryItem.inventoryPrices ); resubmitInventoryLineItem.reportedPrice = this.clone( inventoryItem.reportedPrice, inventoryResubmitInput.reportedPrice ); resubmitInventoryLineItem.reportingPartner = this.clone( await inventoryItem.reportingPartner ); return resubmitInventoryLineItem; } async updateInventory( customerId: string, partnerId: string, data: InventoryInput[] ): Promise<ServiceError[]> { let inventoryToCreate: Inventory[] = []; let sids: number[] = data.map((input: InventoryInput) => { return input.sid; }); let errors: ServiceError[] = []; // Check if partner has access to ili let options: FindOptions = { offset: 0, limit: 1000, filters: { sid: { operator: Operator.IN, values: sids } } }; let inventory: Inventory[] = await this.findNeedCorrectionInventory( customerId, partnerId, options ); let sidsToUpdate: number[] = []; errors = sids.map((sid) => { if (inventory) { let s: Inventory = inventory.find((inv: Inventory) => { return inv.sid.toString() === sid.toString(); }); if (s) { sidsToUpdate.push(sid); return null; } } return new ServiceError( 'INVENTORY_NOT_FOUND', `Inventory line sid : ${sid} not found` ); }); if (inventory && inventory.length > 0) { let invLineItems: Inventory[] = await this.repository .createQueryBuilder('inv') // load partner and gs number .innerJoinAndSelect('inv.reportingPartner', 'rp') .leftJoinAndSelect('rp.gsNumbers', 'gs') // load dynamic attrs .leftJoinAndSelect('inv.dynamicAttrs', 'da') .leftJoinAndMapOne( 'inv.onHandQuantity', 'inv.inventoryQuantities', 'onHandInvQuantity', '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')' ) .leftJoinAndMapOne( 'inv.onOrderQuantity', 'inv.inventoryQuantities', 'onOrderInvQuantity', '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')' ) .leftJoinAndMapOne( 'inv.committedQuantity', 'inv.inventoryQuantities', 'committedInvQuantity', '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')' ) .leftJoinAndMapOne( 'inv.floatQuantity', 'inv.inventoryQuantities', 'floatInvQuantity', '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')' ) .leftJoinAndMapOne( 'inv.backorderedQuantity', 'inv.inventoryQuantities', 'backorderedInvQuantity', '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')' ) .leftJoinAndMapOne( 'inv.returnedQuantity', 'inv.inventoryQuantities', 'returnedInvQuantity', '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')' ) .leftJoinAndMapOne( 'inv.inTransitQuantity', 'inv.inventoryQuantities', 'inTransitInvQuantity', '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')' ) .leftJoinAndMapOne( 'inv.unitPrice', 'inv.inventoryPrices', 'invPrice', '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0' ) .where({ sid: In(sidsToUpdate) }) .andWhere('"gs"."CUSTOMER_SID" = :customerSid', { customerSid: inventory[0].customerSid }) .getMany(); await Promise.all( invLineItems.map(async (invLineItem) => { // load serial numbers let input: InventoryInput = data.find((inv: InventoryInput) => { return inv.sid.toString() === invLineItem.sid.toString(); }); invLineItem = Object.assign({}, invLineItem, input); // add inv line to list to write to S3. inventoryToCreate.push(invLineItem); }) ); console.log(`Inventory to write to S3 : ${inventoryToCreate.length}`); // Write to S3 if (inventoryToCreate.length > 0) { await this.writer.write( customerId, partnerId, this.getServiceName(), inventoryToCreate ); } // It is safe to delete from PEH after writing to S3, just in case if delete fails, // the inv will still be deleted from PEH the json file from S3 is loaded into nucleus. // If we delete first and for some reason the writing to S3 fails, there is no way to roll back the db update. await Promise.all( inventoryToCreate.map(async (invLineItem) => { try { // delete inventory line from PEH await AppDataSource.query( 'delete from peh_inv_queue where inv_line_item_sid = :sid', [invLineItem.sid] ); console.log(`Deleted line item : ${invLineItem.sid} from PEH`); } catch (e) { console.log( `Error while deleting from PEH for inv line : ${JSON.stringify( invLineItem )} for Customer : ${customerId}` ); console.error(e); // eat the error as if delete fails, the only con is User will still be able to see the inv line // until the file on S3 is loaded into nucleus } }) ); } return errors; } }
{email:/.*orellana.*/}
package com.modeln.cdm.service.translation; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.infonow.service.recovery.RecoveryQueries; import org.json.JSONException; import org.json.JSONObject; import com.infonow.service.recovery.TranslationOrphanStatusEnum; import com.infonow.crux.dao.InowProfileDao; import com.infonow.crux.impl.InowProfileImpl; import com.infonow.framework.service.ServiceResponse; import com.infonow.framework.service.configuration.support.ServiceDefinition; import com.infonow.framework.service.context.ServiceContext; import com.infonow.framework.service.support.ServiceException; import com.infonow.service.configuration.ConfigurationException; import com.infonow.service.configuration.impl.AbstractBaseServiceWithConfiguration; import com.infonow.service.recovery.TranslationOrphan; import com.modeln.cdm.integration.aws.AmazonSNSClientImpl; import com.modeln.cdm.service.translation.configuration.TranslationConfguration; import software.amazon.awssdk.utils.StringUtils; @ServiceDefinition(name = "translationService", abstraction = com.modeln.cdm.service.translation.TranslationService.class, implementation = com.modeln.cdm.service.translation.TranslationServiceImpl.class) public class TranslationServiceImpl extends AbstractBaseServiceWithConfiguration implements TranslationService { private InowProfileRelationService inowProfileRelationService; private RecoveryQueries recoveryQueries; private AmazonSNSClientImpl awsSnsClient; private String awsSnsTopic; private InowProfileDao inowProfileDao; private static String UNWANTED_CHARS; private static String LATIN_CHARS; private static Pattern UNWANTED_PATTERN; private static Pattern LATIN_PATTERN; private TranslationConfguration translationConfig; Matcher matcher; public TranslationServiceImpl() { if (UNWANTED_CHARS == null) { UNWANTED_CHARS = "[\\u0020-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E\\u0030-\\u0039\\u00A0-\\u00BF\\u2013-\\u204A]"; } if (LATIN_CHARS == null) { LATIN_CHARS = "[\\u0041-\\u005A\\u0061-\\u007A\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\uFF00-\\uFF60]+"; } if (UNWANTED_PATTERN == null) { UNWANTED_PATTERN = Pattern.compile(UNWANTED_CHARS); } if (LATIN_PATTERN == null) { LATIN_PATTERN = Pattern.compile(LATIN_CHARS); } } public RecoveryQueries getRecoveryQueries() { if (recoveryQueries == null) { throw new IllegalStateException("The attribute _recoveryQueries can not be null"); } return recoveryQueries; } public void setRecoveryQueries(RecoveryQueries recoveryQueries) { this.recoveryQueries = recoveryQueries; } @SuppressWarnings("unchecked") @Override public ServiceResponse execute(ServiceContext serviceContext, Object userObject, Object userData) throws ServiceException { if (!(userData instanceof List<?>)) { throw new IllegalArgumentException("Argument userData must be a List but was " + userData == null ? null : userData.getClass().getName()); } List<TranslationOrphan> ids = ((List<TranslationOrphan>) userData); List<JSONObject> addrs = new ArrayList<JSONObject>(); translationConfig = getTranslationConfig(); List<Long> inProgressIds = new ArrayList<Long>(); for (int i = 0; i < ids.size(); i++) { Long sid = ids.get(i).getSid(); InowProfileImpl inowProfile = (InowProfileImpl) getInowProfileDao().getBySid(ids.get(i).getInowProfileSid()); boolean entityNeedsTranslation = isNonLatin(inowProfile.getName()); String address = inowProfile.getStreet1() + inowProfile.getStreet2() + inowProfile.getCity() + inowProfile.getStateProvince() + inowProfile.getPostalCode(); boolean addressNeedsTranslation = isNonLatin(address); JSONObject addr = createTranslationInput(inowProfile, entityNeedsTranslation, addressNeedsTranslation); if (addr != null) { addrs.add(addr); inProgressIds.add(sid); } } if(inProgressIds.size() > 0) { for(int j = 0; j<inProgressIds.size();j++){ ids.remove(inProgressIds.get(j)); } } if (!addrs.isEmpty()) { publish(addrs); changeStatus(inProgressIds, TranslationOrphanStatusEnum.IN_PROGRESS.name()); } return new ServiceResponse("Success", ServiceResponse.SUCCESS); } public void changeStatus(List<Long> inProgressIds, String status) { getRecoveryQueries().updateStatusTranslationOrphans(status, inProgressIds); } protected JSONObject createTranslationInput(InowProfileImpl inowProfile, boolean entityNeedsTranslation, boolean addressNeedsTranslation) throws ServiceException { JSONObject addr = null; if ((entityNeedsTranslation || addressNeedsTranslation) && isTranslationNeededForCountry(inowProfile.getCountryObject().getTwoCharCode()) && !isInowRelationAlreadyExists(inowProfile)) { addr = new JSONObject(); try { addr.put("id", inowProfile.getIdentifier()); JSONObject addrDetails = new JSONObject(); if (entityNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getName())) { addrDetails.put("name", inowProfile.getName()); } } if (addressNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getStreet1())) { addrDetails.put("street1", inowProfile.getStreet1()); } if (!StringUtils.isEmpty(inowProfile.getStreet2())) { addrDetails.put("street2", inowProfile.getStreet2()); } if (!StringUtils.isEmpty(inowProfile.getCity())) { addrDetails.put("city", inowProfile.getCity()); } if (!StringUtils.isEmpty(inowProfile.getStateProvince())) { addrDetails.put("stateprovince", inowProfile.getStateProvince()); } if (!StringUtils.isEmpty(inowProfile.getPostalCode())) { addrDetails.put("postalcode", inowProfile.getPostalCode()); } if (!StringUtils.isEmpty(inowProfile.getCountry())) { addrDetails.put("country", inowProfile.getCountryObject().getTwoCharCode()); } } addr.put("query", addrDetails); addr.put("target", "EN"); } catch (JSONException e) { throw new ServiceException("Exception while converting InowProfile to JSONObject" + e); } } return addr; } public void publish(List<JSONObject> addrs) throws ServiceException { try { getAwsSnsClient().publishSingleMessages(getAwsSnsTopic(), addrs); } catch (Exception e) { throw new ServiceException("Exception while publishing message to Amazon SNS", e); } } private boolean isTranslationNeededForCountry(String country) { return translationConfig.getCountries().contains(country); } private boolean isNonLatin(String addressComponent) { addressComponent = addressComponent.replace("null", ""); matcher = UNWANTED_PATTERN.matcher(addressComponent); String fulladdress = matcher.replaceAll(""); if (StringUtils.isEmpty(fulladdress)) { return false; } String latinAddress = ""; matcher = LATIN_PATTERN.matcher(fulladdress); while (matcher.find()) { latinAddress += matcher.group(); } float matchPercent = (latinAddress.length() * 100 / fulladdress.length()); return matchPercent < translationConfig.getThreshold(); } private boolean isInowRelationAlreadyExists(InowProfileImpl inowProfile) { return getInowProfileRelationService().isRelationExists(inowProfile.getSid()); } private TranslationConfguration getTranslationConfig() { ServiceContext configContext = new ServiceContext(null, null); try { return (TranslationConfguration) getRequiredConfiguration(configContext); } catch (ConfigurationException e) { throw new IllegalStateException(e); } } public AmazonSNSClientImpl getAwsSnsClient() { return awsSnsClient; } public void setAwsSnsClient(AmazonSNSClientImpl awsSnsClient) { this.awsSnsClient = awsSnsClient; } public String getAwsSnsTopic() { return awsSnsTopic; } public void setAwsSnsTopic(String awsSnsTopic) { this.awsSnsTopic = awsSnsTopic; } public InowProfileDao getInowProfileDao() { return inowProfileDao; } public void setInowProfileDao(InowProfileDao inowProfileDao) { this.inowProfileDao = inowProfileDao; } public InowProfileRelationService getInowProfileRelationService() { return inowProfileRelationService; } public void setInowProfileRelationService(InowProfileRelationService inowProfileRelationService) { this.inowProfileRelationService = inowProfileRelationService; } }
SELECT CASE WHEN column1 IS NULL OR column1 = 0 THEN column2 ELSE column1 END AS result_column FROM example_table; SELECT COALESCE(NULLIF(column1, 0), column2) AS result_column FROM example_table; AND CAST(CC.EDITDATE AS DATE) > CAST(DATEADD(DAY, -1, GETDATE()) AS DATE) --AND CONVERT(DATE,(CC.EDITDATE)) = CONVERT(DATE, DATEADD(DAY, -30 , GETDATE()))
WITH RECURSIVE date_range AS ( SELECT date'2019-01-03' dateval, 0 mes /*start date, use cast(? as date) if you need a parameter */ FROM rdb$database UNION ALL SELECT DATEADD(MONTH,1,dateval), mes + 1 FROM date_range WHERE mes < 12 /* end date */ ) SELECT * FROM date_range;
SHOW search_path; SET search_path TO Schema1, public;
INSERT INTO `logs` (`id`, `Log`, `Info`, `Ip`, `Date`, `sn`) VALUES (NULL, '<a href=\"?limit=1000&player=Sam_Mason\"><strong>Sam_Mason</strong></a> Получил Анти-Варн', '<code><strong>I:</strong></code> <code>200,000,000</code> / <code>500,000,000</code> / <code>10000</code>', '<td><div class=\"table-ip\"><strong><code>I:</code></strong><span class=\"badge badge-secondary\">127.0.1.1</span><span class=\"badge badge-primary\">127.0.0.1</span></div><div class=\"table-ip\"><strong><code>II:</code></strong> <span class=\"badge badge-secondary\">127.0.0.1</span><span class=\"badge badge-primary\">127.0.0.1</span></div></td>', '2024-06-28 05:00:00', '1')
The Alphacodez Cryptocurrency Exchange Script is a robust solution for launching secure and efficient trading platforms, featuring user management, a high-performance trading engine, and wallet integration. It offers advanced security measures and customization options. Ongoing support and maintenance ensure smooth operation.
SELECT uid, pid, ExtractValue(pi_flexform,'//field[@index="settings.flexform.sender.subject"]/value') as psubject, ExtractValue(pi_flexform,'//field[@index="settings.flexform.main.form"]/value') as pform FRoM tt_content WHERE CType LIKE "%powermail%" OR list_type LIKE "%powermail%"
EXEC sp_spaceused N'[dbo].[MY_TABLE]'
package com.modeln.cdm.service.translation; public enum TranslationOrphanStatusEnum { PENDING, IN_PROGRESS; }
/** * RecoveryQueriesImpl.java $Revision$ * * Copyright (c) 2005-2008 InfoNow Corporation. All rights reserved. * INFONOW PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.infonow.service.recovery; import com.infonow.crux.DataFile; import com.infonow.crux.composite.CompositeAccountClassificationOrphan; import com.infonow.crux.dao.jdbc.mapper.GenericMapper; import com.infonow.crux.dao.jdbc.mapper.GenericRowMapper; import com.infonow.crux.dataFile.DataFileOrphanId; import com.infonow.crux.learning.LearnedName; import com.infonow.crux.learning.LearnedName.ApprovalStatus; import com.infonow.crux.learning.LearnedNameOrphan; import com.infonow.crux.schedule.submissionSchedule.SubmissionScheduleOrphan; import com.infonow.crux.sqlGeneration.SqlGenerationUtils; import com.infonow.crux.util.CollectionUtils; import com.infonow.crux.util.Constants.DataAddressTypeEnum; import com.infonow.framework.logging.Logger; import com.infonow.framework.util.spring.JdbcTemplateProxy; import com.infonow.framework.util.spring.NamedParameterJdbcTemplateProxy; import com.infonow.service.submissionPeriodUpdate.SubmissionPeriodUpdateOrphanId; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang.StringUtils; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; /** * Query implementations for the recovery service. * * @author Chris Lambrecht * * @version $Revision$ */ @SuppressWarnings("rawtypes") public class RecoveryQueriesImpl implements RecoveryQueries { private static final Logger LOG = Logger.getLogger(RecoveryQueriesImpl.class.getName()); private static final String DELETE_RL_ORPHAN = "delete from rl_orphans where master_run_id = ?"; private final RowMapper SID_MAPPER = new SidRowMapper(); private final RowMapper LINE_ITEM_MAPPER = new LineItemRowMapper(); private final RowMapper VALIDATION_ITEM_MAPPER = new ValidationRowMapper(); private final RowMapper SERIAL_NUMBER_MAPPER = new SerialNumberRowMapper(); private final RowMapper TUPPLE_MAPPER = new TupleMapper(); private final RowMapper SLIA_MAPPER = new SliaProfileMapper(); private final RowMapper INOW_PROFILE_HIERARCHY_MAPPER = new InowProfileHierarchyRowMapper(); private final RowMapper HIERARCHY_PARENT_MAPPER = new HierarchyParentMapper(); private final RowMapper ADDRESS_HISTORY_MAPPER = new AddressHistoryMapper(); private final RowMapper INOW_PROFILE_MAPPER = new InowProfileRowMapper(); private final RowMapper SALES_LINE_ITEM_NORMALIZATION_MAPPER = new SalesLineItemNormalizationRowMapper(); private final RowMapper REPORTING_PARTNER_MAPPER = new ReportingPartnerRowMapper(); private final RowMapper PROFILE_PARTNER_MAPPER = new ProfilePartnerRowMapper(); private final RowMapper EXPORTER_ORPHAN_MAPPER = new ExporterOrphanRowMapper(); private final RowMapper COMPOSITE_ACCOUNT_CLASS_ORPHAN_MAPPER = new CompositeAccountClassificationOrphanMapper(); private final RowMapper SUBMISSION_SCHEDULE_ORPHAN_MAPPER = new SubmissionScheduleOrphanMapper(); private final RowMapper LEARNED_NAME_ORPHAN_MAPPER = new LearnedNameOrphanMapper(); private final RowMapper INOW_STANDARDIZATION_ORPHAN_MAPPER = new InowStandardizationOrphanMapper(); private final RowMapper INOW_TRANSLATION_ORPHAN_MAPPER = new InowTranslationOrphanMapper(); private final RowMapper SUBMISSION_SCHEDULE_UPDATE_ORPHAN_MAPPER = new SubmissionPeriodUpdateOrphanMapper(); private final RowMapper INOW_RELATION_ORPHAN_MAPPER = new InowRelationOrphanMapper(); private final RowMapper EXPORT_OUTPUT_ORPHAN_MAPPER = new ExportOutputOrphanMapper(); private final RowMapper VALIDATION_TRACKING_ORPHAN_MAPPER = new ValidationTrackingRowMapper(); private final RowMapper VALIDATION_DELETED_ORPHAN_MAPPER = new ValidationDeletedRowMapper(); private JdbcTemplate template; private NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** * Default Constructor */ public RecoveryQueriesImpl() { super(); } /** * Get the value of the template field. * * @return Returns the value of template. */ public JdbcTemplate getTemplate() { return this.template; } /** * Set the value of the template field. * * @param template * The template value to set. */ public void setTemplate(JdbcTemplate template) { this.template = template; } /** * Get the value of the namedParameterJdbcTemplate field. * * @return Returns the value of namedParameterJdbcTemplate. */ public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return this.namedParameterJdbcTemplate; } /** * Set the value of the namedParameterJdbcTemplate field. * * @param namedParameterJdbcTemplate * The namedParameterJdbcTemplate value to set. */ public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; } /** * Inject a reference to the {@link DataSource} to use for all queries * * @param dataSource * - database connect source */ public void setDataSource(DataSource dataSource) { template = new JdbcTemplateProxy(dataSource); namedParameterJdbcTemplate = new NamedParameterJdbcTemplateProxy(dataSource); } /** * Selects input file ids from the orphan table. Limit the number of rows returned to numIds and make sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<Long> getParserOrphans(int numIds, int maxPerCustomer) { final String sql = "select data_file_sid from ( " + "select * from ( " + "select ifo.*, " + " rank() over( partition by ifo.customer_sid order by sid ) rank_overall " + "from ( " + "select ifo.*, " + " rank() over( partition by ifo.customer_sid, ifo.type order by nvl(ifo.update_date,ifo.create_date) ) rank_of_type " + "from ( " + "select ifo.data_file_sid, " + " if.customer_sid, " + " ifo.sid, " + " ifo.process_time, if.create_date, if.update_date, " + " CASE WHEN (instr(upper(data_type),'CATALOG') > 0) THEN 'CATALOG' " + " WHEN (instr(upper(data_type),'PROFILE') > 0) THEN 'PROFILE' " + " ELSE data_type " + " END as type " + "from input_file_orphans ifo " + "join data_file if on ifo.data_file_sid = if.sid " + "where process_time < sysdate " + ") ifo " + ") ifo " + "where ifo.type not in ('CATALOG','PROFILE') " + " or ifo.rank_of_type = 1 " + ") " + "where rank_overall <= ? " + "order by rank_overall " + ") where rownum < ? "; return getTemplate().query(sql, new Object[] { maxPerCustomer, numIds }, SID_MAPPER); } /** * Select sales product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<LineItemOrphanId> getSalesProductOrphanIds(int numIds) { return getIds("sales_line_item_orphans", new String[] { "sid", "sales_line_item_sid", "match_type", "customer_sid" }, null, numIds, LINE_ITEM_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getSalesLineItemSerialNumberOrphanIds(int, * com.infonow.service.recovery.SerialNumberOrphanId) */ @SuppressWarnings("unchecked") public List<SerialNumberOrphanId> getSalesLineItemSerialNumberOrphanIds(int numIds) { return getIds("SLI_SERIAL_NUMBER_ORPHANS", new String[] { "sid", "sli_serial_number_sid", "match_type", "customer_sid" }, null, numIds, SERIAL_NUMBER_MAPPER); } /** * Select inv product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<LineItemOrphanId> getInvProductOrphanIds(int numIds) { return getIds("inv_line_item_orphans", new String[] { "sid", "inv_line_item_sid", "match_type", "customer_sid" }, null, numIds, LINE_ITEM_MAPPER); } /** * Select Profile Partner ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<ProfilePartnerOrphanId> getProfilePartnerOrphanIds(int numIds) { final String query = "SELECT" + " sid," + " profile_partner_sid," + " customer_sid," + " match_type," + " retry_count" + " FROM" + " (" + " SELECT" + " *" + " FROM" + " (" + " SELECT" + " sid," + " profile_partner_sid," + " customer_sid," + " match_type," + " retry_count," + " RANK() OVER(" + " PARTITION BY customer_sid" + " ORDER BY" + " pp_create_date" + " ) rank" + " FROM" + " (" + " SELECT" + " po.sid," + " po.profile_partner_sid," + " pp.customer_sid," + " po.match_type," + " po.retry_count," + " pp.create_date pp_create_date" + " FROM" + " profile_orphans po" + " JOIN profile_partner pp ON pp.sid = po.profile_partner_sid" + " WHERE" + " process_time < SYSDATE AND (pp.address_sid is null or pp.address_sid = 0)" + " " + " UNION " + " " + " SELECT" + " po.sid," + " po.profile_partner_sid," + " pp.customer_sid," + " po.match_type," + " po.retry_count," + " pp.create_date pp_create_date" + " FROM" + " profile_orphans po" + " JOIN profile_partner pp ON pp.sid = po.profile_partner_sid" + " JOIN address_history ah ON ah.address_sid = pp.address_sid" + " WHERE" + " process_time < SYSDATE AND ah.stage = 'API_ENRICHED' " + " )" + " )" + " ORDER BY" + " rank" + " )" + "WHERE" + " ROWNUM < ?"; return getTemplate().query(query, new Object[] { numIds }, PROFILE_PARTNER_MAPPER); } /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaProfileOrphanIds(int numIds) { final String query = "select * from (select * from (select sliapo.sid, " + " sliapo.sales_line_item_sid, " + " sliapo.address_Sid, " + " sliapo.address_type, " + " sliapo.match_type, sliapo.customer_sid, sli.BILL_TO_ADDR_EXTERNAL_ID" + " ,sli.SOLD_TO_ADDR_EXTERNAL_ID, sli.SHIP_TO_ADDR_EXTERNAL_ID" + " ,sli.SELL_FROM_ADDR_EXTERNAL_ID, sli.SHIP_FROM_ADDR_EXTERNAL_ID" + " ,sli.SALES_IN_ADDR_EXTERNAL_ID, sli.PURCH_CUST_ADDR_EXTERNAL_ID" + " ,sli.DER_END_CUST_ADDR_EXTERNAL_ID,sli.deleted " + " ,case when exists (select 1 from address_history ah where ah.address_sid = sliapo.address_sid and ah.stage = 'RAW')" + " then 1 else 0 end raw_exists " + " ,case when exists (select 1 from address_history ah where ah.address_sid = sliapo.address_sid and ah.stage = 'REF_DATA_ENRICHED') " + " then 1 else 0 end ref_data_exists," + " rank() over(partition by sliapo.customer_sid order by sliapo.sid) rank " + " from slia_profile_orphans sliapo join sales_line_item sli on sli.sid = sliapo.sales_line_item_sid and " + " sli.customer_sid = sliapo.customer_sid where process_time < sysdate" + " order by rank,address_sid) where (raw_exists = 0 or (raw_exists = 1 and ref_data_exists = 1))) where rownum < ? "; return getTemplate().query(query, new Object[] { numIds }, SLIA_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getSliaCompositeAccountOrphanIds(int) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaCompositeAccountOrphanIds(int numIds) { return getIds("slia_composite_acct_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type", "customer_sid" }, null, numIds, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<InowProfileHierarchyOrphanId> getInowProfileHierarchyOrphanIds(int numToRead) { final String query = "SELECT" + " * " + " FROM" + " (" + " SELECT" + " *" + " FROM" + " (" + " SELECT" + " ipho.sid," + " ipho.inow_profile_sid," + " ipho.customer_sid," + " ipho.named_ip_hierarchy_sid," + " ipho.reprocess_flag," + " ipho.retry_count," + " ipho.priority," + " RANK() OVER(" + " PARTITION BY ipho.customer_sid" + " ORDER BY" + " sid ASC" + " ) rank," + " upper(csr.entity_name)" + " || '-----'" + " || csr.country orphan_key" + " FROM" + " inow_profile_hierarchy_orphans ipho" + " LEFT JOIN csr_overlay_v csr ON csr.customer_sid = ipho.customer_sid" + " AND ipho.inow_profile_sid = csr.ip_sid" + " WHERE" + " process_time < sysdate" + " )" + " ORDER BY" + " priority," + " rank" + " ) " + " WHERE " + " ROWNUM < :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_PROFILE_HIERARCHY_MAPPER); } @SuppressWarnings("unchecked") public List<HierarchyParentOrphanId> getHierarchyParentOrphanIds(int numToRead) { final String query = "select * from ( " + "select * from ( " + "select hpo.sid, " + " hpo.inow_profile_sid, " + " hpo.customer_sid, " + " hpo.named_ip_hierarchy_sid, " + " hpo.reprocess_flag, " + " hpo.retry_count, " + " hpo.priority, " + " rank() over( partition by hpo.customer_sid order by sid asc) rank " + "from hierarchy_parent_orphans hpo " + "where process_time < sysdate) " + "order by priority,rank " + ") " + "where rownum < :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, HIERARCHY_PARENT_MAPPER); } @SuppressWarnings("unchecked") public List<AddressHistoryOrphanId> getAddressHistoryOrphanIds(int numToRead, String tableName) { final String query = "select * from ( " + "select * from ( " + "select aho.sid, " + " aho.address_history_sid, aho.retry_count " + "from " + tableName + " aho " + "where process_time < sysdate) " + "order by sid " + ") " + "where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, ADDRESS_HISTORY_MAPPER); } @SuppressWarnings("unchecked") public List<SalesLineItemNormalizationOrphanId> getSalesLineItemNormalizationOrphanIds(int numToRead) { return getIds("sli_normalization_orphans", new String[] { "sid", "sales_line_item_sid", "customer_sid", "price_type, entity_sid" }, null, numToRead, SALES_LINE_ITEM_NORMALIZATION_MAPPER); } /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaReportingPartnerOrphanIds(int numIds) { return getIds("reporting_partner_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "null" }, null, numIds, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationOrphanId> getSalesLineItemValidationOrphanIds(int numToRead) { final String query = "select * from ( " + "select sv.sid,sv.sales_line_item_sid,sv.match_type,sv.customer_sid, " + " sli.reporting_partner_sid,sli.data_file_sid,rank() over(partition by sv.customer_sid order by sv.create_date) rank_by_cust" + " from sli_validation_orphans sv" + " join sales_line_item sli on sli.sid = sv.sales_line_item_sid " + " and sli.customer_sid = sli.customer_Sid where process_time < sysdate order by rank_by_cust,sv.create_date " + ") where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, VALIDATION_ITEM_MAPPER); } @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaValidationOrphanIds(int numToRead) { return getIds("slia_validation_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type", "customer_sid" }, null, numToRead, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationTrackingOrphanId> getValidationTrackingOrphanIds(int numToRead) { return getIds("validation_tracking_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "create_date", "update_date", "retry_count" }, null, numToRead, VALIDATION_TRACKING_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationNotificationOrphanId> getValidationNotificationOrphanIds(int numToRead) { return getIds("validation_notification_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "create_date", "update_date", "retry_count" }, null, numToRead, VALIDATION_DELETED_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationOrphanId> getInventoryLineItemValidationOrphanIds(int numToRead) { final String query = "select * from ( " + "select sv.sid,sv.inv_line_item_sid,sv.match_type,sv.customer_sid, " + " ili.reporting_partner_sid,ili.data_file_sid,rank() over(partition by sv.customer_sid order by sv.create_date) rank_by_cust" + " from ili_validation_orphans sv" + " join inv_line_item ili on ili.sid = sv.inv_line_item_sid " + " and ili.customer_sid = ili.customer_Sid where process_time < sysdate order by rank_by_cust,sv.create_date " + ") where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, VALIDATION_ITEM_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getReportingPartnerOrphanIds(int) */ @SuppressWarnings("unchecked") @Override public List<ReportingPartnerOrphanId> getReportingPartnerOrphanIds(int numToRead) { return getIds("reporting_partner_inow_orphs", new String[] { "sid", "reporting_partner_sid" }, null, numToRead, REPORTING_PARTNER_MAPPER); } @SuppressWarnings("unchecked") @Override public List<Long> getAddressStandardizationOrphans(int numToRead) { return getIds("addr_standardization_orphans", new String[] { "address_sid" }, null, numToRead, SID_MAPPER); } @SuppressWarnings("unchecked") @Override public List<InowStandardizationOrphanId> getInowProfileStandardizationOrphans(int numToRead) { return getIds("inow_profile_std_orphans", new String[] { "sid", "inow_profile_sid", "retry_count" }, null, numToRead, INOW_STANDARDIZATION_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") @Override public List<InowProfileOrphanId> getInowProfileDedupOrphans(int numToRead) { return getIds("inow_profile_dedup_orphans", new String[] { "sid", "inow_profile_sid", "customer_sid" }, null, numToRead, INOW_PROFILE_MAPPER); } @SuppressWarnings("unchecked") @Override public List<Long> getProfilePartnerRematchOrphanIds(int numToRead) { return getIds("profile_rematch_orphans", new String[] { "profile_partner_sid" }, null, numToRead, SID_MAPPER); } @SuppressWarnings("unchecked") @Override public List<SalesLineItemAddressOrphanId> getSliaRematchOrphanIds(int numToRead) { return getIds("slia_profile_rematch_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type" }, null, numToRead, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") @Override public List<ExporterOrphanId> getExporterOrphanIds(int numToRead) { return getIds("exporter_orphans", new String[] { "sid", "customer_sid", "export_name" }, null, numToRead, EXPORTER_ORPHAN_MAPPER); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteDataFileId(Long id) { if (id == null) { return; } deleteId("input_file_orphans", "data_file_sid", id); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteSalesProductId(LineItemOrphanId id) { deleteId("sales_line_item_orphans", id.getSid()); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteSalesLineItemSerialNumberId(com.infonow.service.recovery. * SerialNumberOrphanId) */ public void deleteSalesLineItemSerialNumberId(SerialNumberOrphanId id) { deleteId("sli_serial_number_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteProfilePartnerId(ProfilePartnerOrphanId id) { deleteId("profile_orphans", "sid", id.getSid()); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteInvProductId(LineItemOrphanId id) { deleteId("inv_line_item_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSliaProfileId(SalesLineItemAddressOrphanId id) { deleteId("slia_profile_orphans", id.getSid()); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteSliaCompositeAccountId(com.infonow.service.recovery. * SalesLineItemAddressOrphanId) */ public void deleteSliaCompositeAccountId(SalesLineItemAddressOrphanId id) { deleteId("slia_composite_acct_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSliaReportingPartnerId(SalesLineItemAddressOrphanId id) { deleteId("reporting_partner_orphans", id.getSid()); } public void deleteSalesLineItemValidationId(List<ValidationOrphanId> ids) { String sql = new String("delete from sli_validation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteValidationTrackingIds(List<ValidationTrackingOrphanId> ids) { String sql = new String("delete from validation_tracking_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteValidationNotificationIds(List<ValidationNotificationOrphanId> ids) { String sql = new String("delete from validation_notification_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteSliaValidationId(SalesLineItemAddressOrphanId id) { deleteId("slia_validation_orphans", id.getSid()); } public void deleteInventoryLineItemValidationId(List<ValidationOrphanId> ids) { String sql = new String("delete from ili_validation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteSalesLineItemOrphans(List<Long> salesLineItemSids) { String sql = new String("delete from sales_line_item_orphans where sales_line_item_sid in (:sids)"); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", salesLineItemSids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteSalesLineItemOrphans(DataFile dataFile) { String sql = new String("delete from sales_line_item_orphans where sales_line_item_sid in " + " (select sid from sales_line_item where data_file_sid = ? and customer_sid = " + dataFile.getCustomer().getSid().toString() + ")"); getTemplate().update(sql, new Object[] { dataFile.getSid() }); } @Override public void deleteInvLineItemOrphans(List<Long> invLineItemSids) { String sql = new String("delete from inv_line_item_orphans where inv_line_item_sid in (:sids)"); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", invLineItemSids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void updateStatusTranslationOrphans(String status, List<Long> translationOrphanSids)//pass the array of sids, and pass status { String sql = new String("update translation_orphans set status = :status where sid in (:sids)"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("sids", translationOrphanSids); paramMap.put("status", status); try { getNamedParameterJdbcTemplate().update(sql, paramMap); } catch(Exception e){ System.out.println(e.getMessage()); } } public void deleteRegexStandardizationOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from regex_std_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteRefDataStandardizationOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from ref_data_std_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressHistoryOrphans(List<AddressHistoryOrphanId> orphanIds, String orphanTable) { String sql = new String("delete from " + orphanTable + " where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressGradingOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from address_grading_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteTranslateOrphans(List<TranslationOrphan> orphanIds) { for (List<TranslationOrphan> orphans : CollectionUtils.partition(orphanIds, 1000)) { String sql = new String( "delete from translation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphans.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } } @Override public void deleteExportOutputOrphans(List<ExportOutputOrphanId> orphanIds) { String sql = new String( "delete from export_output_orphans where sid in (:sids)"); Map<String, Object> paramMap = new HashMap<String, Object>(); List<Long> sids = orphanIds.stream().map(o -> o.getSid()) .collect(Collectors.toList()); List<List<Long>> sidsPartition = CollectionUtils.partition(sids, 1000); for (List<Long> batch : sidsPartition) { paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } } @Override public void deleteSubmissionPeriodUpdateOrphans( SubmissionPeriodUpdateOrphanId orphanId) { String sql = new String( "delete from SP_UPDATE_ORPHANS where sid in (:sid)"); Map<String, Long> paramMap = new HashMap<String, Long>(); paramMap.put("sid", orphanId.getSid()); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteInowRelationOrphan(InowRelationOrphan orphanId) { String sql = new String("delete from relation_orphans where sid = :sid"); Map<String, Long> paramMap = new HashMap<String, Long>(); paramMap.put("sid", orphanId.getSid()); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressQualityOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from address_quality_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteInvLineItemOrphans(DataFile dataFile) { String sql = new String("delete from inv_line_item_orphans where inv_line_item_sid in " + " (select sid from inv_line_item where data_file_sid = ? and customer_sid = " + dataFile.getCustomer().getSid().toString() + ")"); getTemplate().update(sql, new Object[] { dataFile.getSid() }); } @Override public List<DataFileOrphanId> getDataFileDeleteOrphans(int numToRead) { List<?> orphanIds = null; orphanIds = getIds("data_file_delete_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "reprocess", "user_login", "retry_count", "preserve_date" }, null, null, numToRead, new GenericRowMapper() { @Override public Object mapRow(ResultSet rs, int arg1) throws SQLException { DataFileOrphanId dfoi = new DataFileOrphanId(); dfoi.setDataFileSid(this.getLong(rs, "data_file_sid")); dfoi.setCustomerSid(this.getLong(rs, "customer_sid")); dfoi.setReprocess(this.getBooleanValue(rs, "reprocess")); dfoi.setUserLogin(this.getString(rs, "user_login")); dfoi.setSid(this.getLong(rs, "sid")); dfoi.setRetryCount(this.getLong(rs, "retry_count")); dfoi.setPreserveDate(this.getBooleanValue(rs, "preserve_date")); return dfoi; } }); return (List<DataFileOrphanId>) orphanIds; } @SuppressWarnings("unchecked") public List<TranslationOrphan> getTranslationOrphans(int numToRead, String status) { String query = "select * from ( select ipro.sid, ipro.inow_profile_sid, ipro.retry_count, ipro.status, rownum cnt " + "from translation_orphans ipro where process_time < sysdate " + "order by sid ) result where rownum <= :numToRead "; Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("numToRead", String.valueOf(numToRead)); if(status!=null){ query = query + "and result.status = :status"; paramMap.put("status",status); } return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_TRANSLATION_ORPHAN_MAPPER); } @Override @SuppressWarnings("unchecked") public List<SubmissionPeriodUpdateOrphanId> getSubmissionPeriodUpdateOrphans(int numToRead) { final String query = "select * from ( select spuo.sid, spuo.customer_sid, spuo.old_start_date, spuo.retry_count, rownum cnt " + "from sp_update_orphans spuo where process_time < sysdate " + "order by sid ) where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, SUBMISSION_SCHEDULE_UPDATE_ORPHAN_MAPPER); } @Override public List<ExportOutputOrphanId> getExportOutputOrphans(int numToRead) { final String query = "WITH rowlimit AS (" + "SELECT * FROM (" + "SELECT EXPORT_STATUS_SID FROM export_output eo JOIN export_output_orphans eoo " + "ON eoo.EXPORT_OUTPUT_SID= eo.sid AND eo.customer_sid = eoo.customer_sid " + "WHERE eoo.process_time < sysdate + interval '10' second " + "GROUP BY EXPORT_STATUS_SID ) " + "WHERE rownum < :numToRead ) " + "SELECT eoo.SID,eoo.CUSTOMER_SID,eoo.SESSION_ID,eoo.EXPORT_OUTPUT_SID," + "eo.EXPORT_STATUS_SID,eoo.retry_count,es.export_name, eoo.export_request_sid" + ",RANK() OVER (PARTITION BY eo.customer_sid,eo.EXPORT_STATUS_SID ORDER BY eoo.sid ) rankof " + "FROM EXPORT_OUTPUT eo JOIN EXPORT_OUTPUT_ORPHANS eoo ON eoo.EXPORT_OUTPUT_SID = eo.sid " + "JOIN rowlimit ON rowlimit.export_status_sid = eo.EXPORT_STATUS_SID " + "join export_status es on es.sid = eo.export_status_sid and es.customer_sid = eo.customer_sid " + "ORDER BY rankof"; Map<String, Object> params = new HashMap<>(); params.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, params, EXPORT_OUTPUT_ORPHAN_MAPPER); } @Override @SuppressWarnings("unchecked") public List<InowRelationOrphan> getInowRelationOrphans(int numToRead) { final String query = "select * from ( select ro.sid, ro.inow_profile_sid, ro.related_inow_profile_sid, ro.retry_count, rownum cnt " + "from relation_orphans ro where process_time < sysdate " + "order by sid ) where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_RELATION_ORPHAN_MAPPER); } @Override public void deleteDataFileDeleteOrphanId(DataFileOrphanId id) { String sql = new String("delete from data_file_delete_orphans where sid = ? " + " and customer_sid = " + id.getCustomerSid()); getTemplate().update(sql, new Object[] { id.getSid() }); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteReportingPartnerId(com.infonow.service.recovery. * ReportingPartnerOrphanId) */ @Override public void deleteReportingPartnerId(ReportingPartnerOrphanId id) { if (id == null || id.getSid() == null || id.getSid() <= 0) { return; } deleteId("reporting_partner_inow_orphs", id.getSid()); } public void deleteInowProfileHierarchyId(InowProfileHierarchyOrphanId id) { deleteId("inow_profile_hierarchy_orphans", id.getSid()); } public void deleteHierarchyParentId(HierarchyParentOrphanId id) { deleteId("hierarchy_parent_orphans", id.getSid()); } public void deleteHierarchyParentIds(List<HierarchyParentOrphanId> ids) { List<Long> sids = new ArrayList<Long>(); for (HierarchyParentOrphanId id : ids) { sids.add(id.getSid()); } deleteIds("hierarchy_parent_orphans", sids); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSalesLineItemNormalizationId(SalesLineItemNormalizationOrphanId id) { deleteId("sli_normalization_orphans", id.getSid()); } @Override public void deleteAddressStandardizationOrphan(Long id) { deleteId("addr_standardization_orphans", "address_sid", id); } @Override public void deleteInowProfileStandardizationOrphan(InowStandardizationOrphanId id) { deleteId("inow_profile_std_orphans", "inow_profile_sid", id.getInowProfileSid()); } @Override public void deleteInowProfileDedupOrphan(InowProfileOrphanId id) { deleteId("inow_profile_dedup_orphans", id.getSid()); } @Override public void deleteProfilePartnerRematchId(Long id) { deleteId("profile_rematch_orphans", "profile_partner_sid", id); } @Override public void deleteSliaRematchId(SalesLineItemAddressOrphanId id) { deleteId("slia_profile_rematch_orphans", id.getSid()); } @Override public void deleteExporterOrphan(ExporterOrphanId id) { deleteId("exporter_orphans", id.getSid()); } /** * Dynamically generates a recovery orphan query for select * This function will alternate customers round robin if no orderByClause is specified * and there is customer_sid in the columns * @param tableName * @param columns * @param orderByClause * @param numIds * @param rowMapper * @return list of rowMaper */ @SuppressWarnings("rawtypes") private List getIds(String tableName, String[] columns, String orderByClause, Integer numIds, RowMapper rowMapper) { return getIds(tableName, columns, null, orderByClause, numIds, rowMapper); } /** * Dynamically generates a recovery orphan query for select * This function will alternate customers round robin if no orderByClause is specified * and there is customer_sid in the columns * @param tableName * @param columns * @param additionalWhereClause * @param orderByClause * @param numIds * @param rowMapper * @return list of rowMaper */ @SuppressWarnings("rawtypes") private List getIds(String tableName, String[] columns, String additionalWhereClause, String orderByClause, Integer numIds, RowMapper rowMapper) { if (columns == null || columns.length <= 0) { return null; } StringBuilder sqlBuffer = new StringBuilder("select * from (select "); for (int i = 0; i < columns.length; ++i) { if (i > 0) { sqlBuffer.append(", "); } sqlBuffer.append(columns[i]); // automatically implement customer 100 functions for all queues. if (StringUtils.equalsIgnoreCase(columns[i], "customer_sid")) { if (i > 0) { sqlBuffer.append(", "); } sqlBuffer.append("rank() over(partition by customer_sid order by sid) rank_by_cust "); if (StringUtils.isEmpty(orderByClause)) { orderByClause = "order by rank_by_cust"; } } } sqlBuffer.append(" from "); sqlBuffer.append(tableName); // Construct the WHERE clause sqlBuffer.append(" where process_time < sysdate "); if (!StringUtils.isEmpty(additionalWhereClause)) { sqlBuffer.append(" and "); sqlBuffer.append(additionalWhereClause); } if (StringUtils.isEmpty(orderByClause)) { sqlBuffer.append(" order by process_time desc "); } else { sqlBuffer.append(orderByClause); } sqlBuffer.append(" ) where rownum <= ?"); String query = sqlBuffer.toString(); return getTemplate().query(query, new Object[] { numIds }, rowMapper); } private void deleteId(String tableName, Long sid) { deleteId(tableName, null, sid); } private void deleteId(String tableName, String columnName, Long sid) { StringBuffer sqlBuffer = new StringBuffer("delete from "); sqlBuffer.append(tableName); if (StringUtils.isEmpty(columnName)) { sqlBuffer.append(" where sid = ?"); } else { sqlBuffer.append(" where "); sqlBuffer.append(columnName); sqlBuffer.append(" = ?"); } template.update(sqlBuffer.toString(), new Object[] { sid }); } private void deleteIds(String tableName, List<Long> sids) { for (List<Long> inList : CollectionUtils.partition(sids, 1000)) { deleteIds(tableName, null, inList); } } private void deleteIds(String tableName, String columnName, List<Long> sids) { StringBuffer sqlBuffer = new StringBuffer("delete from "); sqlBuffer.append(tableName); if (StringUtils.isEmpty(columnName)) { sqlBuffer.append(" where sid in "); } else { sqlBuffer.append(" where "); sqlBuffer.append(columnName); sqlBuffer.append(" in "); } String deleteQuery = SqlGenerationUtils.buildInClauseVariables(sqlBuffer.toString(), sids.size()); List<Object> params = new ArrayList<Object>(); params.addAll(sids); template.update(deleteQuery, params.toArray()); } /** * RowMapper instance used to extract the sid from a query */ private class SidRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return (rs.getLong(1)); } } /** * RowMapper instance used to extract the line item from a query */ private class LineItemRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { if (rs.getMetaData().getColumnCount() == 2) { // SID and SLI_SID return new LineItemOrphanId(rs.getLong(1), rs.getLong(2), null); } else { // SID, SLI_SID and MATCH_TYPE return new LineItemOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); } } } /** * RowMapper instance used to extract the line item from a query */ private class ValidationRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { ValidationOrphanId orphan = new ValidationOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); orphan.setCustomerSid(rs.getLong(4)); orphan.setReportingPartnerSid(rs.getLong(5)); orphan.setDataFileSid(rs.getLong(6)); return orphan; } } private class ValidationTrackingRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ValidationTrackingOrphanId(rs.getLong("sid"), rs.getLong("data_file_sid"), rs.getLong("customer_sid"), rs.getDate("create_date"), rs.getDate("update_date"), rs.getLong("retry_count")); } } private class ValidationDeletedRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ValidationNotificationOrphanId(rs.getLong("sid"), rs.getLong("data_file_sid"), rs.getLong("customer_sid"), rs.getDate("create_date"), rs.getDate("update_date"), rs.getLong("retry_count")); } } private class ReportingPartnerRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ReportingPartnerOrphanId(rs.getLong(1), rs.getLong(2)); } } /** * RowMapper instance used to extract the serial number from a query */ private class SerialNumberRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new SerialNumberOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); } } private class SliaProfileMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { SalesLineItemAddressOrphanId orphan = new SalesLineItemAddressOrphanId(rs.getLong(1), rs.getLong(2), rs.getLong(3), DataAddressTypeEnum.fromDbCode(rs.getString(4)), rs.getString(5), rs.getLong(6)); /* * the natural key for slia_profile orphans is the address, and any external id for that line item if it is * deleted and the customer this is because external id's / deleted line items have different code paths for * short circuit matching */ StringBuilder sb = new StringBuilder(); sb.append(orphan.getAddressSid()); sb.append(orphan.getCustomerSid()); // we need this so that we don't cause a race condition on saving the ami data in the amidao sb.append(orphan.getSalesLineItemSid()); switch (orphan.getAddressType()) { case BILL_TO: sb.append(rs.getString("BILL_TO_ADDR_EXTERNAL_ID")); break; case SHIP_TO: sb.append(rs.getString("SHIP_TO_ADDR_EXTERNAL_ID")); break; case SOLD_TO: sb.append(rs.getString("SOLD_TO_ADDR_EXTERNAL_ID")); break; case SHIP_FROM: sb.append(rs.getString("SHIP_FROM_ADDR_EXTERNAL_ID")); break; case SELL_FROM: sb.append(rs.getString("SELL_FROM_ADDR_EXTERNAL_ID")); break; case SALES_IN: sb.append(rs.getString("SALES_IN_ADDR_EXTERNAL_ID")); break; case PURCHASING_CUSTOMER: sb.append(rs.getString("PURCH_CUST_ADDR_EXTERNAL_ID")); break; case DERIVED_END_CUSTOMER: sb.append(rs.getString("DER_END_CUST_ADDR_EXTERNAL_ID")); break; } sb.append(rs.getInt("deleted")); orphan.setGroupByValue(sb.toString()); return orphan; } } private class TupleMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new SalesLineItemAddressOrphanId(rs.getLong(1), rs.getLong(2), rs.getLong(3), DataAddressTypeEnum.fromDbCode(rs.getString(4)), rs.getString(5), 0l); } } private class InowProfileHierarchyRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { InowProfileHierarchyOrphanId row = new InowProfileHierarchyOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setHierarchySid(rs.getLong("named_ip_hierarchy_sid")); if (rs.wasNull()) { row.setHierarchySid(null); } Long reprocess = rs.getLong("reprocess_flag"); if (!rs.wasNull()) { row.setReprocess(reprocess == 0 ? Boolean.FALSE : Boolean.TRUE); } row.setRetryCount(rs.getLong("retry_count")); row.setOrphanKey(rs.getString("orphan_key")); return row; } } private class HierarchyParentMapper extends InowProfileHierarchyRowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { HierarchyParentOrphanId row = new HierarchyParentOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setHierarchySid(rs.getLong("named_ip_hierarchy_sid")); if (rs.wasNull()) { row.setHierarchySid(null); } Long reprocess = rs.getLong("reprocess_flag"); if (!rs.wasNull()) { row.setReprocess(reprocess == 0 ? Boolean.FALSE : Boolean.TRUE); } row.setRetryCount(rs.getLong("retry_count")); row.setGroupByValue(rs.getLong("named_ip_hierarchy_sid")); return row; } } private class AddressHistoryMapper extends GenericMapper implements RowMapper<AddressHistoryOrphanId> { public AddressHistoryOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { this.columnNames = null; AddressHistoryOrphanId row = new AddressHistoryOrphanId(); row.setSid(rs.getLong("sid")); row.setAddressHistorySid(rs.getLong("address_history_sid")); row.setRetryCount(rs.getLong("retry_count")); return row; } } private class InowStandardizationOrphanMapper implements RowMapper<InowStandardizationOrphanId> { public InowStandardizationOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { InowStandardizationOrphanId row = new InowStandardizationOrphanId(); row.setSid(rs.getLong("sid")); row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setRetryCount(rs.getLong("retry_count")); return row; } } private class InowProfileRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { InowProfileOrphanId row = new InowProfileOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); return row; } } private class SalesLineItemNormalizationRowMapper extends GenericRowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = this.getLong(rs, "sid"); Long salesLineItemSid = this.getLong(rs, "sales_line_item_sid"); Long entitySid = this.getLong(rs, "entity_sid"); Long customerSid = this.getLong(rs, "customer_sid"); String priceType = this.getString(rs, "price_type"); SalesLineItemNormalizationOrphanId sliNormOrph = new SalesLineItemNormalizationOrphanId(sid, salesLineItemSid, customerSid, priceType, entitySid); return sliNormOrph; } } private class ProfilePartnerRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); Long profilePartnerSid = rs.getLong("profile_partner_sid"); String matchType = rs.getString("match_type"); ProfilePartnerOrphanId profileSummaryOrphan = new ProfilePartnerOrphanId(sid, customerSid, profilePartnerSid, matchType); profileSummaryOrphan.setRetryCount(rs.getLong("retry_count")); return profileSummaryOrphan; } } private final class CompositeAccountClassificationOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int row) throws SQLException { Long sid = rs.getLong("sid"); Long inowProfileSid = rs.getLong("inow_profile_sid"); String classificationCode = rs.getString("classification_code"); return new CompositeAccountClassificationOrphan(sid, inowProfileSid, classificationCode); } } private class ExporterOrphanRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); String exportName = rs.getString("export_name"); ExporterOrphanId id = new ExporterOrphanId(); id.setSid(sid); id.setCustomerSid(customerSid); id.setExportName(exportName); return id; } } @SuppressWarnings("unchecked") @Override public List<CompositeAccountClassificationOrphan> getCompositeAccountClassificationOrphans(int numToRead) { return getIds("comp_acct_class_orphan", new String[] { "sid", "inow_profile_sid", "classification_code" }, null, numToRead, COMPOSITE_ACCOUNT_CLASS_ORPHAN_MAPPER); } @Override public void deleteCompositeAccountClassificationOrphan(CompositeAccountClassificationOrphan id) { deleteId("comp_acct_class_orphan", id.getSid()); } private final class SubmissionScheduleOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int row) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); Long submissionPeriodSid = rs.getLong("submission_period_sid"); if (rs.wasNull()) { submissionPeriodSid = null; } Long dataFileSid = rs.getLong("data_file_sid"); if (rs.wasNull()) { dataFileSid = null; } SubmissionScheduleOrphan.Action action = SubmissionScheduleOrphan.Action.valueOf(rs.getString("action")); SubmissionScheduleOrphan orphan = new SubmissionScheduleOrphan(sid, customerSid, submissionPeriodSid, dataFileSid, action); orphan.setProcessTime(rs.getTimestamp("process_time")); orphan.setCreateDate(rs.getTimestamp("create_date")); orphan.setRetryCount(rs.getLong("retry_count")); return orphan; } } @SuppressWarnings("unchecked") @Override public List<SubmissionScheduleOrphan> getSubmissionScheduleOrphans(int numToRead) { // We only want to return one orphan per customer to avoid multi-threaded // contention issues with the database. For instance, 2 threads may need to // rebuild the same set of data_file_summary_info records for a given data_file. // We also want to give the CLEANUP action orphans a lower priority than // the normal orphans which is why a decode of the action shows up in the order by // within the analytical function row_number. String sql = "SELECT * FROM " + "( " + " SELECT o.sid, " + " o.customer_sid, " + " o.submission_period_sid, " + " o.data_file_sid, " + " o.action, " + " o.process_time, " + " o.create_date, " + " o.retry_count, " + " row_number() over (partition by o.customer_sid " + " order by " + " decode(o.action,'CLEANUP',100,10)," + " o.process_time) rn " + " FROM submission_schedule_orphan o " + " WHERE o.process_time < sysdate " + ") " + "WHERE rownum < ? " + " AND rn = 1"; List<SubmissionScheduleOrphan> orphans = getTemplate().query(sql, new Object[] { numToRead }, SUBMISSION_SCHEDULE_ORPHAN_MAPPER); return orphans; } @Override public void deleteSubmissionScheduleOrphan(SubmissionScheduleOrphan id) { deleteId("submission_schedule_orphan", id.getSid()); } @SuppressWarnings("unchecked") @Override public List<LearnedNameOrphan> getLearnedNameOrphans(int numToRead) { final String sql = "SELECT * FROM (SELECT o.sid as orphan_sid, l.sid as name_learning_sid, l.from_name, l.to_name, l.approval_status" + " FROM name_learning l" + " JOIN name_learning_orphan o ON o.name_learning_sid = l.sid" + " WHERE o.process_time < sysdate" + " ) WHERE rownum < ?"; return getTemplate().query(sql, new Object[] { numToRead }, LEARNED_NAME_ORPHAN_MAPPER); } @Override public void deleteLearnedNameOrphan(LearnedNameOrphan orphan) { deleteId("name_learning_orphan", orphan.getSid()); } private static class LearnedNameOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { LearnedName learnedName = new LearnedName(rs.getString("from_name"), rs.getString("to_name")); learnedName.setApprovalStatus(ApprovalStatus.fromString(rs.getString("approval_status"))); learnedName.setSid(rs.getLong("name_learning_sid")); LearnedNameOrphan learnedNameOrphan = new LearnedNameOrphan(learnedName); learnedNameOrphan.setSid(rs.getLong("orphan_sid")); return learnedNameOrphan; } } private static class InowTranslationOrphanMapper implements RowMapper<TranslationOrphan> { public TranslationOrphan mapRow(ResultSet rs, int rowNum) throws SQLException { TranslationOrphan translationOrphan = new TranslationOrphan(); translationOrphan.setSid(rs.getLong("sid")); translationOrphan.setInowProfileSid(rs.getLong("inow_profile_sid")); translationOrphan.setRetryCount(rs.getLong("retry_count")); translationOrphan.setGroupByValue(Math.round(rs.getLong("cnt") / 10)); return translationOrphan; } } private static class SubmissionPeriodUpdateOrphanMapper implements RowMapper<SubmissionPeriodUpdateOrphanId> { public SubmissionPeriodUpdateOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { SubmissionPeriodUpdateOrphanId submissionPeriodUpdateOrphanId = new SubmissionPeriodUpdateOrphanId(); submissionPeriodUpdateOrphanId.setSid(rs.getLong("sid")); submissionPeriodUpdateOrphanId.setCustomerSid(rs.getLong("customer_sid")); submissionPeriodUpdateOrphanId.setOldStartDate(rs.getDate("old_start_date")); submissionPeriodUpdateOrphanId.setRetryCount(rs.getLong("retry_count")); return submissionPeriodUpdateOrphanId; } } private static class InowRelationOrphanMapper implements RowMapper<InowRelationOrphan> { public InowRelationOrphan mapRow(ResultSet rs, int rowNum) throws SQLException { InowRelationOrphan inowRelationOrphan = new InowRelationOrphan(); inowRelationOrphan.setSid(rs.getLong("sid")); inowRelationOrphan.setInowProfileSid( rs.getLong("inow_profile_sid")); inowRelationOrphan.setRelatedInowProfileSid( rs.getLong("related_inow_profile_sid")); inowRelationOrphan.setRetryCount(rs.getLong("retry_count")); return inowRelationOrphan; } } private static class ExportOutputOrphanMapper implements RowMapper<ExportOutputOrphanId> { public ExportOutputOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { ExportOutputOrphanId exportOutputOrphan = new ExportOutputOrphanId(); exportOutputOrphan.setCustomerSid(rs.getLong("CUSTOMER_SID")); exportOutputOrphan.setExportOutputSid( rs.getLong("EXPORT_OUTPUT_SID")); exportOutputOrphan.setSid(rs.getLong("SID")); exportOutputOrphan.setRetryCount(rs.getLong("RETRY_COUNT")); exportOutputOrphan.setExportRequestSid( rs.getLong("EXPORT_REQUEST_SID")); exportOutputOrphan.setGroupByValue(rs.getLong("EXPORT_STATUS_SID")); exportOutputOrphan.setSessionId(rs.getString("SESSION_ID")); return exportOutputOrphan; } } }
package com.modeln.cdm.service.translation; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.infonow.service.recovery.RecoveryQueries; import org.json.JSONException; import org.json.JSONObject; import com.infonow.crux.dao.InowProfileDao; import com.infonow.crux.impl.InowProfileImpl; import com.infonow.framework.service.ServiceResponse; import com.infonow.framework.service.configuration.support.ServiceDefinition; import com.infonow.framework.service.context.ServiceContext; import com.infonow.framework.service.support.ServiceException; import com.infonow.service.configuration.ConfigurationException; import com.infonow.service.configuration.impl.AbstractBaseServiceWithConfiguration; import com.infonow.service.recovery.TranslationOrphan; import com.modeln.cdm.integration.aws.AmazonSNSClientImpl; import com.modeln.cdm.service.translation.configuration.TranslationConfguration; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import software.amazon.awssdk.utils.StringUtils; @ServiceDefinition(name = "translationService", abstraction = com.modeln.cdm.service.translation.TranslationService.class, implementation = com.modeln.cdm.service.translation.TranslationServiceImpl.class) public class TranslationServiceImpl extends AbstractBaseServiceWithConfiguration implements TranslationService { private InowProfileRelationService inowProfileRelationService; private RecoveryQueries _recoveryQueries; private AmazonSNSClientImpl awsSnsClient; private String awsSnsTopic; private InowProfileDao inowProfileDao; private static String UNWANTED_CHARS; private static String LATIN_CHARS; private static Pattern UNWANTED_PATTERN; private static Pattern LATIN_PATTERN; private NamedParameterJdbcTemplate namedParameterJdbcTemplate; private TranslationConfguration translationConfig; Matcher matcher; public TranslationServiceImpl() { if (UNWANTED_CHARS == null) { UNWANTED_CHARS = "[\\u0020-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E\\u0030-\\u0039\\u00A0-\\u00BF\\u2013-\\u204A]"; } if (LATIN_CHARS == null) { LATIN_CHARS = "[\\u0041-\\u005A\\u0061-\\u007A\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\uFF00-\\uFF60]+"; } if (UNWANTED_PATTERN == null) { UNWANTED_PATTERN = Pattern.compile(UNWANTED_CHARS); } if (LATIN_PATTERN == null) { LATIN_PATTERN = Pattern.compile(LATIN_CHARS); } } public RecoveryQueries getRecoveryQueries() { if (_recoveryQueries == null) { throw new IllegalStateException("The attribute _recoveryQueries can not be null"); } return _recoveryQueries; } public void setRecoveryQueries(RecoveryQueries recoveryQueries) { _recoveryQueries = recoveryQueries; } public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return this.namedParameterJdbcTemplate; } @SuppressWarnings("unchecked") @Override public ServiceResponse execute(ServiceContext serviceContext, Object userObject, Object userData) throws ServiceException { if (!(userData instanceof List<?>)) { throw new IllegalArgumentException("Argument userData must be a List but was " + userData == null ? null : userData.getClass().getName()); } List<TranslationOrphan> ids = ((List<TranslationOrphan>) userData); List<JSONObject> addrs = new ArrayList<JSONObject>(); translationConfig = getTranslationConfig(); List<Long> inProgressIds = new ArrayList<Long>(); for (TranslationOrphan id : ids) { Long sid = id.getSid(); InowProfileImpl inowProfile = (InowProfileImpl) getInowProfileDao().getBySid(id.getInowProfileSid()); boolean entityNeedsTranslation = isNonLatin(inowProfile.getName()); String address = inowProfile.getStreet1() + inowProfile.getStreet2() + inowProfile.getCity() + inowProfile.getStateProvince() + inowProfile.getPostalCode(); boolean addressNeedsTranslation = isNonLatin(address); JSONObject addr = createTranslationInput(inowProfile, entityNeedsTranslation, addressNeedsTranslation); inProgressIds.add(sid); if (addr != null) { addrs.add(addr); inProgressIds.add(sid); ids.remove(id);//since the ids which are in pending state must not be deleted } } changeStatus(TranslationOrphanStatusEnum.IN_PROGRESS.toString(), inProgressIds); if (!addrs.isEmpty()) { publish(addrs); changeStatus(TranslationOrphanStatusEnum.IN_PROGRESS.toString(), inProgressIds); } return new ServiceResponse("Success", ServiceResponse.SUCCESS); } public void changeStatus(String status,List<Long> inProgressIds){ getRecoveryQueries().updateStatusTranslationOrphans(status, inProgressIds); } protected JSONObject createTranslationInput(InowProfileImpl inowProfile, boolean entityNeedsTranslation, boolean addressNeedsTranslation) throws ServiceException { JSONObject addr = null; if ((entityNeedsTranslation || addressNeedsTranslation) && isTranslationNeededForCountry(inowProfile.getCountryObject().getTwoCharCode()) && !isInowRelationAlreadyExists(inowProfile)) { addr = new JSONObject(); try { addr.put("id", inowProfile.getIdentifier()); JSONObject addrDetails = new JSONObject(); if (entityNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getName())) { addrDetails.put("name", inowProfile.getName()); } } if (addressNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getStreet1())) { addrDetails.put("street1", inowProfile.getStreet1()); } if (!StringUtils.isEmpty(inowProfile.getStreet2())) { addrDetails.put("street2", inowProfile.getStreet2()); } if (!StringUtils.isEmpty(inowProfile.getCity())) { addrDetails.put("city", inowProfile.getCity()); } if (!StringUtils.isEmpty(inowProfile.getStateProvince())) { addrDetails.put("stateprovince", inowProfile.getStateProvince()); } if (!StringUtils.isEmpty(inowProfile.getPostalCode())) { addrDetails.put("postalcode", inowProfile.getPostalCode()); } if (!StringUtils.isEmpty(inowProfile.getCountry())) { addrDetails.put("country", inowProfile.getCountryObject().getTwoCharCode()); } } addr.put("query", addrDetails); addr.put("target", "EN"); } catch (JSONException e) { throw new ServiceException("Exception while converting InowProfile to JSONObject" + e); } } return addr; } public void publish(List<JSONObject> addrs) throws ServiceException { try { getAwsSnsClient().publishSingleMessages(getAwsSnsTopic(), addrs); } catch (Exception e) { throw new ServiceException("Exception while publishing message to Amazon SNS", e); } } private boolean isTranslationNeededForCountry(String country) { return translationConfig.getCountries().contains(country); } private boolean isNonLatin(String addressComponent) { addressComponent = addressComponent.replace("null", ""); matcher = UNWANTED_PATTERN.matcher(addressComponent); String fulladdress = matcher.replaceAll(""); if (StringUtils.isEmpty(fulladdress)) { return false; } String latinAddress = ""; matcher = LATIN_PATTERN.matcher(fulladdress); while (matcher.find()) { latinAddress += matcher.group(); } float matchPercent = (latinAddress.length() * 100 / fulladdress.length()); return matchPercent < translationConfig.getThreshold(); } private boolean isInowRelationAlreadyExists(InowProfileImpl inowProfile) { return getInowProfileRelationService().isRelationExists(inowProfile.getSid()); } private TranslationConfguration getTranslationConfig() { ServiceContext configContext = new ServiceContext(null, null); try { return (TranslationConfguration) getRequiredConfiguration(configContext); } catch (ConfigurationException e) { throw new IllegalStateException(e); } } public AmazonSNSClientImpl getAwsSnsClient() { return awsSnsClient; } public void setAwsSnsClient(AmazonSNSClientImpl awsSnsClient) { this.awsSnsClient = awsSnsClient; } public String getAwsSnsTopic() { return awsSnsTopic; } public void setAwsSnsTopic(String awsSnsTopic) { this.awsSnsTopic = awsSnsTopic; } public InowProfileDao getInowProfileDao() { return inowProfileDao; } public void setInowProfileDao(InowProfileDao inowProfileDao) { this.inowProfileDao = inowProfileDao; } public InowProfileRelationService getInowProfileRelationService() { return inowProfileRelationService; } public void setInowProfileRelationService(InowProfileRelationService inowProfileRelationService) { this.inowProfileRelationService = inowProfileRelationService; } }
-- Adding new attribute named status to translation orphans table ALTER TABLE TRANSLATION_ORPHANS ADD STATUS VARCHAR2(20) DEFAULT 'PENDING' NOT NULL; COMMIT; /
package com.modeln.cdm.service.translation; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.infonow.framework.util.spring.JdbcTemplateProxy; import com.infonow.framework.util.spring.NamedParameterJdbcTemplateProxy; import com.infonow.service.recovery.RecoveryQueries; import com.infonow.service.recovery.RecoveryQueriesImpl; import com.infonow.service.recovery.controller.TranslationController; import org.json.JSONException; import org.json.JSONObject; import com.infonow.crux.dao.InowProfileDao; import com.infonow.crux.impl.InowProfileImpl; import com.infonow.framework.service.ServiceResponse; import com.infonow.framework.service.configuration.support.ServiceDefinition; import com.infonow.framework.service.context.ServiceContext; import com.infonow.framework.service.support.ServiceException; import com.infonow.service.configuration.ConfigurationException; import com.infonow.service.configuration.impl.AbstractBaseServiceWithConfiguration; import com.infonow.service.recovery.TranslationOrphan; import com.modeln.cdm.integration.aws.AmazonSNSClientImpl; import com.modeln.cdm.service.translation.configuration.TranslationConfguration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import software.amazon.awssdk.utils.StringUtils; import javax.sql.DataSource; @ServiceDefinition(name = "translationService", abstraction = com.modeln.cdm.service.translation.TranslationService.class, implementation = com.modeln.cdm.service.translation.TranslationServiceImpl.class) public class TranslationServiceImpl extends AbstractBaseServiceWithConfiguration implements TranslationService { private InowProfileRelationService inowProfileRelationService; private RecoveryQueries _recoveryQueries; private AmazonSNSClientImpl awsSnsClient; private String awsSnsTopic; private InowProfileDao inowProfileDao; private static String UNWANTED_CHARS; private static String LATIN_CHARS; private static Pattern UNWANTED_PATTERN; private static Pattern LATIN_PATTERN; private TranslationConfguration translationConfig; private NamedParameterJdbcTemplate namedParameterJdbcTemplate; private JdbcTemplate template; private TranslationController translationController; Matcher matcher; public TranslationServiceImpl() { if (UNWANTED_CHARS == null) { UNWANTED_CHARS = "[\\u0020-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E\\u0030-\\u0039\\u00A0-\\u00BF\\u2013-\\u204A]"; } if (LATIN_CHARS == null) { LATIN_CHARS = "[\\u0041-\\u005A\\u0061-\\u007A\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\uFF00-\\uFF60]+"; } if (UNWANTED_PATTERN == null) { UNWANTED_PATTERN = Pattern.compile(UNWANTED_CHARS); } if (LATIN_PATTERN == null) { LATIN_PATTERN = Pattern.compile(LATIN_CHARS); } } public RecoveryQueries getRecoveryQueries() { if (_recoveryQueries == null) { throw new IllegalStateException("The attribute _recoveryQueries can not be null"); } return _recoveryQueries; } // public RecoveryQueries getRecoveryQueries() // { // return recoveryQueries; // } public void setRecoveryQueries(RecoveryQueries recoveryQueries) { _recoveryQueries = recoveryQueries; } public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return this.namedParameterJdbcTemplate; } @SuppressWarnings("unchecked") @Override public ServiceResponse execute(ServiceContext serviceContext, Object userObject, Object userData) throws ServiceException { if (!(userData instanceof List<?>)) { throw new IllegalArgumentException("Argument userData must be a List but was " + userData == null ? null : userData.getClass().getName()); } System.out.println("userdata : "); System.out.println(userData); List<TranslationOrphan> ids = ((List<TranslationOrphan>) userData); List<JSONObject> addrs = new ArrayList<JSONObject>(); translationConfig = getTranslationConfig(); String sql = "update translation_orphans set status = :status where sid = :sid"; List<Long> translationIds = new ArrayList<Long>(); for (TranslationOrphan id : ids) { Long sid = id.getSid(); // Map<String, Object> paramMap = new HashMap<String, Object>(); // paramMap.put("sid", sid); // paramMap.put("status","IN PROGRESS"); InowProfileImpl inowProfile = (InowProfileImpl) getInowProfileDao().getBySid(id.getInowProfileSid()); boolean entityNeedsTranslation = isNonLatin(inowProfile.getName()); String address = inowProfile.getStreet1() + inowProfile.getStreet2() + inowProfile.getCity() + inowProfile.getStateProvince() + inowProfile.getPostalCode(); boolean addressNeedsTranslation = isNonLatin(address);//The method returns true if the percentage of Latin characters in the cleaned addressComponent is below the threshold specified in translationConfig. //entity needs translation and address needs translation both are false => addr turns out to be null JSONObject addr = createTranslationInput(inowProfile, entityNeedsTranslation, addressNeedsTranslation); // if(getNamedParameterJdbcTemplate() != null) // { // getNamedParameterJdbcTemplate().update(sql, paramMap); // } translationIds.add(sid);//just trying it out if (addr != null) { translationIds.add(sid); addrs.add(addr); ids.remove(id);//since the ids which are in pending state must not be deleted } } // getRecoveryQueries().test();//is it because of getRecoveryQueries changeStatus("IN PROGRESS",translationIds);//just trying it out if (!addrs.isEmpty())//addrs list is empty, when does it enter into this condition?? { publish(addrs); changeStatus("IN PROGRESS",translationIds); //call a method, pass translation orphans ids list } return new ServiceResponse("Success", ServiceResponse.SUCCESS); } public void changeStatus(String status,List<Long> translationIds){ getRecoveryQueries().updateStatusTranslationOrphans(status, translationIds); } protected JSONObject createTranslationInput(InowProfileImpl inowProfile, boolean entityNeedsTranslation, boolean addressNeedsTranslation) throws ServiceException { JSONObject addr = null; if ((entityNeedsTranslation || addressNeedsTranslation) && isTranslationNeededForCountry(inowProfile.getCountryObject().getTwoCharCode()) && !isInowRelationAlreadyExists(inowProfile)) { addr = new JSONObject(); //pick the orphans which are in pending state /*Fetch the pending orphans. Update their status to IN PROGRESS. Save the updated status back to the database. */ // loadIds(10); // //change the value of the attribute status in the table translation_orphans from pending to in progress // TranslationController translationController = new TranslationController(); // List<TranslationOrphan> pendingOrphans = translationController.getPendingOrphans();//these orphans must be sent to the amazon SQS and the status of those orphans must be changed to in progress // translationController.updateOrphanStatus(pendingOrphans, "IN PROGRESS");//is this where im supposed to change the //status of the orphan, I dont think so since im updating the status of all the orphans which are in pending //state but I'll only have to update the status of the orphan which is picked up AWS queue(SQS) System.out.println("inow id : "+inowProfile.getId()); try { addr.put("id", inowProfile.getIdentifier()); JSONObject addrDetails = new JSONObject(); if (entityNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getName())) { addrDetails.put("name", inowProfile.getName()); } } if (addressNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getStreet1())) { addrDetails.put("street1", inowProfile.getStreet1()); } if (!StringUtils.isEmpty(inowProfile.getStreet2())) { addrDetails.put("street2", inowProfile.getStreet2()); } if (!StringUtils.isEmpty(inowProfile.getCity())) { addrDetails.put("city", inowProfile.getCity()); } if (!StringUtils.isEmpty(inowProfile.getStateProvince())) { addrDetails.put("stateprovince", inowProfile.getStateProvince()); } if (!StringUtils.isEmpty(inowProfile.getPostalCode())) { addrDetails.put("postalcode", inowProfile.getPostalCode()); } if (!StringUtils.isEmpty(inowProfile.getCountry())) { addrDetails.put("country", inowProfile.getCountryObject().getTwoCharCode()); } } addr.put("query", addrDetails); addr.put("target", "EN"); } catch (JSONException e) { throw new ServiceException("Exception while converting InowProfile to JSONObject" + e); } } return addr; } public void publish(List<JSONObject> addrs) throws ServiceException { //here change the orphan's status to in progress try { getAwsSnsClient().publishSingleMessages(getAwsSnsTopic(), addrs); } catch (Exception e) { throw new ServiceException("Exception while publishing message to Amazon SNS", e); } } private boolean isTranslationNeededForCountry(String country) { return translationConfig.getCountries().contains(country); } private boolean isNonLatin(String addressComponent) { addressComponent = addressComponent.replace("null", ""); matcher = UNWANTED_PATTERN.matcher(addressComponent); String fulladdress = matcher.replaceAll(""); if (StringUtils.isEmpty(fulladdress)) { return false; } String latinAddress = ""; matcher = LATIN_PATTERN.matcher(fulladdress); while (matcher.find()) { latinAddress += matcher.group(); } float matchPercent = (latinAddress.length() * 100 / fulladdress.length()); return matchPercent < translationConfig.getThreshold(); } private boolean isInowRelationAlreadyExists(InowProfileImpl inowProfile) { return getInowProfileRelationService().isRelationExists(inowProfile.getSid()); } private TranslationConfguration getTranslationConfig() { ServiceContext configContext = new ServiceContext(null, null); try { return (TranslationConfguration) getRequiredConfiguration(configContext); } catch (ConfigurationException e) { throw new IllegalStateException(e); } } public AmazonSNSClientImpl getAwsSnsClient() { return awsSnsClient; } public void setAwsSnsClient(AmazonSNSClientImpl awsSnsClient) { this.awsSnsClient = awsSnsClient; } public String getAwsSnsTopic() { return awsSnsTopic; } public void setAwsSnsTopic(String awsSnsTopic) { this.awsSnsTopic = awsSnsTopic; } public InowProfileDao getInowProfileDao() { return inowProfileDao; } public void setInowProfileDao(InowProfileDao inowProfileDao) { this.inowProfileDao = inowProfileDao; } public InowProfileRelationService getInowProfileRelationService() { return inowProfileRelationService; } public void setInowProfileRelationService(InowProfileRelationService inowProfileRelationService) { this.inowProfileRelationService = inowProfileRelationService; } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <import resource="commonService.xml" /> <!-- Start of Locator service definition --> <bean id="serviceLocatorService" class="com.infonow.framework.service.remoting.local.ServiceAccessor"> <property name="serviceInterface" value="com.infonow.framework.service.locator.ServiceLocatorService" /> </bean> <!-- Start of TranslationService definition --> <bean id="translationService" class="com.modeln.cdm.service.translation.TranslationServiceImpl"> <property name="serviceLocatorService" ref="serviceLocatorService" /> <property name="configurationServiceUrl" value="local://localhost/configurationService" /> <property name="inowProfileRelationService" ref="inowProfileRelationService" /> <property name="awsSnsClient" ref="awsSnsClient" /> <property name="inowProfileDao" ref="inowProfileDao" /> <property name="mappingFileName" value="translationMapping.xml" /> <property name="awsSnsTopic" value="${translation.aws.sns.topicArn}" /> <property name="recoveryQueries" ref="recoveryQueries" /> </bean> <bean id="recoveryQueries" class="com.infonow.service.recovery.RecoveryQueriesImpl"> <property name="template" ref="nucleusJdbcTemplate"/> <property name="namedParameterJdbcTemplate" ref="nucleusNamedParameterJdbcTemplate"/> </bean> <bean id="inowProfileRelationService" class="com.infonow.framework.service.locator.impl.ServiceLocatorServiceProxyFactory"> <property name="serviceUrl" value="local://localhost/relationService" /> <property name="serviceLocatorService" ref="serviceLocatorService" /> <property name="className" value="com.modeln.cdm.service.relation.InowProfileRelationServiceImpl" /> </bean> <bean id="awsSnsClient" class="com.modeln.cdm.integration.aws.AmazonSNSClientImpl" init-method="startup" destroy-method="shutdown"> <property name="awsCredentials" ref="awsCredentials" /> </bean> <bean id="inowProfileRelationDao" class="com.infonow.crux.dao.orm.hibernate.InowProfileRelationDaoImpl"> <property name="sessionFactory" ref="nucleusSessionFactory" /> </bean> <bean id="inowProfileDao" class="com.infonow.crux.dao.orm.hibernate.InowProfileDao"> <property name="sessionFactory" ref="nucleusSessionFactory" /> </bean> </beans>
package com.infonow.service.recovery.controller; import java.util.Iterator; import java.util.List; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import com.infonow.framework.logging.Level; import com.infonow.framework.logging.Logger; import com.infonow.framework.service.context.ServiceContext; import com.infonow.service.recovery.AbstractRunner; import com.infonow.service.recovery.TranslationOrphan; import static org.apache.commons.collections4.CollectionUtils.collect; public class TranslationController extends ServiceCallerBatchController<TranslationOrphan> { private static final String NAME = "Translation"; public TranslationController() { super(NAME); } @Override public List<TranslationOrphan> loadIds(int numToRead) { List<TranslationOrphan> relationOrphans = getRecoveryQueries().getTranslationOrphans(numToRead,"PENDING");//new attribute here named status, gets all the orphans which are in pending state //TranslationController will load orphans that are in PENDING(or NULL for backward compatibility) status to be processed by TranslationService, when does the entry in the table happen? return relationOrphans; } public void changeStatus() { List<TranslationOrphan> relationOrphans = loadIds(10); } @Override protected RecoveryRunner<List<TranslationOrphan>, ?> createRunner(List<TranslationOrphan> ids) { return new InowRelationRunner(ids); } @Override protected void cleanUp(RecoveryRunner<List<TranslationOrphan>, ?> runner) { List<TranslationOrphan> ids = runner.getId();//skip the orphans which are in pending or inprogress state //loop over ids, create a new list of ids without inprogress and pending status System.out.println("ids"); System.out.println(ids); getRecoveryQueries().deleteTranslateOrphans(ids); } @Override public int getNumberOfIdsPerBatch() { return getNumberOfIdsToRead(); } /** * The Runnable instance use to process a batch of staging Addresses */ private class InowRelationRunner extends AbstractRunner<List<TranslationOrphan>, Object> { ServiceContext _context = null; private Logger LOG = Logger.getLogger(TranslationOrphan.class.getName()); InowRelationRunner(List<TranslationOrphan> ids) { super(ids, NAME, getService(), getTransactionTemplate()); _context = new ServiceContext(); _context.setContextType("default"); } @Override public Object loadDataObject(List<TranslationOrphan> ids) { return loadMatchType(ids); } @Override public Object loadUserObject(List<TranslationOrphan> ids) { // There is a bug in AbstractRunner where the userObject and userData are swapped. // I don't want to change it because it might break every service, so I'll just // flip the objects here like the other services seem to do. // This is actually the userData in the service. return ids; } @Override public String loadMatchType(List<TranslationOrphan> ids) { return null; } @Override public ServiceContext createServiceContext(Object dataObject) { return _context; } @Override protected void handleRunException(Exception exception) { // We are going to make a new orphan with an incremented retry count // and put it back in the queue. List<TranslationOrphan> oldOrphans = (List<TranslationOrphan>) this.getId(); for (Iterator<TranslationOrphan> i = oldOrphans.iterator(); i.hasNext();) { TranslationOrphan oldOrphan = i.next(); long newRetryCount = oldOrphan.getRetryCount() + 1; // First, compute the severity of the exception to be logged based on the retryCount. Level loggingLevel = Level.WARNING; // We only make it SEVERE if the retryCount is a multiple of 10 // to avoid hammering engineering support with e-mails. if ((newRetryCount % 10) == 0) { loggingLevel = Level.SEVERE; } LOG.log(loggingLevel, getDescription() + ": Error processing id - " + getId().toString() + ", re-submitting orphan.", exception); PlatformTransactionManager txnMgr = null; TransactionStatus status = null; try { txnMgr = _transactionTemplate.getTransactionManager(); status = txnMgr.getTransaction( new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW)); double delayMinutesAsDouble = 0.0; int delayMinutesAsInteger = 0; // Compute the delay minutes for the new orphan. // Since there is the potential for numeric overflows, // we are wrapping the math in a try/catch block. try { delayMinutesAsDouble = Math.pow(2, newRetryCount); delayMinutesAsInteger = (int) delayMinutesAsDouble; } catch (Exception e) { delayMinutesAsInteger = 7 * 24 * 60; // Push re-try out to 7 days if numeric overflows occur. } getOrchestrationDao().insertTranslationOrphan(delayMinutesAsInteger, oldOrphan.getInowProfileSid(), newRetryCount); try { if (!status.isRollbackOnly()) { txnMgr.commit(status); } } catch (Exception e) { String msg = getDescription() + ": Error processing id - " + getId().toString(); LOG.log(Level.SEVERE, msg, e); } } catch (Exception e) { String msg = getDescription() + ": Error processing id - " + getId().toString(); LOG.log(Level.SEVERE, msg, e); } finally { try { if (txnMgr != null && status != null && !status.isCompleted()) { txnMgr.rollback(status); } } catch (Exception ee) { String msg = getDescription() + ": Error processing id - " + getId().toString(); LOG.log(Level.SEVERE, msg, ee); } } } } } // end inner-class InowRelationRunner }
/** * RecoveryQueriesImpl.java $Revision$ * * Copyright (c) 2005-2008 InfoNow Corporation. All rights reserved. * INFONOW PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.infonow.service.recovery; import com.infonow.crux.DataFile; import com.infonow.crux.composite.CompositeAccountClassificationOrphan; import com.infonow.crux.dao.jdbc.mapper.GenericMapper; import com.infonow.crux.dao.jdbc.mapper.GenericRowMapper; import com.infonow.crux.dataFile.DataFileOrphanId; import com.infonow.crux.learning.LearnedName; import com.infonow.crux.learning.LearnedName.ApprovalStatus; import com.infonow.crux.learning.LearnedNameOrphan; import com.infonow.crux.schedule.submissionSchedule.SubmissionScheduleOrphan; import com.infonow.crux.sqlGeneration.SqlGenerationUtils; import com.infonow.crux.util.CollectionUtils; import com.infonow.crux.util.Constants.DataAddressTypeEnum; import com.infonow.framework.logging.Logger; import com.infonow.framework.util.spring.JdbcTemplateProxy; import com.infonow.framework.util.spring.NamedParameterJdbcTemplateProxy; import com.infonow.service.submissionPeriodUpdate.SubmissionPeriodUpdateOrphanId; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.transaction.annotation.Transactional; /** * Query implementations for the recovery service. * * @author Chris Lambrecht * * @version $Revision$ */ @SuppressWarnings("rawtypes") public class RecoveryQueriesImpl implements RecoveryQueries { private static final Logger LOG = Logger.getLogger(RecoveryQueriesImpl.class.getName()); private static final String DELETE_RL_ORPHAN = "delete from rl_orphans where master_run_id = ?"; private final RowMapper SID_MAPPER = new SidRowMapper(); private final RowMapper LINE_ITEM_MAPPER = new LineItemRowMapper(); private final RowMapper VALIDATION_ITEM_MAPPER = new ValidationRowMapper(); private final RowMapper SERIAL_NUMBER_MAPPER = new SerialNumberRowMapper(); private final RowMapper TUPPLE_MAPPER = new TupleMapper(); private final RowMapper SLIA_MAPPER = new SliaProfileMapper(); private final RowMapper INOW_PROFILE_HIERARCHY_MAPPER = new InowProfileHierarchyRowMapper(); private final RowMapper HIERARCHY_PARENT_MAPPER = new HierarchyParentMapper(); private final RowMapper ADDRESS_HISTORY_MAPPER = new AddressHistoryMapper(); private final RowMapper INOW_PROFILE_MAPPER = new InowProfileRowMapper(); private final RowMapper SALES_LINE_ITEM_NORMALIZATION_MAPPER = new SalesLineItemNormalizationRowMapper(); private final RowMapper REPORTING_PARTNER_MAPPER = new ReportingPartnerRowMapper(); private final RowMapper PROFILE_PARTNER_MAPPER = new ProfilePartnerRowMapper(); private final RowMapper EXPORTER_ORPHAN_MAPPER = new ExporterOrphanRowMapper(); private final RowMapper COMPOSITE_ACCOUNT_CLASS_ORPHAN_MAPPER = new CompositeAccountClassificationOrphanMapper(); private final RowMapper SUBMISSION_SCHEDULE_ORPHAN_MAPPER = new SubmissionScheduleOrphanMapper(); private final RowMapper LEARNED_NAME_ORPHAN_MAPPER = new LearnedNameOrphanMapper(); private final RowMapper INOW_STANDARDIZATION_ORPHAN_MAPPER = new InowStandardizationOrphanMapper(); private final RowMapper INOW_TRANSLATION_ORPHAN_MAPPER = new InowTranslationOrphanMapper(); private final RowMapper SUBMISSION_SCHEDULE_UPDATE_ORPHAN_MAPPER = new SubmissionPeriodUpdateOrphanMapper(); private final RowMapper INOW_RELATION_ORPHAN_MAPPER = new InowRelationOrphanMapper(); private final RowMapper EXPORT_OUTPUT_ORPHAN_MAPPER = new ExportOutputOrphanMapper(); private final RowMapper VALIDATION_TRACKING_ORPHAN_MAPPER = new ValidationTrackingRowMapper(); private final RowMapper VALIDATION_DELETED_ORPHAN_MAPPER = new ValidationDeletedRowMapper(); @Autowired private JdbcTemplate template; @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** * Default Constructor */ public RecoveryQueriesImpl() { super(); } /** * Get the value of the template field. * * @return Returns the value of template. */ public JdbcTemplate getTemplate() { return this.template; } /** * Set the value of the template field. * * @param template * The template value to set. */ public void setTemplate(JdbcTemplate template) { this.template = template; } /** * Get the value of the namedParameterJdbcTemplate field. * * @return Returns the value of namedParameterJdbcTemplate. */ public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { System.out.println("in getNamedParameterejdbctem"); System.out.println(this); System.out.println(this.namedParameterJdbcTemplate); // Get the current stack trace StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); // stackTraceElements[0] is getStackTrace // stackTraceElements[1] is getNamedParameterJdbcTemplate // stackTraceElements[2] is the method that called getNamedParameterJdbcTemplate if (stackTraceElements.length > 2) { String callerMethodName = stackTraceElements[2].getMethodName(); System.out.println("Caller Method: " + callerMethodName); System.out.println(this); System.out.println(this.namedParameterJdbcTemplate); } return this.namedParameterJdbcTemplate; } /** * Set the value of the namedParameterJdbcTemplate field. * * @param namedParameterJdbcTemplate * The namedParameterJdbcTemplate value to set. */ public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; } /** * Inject a reference to the {@link DataSource} to use for all queries * * @param dataSource * - database connect source */ public void setDataSource(DataSource dataSource) { template = new JdbcTemplateProxy(dataSource); namedParameterJdbcTemplate = new NamedParameterJdbcTemplateProxy(dataSource); } /** * Selects input file ids from the orphan table. Limit the number of rows returned to numIds and make sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<Long> getParserOrphans(int numIds, int maxPerCustomer) { final String sql = "select data_file_sid from ( " + "select * from ( " + "select ifo.*, " + " rank() over( partition by ifo.customer_sid order by sid ) rank_overall " + "from ( " + "select ifo.*, " + " rank() over( partition by ifo.customer_sid, ifo.type order by nvl(ifo.update_date,ifo.create_date) ) rank_of_type " + "from ( " + "select ifo.data_file_sid, " + " if.customer_sid, " + " ifo.sid, " + " ifo.process_time, if.create_date, if.update_date, " + " CASE WHEN (instr(upper(data_type),'CATALOG') > 0) THEN 'CATALOG' " + " WHEN (instr(upper(data_type),'PROFILE') > 0) THEN 'PROFILE' " + " ELSE data_type " + " END as type " + "from input_file_orphans ifo " + "join data_file if on ifo.data_file_sid = if.sid " + "where process_time < sysdate " + ") ifo " + ") ifo " + "where ifo.type not in ('CATALOG','PROFILE') " + " or ifo.rank_of_type = 1 " + ") " + "where rank_overall <= ? " + "order by rank_overall " + ") where rownum < ? "; return getTemplate().query(sql, new Object[] { maxPerCustomer, numIds }, SID_MAPPER); } /** * Select sales product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<LineItemOrphanId> getSalesProductOrphanIds(int numIds) { return getIds("sales_line_item_orphans", new String[] { "sid", "sales_line_item_sid", "match_type", "customer_sid" }, null, numIds, LINE_ITEM_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getSalesLineItemSerialNumberOrphanIds(int, * com.infonow.service.recovery.SerialNumberOrphanId) */ @SuppressWarnings("unchecked") public List<SerialNumberOrphanId> getSalesLineItemSerialNumberOrphanIds(int numIds) { return getIds("SLI_SERIAL_NUMBER_ORPHANS", new String[] { "sid", "sli_serial_number_sid", "match_type", "customer_sid" }, null, numIds, SERIAL_NUMBER_MAPPER); } /** * Select inv product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<LineItemOrphanId> getInvProductOrphanIds(int numIds) { return getIds("inv_line_item_orphans", new String[] { "sid", "inv_line_item_sid", "match_type", "customer_sid" }, null, numIds, LINE_ITEM_MAPPER); } /** * Select Profile Partner ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<ProfilePartnerOrphanId> getProfilePartnerOrphanIds(int numIds) { final String query = "SELECT" + " sid," + " profile_partner_sid," + " customer_sid," + " match_type," + " retry_count" + " FROM" + " (" + " SELECT" + " *" + " FROM" + " (" + " SELECT" + " sid," + " profile_partner_sid," + " customer_sid," + " match_type," + " retry_count," + " RANK() OVER(" + " PARTITION BY customer_sid" + " ORDER BY" + " sid" + " ) rank" + " FROM" + " (" + " SELECT" + " po.sid," + " po.profile_partner_sid," + " pp.customer_sid," + " po.match_type," + " po.retry_count" + " FROM" + " profile_orphans po" + " JOIN profile_partner pp ON pp.sid = po.profile_partner_sid" + " WHERE" + " process_time < SYSDATE AND (pp.address_sid is null or pp.address_sid = 0)" + " " + " UNION " + " " + " SELECT" + " po.sid," + " po.profile_partner_sid," + " pp.customer_sid," + " po.match_type," + " po.retry_count" + " FROM" + " profile_orphans po" + " JOIN profile_partner pp ON pp.sid = po.profile_partner_sid" + " JOIN address_history ah ON ah.address_sid = pp.address_sid" + " WHERE" + " process_time < SYSDATE AND ah.stage = 'API_ENRICHED' " + " )" + " )" + " ORDER BY" + " rank" + " )" + "WHERE" + " ROWNUM < ?"; return getTemplate().query(query, new Object[] { numIds }, PROFILE_PARTNER_MAPPER); } /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaProfileOrphanIds(int numIds) { final String query = "select * from (select * from (select sliapo.sid, " + " sliapo.sales_line_item_sid, " + " sliapo.address_Sid, " + " sliapo.address_type, " + " sliapo.match_type, sliapo.customer_sid, sli.BILL_TO_ADDR_EXTERNAL_ID" + " ,sli.SOLD_TO_ADDR_EXTERNAL_ID, sli.SHIP_TO_ADDR_EXTERNAL_ID" + " ,sli.SELL_FROM_ADDR_EXTERNAL_ID, sli.SHIP_FROM_ADDR_EXTERNAL_ID" + " ,sli.SALES_IN_ADDR_EXTERNAL_ID, sli.PURCH_CUST_ADDR_EXTERNAL_ID" + " ,sli.DER_END_CUST_ADDR_EXTERNAL_ID,sli.deleted " + " ,case when exists (select 1 from address_history ah where ah.address_sid = sliapo.address_sid and ah.stage = 'RAW')" + " then 1 else 0 end raw_exists " + " ,case when exists (select 1 from address_history ah where ah.address_sid = sliapo.address_sid and ah.stage = 'REF_DATA_ENRICHED') " + " then 1 else 0 end ref_data_exists," + " rank() over(partition by sliapo.customer_sid order by sliapo.sid) rank " + " from slia_profile_orphans sliapo join sales_line_item sli on sli.sid = sliapo.sales_line_item_sid and " + " sli.customer_sid = sliapo.customer_sid where process_time < sysdate" + " order by rank,address_sid) where (raw_exists = 0 or (raw_exists = 1 and ref_data_exists = 1))) where rownum < ? "; return getTemplate().query(query, new Object[] { numIds }, SLIA_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getSliaCompositeAccountOrphanIds(int) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaCompositeAccountOrphanIds(int numIds) { return getIds("slia_composite_acct_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type", "customer_sid" }, null, numIds, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<InowProfileHierarchyOrphanId> getInowProfileHierarchyOrphanIds(int numToRead) { final String query = "SELECT" + " * " + " FROM" + " (" + " SELECT" + " *" + " FROM" + " (" + " SELECT" + " ipho.sid," + " ipho.inow_profile_sid," + " ipho.customer_sid," + " ipho.named_ip_hierarchy_sid," + " ipho.reprocess_flag," + " ipho.retry_count," + " ipho.priority," + " RANK() OVER(" + " PARTITION BY ipho.customer_sid" + " ORDER BY" + " sid ASC" + " ) rank," + " upper(csr.entity_name)" + " || '-----'" + " || csr.country orphan_key" + " FROM" + " inow_profile_hierarchy_orphans ipho" + " LEFT JOIN csr_overlay_v csr ON csr.customer_sid = ipho.customer_sid" + " AND ipho.inow_profile_sid = csr.ip_sid" + " WHERE" + " process_time < sysdate" + " )" + " ORDER BY" + " priority," + " rank" + " ) " + " WHERE " + " ROWNUM < :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_PROFILE_HIERARCHY_MAPPER); } @SuppressWarnings("unchecked") public List<HierarchyParentOrphanId> getHierarchyParentOrphanIds(int numToRead) { final String query = "select * from ( " + "select * from ( " + "select hpo.sid, " + " hpo.inow_profile_sid, " + " hpo.customer_sid, " + " hpo.named_ip_hierarchy_sid, " + " hpo.reprocess_flag, " + " hpo.retry_count, " + " hpo.priority, " + " rank() over( partition by hpo.customer_sid order by sid asc) rank " + "from hierarchy_parent_orphans hpo " + "where process_time < sysdate) " + "order by priority,rank " + ") " + "where rownum < :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, HIERARCHY_PARENT_MAPPER); } @SuppressWarnings("unchecked") public List<AddressHistoryOrphanId> getAddressHistoryOrphanIds(int numToRead, String tableName) { final String query = "select * from ( " + "select * from ( " + "select aho.sid, " + " aho.address_history_sid, aho.retry_count " + "from " + tableName + " aho " + "where process_time < sysdate) " + "order by sid " + ") " + "where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, ADDRESS_HISTORY_MAPPER); } @SuppressWarnings("unchecked") public List<SalesLineItemNormalizationOrphanId> getSalesLineItemNormalizationOrphanIds(int numToRead) { return getIds("sli_normalization_orphans", new String[] { "sid", "sales_line_item_sid", "customer_sid", "price_type, entity_sid" }, null, numToRead, SALES_LINE_ITEM_NORMALIZATION_MAPPER); } /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaReportingPartnerOrphanIds(int numIds) { return getIds("reporting_partner_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "null" }, null, numIds, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationOrphanId> getSalesLineItemValidationOrphanIds(int numToRead) { final String query = "select * from ( " + "select sv.sid,sv.sales_line_item_sid,sv.match_type,sv.customer_sid, " + " sli.reporting_partner_sid,sli.data_file_sid,rank() over(partition by sv.customer_sid order by sv.create_date) rank_by_cust" + " from sli_validation_orphans sv" + " join sales_line_item sli on sli.sid = sv.sales_line_item_sid " + " and sli.customer_sid = sli.customer_Sid where process_time < sysdate order by rank_by_cust,sv.create_date " + ") where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, VALIDATION_ITEM_MAPPER); } @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaValidationOrphanIds(int numToRead) { return getIds("slia_validation_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type", "customer_sid" }, null, numToRead, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationTrackingOrphanId> getValidationTrackingOrphanIds(int numToRead) { return getIds("validation_tracking_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "create_date", "update_date", "retry_count" }, null, numToRead, VALIDATION_TRACKING_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationNotificationOrphanId> getValidationNotificationOrphanIds(int numToRead) { return getIds("validation_notification_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "create_date", "update_date", "retry_count" }, null, numToRead, VALIDATION_DELETED_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationOrphanId> getInventoryLineItemValidationOrphanIds(int numToRead) { final String query = "select * from ( " + "select sv.sid,sv.inv_line_item_sid,sv.match_type,sv.customer_sid, " + " ili.reporting_partner_sid,ili.data_file_sid,rank() over(partition by sv.customer_sid order by sv.create_date) rank_by_cust" + " from ili_validation_orphans sv" + " join inv_line_item ili on ili.sid = sv.inv_line_item_sid " + " and ili.customer_sid = ili.customer_Sid where process_time < sysdate order by rank_by_cust,sv.create_date " + ") where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, VALIDATION_ITEM_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getReportingPartnerOrphanIds(int) */ @SuppressWarnings("unchecked") @Override public List<ReportingPartnerOrphanId> getReportingPartnerOrphanIds(int numToRead) { return getIds("reporting_partner_inow_orphs", new String[] { "sid", "reporting_partner_sid" }, null, numToRead, REPORTING_PARTNER_MAPPER); } @SuppressWarnings("unchecked") @Override public List<Long> getAddressStandardizationOrphans(int numToRead) { return getIds("addr_standardization_orphans", new String[] { "address_sid" }, null, numToRead, SID_MAPPER); } @SuppressWarnings("unchecked") @Override public List<InowStandardizationOrphanId> getInowProfileStandardizationOrphans(int numToRead) { return getIds("inow_profile_std_orphans", new String[] { "sid", "inow_profile_sid", "retry_count" }, null, numToRead, INOW_STANDARDIZATION_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") @Override public List<InowProfileOrphanId> getInowProfileDedupOrphans(int numToRead) { return getIds("inow_profile_dedup_orphans", new String[] { "sid", "inow_profile_sid", "customer_sid" }, null, numToRead, INOW_PROFILE_MAPPER); } @SuppressWarnings("unchecked") @Override public List<Long> getProfilePartnerRematchOrphanIds(int numToRead) { return getIds("profile_rematch_orphans", new String[] { "profile_partner_sid" }, null, numToRead, SID_MAPPER); } @SuppressWarnings("unchecked") @Override public List<SalesLineItemAddressOrphanId> getSliaRematchOrphanIds(int numToRead) { return getIds("slia_profile_rematch_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type" }, null, numToRead, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") @Override public List<ExporterOrphanId> getExporterOrphanIds(int numToRead) { return getIds("exporter_orphans", new String[] { "sid", "customer_sid", "export_name" }, null, numToRead, EXPORTER_ORPHAN_MAPPER); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteDataFileId(Long id) { if (id == null) { return; } deleteId("input_file_orphans", "data_file_sid", id); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteSalesProductId(LineItemOrphanId id) { deleteId("sales_line_item_orphans", id.getSid()); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteSalesLineItemSerialNumberId(com.infonow.service.recovery. * SerialNumberOrphanId) */ public void deleteSalesLineItemSerialNumberId(SerialNumberOrphanId id) { deleteId("sli_serial_number_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteProfilePartnerId(ProfilePartnerOrphanId id) { deleteId("profile_orphans", "sid", id.getSid()); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteInvProductId(LineItemOrphanId id) { deleteId("inv_line_item_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSliaProfileId(SalesLineItemAddressOrphanId id) { deleteId("slia_profile_orphans", id.getSid()); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteSliaCompositeAccountId(com.infonow.service.recovery. * SalesLineItemAddressOrphanId) */ public void deleteSliaCompositeAccountId(SalesLineItemAddressOrphanId id) { deleteId("slia_composite_acct_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSliaReportingPartnerId(SalesLineItemAddressOrphanId id) { deleteId("reporting_partner_orphans", id.getSid()); } public void deleteSalesLineItemValidationId(List<ValidationOrphanId> ids) { String sql = new String("delete from sli_validation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteValidationTrackingIds(List<ValidationTrackingOrphanId> ids) { String sql = new String("delete from validation_tracking_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteValidationNotificationIds(List<ValidationNotificationOrphanId> ids) { String sql = new String("delete from validation_notification_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteSliaValidationId(SalesLineItemAddressOrphanId id) { deleteId("slia_validation_orphans", id.getSid()); } public void deleteInventoryLineItemValidationId(List<ValidationOrphanId> ids) { String sql = new String("delete from ili_validation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteSalesLineItemOrphans(List<Long> salesLineItemSids) { String sql = new String("delete from sales_line_item_orphans where sales_line_item_sid in (:sids)"); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", salesLineItemSids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteSalesLineItemOrphans(DataFile dataFile) { String sql = new String("delete from sales_line_item_orphans where sales_line_item_sid in " + " (select sid from sales_line_item where data_file_sid = ? and customer_sid = " + dataFile.getCustomer().getSid().toString() + ")"); getTemplate().update(sql, new Object[] { dataFile.getSid() }); } @Override public void deleteInvLineItemOrphans(List<Long> invLineItemSids) { String sql = new String("delete from inv_line_item_orphans where inv_line_item_sid in (:sids)"); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", invLineItemSids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Transactional @Override public void updateStatusTranslationOrphans(String status, List<Long> translationOrphanSids)//pass the array of sids, and pass status { String sql = new String("update translation_orphans set status = :status where sid in (:sids)"); String commit = new String("commit"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("sids", translationOrphanSids); paramMap.put("status", status); System.out.println("getNamedParameterJdbcTemplate() in update status method: "+getNamedParameterJdbcTemplate()); System.out.println(getNamedParameterJdbcTemplate()); if(getNamedParameterJdbcTemplate() != null || getTemplate() != null)//why are these null? { int rowsUpdated = getNamedParameterJdbcTemplate().update(sql, paramMap); System.out.println("Number of rows updated: " + rowsUpdated); getNamedParameterJdbcTemplate().query(commit,SID_MAPPER); } else{ System.out.println("printing getNamedParameterJdbcTemplate : "+getNamedParameterJdbcTemplate());//why is this null??? System.out.println("printing getTemplate : "+getTemplate()); System.out.println("getNamedParameterJdbcTemplate is null"); } } @Override public void test()//pass the array of sids, and pass status { String sql = new String("select sid from translation_orphans where sid = :sid"); System.out.println("getNamedParameterJdbcTemplate() in test method: "+getNamedParameterJdbcTemplate()); System.out.println(getNamedParameterJdbcTemplate()); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("sid", 2); System.out.println("getNamedParameterJdbcTemplate from test method : "+getNamedParameterJdbcTemplate()); if(getNamedParameterJdbcTemplate() != null || getTemplate() != null)//why are these null? { getTemplate().update(sql,paramMap); getNamedParameterJdbcTemplate().update(sql, paramMap); } else{ System.out.println("printing getNamedParameterJdbcTemplate : "+getNamedParameterJdbcTemplate());//why is this null??? System.out.println("printing getTemplate : "+getTemplate()); System.out.println("getNamedParameterJdbcTemplate is null"); } } public void deleteRegexStandardizationOrphans(List<AddressHistoryOrphanId> orphanIds)//follow this { String sql = new String("delete from regex_std_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteRefDataStandardizationOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from ref_data_std_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressHistoryOrphans(List<AddressHistoryOrphanId> orphanIds, String orphanTable) { String sql = new String("delete from " + orphanTable + " where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressGradingOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from address_grading_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteTranslateOrphans(List<TranslationOrphan> orphanIds) { for (List<TranslationOrphan> orphans : CollectionUtils.partition(orphanIds, 1000)) { String sql = new String( "delete from translation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphans.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } } @Override public void deleteExportOutputOrphans(List<ExportOutputOrphanId> orphanIds) { String sql = new String( "delete from export_output_orphans where sid in (:sids)"); Map<String, Object> paramMap = new HashMap<String, Object>(); List<Long> sids = orphanIds.stream().map(o -> o.getSid()) .collect(Collectors.toList()); List<List<Long>> sidsPartition = CollectionUtils.partition(sids, 1000); for (List<Long> batch : sidsPartition) { paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } } @Override public void deleteSubmissionPeriodUpdateOrphans( SubmissionPeriodUpdateOrphanId orphanId) { String sql = new String( "delete from SP_UPDATE_ORPHANS where sid in (:sid)"); Map<String, Long> paramMap = new HashMap<String, Long>(); paramMap.put("sid", orphanId.getSid()); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteInowRelationOrphan(InowRelationOrphan orphanId) { String sql = new String("delete from relation_orphans where sid = :sid"); Map<String, Long> paramMap = new HashMap<String, Long>(); paramMap.put("sid", orphanId.getSid()); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressQualityOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from address_quality_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteInvLineItemOrphans(DataFile dataFile) { String sql = new String("delete from inv_line_item_orphans where inv_line_item_sid in " + " (select sid from inv_line_item where data_file_sid = ? and customer_sid = " + dataFile.getCustomer().getSid().toString() + ")"); getTemplate().update(sql, new Object[] { dataFile.getSid() }); } @Override public List<DataFileOrphanId> getDataFileDeleteOrphans(int numToRead) { List<?> orphanIds = null; orphanIds = getIds("data_file_delete_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "reprocess", "user_login", "retry_count", "preserve_date" }, null, null, numToRead, new GenericRowMapper() { @Override public Object mapRow(ResultSet rs, int arg1) throws SQLException { DataFileOrphanId dfoi = new DataFileOrphanId(); dfoi.setDataFileSid(this.getLong(rs, "data_file_sid")); dfoi.setCustomerSid(this.getLong(rs, "customer_sid")); dfoi.setReprocess(this.getBooleanValue(rs, "reprocess")); dfoi.setUserLogin(this.getString(rs, "user_login")); dfoi.setSid(this.getLong(rs, "sid")); dfoi.setRetryCount(this.getLong(rs, "retry_count")); dfoi.setPreserveDate(this.getBooleanValue(rs, "preserve_date")); return dfoi; } }); return (List<DataFileOrphanId>) orphanIds; } @SuppressWarnings("unchecked") public List<TranslationOrphan> getTranslationOrphans(int numToRead, String status) { String query = "select * from ( select ipro.sid, ipro.inow_profile_sid, ipro.retry_count, ipro.status, rownum cnt " + "from translation_orphans ipro where process_time < sysdate " + "order by sid ) result where rownum <= :numToRead "; Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("numToRead", String.valueOf(numToRead)); if(status!=null){ query = query + "and result.status = :status"; paramMap.put("status",status); } System.out.println("getNamedParameterJdbcTemplate() in method getTranslationOrphans : "+getNamedParameterJdbcTemplate()); System.out.println(getNamedParameterJdbcTemplate()); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_TRANSLATION_ORPHAN_MAPPER); } @Override @SuppressWarnings("unchecked") public List<SubmissionPeriodUpdateOrphanId> getSubmissionPeriodUpdateOrphans(int numToRead) { final String query = "select * from ( select spuo.sid, spuo.customer_sid, spuo.old_start_date, spuo.retry_count, rownum cnt " + "from sp_update_orphans spuo where process_time < sysdate " + "order by sid ) where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, SUBMISSION_SCHEDULE_UPDATE_ORPHAN_MAPPER); } @Override public List<ExportOutputOrphanId> getExportOutputOrphans(int numToRead) { final String query = "WITH rowlimit AS (" + "SELECT * FROM (" + "SELECT EXPORT_STATUS_SID FROM export_output eo JOIN export_output_orphans eoo " + "ON eoo.EXPORT_OUTPUT_SID= eo.sid AND eo.customer_sid = eoo.customer_sid " + "WHERE eoo.process_time < sysdate + interval '10' second " + "GROUP BY EXPORT_STATUS_SID ) " + "WHERE rownum < :numToRead ) " + "SELECT eoo.SID,eoo.CUSTOMER_SID,eoo.SESSION_ID,eoo.EXPORT_OUTPUT_SID," + "eo.EXPORT_STATUS_SID,eoo.retry_count,es.export_name, eoo.export_request_sid" + ",RANK() OVER (PARTITION BY eo.customer_sid,eo.EXPORT_STATUS_SID ORDER BY eoo.sid ) rankof " + "FROM EXPORT_OUTPUT eo JOIN EXPORT_OUTPUT_ORPHANS eoo ON eoo.EXPORT_OUTPUT_SID = eo.sid " + "JOIN rowlimit ON rowlimit.export_status_sid = eo.EXPORT_STATUS_SID " + "join export_status es on es.sid = eo.export_status_sid and es.customer_sid = eo.customer_sid " + "ORDER BY rankof"; Map<String, Object> params = new HashMap<>(); params.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, params, EXPORT_OUTPUT_ORPHAN_MAPPER); } @Override @SuppressWarnings("unchecked") public List<InowRelationOrphan> getInowRelationOrphans(int numToRead) { final String query = "select * from ( select ro.sid, ro.inow_profile_sid, ro.related_inow_profile_sid, ro.retry_count, rownum cnt " + "from relation_orphans ro where process_time < sysdate " + "order by sid ) where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_RELATION_ORPHAN_MAPPER); } @Override public void deleteDataFileDeleteOrphanId(DataFileOrphanId id) { String sql = new String("delete from data_file_delete_orphans where sid = ? " + " and customer_sid = " + id.getCustomerSid()); getTemplate().update(sql, new Object[] { id.getSid() }); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteReportingPartnerId(com.infonow.service.recovery. * ReportingPartnerOrphanId) */ @Override public void deleteReportingPartnerId(ReportingPartnerOrphanId id) { if (id == null || id.getSid() == null || id.getSid() <= 0) { return; } deleteId("reporting_partner_inow_orphs", id.getSid()); } public void deleteInowProfileHierarchyId(InowProfileHierarchyOrphanId id) { deleteId("inow_profile_hierarchy_orphans", id.getSid()); } public void deleteHierarchyParentId(HierarchyParentOrphanId id) { deleteId("hierarchy_parent_orphans", id.getSid()); } public void deleteHierarchyParentIds(List<HierarchyParentOrphanId> ids) { List<Long> sids = new ArrayList<Long>(); for (HierarchyParentOrphanId id : ids) { sids.add(id.getSid()); } deleteIds("hierarchy_parent_orphans", sids); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSalesLineItemNormalizationId(SalesLineItemNormalizationOrphanId id) { deleteId("sli_normalization_orphans", id.getSid()); } @Override public void deleteAddressStandardizationOrphan(Long id) { deleteId("addr_standardization_orphans", "address_sid", id); } @Override public void deleteInowProfileStandardizationOrphan(InowStandardizationOrphanId id) { deleteId("inow_profile_std_orphans", "inow_profile_sid", id.getInowProfileSid()); } @Override public void deleteInowProfileDedupOrphan(InowProfileOrphanId id) { deleteId("inow_profile_dedup_orphans", id.getSid()); } @Override public void deleteProfilePartnerRematchId(Long id) { deleteId("profile_rematch_orphans", "profile_partner_sid", id); } @Override public void deleteSliaRematchId(SalesLineItemAddressOrphanId id) { deleteId("slia_profile_rematch_orphans", id.getSid()); } @Override public void deleteExporterOrphan(ExporterOrphanId id) { deleteId("exporter_orphans", id.getSid()); } /** * Dynamically generates a recovery orphan query for select * This function will alternate customers round robin if no orderByClause is specified * and there is customer_sid in the columns * @param tableName * @param columns * @param orderByClause * @param numIds * @param rowMapper * @return list of rowMaper */ @SuppressWarnings("rawtypes") private List getIds(String tableName, String[] columns, String orderByClause, Integer numIds, RowMapper rowMapper) { return getIds(tableName, columns, null, orderByClause, numIds, rowMapper); } /** * Dynamically generates a recovery orphan query for select * This function will alternate customers round robin if no orderByClause is specified * and there is customer_sid in the columns * @param tableName * @param columns * @param additionalWhereClause * @param orderByClause * @param numIds * @param rowMapper * @return list of rowMaper */ @SuppressWarnings("rawtypes") private List getIds(String tableName, String[] columns, String additionalWhereClause, String orderByClause, Integer numIds, RowMapper rowMapper) { if (columns == null || columns.length <= 0) { return null; } StringBuilder sqlBuffer = new StringBuilder("select * from (select "); for (int i = 0; i < columns.length; ++i) { if (i > 0) { sqlBuffer.append(", "); } sqlBuffer.append(columns[i]); // automatically implement customer 100 functions for all queues. if (StringUtils.equalsIgnoreCase(columns[i], "customer_sid")) { if (i > 0) { sqlBuffer.append(", "); } sqlBuffer.append("rank() over(partition by customer_sid order by sid) rank_by_cust "); if (StringUtils.isEmpty(orderByClause)) { orderByClause = "order by rank_by_cust"; } } } sqlBuffer.append(" from "); sqlBuffer.append(tableName); // Construct the WHERE clause sqlBuffer.append(" where process_time < sysdate "); if (!StringUtils.isEmpty(additionalWhereClause)) { sqlBuffer.append(" and "); sqlBuffer.append(additionalWhereClause); } if (StringUtils.isEmpty(orderByClause)) { sqlBuffer.append(" order by process_time desc "); } else { sqlBuffer.append(orderByClause); } sqlBuffer.append(" ) where rownum <= ?"); String query = sqlBuffer.toString(); return getTemplate().query(query, new Object[] { numIds }, rowMapper); } private void deleteId(String tableName, Long sid) { deleteId(tableName, null, sid); } private void deleteId(String tableName, String columnName, Long sid) { StringBuffer sqlBuffer = new StringBuffer("delete from "); sqlBuffer.append(tableName); if (StringUtils.isEmpty(columnName)) { sqlBuffer.append(" where sid = ?"); } else { sqlBuffer.append(" where "); sqlBuffer.append(columnName); sqlBuffer.append(" = ?"); } template.update(sqlBuffer.toString(), new Object[] { sid }); } private void deleteIds(String tableName, List<Long> sids) { for (List<Long> inList : CollectionUtils.partition(sids, 1000)) { deleteIds(tableName, null, inList); } } private void deleteIds(String tableName, String columnName, List<Long> sids) { StringBuffer sqlBuffer = new StringBuffer("delete from "); sqlBuffer.append(tableName); if (StringUtils.isEmpty(columnName)) { sqlBuffer.append(" where sid in "); } else { sqlBuffer.append(" where "); sqlBuffer.append(columnName); sqlBuffer.append(" in "); } String deleteQuery = SqlGenerationUtils.buildInClauseVariables(sqlBuffer.toString(), sids.size()); List<Object> params = new ArrayList<Object>(); params.addAll(sids); template.update(deleteQuery, params.toArray()); } /** * RowMapper instance used to extract the sid from a query */ private class SidRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return (rs.getLong(1)); } } /** * RowMapper instance used to extract the line item from a query */ private class LineItemRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { if (rs.getMetaData().getColumnCount() == 2) { // SID and SLI_SID return new LineItemOrphanId(rs.getLong(1), rs.getLong(2), null); } else { // SID, SLI_SID and MATCH_TYPE return new LineItemOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); } } } /** * RowMapper instance used to extract the line item from a query */ private class ValidationRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { ValidationOrphanId orphan = new ValidationOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); orphan.setCustomerSid(rs.getLong(4)); orphan.setReportingPartnerSid(rs.getLong(5)); orphan.setDataFileSid(rs.getLong(6)); return orphan; } } private class ValidationTrackingRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ValidationTrackingOrphanId(rs.getLong("sid"), rs.getLong("data_file_sid"), rs.getLong("customer_sid"), rs.getDate("create_date"), rs.getDate("update_date"), rs.getLong("retry_count")); } } private class ValidationDeletedRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ValidationNotificationOrphanId(rs.getLong("sid"), rs.getLong("data_file_sid"), rs.getLong("customer_sid"), rs.getDate("create_date"), rs.getDate("update_date"), rs.getLong("retry_count")); } } private class ReportingPartnerRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ReportingPartnerOrphanId(rs.getLong(1), rs.getLong(2)); } } /** * RowMapper instance used to extract the serial number from a query */ private class SerialNumberRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new SerialNumberOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); } } private class SliaProfileMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { SalesLineItemAddressOrphanId orphan = new SalesLineItemAddressOrphanId(rs.getLong(1), rs.getLong(2), rs.getLong(3), DataAddressTypeEnum.fromDbCode(rs.getString(4)), rs.getString(5), rs.getLong(6)); /* * the natural key for slia_profile orphans is the address, and any external id for that line item if it is * deleted and the customer this is because external id's / deleted line items have different code paths for * short circuit matching */ StringBuilder sb = new StringBuilder(); sb.append(orphan.getAddressSid()); sb.append(orphan.getCustomerSid()); // we need this so that we don't cause a race condition on saving the ami data in the amidao sb.append(orphan.getSalesLineItemSid()); switch (orphan.getAddressType()) { case BILL_TO: sb.append(rs.getString("BILL_TO_ADDR_EXTERNAL_ID")); break; case SHIP_TO: sb.append(rs.getString("SHIP_TO_ADDR_EXTERNAL_ID")); break; case SOLD_TO: sb.append(rs.getString("SOLD_TO_ADDR_EXTERNAL_ID")); break; case SHIP_FROM: sb.append(rs.getString("SHIP_FROM_ADDR_EXTERNAL_ID")); break; case SELL_FROM: sb.append(rs.getString("SELL_FROM_ADDR_EXTERNAL_ID")); break; case SALES_IN: sb.append(rs.getString("SALES_IN_ADDR_EXTERNAL_ID")); break; case PURCHASING_CUSTOMER: sb.append(rs.getString("PURCH_CUST_ADDR_EXTERNAL_ID")); break; case DERIVED_END_CUSTOMER: sb.append(rs.getString("DER_END_CUST_ADDR_EXTERNAL_ID")); break; } sb.append(rs.getInt("deleted")); orphan.setGroupByValue(sb.toString()); return orphan; } } private class TupleMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new SalesLineItemAddressOrphanId(rs.getLong(1), rs.getLong(2), rs.getLong(3), DataAddressTypeEnum.fromDbCode(rs.getString(4)), rs.getString(5), 0l); } } private class InowProfileHierarchyRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { InowProfileHierarchyOrphanId row = new InowProfileHierarchyOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setHierarchySid(rs.getLong("named_ip_hierarchy_sid")); if (rs.wasNull()) { row.setHierarchySid(null); } Long reprocess = rs.getLong("reprocess_flag"); if (!rs.wasNull()) { row.setReprocess(reprocess == 0 ? Boolean.FALSE : Boolean.TRUE); } row.setRetryCount(rs.getLong("retry_count")); row.setOrphanKey(rs.getString("orphan_key")); return row; } } private class HierarchyParentMapper extends InowProfileHierarchyRowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { HierarchyParentOrphanId row = new HierarchyParentOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setHierarchySid(rs.getLong("named_ip_hierarchy_sid")); if (rs.wasNull()) { row.setHierarchySid(null); } Long reprocess = rs.getLong("reprocess_flag"); if (!rs.wasNull()) { row.setReprocess(reprocess == 0 ? Boolean.FALSE : Boolean.TRUE); } row.setRetryCount(rs.getLong("retry_count")); row.setGroupByValue(rs.getLong("named_ip_hierarchy_sid")); return row; } } private class AddressHistoryMapper extends GenericMapper implements RowMapper<AddressHistoryOrphanId> { public AddressHistoryOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { this.columnNames = null; AddressHistoryOrphanId row = new AddressHistoryOrphanId(); row.setSid(rs.getLong("sid")); row.setAddressHistorySid(rs.getLong("address_history_sid")); row.setRetryCount(rs.getLong("retry_count")); return row; } } private class InowStandardizationOrphanMapper implements RowMapper<InowStandardizationOrphanId> { public InowStandardizationOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { InowStandardizationOrphanId row = new InowStandardizationOrphanId(); row.setSid(rs.getLong("sid")); row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setRetryCount(rs.getLong("retry_count")); return row; } } private class InowProfileRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { InowProfileOrphanId row = new InowProfileOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); return row; } } private class SalesLineItemNormalizationRowMapper extends GenericRowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = this.getLong(rs, "sid"); Long salesLineItemSid = this.getLong(rs, "sales_line_item_sid"); Long entitySid = this.getLong(rs, "entity_sid"); Long customerSid = this.getLong(rs, "customer_sid"); String priceType = this.getString(rs, "price_type"); SalesLineItemNormalizationOrphanId sliNormOrph = new SalesLineItemNormalizationOrphanId(sid, salesLineItemSid, customerSid, priceType, entitySid); return sliNormOrph; } } private class ProfilePartnerRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); Long profilePartnerSid = rs.getLong("profile_partner_sid"); String matchType = rs.getString("match_type"); ProfilePartnerOrphanId profileSummaryOrphan = new ProfilePartnerOrphanId(sid, customerSid, profilePartnerSid, matchType); profileSummaryOrphan.setRetryCount(rs.getLong("retry_count")); return profileSummaryOrphan; } } private final class CompositeAccountClassificationOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int row) throws SQLException { Long sid = rs.getLong("sid"); Long inowProfileSid = rs.getLong("inow_profile_sid"); String classificationCode = rs.getString("classification_code"); return new CompositeAccountClassificationOrphan(sid, inowProfileSid, classificationCode); } } private class ExporterOrphanRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); String exportName = rs.getString("export_name"); ExporterOrphanId id = new ExporterOrphanId(); id.setSid(sid); id.setCustomerSid(customerSid); id.setExportName(exportName); return id; } } @SuppressWarnings("unchecked") @Override public List<CompositeAccountClassificationOrphan> getCompositeAccountClassificationOrphans(int numToRead) { return getIds("comp_acct_class_orphan", new String[] { "sid", "inow_profile_sid", "classification_code" }, null, numToRead, COMPOSITE_ACCOUNT_CLASS_ORPHAN_MAPPER); } @Override public void deleteCompositeAccountClassificationOrphan(CompositeAccountClassificationOrphan id) { deleteId("comp_acct_class_orphan", id.getSid()); } private final class SubmissionScheduleOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int row) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); Long submissionPeriodSid = rs.getLong("submission_period_sid"); if (rs.wasNull()) { submissionPeriodSid = null; } Long dataFileSid = rs.getLong("data_file_sid"); if (rs.wasNull()) { dataFileSid = null; } SubmissionScheduleOrphan.Action action = SubmissionScheduleOrphan.Action.valueOf(rs.getString("action")); SubmissionScheduleOrphan orphan = new SubmissionScheduleOrphan(sid, customerSid, submissionPeriodSid, dataFileSid, action); orphan.setProcessTime(rs.getTimestamp("process_time")); orphan.setCreateDate(rs.getTimestamp("create_date")); orphan.setRetryCount(rs.getLong("retry_count")); return orphan; } } @SuppressWarnings("unchecked") @Override public List<SubmissionScheduleOrphan> getSubmissionScheduleOrphans(int numToRead) { // We only want to return one orphan per customer to avoid multi-threaded // contention issues with the database. For instance, 2 threads may need to // rebuild the same set of data_file_summary_info records for a given data_file. // We also want to give the CLEANUP action orphans a lower priority than // the normal orphans which is why a decode of the action shows up in the order by // within the analytical function row_number. String sql = "SELECT * FROM " + "( " + " SELECT o.sid, " + " o.customer_sid, " + " o.submission_period_sid, " + " o.data_file_sid, " + " o.action, " + " o.process_time, " + " o.create_date, " + " o.retry_count, " + " row_number() over (partition by o.customer_sid " + " order by " + " decode(o.action,'CLEANUP',100,10)," + " o.process_time) rn " + " FROM submission_schedule_orphan o " + " WHERE o.process_time < sysdate " + ") " + "WHERE rownum < ? " + " AND rn = 1"; List<SubmissionScheduleOrphan> orphans = getTemplate().query(sql, new Object[] { numToRead }, SUBMISSION_SCHEDULE_ORPHAN_MAPPER); return orphans; } @Override public void deleteSubmissionScheduleOrphan(SubmissionScheduleOrphan id) { deleteId("submission_schedule_orphan", id.getSid()); } @SuppressWarnings("unchecked") @Override public List<LearnedNameOrphan> getLearnedNameOrphans(int numToRead) { final String sql = "SELECT * FROM (SELECT o.sid as orphan_sid, l.sid as name_learning_sid, l.from_name, l.to_name, l.approval_status" + " FROM name_learning l" + " JOIN name_learning_orphan o ON o.name_learning_sid = l.sid" + " WHERE o.process_time < sysdate" + " ) WHERE rownum < ?"; return getTemplate().query(sql, new Object[] { numToRead }, LEARNED_NAME_ORPHAN_MAPPER); } @Override public void deleteLearnedNameOrphan(LearnedNameOrphan orphan) { deleteId("name_learning_orphan", orphan.getSid()); } private static class LearnedNameOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { LearnedName learnedName = new LearnedName(rs.getString("from_name"), rs.getString("to_name")); learnedName.setApprovalStatus(ApprovalStatus.fromString(rs.getString("approval_status"))); learnedName.setSid(rs.getLong("name_learning_sid")); LearnedNameOrphan learnedNameOrphan = new LearnedNameOrphan(learnedName); learnedNameOrphan.setSid(rs.getLong("orphan_sid")); return learnedNameOrphan; } } private static class InowTranslationOrphanMapper implements RowMapper<TranslationOrphan> { public TranslationOrphan mapRow(ResultSet rs, int rowNum) throws SQLException { TranslationOrphan translationOrphan = new TranslationOrphan(); translationOrphan.setSid(rs.getLong("sid")); translationOrphan.setInowProfileSid(rs.getLong("inow_profile_sid")); translationOrphan.setRetryCount(rs.getLong("retry_count")); translationOrphan.setGroupByValue(Math.round(rs.getLong("cnt") / 10)); return translationOrphan; } } private static class SubmissionPeriodUpdateOrphanMapper implements RowMapper<SubmissionPeriodUpdateOrphanId> { public SubmissionPeriodUpdateOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { SubmissionPeriodUpdateOrphanId submissionPeriodUpdateOrphanId = new SubmissionPeriodUpdateOrphanId(); submissionPeriodUpdateOrphanId.setSid(rs.getLong("sid")); submissionPeriodUpdateOrphanId.setCustomerSid(rs.getLong("customer_sid")); submissionPeriodUpdateOrphanId.setOldStartDate(rs.getDate("old_start_date")); submissionPeriodUpdateOrphanId.setRetryCount(rs.getLong("retry_count")); return submissionPeriodUpdateOrphanId; } } private static class InowRelationOrphanMapper implements RowMapper<InowRelationOrphan> { public InowRelationOrphan mapRow(ResultSet rs, int rowNum) throws SQLException { InowRelationOrphan inowRelationOrphan = new InowRelationOrphan(); inowRelationOrphan.setSid(rs.getLong("sid")); inowRelationOrphan.setInowProfileSid( rs.getLong("inow_profile_sid")); inowRelationOrphan.setRelatedInowProfileSid( rs.getLong("related_inow_profile_sid")); inowRelationOrphan.setRetryCount(rs.getLong("retry_count")); return inowRelationOrphan; } } private static class ExportOutputOrphanMapper implements RowMapper<ExportOutputOrphanId> { public ExportOutputOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { ExportOutputOrphanId exportOutputOrphan = new ExportOutputOrphanId(); exportOutputOrphan.setCustomerSid(rs.getLong("CUSTOMER_SID")); exportOutputOrphan.setExportOutputSid( rs.getLong("EXPORT_OUTPUT_SID")); exportOutputOrphan.setSid(rs.getLong("SID")); exportOutputOrphan.setRetryCount(rs.getLong("RETRY_COUNT")); exportOutputOrphan.setExportRequestSid( rs.getLong("EXPORT_REQUEST_SID")); exportOutputOrphan.setGroupByValue(rs.getLong("EXPORT_STATUS_SID")); exportOutputOrphan.setSessionId(rs.getString("SESSION_ID")); return exportOutputOrphan; } } }
/** * RecoveryQueries.java $Revision: 1 $ * * Copyright (c) 2005-2008 InfoNow Corporation. All rights reserved. * INFONOW PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.infonow.service.recovery; import com.infonow.crux.DataFile; import com.infonow.crux.composite.CompositeAccountClassificationOrphan; import com.infonow.crux.dataFile.DataFileOrphanId; import com.infonow.crux.learning.LearnedNameOrphan; import com.infonow.crux.schedule.submissionSchedule.SubmissionScheduleOrphan; import com.infonow.service.submissionPeriodUpdate.SubmissionPeriodUpdateOrphanId; import java.util.List; /** * RecoveryQueries * * @author clambrecht * @version :$ */ public interface RecoveryQueries { /** * Selects input file ids from the orphan table. Limit the number of rows returned to numIds and make sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * @return List<Long> - a list of ids (may be empty) */ List<Long> getParserOrphans(int numIds, int maxPerCustomer); /** * Select sales product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * @return List<LineItemOrphanId> - a list of ids (may be empty) */ List<LineItemOrphanId> getSalesProductOrphanIds(int numIds); /** * Select sales line item serial number ids from the orphan table. Limit the number of rows returned to numIds and * makes sure that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * * @return List<SerialNumberOrphanId> - a list of ids (may be empty) */ List<SerialNumberOrphanId> getSalesLineItemSerialNumberOrphanIds(int numIds); /** * Select inv product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * @return List<LineItemOrphanId> - a list of ids (may be empty) */ List<LineItemOrphanId> getInvProductOrphanIds(int numIds); /** * Select Profile Partner ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * @return List<Long> - a list of ids (may be empty) */ List<ProfilePartnerOrphanId> getProfilePartnerOrphanIds(int numIds); /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ List<SalesLineItemAddressOrphanId> getSliaProfileOrphanIds(int numIds); /** * Select Validation Tracking ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numToRead * - the number of ids to return (at most) * @return List<ValidationTrackingOrphanId> - a list of ids (may be empty) */ List<ValidationTrackingOrphanId> getValidationTrackingOrphanIds(int numToRead); /** * Select Validation Deleted ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numToRead * - the number of ids to return (at most) * @return List<ValidationTrackingOrphanId> - a list of ids (may be empty) */ List<ValidationNotificationOrphanId> getValidationNotificationOrphanIds(int numToRead); /** * Select Sales Record Address identifiers from the orphan table associated with composite account processing. Limit * the number of rows returned to numIds and makes sure that the identifiers returned are greater than the lastId * * @param numIds * The maximum number of identifiers to return. * @param lastId * The last identifier returned * * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ List<SalesLineItemAddressOrphanId> getSliaCompositeAccountOrphanIds(int numIds); /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @param lastId * - the last id returned * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ List<SalesLineItemAddressOrphanId> getSliaReportingPartnerOrphanIds(int numIds); /** * @param numToRead * @param lastId * @return */ List<SalesLineItemAddressOrphanId> getSliaValidationOrphanIds(int numToRead); /** * @param numToRead * @param lastId * @return */ List<ValidationOrphanId> getSalesLineItemValidationOrphanIds(int numToRead); /** * @param numToRead * @param lastId * @return */ List<ValidationOrphanId> getInventoryLineItemValidationOrphanIds(int numToRead); /** * Retrieve the orphans for the reporting partner InfoNow ID'ing process. * * @param numToRead * The size of number of orphans to retrieve. * * @return A {@link List} of {@link ReportingPartnerOrphanId} objects, if found in the orphan data store, else a * null or empty list. */ List<ReportingPartnerOrphanId> getReportingPartnerOrphanIds(int numToRead); List<InowProfileHierarchyOrphanId> getInowProfileHierarchyOrphanIds(int numToRead); List<HierarchyParentOrphanId> getHierarchyParentOrphanIds(int numToRead); List<AddressHistoryOrphanId> getAddressHistoryOrphanIds(int numToRead, String tableName); List<SalesLineItemNormalizationOrphanId> getSalesLineItemNormalizationOrphanIds(int numToRead); List<Long> getProfilePartnerRematchOrphanIds(int numToRead); List<Long> getAddressStandardizationOrphans(int numToRead); List<InowProfileOrphanId> getInowProfileDedupOrphans(int numToRead); List<SalesLineItemAddressOrphanId> getSliaRematchOrphanIds(int numToRead); List<InowStandardizationOrphanId> getInowProfileStandardizationOrphans( int numToRead); List<ExporterOrphanId> getExporterOrphanIds(int numIds); List<CompositeAccountClassificationOrphan> getCompositeAccountClassificationOrphans( int numToRead); List<SubmissionScheduleOrphan> getSubmissionScheduleOrphans(int numToRead); List<DataFileOrphanId> getDataFileDeleteOrphans(int numToRead); List<TranslationOrphan> getTranslationOrphans(int numToRead, String status); List<ExportOutputOrphanId> getExportOutputOrphans(int numToRead); List<InowRelationOrphan> getInowRelationOrphans(int numToRead); void deleteDataFileDeleteOrphanId(DataFileOrphanId id); List<LearnedNameOrphan> getLearnedNameOrphans(int numToRead); /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ void deleteDataFileId(Long id); /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ void deleteSalesProductId(LineItemOrphanId id); /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ void deleteSalesLineItemSerialNumberId(SerialNumberOrphanId id); /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ void deleteInvProductId(LineItemOrphanId id); /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ void deleteProfilePartnerId(ProfilePartnerOrphanId id); /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ void deleteSliaProfileId(SalesLineItemAddressOrphanId id); /** * Deletes the specifed orphan id from the orphan table associated with composite account processing * * @param id * The id to delete from the orphan table. */ void deleteSliaCompositeAccountId(SalesLineItemAddressOrphanId id); /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ void deleteSliaReportingPartnerId(SalesLineItemAddressOrphanId id); void deleteSalesLineItemNormalizationId(SalesLineItemNormalizationOrphanId id); public void deleteInowProfileHierarchyId(InowProfileHierarchyOrphanId id); public void deleteHierarchyParentId(HierarchyParentOrphanId id); public void deleteHierarchyParentIds(List<HierarchyParentOrphanId> ids); public void deleteRegexStandardizationOrphans(List<AddressHistoryOrphanId> ids); public void deleteRefDataStandardizationOrphans(List<AddressHistoryOrphanId> ids); public void deleteAddressHistoryOrphans(List<AddressHistoryOrphanId> ids, String orphanTable); public void deleteAddressGradingOrphans(List<AddressHistoryOrphanId> ids); public void deleteAddressQualityOrphans(List<AddressHistoryOrphanId> ids); /** * @param id */ void deleteSliaValidationId(SalesLineItemAddressOrphanId id); /** * @param list */ void deleteSalesLineItemValidationId(List<ValidationOrphanId> list); void deleteValidationTrackingIds(List<ValidationTrackingOrphanId> ids); void deleteValidationNotificationIds(List<ValidationNotificationOrphanId> ids); /** * @param list */ void deleteInventoryLineItemValidationId(List<ValidationOrphanId> list); void deleteReportingPartnerId(ReportingPartnerOrphanId id); void deleteProfilePartnerRematchId(Long id); void deleteAddressStandardizationOrphan(Long id); void deleteSliaRematchId(SalesLineItemAddressOrphanId id); void deleteInowProfileDedupOrphan(InowProfileOrphanId id); void deleteInowProfileStandardizationOrphan(InowStandardizationOrphanId id); void deleteExporterOrphan(ExporterOrphanId id); void deleteCompositeAccountClassificationOrphan(CompositeAccountClassificationOrphan id); void deleteSubmissionScheduleOrphan(SubmissionScheduleOrphan id); void deleteLearnedNameOrphan(LearnedNameOrphan orphan); /** * Deletes the orphans associated with the specific salesLineItemSids from the table * * @param List<Long> * salesLineItemSids */ void deleteSalesLineItemOrphans(List<Long> salesLineItemSids); /** * Deletes the line item orphans associated with the data file * * @param dataFile */ void deleteSalesLineItemOrphans(DataFile dataFile); /** * Deletes the orphans associated with the specific invLineItemSids from the table * * @param invLineItemSids */ void deleteInvLineItemOrphans(List<Long> invLineItemSids); /** * Deletes the line item orphans associated with the data file * * @param dataFile */ void deleteInvLineItemOrphans(DataFile dataFile); /** * Deletes the orphans associated with the INOW transaltion * * @param orphanIds */ void deleteTranslateOrphans(List<TranslationOrphan> orphanIds); /** * Deletes the orphans associated with the export output * * @param orphanIds */ void deleteExportOutputOrphans(List<ExportOutputOrphanId> orphanIds); /** * Deletes the orphans associated with the INOW relation * * @param orphanIds */ void deleteInowRelationOrphan(InowRelationOrphan orphanId); void deleteSubmissionPeriodUpdateOrphans( SubmissionPeriodUpdateOrphanId submissionPeriodUpdateOrphanId); List<SubmissionPeriodUpdateOrphanId> getSubmissionPeriodUpdateOrphans( int numToRead); void updateStatusTranslationOrphans(String status, List<Long> translationOrphanSids); void test(); }
package com.infonow.service.recovery.controller; import java.util.Iterator; import java.util.List; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import com.infonow.framework.logging.Level; import com.infonow.framework.logging.Logger; import com.infonow.framework.service.context.ServiceContext; import com.infonow.service.recovery.AbstractRunner; import com.infonow.service.recovery.TranslationOrphan; import static org.apache.commons.collections4.CollectionUtils.collect; public class TranslationController extends ServiceCallerBatchController<TranslationOrphan> { private static final String NAME = "Translation"; public TranslationController() { super(NAME); } @Override public List<TranslationOrphan> loadIds(int numToRead) { List<TranslationOrphan> relationOrphans = getRecoveryQueries().getTranslationOrphans(numToRead,"PENDING");//new attribute here named status, gets all the orphans which are in pending state //TranslationController will load orphans that are in PENDING(or NULL for backward compatibility) status to be processed by TranslationService, when does the entry in the table happen? return relationOrphans; } public void changeStatus() { List<TranslationOrphan> relationOrphans = loadIds(10); } @Override protected RecoveryRunner<List<TranslationOrphan>, ?> createRunner(List<TranslationOrphan> ids) { return new InowRelationRunner(ids); } @Override protected void cleanUp(RecoveryRunner<List<TranslationOrphan>, ?> runner) { List<TranslationOrphan> ids = runner.getId();//skip the orphans which are in pending or inprogress state //loop over ids, create a new list of ids without inprogress and pending status System.out.println("ids"); System.out.println(ids); getRecoveryQueries().deleteTranslateOrphans(ids); } @Override public int getNumberOfIdsPerBatch() { return getNumberOfIdsToRead(); } /** * The Runnable instance use to process a batch of staging Addresses */ private class InowRelationRunner extends AbstractRunner<List<TranslationOrphan>, Object> { ServiceContext _context = null; private Logger LOG = Logger.getLogger(TranslationOrphan.class.getName()); InowRelationRunner(List<TranslationOrphan> ids) { super(ids, NAME, getService(), getTransactionTemplate()); _context = new ServiceContext(); _context.setContextType("default"); } @Override public Object loadDataObject(List<TranslationOrphan> ids) { return loadMatchType(ids); } @Override public Object loadUserObject(List<TranslationOrphan> ids) { // There is a bug in AbstractRunner where the userObject and userData are swapped. // I don't want to change it because it might break every service, so I'll just // flip the objects here like the other services seem to do. // This is actually the userData in the service. return ids; } @Override public String loadMatchType(List<TranslationOrphan> ids) { return null; } @Override public ServiceContext createServiceContext(Object dataObject) { return _context; } @Override protected void handleRunException(Exception exception) { // We are going to make a new orphan with an incremented retry count // and put it back in the queue. List<TranslationOrphan> oldOrphans = (List<TranslationOrphan>) this.getId(); for (Iterator<TranslationOrphan> i = oldOrphans.iterator(); i.hasNext();) { TranslationOrphan oldOrphan = i.next(); long newRetryCount = oldOrphan.getRetryCount() + 1; // First, compute the severity of the exception to be logged based on the retryCount. Level loggingLevel = Level.WARNING; // We only make it SEVERE if the retryCount is a multiple of 10 // to avoid hammering engineering support with e-mails. if ((newRetryCount % 10) == 0) { loggingLevel = Level.SEVERE; } LOG.log(loggingLevel, getDescription() + ": Error processing id - " + getId().toString() + ", re-submitting orphan.", exception); PlatformTransactionManager txnMgr = null; TransactionStatus status = null; try { txnMgr = _transactionTemplate.getTransactionManager(); status = txnMgr.getTransaction( new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW)); double delayMinutesAsDouble = 0.0; int delayMinutesAsInteger = 0; // Compute the delay minutes for the new orphan. // Since there is the potential for numeric overflows, // we are wrapping the math in a try/catch block. try { delayMinutesAsDouble = Math.pow(2, newRetryCount); delayMinutesAsInteger = (int) delayMinutesAsDouble; } catch (Exception e) { delayMinutesAsInteger = 7 * 24 * 60; // Push re-try out to 7 days if numeric overflows occur. } getOrchestrationDao().insertTranslationOrphan(delayMinutesAsInteger, oldOrphan.getInowProfileSid(), newRetryCount); try { if (!status.isRollbackOnly()) { txnMgr.commit(status); } } catch (Exception e) { String msg = getDescription() + ": Error processing id - " + getId().toString(); LOG.log(Level.SEVERE, msg, e); } } catch (Exception e) { String msg = getDescription() + ": Error processing id - " + getId().toString(); LOG.log(Level.SEVERE, msg, e); } finally { try { if (txnMgr != null && status != null && !status.isCompleted()) { txnMgr.rollback(status); } } catch (Exception ee) { String msg = getDescription() + ": Error processing id - " + getId().toString(); LOG.log(Level.SEVERE, msg, ee); } } } } } // end inner-class InowRelationRunner }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <import resource="commonService.xml" /> <!-- Start of Locator service definition --> <bean id="serviceLocatorService" class="com.infonow.framework.service.remoting.local.ServiceAccessor"> <property name="serviceInterface" value="com.infonow.framework.service.locator.ServiceLocatorService" /> </bean> <!-- Start of TranslationService definition --> <bean id="translationService" class="com.modeln.cdm.service.translation.TranslationServiceImpl"> <property name="serviceLocatorService" ref="serviceLocatorService" /> <property name="configurationServiceUrl" value="local://localhost/configurationService" /> <property name="inowProfileRelationService" ref="inowProfileRelationService" /> <property name="awsSnsClient" ref="awsSnsClient" /> <property name="inowProfileDao" ref="inowProfileDao" /> <property name="mappingFileName" value="translationMapping.xml" /> <property name="awsSnsTopic" value="${translation.aws.sns.topicArn}" /> <property name="recoveryQueries" ref="recoveryQueries" /> </bean> <bean id="recoveryQueries" class="com.infonow.service.recovery.RecoveryQueriesImpl"> <property name="template" ref="nucleusJdbcTemplate"/> <property name="namedParameterJdbcTemplate" ref="nucleusNamedParameterJdbcTemplate"/> </bean> <bean id="inowProfileRelationService" class="com.infonow.framework.service.locator.impl.ServiceLocatorServiceProxyFactory"> <property name="serviceUrl" value="local://localhost/relationService" /> <property name="serviceLocatorService" ref="serviceLocatorService" /> <property name="className" value="com.modeln.cdm.service.relation.InowProfileRelationServiceImpl" /> </bean> <bean id="awsSnsClient" class="com.modeln.cdm.integration.aws.AmazonSNSClientImpl" init-method="startup" destroy-method="shutdown"> <property name="awsCredentials" ref="awsCredentials" /> </bean> <bean id="inowProfileRelationDao" class="com.infonow.crux.dao.orm.hibernate.InowProfileRelationDaoImpl"> <property name="sessionFactory" ref="nucleusSessionFactory" /> </bean> <bean id="inowProfileDao" class="com.infonow.crux.dao.orm.hibernate.InowProfileDao"> <property name="sessionFactory" ref="nucleusSessionFactory" /> </bean> </beans>
/** * RecoveryQueriesImpl.java $Revision$ * * Copyright (c) 2005-2008 InfoNow Corporation. All rights reserved. * INFONOW PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.infonow.service.recovery; import com.infonow.crux.DataFile; import com.infonow.crux.composite.CompositeAccountClassificationOrphan; import com.infonow.crux.dao.jdbc.mapper.GenericMapper; import com.infonow.crux.dao.jdbc.mapper.GenericRowMapper; import com.infonow.crux.dataFile.DataFileOrphanId; import com.infonow.crux.learning.LearnedName; import com.infonow.crux.learning.LearnedName.ApprovalStatus; import com.infonow.crux.learning.LearnedNameOrphan; import com.infonow.crux.schedule.submissionSchedule.SubmissionScheduleOrphan; import com.infonow.crux.sqlGeneration.SqlGenerationUtils; import com.infonow.crux.util.CollectionUtils; import com.infonow.crux.util.Constants.DataAddressTypeEnum; import com.infonow.framework.logging.Logger; import com.infonow.framework.util.spring.JdbcTemplateProxy; import com.infonow.framework.util.spring.NamedParameterJdbcTemplateProxy; import com.infonow.service.submissionPeriodUpdate.SubmissionPeriodUpdateOrphanId; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.transaction.annotation.Transactional; /** * Query implementations for the recovery service. * * @author Chris Lambrecht * * @version $Revision$ */ @SuppressWarnings("rawtypes") public class RecoveryQueriesImpl implements RecoveryQueries { private static final Logger LOG = Logger.getLogger(RecoveryQueriesImpl.class.getName()); private static final String DELETE_RL_ORPHAN = "delete from rl_orphans where master_run_id = ?"; private final RowMapper SID_MAPPER = new SidRowMapper(); private final RowMapper LINE_ITEM_MAPPER = new LineItemRowMapper(); private final RowMapper VALIDATION_ITEM_MAPPER = new ValidationRowMapper(); private final RowMapper SERIAL_NUMBER_MAPPER = new SerialNumberRowMapper(); private final RowMapper TUPPLE_MAPPER = new TupleMapper(); private final RowMapper SLIA_MAPPER = new SliaProfileMapper(); private final RowMapper INOW_PROFILE_HIERARCHY_MAPPER = new InowProfileHierarchyRowMapper(); private final RowMapper HIERARCHY_PARENT_MAPPER = new HierarchyParentMapper(); private final RowMapper ADDRESS_HISTORY_MAPPER = new AddressHistoryMapper(); private final RowMapper INOW_PROFILE_MAPPER = new InowProfileRowMapper(); private final RowMapper SALES_LINE_ITEM_NORMALIZATION_MAPPER = new SalesLineItemNormalizationRowMapper(); private final RowMapper REPORTING_PARTNER_MAPPER = new ReportingPartnerRowMapper(); private final RowMapper PROFILE_PARTNER_MAPPER = new ProfilePartnerRowMapper(); private final RowMapper EXPORTER_ORPHAN_MAPPER = new ExporterOrphanRowMapper(); private final RowMapper COMPOSITE_ACCOUNT_CLASS_ORPHAN_MAPPER = new CompositeAccountClassificationOrphanMapper(); private final RowMapper SUBMISSION_SCHEDULE_ORPHAN_MAPPER = new SubmissionScheduleOrphanMapper(); private final RowMapper LEARNED_NAME_ORPHAN_MAPPER = new LearnedNameOrphanMapper(); private final RowMapper INOW_STANDARDIZATION_ORPHAN_MAPPER = new InowStandardizationOrphanMapper(); private final RowMapper INOW_TRANSLATION_ORPHAN_MAPPER = new InowTranslationOrphanMapper(); private final RowMapper SUBMISSION_SCHEDULE_UPDATE_ORPHAN_MAPPER = new SubmissionPeriodUpdateOrphanMapper(); private final RowMapper INOW_RELATION_ORPHAN_MAPPER = new InowRelationOrphanMapper(); private final RowMapper EXPORT_OUTPUT_ORPHAN_MAPPER = new ExportOutputOrphanMapper(); private final RowMapper VALIDATION_TRACKING_ORPHAN_MAPPER = new ValidationTrackingRowMapper(); private final RowMapper VALIDATION_DELETED_ORPHAN_MAPPER = new ValidationDeletedRowMapper(); @Autowired private JdbcTemplate template; @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** * Default Constructor */ public RecoveryQueriesImpl() { super(); } /** * Get the value of the template field. * * @return Returns the value of template. */ public JdbcTemplate getTemplate() { return this.template; } /** * Set the value of the template field. * * @param template * The template value to set. */ public void setTemplate(JdbcTemplate template) { this.template = template; } /** * Get the value of the namedParameterJdbcTemplate field. * * @return Returns the value of namedParameterJdbcTemplate. */ public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { System.out.println("in getNamedParameterejdbctem"); System.out.println(this); System.out.println(this.namedParameterJdbcTemplate); // Get the current stack trace StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); // stackTraceElements[0] is getStackTrace // stackTraceElements[1] is getNamedParameterJdbcTemplate // stackTraceElements[2] is the method that called getNamedParameterJdbcTemplate if (stackTraceElements.length > 2) { String callerMethodName = stackTraceElements[2].getMethodName(); System.out.println("Caller Method: " + callerMethodName); System.out.println(this); System.out.println(this.namedParameterJdbcTemplate); } return this.namedParameterJdbcTemplate; } /** * Set the value of the namedParameterJdbcTemplate field. * * @param namedParameterJdbcTemplate * The namedParameterJdbcTemplate value to set. */ public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; } /** * Inject a reference to the {@link DataSource} to use for all queries * * @param dataSource * - database connect source */ public void setDataSource(DataSource dataSource) { template = new JdbcTemplateProxy(dataSource); namedParameterJdbcTemplate = new NamedParameterJdbcTemplateProxy(dataSource); } /** * Selects input file ids from the orphan table. Limit the number of rows returned to numIds and make sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<Long> getParserOrphans(int numIds, int maxPerCustomer) { final String sql = "select data_file_sid from ( " + "select * from ( " + "select ifo.*, " + " rank() over( partition by ifo.customer_sid order by sid ) rank_overall " + "from ( " + "select ifo.*, " + " rank() over( partition by ifo.customer_sid, ifo.type order by nvl(ifo.update_date,ifo.create_date) ) rank_of_type " + "from ( " + "select ifo.data_file_sid, " + " if.customer_sid, " + " ifo.sid, " + " ifo.process_time, if.create_date, if.update_date, " + " CASE WHEN (instr(upper(data_type),'CATALOG') > 0) THEN 'CATALOG' " + " WHEN (instr(upper(data_type),'PROFILE') > 0) THEN 'PROFILE' " + " ELSE data_type " + " END as type " + "from input_file_orphans ifo " + "join data_file if on ifo.data_file_sid = if.sid " + "where process_time < sysdate " + ") ifo " + ") ifo " + "where ifo.type not in ('CATALOG','PROFILE') " + " or ifo.rank_of_type = 1 " + ") " + "where rank_overall <= ? " + "order by rank_overall " + ") where rownum < ? "; return getTemplate().query(sql, new Object[] { maxPerCustomer, numIds }, SID_MAPPER); } /** * Select sales product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<LineItemOrphanId> getSalesProductOrphanIds(int numIds) { return getIds("sales_line_item_orphans", new String[] { "sid", "sales_line_item_sid", "match_type", "customer_sid" }, null, numIds, LINE_ITEM_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getSalesLineItemSerialNumberOrphanIds(int, * com.infonow.service.recovery.SerialNumberOrphanId) */ @SuppressWarnings("unchecked") public List<SerialNumberOrphanId> getSalesLineItemSerialNumberOrphanIds(int numIds) { return getIds("SLI_SERIAL_NUMBER_ORPHANS", new String[] { "sid", "sli_serial_number_sid", "match_type", "customer_sid" }, null, numIds, SERIAL_NUMBER_MAPPER); } /** * Select inv product ids from the orphan table. Limit the number of rows returned to numIds and makes sure that the * ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<LineItemOrphanId> getInvProductOrphanIds(int numIds) { return getIds("inv_line_item_orphans", new String[] { "sid", "inv_line_item_sid", "match_type", "customer_sid" }, null, numIds, LINE_ITEM_MAPPER); } /** * Select Profile Partner ids from the orphan table. Limit the number of rows returned to numIds and makes sure that * the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<Long> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<ProfilePartnerOrphanId> getProfilePartnerOrphanIds(int numIds) { final String query = "SELECT" + " sid," + " profile_partner_sid," + " customer_sid," + " match_type," + " retry_count" + " FROM" + " (" + " SELECT" + " *" + " FROM" + " (" + " SELECT" + " sid," + " profile_partner_sid," + " customer_sid," + " match_type," + " retry_count," + " RANK() OVER(" + " PARTITION BY customer_sid" + " ORDER BY" + " sid" + " ) rank" + " FROM" + " (" + " SELECT" + " po.sid," + " po.profile_partner_sid," + " pp.customer_sid," + " po.match_type," + " po.retry_count" + " FROM" + " profile_orphans po" + " JOIN profile_partner pp ON pp.sid = po.profile_partner_sid" + " WHERE" + " process_time < SYSDATE AND (pp.address_sid is null or pp.address_sid = 0)" + " " + " UNION " + " " + " SELECT" + " po.sid," + " po.profile_partner_sid," + " pp.customer_sid," + " po.match_type," + " po.retry_count" + " FROM" + " profile_orphans po" + " JOIN profile_partner pp ON pp.sid = po.profile_partner_sid" + " JOIN address_history ah ON ah.address_sid = pp.address_sid" + " WHERE" + " process_time < SYSDATE AND ah.stage = 'API_ENRICHED' " + " )" + " )" + " ORDER BY" + " rank" + " )" + "WHERE" + " ROWNUM < ?"; return getTemplate().query(query, new Object[] { numIds }, PROFILE_PARTNER_MAPPER); } /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaProfileOrphanIds(int numIds) { final String query = "select * from (select * from (select sliapo.sid, " + " sliapo.sales_line_item_sid, " + " sliapo.address_Sid, " + " sliapo.address_type, " + " sliapo.match_type, sliapo.customer_sid, sli.BILL_TO_ADDR_EXTERNAL_ID" + " ,sli.SOLD_TO_ADDR_EXTERNAL_ID, sli.SHIP_TO_ADDR_EXTERNAL_ID" + " ,sli.SELL_FROM_ADDR_EXTERNAL_ID, sli.SHIP_FROM_ADDR_EXTERNAL_ID" + " ,sli.SALES_IN_ADDR_EXTERNAL_ID, sli.PURCH_CUST_ADDR_EXTERNAL_ID" + " ,sli.DER_END_CUST_ADDR_EXTERNAL_ID,sli.deleted " + " ,case when exists (select 1 from address_history ah where ah.address_sid = sliapo.address_sid and ah.stage = 'RAW')" + " then 1 else 0 end raw_exists " + " ,case when exists (select 1 from address_history ah where ah.address_sid = sliapo.address_sid and ah.stage = 'REF_DATA_ENRICHED') " + " then 1 else 0 end ref_data_exists," + " rank() over(partition by sliapo.customer_sid order by sliapo.sid) rank " + " from slia_profile_orphans sliapo join sales_line_item sli on sli.sid = sliapo.sales_line_item_sid and " + " sli.customer_sid = sliapo.customer_sid where process_time < sysdate" + " order by rank,address_sid) where (raw_exists = 0 or (raw_exists = 1 and ref_data_exists = 1))) where rownum < ? "; return getTemplate().query(query, new Object[] { numIds }, SLIA_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getSliaCompositeAccountOrphanIds(int) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaCompositeAccountOrphanIds(int numIds) { return getIds("slia_composite_acct_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type", "customer_sid" }, null, numIds, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<InowProfileHierarchyOrphanId> getInowProfileHierarchyOrphanIds(int numToRead) { final String query = "SELECT" + " * " + " FROM" + " (" + " SELECT" + " *" + " FROM" + " (" + " SELECT" + " ipho.sid," + " ipho.inow_profile_sid," + " ipho.customer_sid," + " ipho.named_ip_hierarchy_sid," + " ipho.reprocess_flag," + " ipho.retry_count," + " ipho.priority," + " RANK() OVER(" + " PARTITION BY ipho.customer_sid" + " ORDER BY" + " sid ASC" + " ) rank," + " upper(csr.entity_name)" + " || '-----'" + " || csr.country orphan_key" + " FROM" + " inow_profile_hierarchy_orphans ipho" + " LEFT JOIN csr_overlay_v csr ON csr.customer_sid = ipho.customer_sid" + " AND ipho.inow_profile_sid = csr.ip_sid" + " WHERE" + " process_time < sysdate" + " )" + " ORDER BY" + " priority," + " rank" + " ) " + " WHERE " + " ROWNUM < :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_PROFILE_HIERARCHY_MAPPER); } @SuppressWarnings("unchecked") public List<HierarchyParentOrphanId> getHierarchyParentOrphanIds(int numToRead) { final String query = "select * from ( " + "select * from ( " + "select hpo.sid, " + " hpo.inow_profile_sid, " + " hpo.customer_sid, " + " hpo.named_ip_hierarchy_sid, " + " hpo.reprocess_flag, " + " hpo.retry_count, " + " hpo.priority, " + " rank() over( partition by hpo.customer_sid order by sid asc) rank " + "from hierarchy_parent_orphans hpo " + "where process_time < sysdate) " + "order by priority,rank " + ") " + "where rownum < :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, HIERARCHY_PARENT_MAPPER); } @SuppressWarnings("unchecked") public List<AddressHistoryOrphanId> getAddressHistoryOrphanIds(int numToRead, String tableName) { final String query = "select * from ( " + "select * from ( " + "select aho.sid, " + " aho.address_history_sid, aho.retry_count " + "from " + tableName + " aho " + "where process_time < sysdate) " + "order by sid " + ") " + "where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, ADDRESS_HISTORY_MAPPER); } @SuppressWarnings("unchecked") public List<SalesLineItemNormalizationOrphanId> getSalesLineItemNormalizationOrphanIds(int numToRead) { return getIds("sli_normalization_orphans", new String[] { "sid", "sales_line_item_sid", "customer_sid", "price_type, entity_sid" }, null, numToRead, SALES_LINE_ITEM_NORMALIZATION_MAPPER); } /** * Select Sales Record Address ids from the orphan table. Limit the number of rows returned to numIds and makes sure * that the ids returned are greater than the lastId * * @param numIds * - the number of ids to return (at most) * @return List<SalesLineItemAddressOrphanId> - a list of ids (may be empty) */ @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaReportingPartnerOrphanIds(int numIds) { return getIds("reporting_partner_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "null" }, null, numIds, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationOrphanId> getSalesLineItemValidationOrphanIds(int numToRead) { final String query = "select * from ( " + "select sv.sid,sv.sales_line_item_sid,sv.match_type,sv.customer_sid, " + " sli.reporting_partner_sid,sli.data_file_sid,rank() over(partition by sv.customer_sid order by sv.create_date) rank_by_cust" + " from sli_validation_orphans sv" + " join sales_line_item sli on sli.sid = sv.sales_line_item_sid " + " and sli.customer_sid = sli.customer_Sid where process_time < sysdate order by rank_by_cust,sv.create_date " + ") where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, VALIDATION_ITEM_MAPPER); } @SuppressWarnings("unchecked") public List<SalesLineItemAddressOrphanId> getSliaValidationOrphanIds(int numToRead) { return getIds("slia_validation_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type", "customer_sid" }, null, numToRead, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationTrackingOrphanId> getValidationTrackingOrphanIds(int numToRead) { return getIds("validation_tracking_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "create_date", "update_date", "retry_count" }, null, numToRead, VALIDATION_TRACKING_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationNotificationOrphanId> getValidationNotificationOrphanIds(int numToRead) { return getIds("validation_notification_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "create_date", "update_date", "retry_count" }, null, numToRead, VALIDATION_DELETED_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") public List<ValidationOrphanId> getInventoryLineItemValidationOrphanIds(int numToRead) { final String query = "select * from ( " + "select sv.sid,sv.inv_line_item_sid,sv.match_type,sv.customer_sid, " + " ili.reporting_partner_sid,ili.data_file_sid,rank() over(partition by sv.customer_sid order by sv.create_date) rank_by_cust" + " from ili_validation_orphans sv" + " join inv_line_item ili on ili.sid = sv.inv_line_item_sid " + " and ili.customer_sid = ili.customer_Sid where process_time < sysdate order by rank_by_cust,sv.create_date " + ") where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, VALIDATION_ITEM_MAPPER); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#getReportingPartnerOrphanIds(int) */ @SuppressWarnings("unchecked") @Override public List<ReportingPartnerOrphanId> getReportingPartnerOrphanIds(int numToRead) { return getIds("reporting_partner_inow_orphs", new String[] { "sid", "reporting_partner_sid" }, null, numToRead, REPORTING_PARTNER_MAPPER); } @SuppressWarnings("unchecked") @Override public List<Long> getAddressStandardizationOrphans(int numToRead) { return getIds("addr_standardization_orphans", new String[] { "address_sid" }, null, numToRead, SID_MAPPER); } @SuppressWarnings("unchecked") @Override public List<InowStandardizationOrphanId> getInowProfileStandardizationOrphans(int numToRead) { return getIds("inow_profile_std_orphans", new String[] { "sid", "inow_profile_sid", "retry_count" }, null, numToRead, INOW_STANDARDIZATION_ORPHAN_MAPPER); } @SuppressWarnings("unchecked") @Override public List<InowProfileOrphanId> getInowProfileDedupOrphans(int numToRead) { return getIds("inow_profile_dedup_orphans", new String[] { "sid", "inow_profile_sid", "customer_sid" }, null, numToRead, INOW_PROFILE_MAPPER); } @SuppressWarnings("unchecked") @Override public List<Long> getProfilePartnerRematchOrphanIds(int numToRead) { return getIds("profile_rematch_orphans", new String[] { "profile_partner_sid" }, null, numToRead, SID_MAPPER); } @SuppressWarnings("unchecked") @Override public List<SalesLineItemAddressOrphanId> getSliaRematchOrphanIds(int numToRead) { return getIds("slia_profile_rematch_orphans", new String[] { "sid", "sales_line_item_sid", "address_sid", "address_type", "match_type" }, null, numToRead, TUPPLE_MAPPER); } @SuppressWarnings("unchecked") @Override public List<ExporterOrphanId> getExporterOrphanIds(int numToRead) { return getIds("exporter_orphans", new String[] { "sid", "customer_sid", "export_name" }, null, numToRead, EXPORTER_ORPHAN_MAPPER); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteDataFileId(Long id) { if (id == null) { return; } deleteId("input_file_orphans", "data_file_sid", id); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteSalesProductId(LineItemOrphanId id) { deleteId("sales_line_item_orphans", id.getSid()); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteSalesLineItemSerialNumberId(com.infonow.service.recovery. * SerialNumberOrphanId) */ public void deleteSalesLineItemSerialNumberId(SerialNumberOrphanId id) { deleteId("sli_serial_number_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteProfilePartnerId(ProfilePartnerOrphanId id) { deleteId("profile_orphans", "sid", id.getSid()); } /** * Deletes the specified orphan id from the table * * @param id * - the id to delete */ public void deleteInvProductId(LineItemOrphanId id) { deleteId("inv_line_item_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSliaProfileId(SalesLineItemAddressOrphanId id) { deleteId("slia_profile_orphans", id.getSid()); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteSliaCompositeAccountId(com.infonow.service.recovery. * SalesLineItemAddressOrphanId) */ public void deleteSliaCompositeAccountId(SalesLineItemAddressOrphanId id) { deleteId("slia_composite_acct_orphans", id.getSid()); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSliaReportingPartnerId(SalesLineItemAddressOrphanId id) { deleteId("reporting_partner_orphans", id.getSid()); } public void deleteSalesLineItemValidationId(List<ValidationOrphanId> ids) { String sql = new String("delete from sli_validation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteValidationTrackingIds(List<ValidationTrackingOrphanId> ids) { String sql = new String("delete from validation_tracking_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteValidationNotificationIds(List<ValidationNotificationOrphanId> ids) { String sql = new String("delete from validation_notification_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } public void deleteSliaValidationId(SalesLineItemAddressOrphanId id) { deleteId("slia_validation_orphans", id.getSid()); } public void deleteInventoryLineItemValidationId(List<ValidationOrphanId> ids) { String sql = new String("delete from ili_validation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); ids.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteSalesLineItemOrphans(List<Long> salesLineItemSids) { String sql = new String("delete from sales_line_item_orphans where sales_line_item_sid in (:sids)"); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", salesLineItemSids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteSalesLineItemOrphans(DataFile dataFile) { String sql = new String("delete from sales_line_item_orphans where sales_line_item_sid in " + " (select sid from sales_line_item where data_file_sid = ? and customer_sid = " + dataFile.getCustomer().getSid().toString() + ")"); getTemplate().update(sql, new Object[] { dataFile.getSid() }); } @Override public void deleteInvLineItemOrphans(List<Long> invLineItemSids) { String sql = new String("delete from inv_line_item_orphans where inv_line_item_sid in (:sids)"); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", invLineItemSids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Transactional @Override public void updateStatusTranslationOrphans(String status, List<Long> translationOrphanSids)//pass the array of sids, and pass status { String sql = new String("update translation_orphans set status = :status where sid in (:sids)"); String commit = new String("commit"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("sids", translationOrphanSids); paramMap.put("status", status); System.out.println("getNamedParameterJdbcTemplate() in update status method: "+getNamedParameterJdbcTemplate()); System.out.println(getNamedParameterJdbcTemplate()); if(getNamedParameterJdbcTemplate() != null || getTemplate() != null)//why are these null? { int rowsUpdated = getNamedParameterJdbcTemplate().update(sql, paramMap); System.out.println("Number of rows updated: " + rowsUpdated); getNamedParameterJdbcTemplate().query(commit,SID_MAPPER); } else{ System.out.println("printing getNamedParameterJdbcTemplate : "+getNamedParameterJdbcTemplate());//why is this null??? System.out.println("printing getTemplate : "+getTemplate()); System.out.println("getNamedParameterJdbcTemplate is null"); } } @Override public void test()//pass the array of sids, and pass status { String sql = new String("select sid from translation_orphans where sid = :sid"); System.out.println("getNamedParameterJdbcTemplate() in test method: "+getNamedParameterJdbcTemplate()); System.out.println(getNamedParameterJdbcTemplate()); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("sid", 2); System.out.println("getNamedParameterJdbcTemplate from test method : "+getNamedParameterJdbcTemplate()); if(getNamedParameterJdbcTemplate() != null || getTemplate() != null)//why are these null? { getTemplate().update(sql,paramMap); getNamedParameterJdbcTemplate().update(sql, paramMap); } else{ System.out.println("printing getNamedParameterJdbcTemplate : "+getNamedParameterJdbcTemplate());//why is this null??? System.out.println("printing getTemplate : "+getTemplate()); System.out.println("getNamedParameterJdbcTemplate is null"); } } public void deleteRegexStandardizationOrphans(List<AddressHistoryOrphanId> orphanIds)//follow this { String sql = new String("delete from regex_std_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteRefDataStandardizationOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from ref_data_std_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressHistoryOrphans(List<AddressHistoryOrphanId> orphanIds, String orphanTable) { String sql = new String("delete from " + orphanTable + " where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressGradingOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from address_grading_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteTranslateOrphans(List<TranslationOrphan> orphanIds) { for (List<TranslationOrphan> orphans : CollectionUtils.partition(orphanIds, 1000)) { String sql = new String( "delete from translation_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphans.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } } @Override public void deleteExportOutputOrphans(List<ExportOutputOrphanId> orphanIds) { String sql = new String( "delete from export_output_orphans where sid in (:sids)"); Map<String, Object> paramMap = new HashMap<String, Object>(); List<Long> sids = orphanIds.stream().map(o -> o.getSid()) .collect(Collectors.toList()); List<List<Long>> sidsPartition = CollectionUtils.partition(sids, 1000); for (List<Long> batch : sidsPartition) { paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } } @Override public void deleteSubmissionPeriodUpdateOrphans( SubmissionPeriodUpdateOrphanId orphanId) { String sql = new String( "delete from SP_UPDATE_ORPHANS where sid in (:sid)"); Map<String, Long> paramMap = new HashMap<String, Long>(); paramMap.put("sid", orphanId.getSid()); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteInowRelationOrphan(InowRelationOrphan orphanId) { String sql = new String("delete from relation_orphans where sid = :sid"); Map<String, Long> paramMap = new HashMap<String, Long>(); paramMap.put("sid", orphanId.getSid()); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteAddressQualityOrphans(List<AddressHistoryOrphanId> orphanIds) { String sql = new String("delete from address_quality_orphans where sid in (:sids)"); List<Long> sids = new ArrayList<>(); orphanIds.forEach(ad -> sids.add(ad.getSid())); Map<String, List<Long>> paramMap = new HashMap<String, List<Long>>(); paramMap.put("sids", sids); getNamedParameterJdbcTemplate().update(sql, paramMap); } @Override public void deleteInvLineItemOrphans(DataFile dataFile) { String sql = new String("delete from inv_line_item_orphans where inv_line_item_sid in " + " (select sid from inv_line_item where data_file_sid = ? and customer_sid = " + dataFile.getCustomer().getSid().toString() + ")"); getTemplate().update(sql, new Object[] { dataFile.getSid() }); } @Override public List<DataFileOrphanId> getDataFileDeleteOrphans(int numToRead) { List<?> orphanIds = null; orphanIds = getIds("data_file_delete_orphans", new String[] { "sid", "data_file_sid", "customer_sid", "reprocess", "user_login", "retry_count", "preserve_date" }, null, null, numToRead, new GenericRowMapper() { @Override public Object mapRow(ResultSet rs, int arg1) throws SQLException { DataFileOrphanId dfoi = new DataFileOrphanId(); dfoi.setDataFileSid(this.getLong(rs, "data_file_sid")); dfoi.setCustomerSid(this.getLong(rs, "customer_sid")); dfoi.setReprocess(this.getBooleanValue(rs, "reprocess")); dfoi.setUserLogin(this.getString(rs, "user_login")); dfoi.setSid(this.getLong(rs, "sid")); dfoi.setRetryCount(this.getLong(rs, "retry_count")); dfoi.setPreserveDate(this.getBooleanValue(rs, "preserve_date")); return dfoi; } }); return (List<DataFileOrphanId>) orphanIds; } @SuppressWarnings("unchecked") public List<TranslationOrphan> getTranslationOrphans(int numToRead, String status) { String query = "select * from ( select ipro.sid, ipro.inow_profile_sid, ipro.retry_count, ipro.status, rownum cnt " + "from translation_orphans ipro where process_time < sysdate " + "order by sid ) result where rownum <= :numToRead "; Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("numToRead", String.valueOf(numToRead)); if(status!=null){ query = query + "and result.status = :status"; paramMap.put("status",status); } System.out.println("getNamedParameterJdbcTemplate() in method getTranslationOrphans : "+getNamedParameterJdbcTemplate()); System.out.println(getNamedParameterJdbcTemplate()); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_TRANSLATION_ORPHAN_MAPPER); } @Override @SuppressWarnings("unchecked") public List<SubmissionPeriodUpdateOrphanId> getSubmissionPeriodUpdateOrphans(int numToRead) { final String query = "select * from ( select spuo.sid, spuo.customer_sid, spuo.old_start_date, spuo.retry_count, rownum cnt " + "from sp_update_orphans spuo where process_time < sysdate " + "order by sid ) where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, SUBMISSION_SCHEDULE_UPDATE_ORPHAN_MAPPER); } @Override public List<ExportOutputOrphanId> getExportOutputOrphans(int numToRead) { final String query = "WITH rowlimit AS (" + "SELECT * FROM (" + "SELECT EXPORT_STATUS_SID FROM export_output eo JOIN export_output_orphans eoo " + "ON eoo.EXPORT_OUTPUT_SID= eo.sid AND eo.customer_sid = eoo.customer_sid " + "WHERE eoo.process_time < sysdate + interval '10' second " + "GROUP BY EXPORT_STATUS_SID ) " + "WHERE rownum < :numToRead ) " + "SELECT eoo.SID,eoo.CUSTOMER_SID,eoo.SESSION_ID,eoo.EXPORT_OUTPUT_SID," + "eo.EXPORT_STATUS_SID,eoo.retry_count,es.export_name, eoo.export_request_sid" + ",RANK() OVER (PARTITION BY eo.customer_sid,eo.EXPORT_STATUS_SID ORDER BY eoo.sid ) rankof " + "FROM EXPORT_OUTPUT eo JOIN EXPORT_OUTPUT_ORPHANS eoo ON eoo.EXPORT_OUTPUT_SID = eo.sid " + "JOIN rowlimit ON rowlimit.export_status_sid = eo.EXPORT_STATUS_SID " + "join export_status es on es.sid = eo.export_status_sid and es.customer_sid = eo.customer_sid " + "ORDER BY rankof"; Map<String, Object> params = new HashMap<>(); params.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, params, EXPORT_OUTPUT_ORPHAN_MAPPER); } @Override @SuppressWarnings("unchecked") public List<InowRelationOrphan> getInowRelationOrphans(int numToRead) { final String query = "select * from ( select ro.sid, ro.inow_profile_sid, ro.related_inow_profile_sid, ro.retry_count, rownum cnt " + "from relation_orphans ro where process_time < sysdate " + "order by sid ) where rownum <= :numToRead "; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("numToRead", numToRead); return getNamedParameterJdbcTemplate().query(query, paramMap, INOW_RELATION_ORPHAN_MAPPER); } @Override public void deleteDataFileDeleteOrphanId(DataFileOrphanId id) { String sql = new String("delete from data_file_delete_orphans where sid = ? " + " and customer_sid = " + id.getCustomerSid()); getTemplate().update(sql, new Object[] { id.getSid() }); } /* * (non-Javadoc) * * @see com.infonow.service.recovery.RecoveryQueries#deleteReportingPartnerId(com.infonow.service.recovery. * ReportingPartnerOrphanId) */ @Override public void deleteReportingPartnerId(ReportingPartnerOrphanId id) { if (id == null || id.getSid() == null || id.getSid() <= 0) { return; } deleteId("reporting_partner_inow_orphs", id.getSid()); } public void deleteInowProfileHierarchyId(InowProfileHierarchyOrphanId id) { deleteId("inow_profile_hierarchy_orphans", id.getSid()); } public void deleteHierarchyParentId(HierarchyParentOrphanId id) { deleteId("hierarchy_parent_orphans", id.getSid()); } public void deleteHierarchyParentIds(List<HierarchyParentOrphanId> ids) { List<Long> sids = new ArrayList<Long>(); for (HierarchyParentOrphanId id : ids) { sids.add(id.getSid()); } deleteIds("hierarchy_parent_orphans", sids); } /** * Deletes the specifed orphan id from the table * * @param id * - the id to delete */ public void deleteSalesLineItemNormalizationId(SalesLineItemNormalizationOrphanId id) { deleteId("sli_normalization_orphans", id.getSid()); } @Override public void deleteAddressStandardizationOrphan(Long id) { deleteId("addr_standardization_orphans", "address_sid", id); } @Override public void deleteInowProfileStandardizationOrphan(InowStandardizationOrphanId id) { deleteId("inow_profile_std_orphans", "inow_profile_sid", id.getInowProfileSid()); } @Override public void deleteInowProfileDedupOrphan(InowProfileOrphanId id) { deleteId("inow_profile_dedup_orphans", id.getSid()); } @Override public void deleteProfilePartnerRematchId(Long id) { deleteId("profile_rematch_orphans", "profile_partner_sid", id); } @Override public void deleteSliaRematchId(SalesLineItemAddressOrphanId id) { deleteId("slia_profile_rematch_orphans", id.getSid()); } @Override public void deleteExporterOrphan(ExporterOrphanId id) { deleteId("exporter_orphans", id.getSid()); } /** * Dynamically generates a recovery orphan query for select * This function will alternate customers round robin if no orderByClause is specified * and there is customer_sid in the columns * @param tableName * @param columns * @param orderByClause * @param numIds * @param rowMapper * @return list of rowMaper */ @SuppressWarnings("rawtypes") private List getIds(String tableName, String[] columns, String orderByClause, Integer numIds, RowMapper rowMapper) { return getIds(tableName, columns, null, orderByClause, numIds, rowMapper); } /** * Dynamically generates a recovery orphan query for select * This function will alternate customers round robin if no orderByClause is specified * and there is customer_sid in the columns * @param tableName * @param columns * @param additionalWhereClause * @param orderByClause * @param numIds * @param rowMapper * @return list of rowMaper */ @SuppressWarnings("rawtypes") private List getIds(String tableName, String[] columns, String additionalWhereClause, String orderByClause, Integer numIds, RowMapper rowMapper) { if (columns == null || columns.length <= 0) { return null; } StringBuilder sqlBuffer = new StringBuilder("select * from (select "); for (int i = 0; i < columns.length; ++i) { if (i > 0) { sqlBuffer.append(", "); } sqlBuffer.append(columns[i]); // automatically implement customer 100 functions for all queues. if (StringUtils.equalsIgnoreCase(columns[i], "customer_sid")) { if (i > 0) { sqlBuffer.append(", "); } sqlBuffer.append("rank() over(partition by customer_sid order by sid) rank_by_cust "); if (StringUtils.isEmpty(orderByClause)) { orderByClause = "order by rank_by_cust"; } } } sqlBuffer.append(" from "); sqlBuffer.append(tableName); // Construct the WHERE clause sqlBuffer.append(" where process_time < sysdate "); if (!StringUtils.isEmpty(additionalWhereClause)) { sqlBuffer.append(" and "); sqlBuffer.append(additionalWhereClause); } if (StringUtils.isEmpty(orderByClause)) { sqlBuffer.append(" order by process_time desc "); } else { sqlBuffer.append(orderByClause); } sqlBuffer.append(" ) where rownum <= ?"); String query = sqlBuffer.toString(); return getTemplate().query(query, new Object[] { numIds }, rowMapper); } private void deleteId(String tableName, Long sid) { deleteId(tableName, null, sid); } private void deleteId(String tableName, String columnName, Long sid) { StringBuffer sqlBuffer = new StringBuffer("delete from "); sqlBuffer.append(tableName); if (StringUtils.isEmpty(columnName)) { sqlBuffer.append(" where sid = ?"); } else { sqlBuffer.append(" where "); sqlBuffer.append(columnName); sqlBuffer.append(" = ?"); } template.update(sqlBuffer.toString(), new Object[] { sid }); } private void deleteIds(String tableName, List<Long> sids) { for (List<Long> inList : CollectionUtils.partition(sids, 1000)) { deleteIds(tableName, null, inList); } } private void deleteIds(String tableName, String columnName, List<Long> sids) { StringBuffer sqlBuffer = new StringBuffer("delete from "); sqlBuffer.append(tableName); if (StringUtils.isEmpty(columnName)) { sqlBuffer.append(" where sid in "); } else { sqlBuffer.append(" where "); sqlBuffer.append(columnName); sqlBuffer.append(" in "); } String deleteQuery = SqlGenerationUtils.buildInClauseVariables(sqlBuffer.toString(), sids.size()); List<Object> params = new ArrayList<Object>(); params.addAll(sids); template.update(deleteQuery, params.toArray()); } /** * RowMapper instance used to extract the sid from a query */ private class SidRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return (rs.getLong(1)); } } /** * RowMapper instance used to extract the line item from a query */ private class LineItemRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { if (rs.getMetaData().getColumnCount() == 2) { // SID and SLI_SID return new LineItemOrphanId(rs.getLong(1), rs.getLong(2), null); } else { // SID, SLI_SID and MATCH_TYPE return new LineItemOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); } } } /** * RowMapper instance used to extract the line item from a query */ private class ValidationRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { ValidationOrphanId orphan = new ValidationOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); orphan.setCustomerSid(rs.getLong(4)); orphan.setReportingPartnerSid(rs.getLong(5)); orphan.setDataFileSid(rs.getLong(6)); return orphan; } } private class ValidationTrackingRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ValidationTrackingOrphanId(rs.getLong("sid"), rs.getLong("data_file_sid"), rs.getLong("customer_sid"), rs.getDate("create_date"), rs.getDate("update_date"), rs.getLong("retry_count")); } } private class ValidationDeletedRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ValidationNotificationOrphanId(rs.getLong("sid"), rs.getLong("data_file_sid"), rs.getLong("customer_sid"), rs.getDate("create_date"), rs.getDate("update_date"), rs.getLong("retry_count")); } } private class ReportingPartnerRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new ReportingPartnerOrphanId(rs.getLong(1), rs.getLong(2)); } } /** * RowMapper instance used to extract the serial number from a query */ private class SerialNumberRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new SerialNumberOrphanId(rs.getLong(1), rs.getLong(2), rs.getString(3)); } } private class SliaProfileMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { SalesLineItemAddressOrphanId orphan = new SalesLineItemAddressOrphanId(rs.getLong(1), rs.getLong(2), rs.getLong(3), DataAddressTypeEnum.fromDbCode(rs.getString(4)), rs.getString(5), rs.getLong(6)); /* * the natural key for slia_profile orphans is the address, and any external id for that line item if it is * deleted and the customer this is because external id's / deleted line items have different code paths for * short circuit matching */ StringBuilder sb = new StringBuilder(); sb.append(orphan.getAddressSid()); sb.append(orphan.getCustomerSid()); // we need this so that we don't cause a race condition on saving the ami data in the amidao sb.append(orphan.getSalesLineItemSid()); switch (orphan.getAddressType()) { case BILL_TO: sb.append(rs.getString("BILL_TO_ADDR_EXTERNAL_ID")); break; case SHIP_TO: sb.append(rs.getString("SHIP_TO_ADDR_EXTERNAL_ID")); break; case SOLD_TO: sb.append(rs.getString("SOLD_TO_ADDR_EXTERNAL_ID")); break; case SHIP_FROM: sb.append(rs.getString("SHIP_FROM_ADDR_EXTERNAL_ID")); break; case SELL_FROM: sb.append(rs.getString("SELL_FROM_ADDR_EXTERNAL_ID")); break; case SALES_IN: sb.append(rs.getString("SALES_IN_ADDR_EXTERNAL_ID")); break; case PURCHASING_CUSTOMER: sb.append(rs.getString("PURCH_CUST_ADDR_EXTERNAL_ID")); break; case DERIVED_END_CUSTOMER: sb.append(rs.getString("DER_END_CUST_ADDR_EXTERNAL_ID")); break; } sb.append(rs.getInt("deleted")); orphan.setGroupByValue(sb.toString()); return orphan; } } private class TupleMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new SalesLineItemAddressOrphanId(rs.getLong(1), rs.getLong(2), rs.getLong(3), DataAddressTypeEnum.fromDbCode(rs.getString(4)), rs.getString(5), 0l); } } private class InowProfileHierarchyRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { InowProfileHierarchyOrphanId row = new InowProfileHierarchyOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setHierarchySid(rs.getLong("named_ip_hierarchy_sid")); if (rs.wasNull()) { row.setHierarchySid(null); } Long reprocess = rs.getLong("reprocess_flag"); if (!rs.wasNull()) { row.setReprocess(reprocess == 0 ? Boolean.FALSE : Boolean.TRUE); } row.setRetryCount(rs.getLong("retry_count")); row.setOrphanKey(rs.getString("orphan_key")); return row; } } private class HierarchyParentMapper extends InowProfileHierarchyRowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { HierarchyParentOrphanId row = new HierarchyParentOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setHierarchySid(rs.getLong("named_ip_hierarchy_sid")); if (rs.wasNull()) { row.setHierarchySid(null); } Long reprocess = rs.getLong("reprocess_flag"); if (!rs.wasNull()) { row.setReprocess(reprocess == 0 ? Boolean.FALSE : Boolean.TRUE); } row.setRetryCount(rs.getLong("retry_count")); row.setGroupByValue(rs.getLong("named_ip_hierarchy_sid")); return row; } } private class AddressHistoryMapper extends GenericMapper implements RowMapper<AddressHistoryOrphanId> { public AddressHistoryOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { this.columnNames = null; AddressHistoryOrphanId row = new AddressHistoryOrphanId(); row.setSid(rs.getLong("sid")); row.setAddressHistorySid(rs.getLong("address_history_sid")); row.setRetryCount(rs.getLong("retry_count")); return row; } } private class InowStandardizationOrphanMapper implements RowMapper<InowStandardizationOrphanId> { public InowStandardizationOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { InowStandardizationOrphanId row = new InowStandardizationOrphanId(); row.setSid(rs.getLong("sid")); row.setInowProfileSid(rs.getLong("inow_profile_sid")); row.setRetryCount(rs.getLong("retry_count")); return row; } } private class InowProfileRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { InowProfileOrphanId row = new InowProfileOrphanId(); row.setSid(rs.getLong("sid")); row.setCustomerSid(rs.getLong("customer_sid")); if (rs.wasNull()) { row.setCustomerSid(null); } row.setInowProfileSid(rs.getLong("inow_profile_sid")); return row; } } private class SalesLineItemNormalizationRowMapper extends GenericRowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = this.getLong(rs, "sid"); Long salesLineItemSid = this.getLong(rs, "sales_line_item_sid"); Long entitySid = this.getLong(rs, "entity_sid"); Long customerSid = this.getLong(rs, "customer_sid"); String priceType = this.getString(rs, "price_type"); SalesLineItemNormalizationOrphanId sliNormOrph = new SalesLineItemNormalizationOrphanId(sid, salesLineItemSid, customerSid, priceType, entitySid); return sliNormOrph; } } private class ProfilePartnerRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); Long profilePartnerSid = rs.getLong("profile_partner_sid"); String matchType = rs.getString("match_type"); ProfilePartnerOrphanId profileSummaryOrphan = new ProfilePartnerOrphanId(sid, customerSid, profilePartnerSid, matchType); profileSummaryOrphan.setRetryCount(rs.getLong("retry_count")); return profileSummaryOrphan; } } private final class CompositeAccountClassificationOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int row) throws SQLException { Long sid = rs.getLong("sid"); Long inowProfileSid = rs.getLong("inow_profile_sid"); String classificationCode = rs.getString("classification_code"); return new CompositeAccountClassificationOrphan(sid, inowProfileSid, classificationCode); } } private class ExporterOrphanRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); String exportName = rs.getString("export_name"); ExporterOrphanId id = new ExporterOrphanId(); id.setSid(sid); id.setCustomerSid(customerSid); id.setExportName(exportName); return id; } } @SuppressWarnings("unchecked") @Override public List<CompositeAccountClassificationOrphan> getCompositeAccountClassificationOrphans(int numToRead) { return getIds("comp_acct_class_orphan", new String[] { "sid", "inow_profile_sid", "classification_code" }, null, numToRead, COMPOSITE_ACCOUNT_CLASS_ORPHAN_MAPPER); } @Override public void deleteCompositeAccountClassificationOrphan(CompositeAccountClassificationOrphan id) { deleteId("comp_acct_class_orphan", id.getSid()); } private final class SubmissionScheduleOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int row) throws SQLException { Long sid = rs.getLong("sid"); Long customerSid = rs.getLong("customer_sid"); Long submissionPeriodSid = rs.getLong("submission_period_sid"); if (rs.wasNull()) { submissionPeriodSid = null; } Long dataFileSid = rs.getLong("data_file_sid"); if (rs.wasNull()) { dataFileSid = null; } SubmissionScheduleOrphan.Action action = SubmissionScheduleOrphan.Action.valueOf(rs.getString("action")); SubmissionScheduleOrphan orphan = new SubmissionScheduleOrphan(sid, customerSid, submissionPeriodSid, dataFileSid, action); orphan.setProcessTime(rs.getTimestamp("process_time")); orphan.setCreateDate(rs.getTimestamp("create_date")); orphan.setRetryCount(rs.getLong("retry_count")); return orphan; } } @SuppressWarnings("unchecked") @Override public List<SubmissionScheduleOrphan> getSubmissionScheduleOrphans(int numToRead) { // We only want to return one orphan per customer to avoid multi-threaded // contention issues with the database. For instance, 2 threads may need to // rebuild the same set of data_file_summary_info records for a given data_file. // We also want to give the CLEANUP action orphans a lower priority than // the normal orphans which is why a decode of the action shows up in the order by // within the analytical function row_number. String sql = "SELECT * FROM " + "( " + " SELECT o.sid, " + " o.customer_sid, " + " o.submission_period_sid, " + " o.data_file_sid, " + " o.action, " + " o.process_time, " + " o.create_date, " + " o.retry_count, " + " row_number() over (partition by o.customer_sid " + " order by " + " decode(o.action,'CLEANUP',100,10)," + " o.process_time) rn " + " FROM submission_schedule_orphan o " + " WHERE o.process_time < sysdate " + ") " + "WHERE rownum < ? " + " AND rn = 1"; List<SubmissionScheduleOrphan> orphans = getTemplate().query(sql, new Object[] { numToRead }, SUBMISSION_SCHEDULE_ORPHAN_MAPPER); return orphans; } @Override public void deleteSubmissionScheduleOrphan(SubmissionScheduleOrphan id) { deleteId("submission_schedule_orphan", id.getSid()); } @SuppressWarnings("unchecked") @Override public List<LearnedNameOrphan> getLearnedNameOrphans(int numToRead) { final String sql = "SELECT * FROM (SELECT o.sid as orphan_sid, l.sid as name_learning_sid, l.from_name, l.to_name, l.approval_status" + " FROM name_learning l" + " JOIN name_learning_orphan o ON o.name_learning_sid = l.sid" + " WHERE o.process_time < sysdate" + " ) WHERE rownum < ?"; return getTemplate().query(sql, new Object[] { numToRead }, LEARNED_NAME_ORPHAN_MAPPER); } @Override public void deleteLearnedNameOrphan(LearnedNameOrphan orphan) { deleteId("name_learning_orphan", orphan.getSid()); } private static class LearnedNameOrphanMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { LearnedName learnedName = new LearnedName(rs.getString("from_name"), rs.getString("to_name")); learnedName.setApprovalStatus(ApprovalStatus.fromString(rs.getString("approval_status"))); learnedName.setSid(rs.getLong("name_learning_sid")); LearnedNameOrphan learnedNameOrphan = new LearnedNameOrphan(learnedName); learnedNameOrphan.setSid(rs.getLong("orphan_sid")); return learnedNameOrphan; } } private static class InowTranslationOrphanMapper implements RowMapper<TranslationOrphan> { public TranslationOrphan mapRow(ResultSet rs, int rowNum) throws SQLException { TranslationOrphan translationOrphan = new TranslationOrphan(); translationOrphan.setSid(rs.getLong("sid")); translationOrphan.setInowProfileSid(rs.getLong("inow_profile_sid")); translationOrphan.setRetryCount(rs.getLong("retry_count")); translationOrphan.setGroupByValue(Math.round(rs.getLong("cnt") / 10)); return translationOrphan; } } private static class SubmissionPeriodUpdateOrphanMapper implements RowMapper<SubmissionPeriodUpdateOrphanId> { public SubmissionPeriodUpdateOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { SubmissionPeriodUpdateOrphanId submissionPeriodUpdateOrphanId = new SubmissionPeriodUpdateOrphanId(); submissionPeriodUpdateOrphanId.setSid(rs.getLong("sid")); submissionPeriodUpdateOrphanId.setCustomerSid(rs.getLong("customer_sid")); submissionPeriodUpdateOrphanId.setOldStartDate(rs.getDate("old_start_date")); submissionPeriodUpdateOrphanId.setRetryCount(rs.getLong("retry_count")); return submissionPeriodUpdateOrphanId; } } private static class InowRelationOrphanMapper implements RowMapper<InowRelationOrphan> { public InowRelationOrphan mapRow(ResultSet rs, int rowNum) throws SQLException { InowRelationOrphan inowRelationOrphan = new InowRelationOrphan(); inowRelationOrphan.setSid(rs.getLong("sid")); inowRelationOrphan.setInowProfileSid( rs.getLong("inow_profile_sid")); inowRelationOrphan.setRelatedInowProfileSid( rs.getLong("related_inow_profile_sid")); inowRelationOrphan.setRetryCount(rs.getLong("retry_count")); return inowRelationOrphan; } } private static class ExportOutputOrphanMapper implements RowMapper<ExportOutputOrphanId> { public ExportOutputOrphanId mapRow(ResultSet rs, int rowNum) throws SQLException { ExportOutputOrphanId exportOutputOrphan = new ExportOutputOrphanId(); exportOutputOrphan.setCustomerSid(rs.getLong("CUSTOMER_SID")); exportOutputOrphan.setExportOutputSid( rs.getLong("EXPORT_OUTPUT_SID")); exportOutputOrphan.setSid(rs.getLong("SID")); exportOutputOrphan.setRetryCount(rs.getLong("RETRY_COUNT")); exportOutputOrphan.setExportRequestSid( rs.getLong("EXPORT_REQUEST_SID")); exportOutputOrphan.setGroupByValue(rs.getLong("EXPORT_STATUS_SID")); exportOutputOrphan.setSessionId(rs.getString("SESSION_ID")); return exportOutputOrphan; } } }
package com.modeln.cdm.service.translation; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.infonow.framework.util.spring.JdbcTemplateProxy; import com.infonow.framework.util.spring.NamedParameterJdbcTemplateProxy; import com.infonow.service.recovery.RecoveryQueries; import com.infonow.service.recovery.RecoveryQueriesImpl; import com.infonow.service.recovery.controller.TranslationController; import org.json.JSONException; import org.json.JSONObject; import com.infonow.crux.dao.InowProfileDao; import com.infonow.crux.impl.InowProfileImpl; import com.infonow.framework.service.ServiceResponse; import com.infonow.framework.service.configuration.support.ServiceDefinition; import com.infonow.framework.service.context.ServiceContext; import com.infonow.framework.service.support.ServiceException; import com.infonow.service.configuration.ConfigurationException; import com.infonow.service.configuration.impl.AbstractBaseServiceWithConfiguration; import com.infonow.service.recovery.TranslationOrphan; import com.modeln.cdm.integration.aws.AmazonSNSClientImpl; import com.modeln.cdm.service.translation.configuration.TranslationConfguration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import software.amazon.awssdk.utils.StringUtils; import javax.sql.DataSource; @ServiceDefinition(name = "translationService", abstraction = com.modeln.cdm.service.translation.TranslationService.class, implementation = com.modeln.cdm.service.translation.TranslationServiceImpl.class) public class TranslationServiceImpl extends AbstractBaseServiceWithConfiguration implements TranslationService { private InowProfileRelationService inowProfileRelationService; private RecoveryQueries _recoveryQueries; private AmazonSNSClientImpl awsSnsClient; private String awsSnsTopic; private InowProfileDao inowProfileDao; private static String UNWANTED_CHARS; private static String LATIN_CHARS; private static Pattern UNWANTED_PATTERN; private static Pattern LATIN_PATTERN; private TranslationConfguration translationConfig; private NamedParameterJdbcTemplate namedParameterJdbcTemplate; private JdbcTemplate template; private TranslationController translationController; Matcher matcher; public TranslationServiceImpl() { if (UNWANTED_CHARS == null) { UNWANTED_CHARS = "[\\u0020-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E\\u0030-\\u0039\\u00A0-\\u00BF\\u2013-\\u204A]"; } if (LATIN_CHARS == null) { LATIN_CHARS = "[\\u0041-\\u005A\\u0061-\\u007A\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\uFF00-\\uFF60]+"; } if (UNWANTED_PATTERN == null) { UNWANTED_PATTERN = Pattern.compile(UNWANTED_CHARS); } if (LATIN_PATTERN == null) { LATIN_PATTERN = Pattern.compile(LATIN_CHARS); } } public RecoveryQueries getRecoveryQueries() { if (_recoveryQueries == null) { throw new IllegalStateException("The attribute _recoveryQueries can not be null"); } return _recoveryQueries; } // public RecoveryQueries getRecoveryQueries() // { // return recoveryQueries; // } public void setRecoveryQueries(RecoveryQueries recoveryQueries) { _recoveryQueries = recoveryQueries; } public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return this.namedParameterJdbcTemplate; } @SuppressWarnings("unchecked") @Override public ServiceResponse execute(ServiceContext serviceContext, Object userObject, Object userData) throws ServiceException { if (!(userData instanceof List<?>)) { throw new IllegalArgumentException("Argument userData must be a List but was " + userData == null ? null : userData.getClass().getName()); } System.out.println("userdata : "); System.out.println(userData); List<TranslationOrphan> ids = ((List<TranslationOrphan>) userData); List<JSONObject> addrs = new ArrayList<JSONObject>(); translationConfig = getTranslationConfig(); String sql = "update translation_orphans set status = :status where sid = :sid"; List<Long> translationIds = new ArrayList<Long>(); for (TranslationOrphan id : ids) { Long sid = id.getSid(); // Map<String, Object> paramMap = new HashMap<String, Object>(); // paramMap.put("sid", sid); // paramMap.put("status","IN PROGRESS"); InowProfileImpl inowProfile = (InowProfileImpl) getInowProfileDao().getBySid(id.getInowProfileSid()); boolean entityNeedsTranslation = isNonLatin(inowProfile.getName()); String address = inowProfile.getStreet1() + inowProfile.getStreet2() + inowProfile.getCity() + inowProfile.getStateProvince() + inowProfile.getPostalCode(); boolean addressNeedsTranslation = isNonLatin(address);//The method returns true if the percentage of Latin characters in the cleaned addressComponent is below the threshold specified in translationConfig. //entity needs translation and address needs translation both are false => addr turns out to be null JSONObject addr = createTranslationInput(inowProfile, entityNeedsTranslation, addressNeedsTranslation); // if(getNamedParameterJdbcTemplate() != null) // { // getNamedParameterJdbcTemplate().update(sql, paramMap); // } translationIds.add(sid);//just trying it out if (addr != null) { translationIds.add(sid); addrs.add(addr); //ids.remove()//give the id of that particualr orphan } } // getRecoveryQueries().test();//is it because of getRecoveryQueries changeStatus("IN PROGRESS",translationIds);//just trying it out if (!addrs.isEmpty())//addrs list is empty, when does it enter into this condition?? { publish(addrs); changeStatus("IN PROGRESS",translationIds); //call a method, pass translation orphans ids list } return new ServiceResponse("Success", ServiceResponse.SUCCESS); } public void changeStatus(String status,List<Long> translationIds){ getRecoveryQueries().updateStatusTranslationOrphans(status, translationIds); } protected JSONObject createTranslationInput(InowProfileImpl inowProfile, boolean entityNeedsTranslation, boolean addressNeedsTranslation) throws ServiceException { JSONObject addr = null; if ((entityNeedsTranslation || addressNeedsTranslation) && isTranslationNeededForCountry(inowProfile.getCountryObject().getTwoCharCode()) && !isInowRelationAlreadyExists(inowProfile)) { addr = new JSONObject(); //pick the orphans which are in pending state /*Fetch the pending orphans. Update their status to IN PROGRESS. Save the updated status back to the database. */ // loadIds(10); // //change the value of the attribute status in the table translation_orphans from pending to in progress // TranslationController translationController = new TranslationController(); // List<TranslationOrphan> pendingOrphans = translationController.getPendingOrphans();//these orphans must be sent to the amazon SQS and the status of those orphans must be changed to in progress // translationController.updateOrphanStatus(pendingOrphans, "IN PROGRESS");//is this where im supposed to change the //status of the orphan, I dont think so since im updating the status of all the orphans which are in pending //state but I'll only have to update the status of the orphan which is picked up AWS queue(SQS) System.out.println("inow id : "+inowProfile.getId()); try { addr.put("id", inowProfile.getIdentifier()); JSONObject addrDetails = new JSONObject(); if (entityNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getName())) { addrDetails.put("name", inowProfile.getName()); } } if (addressNeedsTranslation) { if (!StringUtils.isEmpty(inowProfile.getStreet1())) { addrDetails.put("street1", inowProfile.getStreet1()); } if (!StringUtils.isEmpty(inowProfile.getStreet2())) { addrDetails.put("street2", inowProfile.getStreet2()); } if (!StringUtils.isEmpty(inowProfile.getCity())) { addrDetails.put("city", inowProfile.getCity()); } if (!StringUtils.isEmpty(inowProfile.getStateProvince())) { addrDetails.put("stateprovince", inowProfile.getStateProvince()); } if (!StringUtils.isEmpty(inowProfile.getPostalCode())) { addrDetails.put("postalcode", inowProfile.getPostalCode()); } if (!StringUtils.isEmpty(inowProfile.getCountry())) { addrDetails.put("country", inowProfile.getCountryObject().getTwoCharCode()); } } addr.put("query", addrDetails); addr.put("target", "EN"); } catch (JSONException e) { throw new ServiceException("Exception while converting InowProfile to JSONObject" + e); } } return addr; } public void publish(List<JSONObject> addrs) throws ServiceException { //here change the orphan's status to in progress try { getAwsSnsClient().publishSingleMessages(getAwsSnsTopic(), addrs); } catch (Exception e) { throw new ServiceException("Exception while publishing message to Amazon SNS", e); } } private boolean isTranslationNeededForCountry(String country) { return translationConfig.getCountries().contains(country); } private boolean isNonLatin(String addressComponent) { addressComponent = addressComponent.replace("null", ""); matcher = UNWANTED_PATTERN.matcher(addressComponent); String fulladdress = matcher.replaceAll(""); if (StringUtils.isEmpty(fulladdress)) { return false; } String latinAddress = ""; matcher = LATIN_PATTERN.matcher(fulladdress); while (matcher.find()) { latinAddress += matcher.group(); } float matchPercent = (latinAddress.length() * 100 / fulladdress.length()); return matchPercent < translationConfig.getThreshold(); } private boolean isInowRelationAlreadyExists(InowProfileImpl inowProfile) { return getInowProfileRelationService().isRelationExists(inowProfile.getSid()); } private TranslationConfguration getTranslationConfig() { ServiceContext configContext = new ServiceContext(null, null); try { return (TranslationConfguration) getRequiredConfiguration(configContext); } catch (ConfigurationException e) { throw new IllegalStateException(e); } } public AmazonSNSClientImpl getAwsSnsClient() { return awsSnsClient; } public void setAwsSnsClient(AmazonSNSClientImpl awsSnsClient) { this.awsSnsClient = awsSnsClient; } public String getAwsSnsTopic() { return awsSnsTopic; } public void setAwsSnsTopic(String awsSnsTopic) { this.awsSnsTopic = awsSnsTopic; } public InowProfileDao getInowProfileDao() { return inowProfileDao; } public void setInowProfileDao(InowProfileDao inowProfileDao) { this.inowProfileDao = inowProfileDao; } public InowProfileRelationService getInowProfileRelationService() { return inowProfileRelationService; } public void setInowProfileRelationService(InowProfileRelationService inowProfileRelationService) { this.inowProfileRelationService = inowProfileRelationService; } }
-- Determining what factors were more prevalent across all collisions SELECT COUNT(*) AS TOTAL_COLLISIONS, (SUM(CASE WHEN INATTENTIONIND = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_INATTENTIONIND, (SUM(CASE WHEN UNDERINFL = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_UNDERINFL, (SUM(CASE WHEN SPEEDING = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_SPEEDING, (SUM(CASE WHEN HITPARKEDCAR = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_HITPARKEDCAR, (SUM(CASE WHEN POORDRIVINGCOND = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_POORDRIVINGCOND, (SUM(CASE WHEN NIGH