Compare commits

...

17 Commits

Author SHA1 Message Date
jfgiraud 85a858d3b8 WIP: bolsa V 1.1 horaires bourses dans footer 2026-07-12 10:41:08 +00:00
jfgiraud 39e5ae87ff WIP: bolsa V 1.0 2026-07-08 15:08:50 +00:00
jfgiraud 3a5e8a70e2 WIP: tout ok et popup centrées et modernes il ne reste plus que ordreJFG 2026-07-07 17:54:53 +00:00
jfgiraud 4df8cf495a WIP: tout fonctionne + corrections de bug v2 2026-07-07 11:30:17 +00:00
jfgiraud 18102d1627 WIP: tout fonctionne + corrections de bug 2026-07-07 10:42:02 +00:00
jfgiraud e55772986b WIP: tout fonctionne meme le scroll il ne reste plus que ordreJFG 2026-07-06 14:51:34 +00:00
jfgiraud 8793bb09d7 WIP: tout fonctionne il ne reste plus que ordreJFG et le scroll 2026-07-06 14:18:36 +00:00
jfgiraud 75de2a46f1 WIP: tout ok sauf btn 'creer un ordre' 2026-07-06 13:37:50 +00:00
jfgiraud 9fc641f93b formulaire ok sauf calcul totaux et btn modifier 2026-07-05 19:22:35 +00:00
jfgiraud c252d648b8 formulaire ok pour tout sauf btn modifier 2026-07-05 18:21:13 +00:00
jfgiraud 9865c17ac8 le btn creer un ordre fctionne 2026-07-05 14:19:13 +00:00
jfgiraud 26c5f06f98 WIP : sauvegarde avant de continuer ordreGF fctionne mais pas les btn 2026-07-05 13:52:19 +00:00
jfgiraud 33a23d0392 menu compteGF et compteJFG full operationnel 2026-07-02 15:03:26 +00:00
jfgiraud 236ae4ab8c menu csv full operationnel 2026-07-02 14:15:39 +00:00
jfgiraud 2675598eee menu csv operationnel 2026-07-02 14:12:33 +00:00
jfgiraud 16c0c594b1 menu actions operationnel 2026-07-02 13:39:17 +00:00
jfgiraud dedf5f1964 menu ok graphiquement et page 404 ok 2026-07-02 10:14:49 +00:00
44 changed files with 6186 additions and 354 deletions
+9
View File
@@ -0,0 +1,9 @@
{
"yaml.schemas": {
"file:///home/jfgiraud/.vscode-server/extensions/continue.continue-2.0.0-linux-x64/config-yaml-schema.json": [
".continue/**/*.yaml",
"file:///home/jfgiraud/.continue/config.yaml"
]
},
"json.schemas": []
}
+692
View File
@@ -0,0 +1,692 @@
isin,ticker,yahoo_code,company_name,updated_at
FR0011184241,ADOC,ADOC.PA,Adocia,"2026-07-02 13:36:06"
FR00140066X4,ALTHO,ALTHO.PA,Metavisio,"2026-07-02 13:31:23"
KR7005380001,005380,005380.KS,"Hyundai Motor Company","2026-07-02 12:40:35"
KR7005930003,005930,005930.KS,"Samsung Electronics Co., Ltd.","2026-07-02 11:03:20"
FR0000039109,SCHP,SCHP.PA,"Seche Environnement","2026-06-17 11:41:00"
DE000BAY0017,BAYN,BAYN.DE,"Bayer AG","2026-06-17 11:38:00"
DE000PASM111,P911,P911.DE,"Porsche AG","2026-06-17 11:38:00"
DK0062498110,NOVOB,NOVO-B.CO,"Novo Nordisk A/S","2026-06-17 11:38:00"
FR0000051732,ALTA,ALTA.PA,Altareit,"2026-06-17 11:38:00"
FR0000073298,ALT,ALT.PA,Alten,"2026-06-17 11:38:00"
GB0007188757,RIO,RIO.L,"Rio Tinto plc","2026-06-17 11:38:00"
NL0000009355,UNA,UNA.AS,"Unilever PLC","2026-06-17 11:38:00"
CH0012005267,NOVN,NOVN.SW,"Novartis AG","2026-06-17 11:35:00"
CH0038863350,NESN,NESN.SW,"Nestlé SA","2026-06-17 11:35:00"
DE0007100000,MBG,MBG.DE,"Mercedes-Benz Group","2026-06-17 11:35:00"
FR0000031122,AIRP,AIRP.PA,"Air France-KLM","2026-06-17 11:35:00"
FR0000035081,ICAD,ICAD.PA,Icade,"2026-06-17 11:35:00"
FR0000053381,VLA,VLA.PA,"Valneva SE","2026-06-17 11:35:00"
FR0010241639,ALM,ALM.PA,"McPhy Energy","2026-06-17 11:35:00"
GB00BP6MXD84,BP,BP.L,"BP plc","2026-06-17 11:35:00"
LU1598081501,MT,MT.PA,ArcelorMittal,"2026-06-17 11:35:00"
NL0015000H23,ASML,ASML.AS,"ASML Holding","2026-06-17 11:35:00"
FR001400IZY7,CO,CO.PA,"Casino Guichard Perrachon","2026-06-17 11:28:00"
ES0139140174,COL,COL.MC,"Colonial SFL, SOCIMI, S.A.","2026-06-17 08:00:34"
ES0177542018,IAG,IAG.MC,"International Consolidated Airlines Group (IAG)","2026-06-17 07:58:31"
US0000000BTC,BTC-USD,BTC-USD,"Bitcoin USD","2026-06-16 19:53:44"
US000000GOLD,GC=F,GC=F,"Gold Ounce","2026-06-16 19:53:44"
XC0009677409,BRN,BZ=F,"Brent Crude Oil","2026-06-16 19:53:44"
BMG0450A1053,ACGL,ACGL,"Arch Capital Group","2026-06-16 19:00:10"
CH0044328745,CB,CB,"Chubb Limited","2026-06-16 19:00:10"
IE00B4BNMY34,ACN,ACN,Accenture,"2026-06-16 19:00:10"
IE00B8KQN827,ETN,ETN,"Eaton Corporation","2026-06-16 19:00:10"
IE00B9699L58,ALLE,ALLE,Allegion,"2026-06-16 19:00:10"
IE00BLP1HW54,AON,AON,Aon,"2026-06-16 19:00:10"
JE00BJ1F3079,AMCR,AMCR,Amcor,"2026-06-16 19:00:10"
US0009041051,ADT,ADT,"ADT Inc.","2026-06-16 19:00:10"
US0010551028,AFL,AFL,Aflac,"2026-06-16 19:00:10"
US00130H1059,AES,AES,"AES Corporation","2026-06-16 19:00:10"
US0017651060,AAL,AAL,"American Airlines Group","2026-06-16 19:00:10"
US0028241000,ABT,ABT,"Abbott Laboratories","2026-06-16 19:00:10"
US00287Y1091,ABBV,ABBV,AbbVie,"2026-06-16 19:00:10"
US00846U1016,A,A,"Agilent Technologies","2026-06-16 19:00:10"
US0090661010,ABNB,ABNB,Airbnb,"2026-06-16 19:00:10"
US0091581068,APD,APD,"Air Products and Chemicals","2026-06-16 19:00:10"
US0097281069,AKAM,AKAM,Akamai,"2026-06-16 19:00:10"
US0126531013,ALB,ALB,"Albemarle Corporation","2026-06-16 19:00:10"
US0152711091,ARE,ARE,"Alexandria Real Estate Equities","2026-06-16 19:00:10"
US0162551016,ALGN,ALGN,"Align Technology","2026-06-16 19:00:10"
US0188021085,LNT,LNT,"Alliant Energy","2026-06-16 19:00:10"
US0200021014,ALL,ALL,Allstate,"2026-06-16 19:00:10"
US02209S1033,MO,MO,Altria,"2026-06-16 19:00:10"
US0231351067,AMZN,AMZN,Amazon,"2026-06-16 19:00:10"
US0236081024,AEE,AEE,Ameren,"2026-06-16 19:00:10"
US0255371017,AEP,AEP,"American Electric Power","2026-06-16 19:00:10"
US0268747849,AIG,AIG,"American International Group","2026-06-16 19:00:10"
US03027X1000,AMT,AMT,"American Tower","2026-06-16 19:00:10"
US0304201033,AWK,AWK,"American Water Works","2026-06-16 19:00:10"
US03076C1062,AMP,AMP,"Ameriprise Financial","2026-06-16 19:00:10"
US0311001004,AME,AME,Ametek,"2026-06-16 19:00:10"
US0320951017,APH,APH,Amphenol,"2026-06-16 19:00:10"
US0326541051,ADI,ADI,"Analog Devices","2026-06-16 19:00:10"
US03662Q1058,ANSS,ANSS,Ansys,"2026-06-16 19:00:10"
US0367521038,ELV,ELV,"Elevance Health","2026-06-16 19:00:10"
US03743Q1085,APA,APA,"APA Corporation","2026-06-16 19:00:10"
US03769M1062,APO,APO,"Apollo Global Management","2026-06-16 19:00:10"
US0382221051,AMAT,AMAT,"Applied Materials","2026-06-16 19:00:10"
US03831W1080,APP,APP,AppLovin,"2026-06-16 19:00:10"
US0394831020,ADM,ADM,Archer-Daniels-Midland,"2026-06-16 19:00:10"
US03990B1017,ARES,ARES,"Ares Management","2026-06-16 19:00:10"
US0404132054,ANET,ANET,"Arista Networks","2026-06-16 19:00:10"
US04586V1026,AIZ,AIZ,Assurant,"2026-06-16 19:00:10"
US0495601058,ATO,ATO,"Atmos Energy","2026-06-16 19:00:10"
US0527691069,ADSK,ADSK,Autodesk,"2026-06-16 19:00:10"
US0533321024,AZO,AZO,AutoZone,"2026-06-16 19:00:10"
US0534841012,AVB,AVB,"AvalonBay Communities","2026-06-16 19:00:10"
US0536111091,AVY,AVY,"Avery Dennison","2026-06-16 19:00:10"
US05464C1018,AXON,AXON,"Axon Enterprise","2026-06-16 19:00:10"
US0584981064,BALL,BALL,"Ball Corporation","2026-06-16 19:00:10"
US0605051046,BAC,BAC,"Bank of America","2026-06-16 19:00:10"
US0635761097,AJG,AJG,"Arthur J. Gallagher & Co.","2026-06-16 19:00:10"
US0640581007,BK,BK,"The Bank of New York Mellon","2026-06-16 19:00:10"
US0718131099,BAX,BAX,"Baxter International","2026-06-16 19:00:10"
US0758871014,BDX,BDX,"Becton Dickinson","2026-06-16 19:00:10"
US0846707026,BRK.B,BRK.B,"Berkshire Hathaway","2026-06-16 19:00:10"
US0865161014,BBY,BBY,"Best Buy","2026-06-16 19:00:10"
US09062X1037,BIIB,BIIB,Biogen,"2026-06-16 19:00:10"
US09290D1019,BLK,BLK,BlackRock,"2026-06-16 19:00:10"
US09857L1048,BKNG,BKNG,"Booking Holdings","2026-06-16 19:00:10"
US1011211018,BXP,BXP,"BXP, Inc.","2026-06-16 19:00:10"
US1011371077,BSX,BSX,"Boston Scientific","2026-06-16 19:00:10"
US1101221007,BMY,BMY,"Bristol Myers Squibb","2026-06-16 19:00:10"
US11133T1034,BR,BR,"Broadridge Financial Solutions","2026-06-16 19:00:10"
US1128071014,LRCX,LRCX,"Lam Research","2026-06-16 19:00:10"
US1152361010,BRO,BRO,"Brown & Brown","2026-06-16 19:00:10"
US1156372096,BF.B,BF.B,Brown-Forman,"2026-06-16 19:00:10"
US12008R1077,BLDR,BLDR,"Builders FirstSource","2026-06-16 19:00:10"
US12503M1080,CBOE,CBOE,"Cboe Global Markets","2026-06-16 19:00:10"
US12504L1098,CBRE,CBRE,"CBRE Group","2026-06-16 19:00:10"
US12514G1085,CDW,CDW,CDW,"2026-06-16 19:00:10"
US1252691001,CF,CF,"CF Industries","2026-06-16 19:00:10"
US12541W2098,CHRW,CHRW,"C.H. Robinson","2026-06-16 19:00:10"
US1255231003,CI,CI,"The Cigna Group","2026-06-16 19:00:10"
US12572Q1058,CME,CME,"CME Group","2026-06-16 19:00:10"
US1258961002,CMS,CMS,"CMS Energy","2026-06-16 19:00:10"
US1264081035,CSX,CSX,"CSX Corporation","2026-06-16 19:00:10"
US1273871087,CDNS,CDNS,"Cadence Design Systems","2026-06-16 19:00:10"
US1331311027,CPT,CPT,"Camden Property Trust","2026-06-16 19:00:10"
US1344291091,CPB,CPB,"Campbell Soup Company","2026-06-16 19:00:10"
US14040H1059,COF,COF,"Capital One","2026-06-16 19:00:10"
US14149Y1082,CAH,CAH,"Cardinal Health","2026-06-16 19:00:10"
US14448C1045,CARR,CARR,"Carrier Global","2026-06-16 19:00:10"
US1468691027,CVNA,CVNA,Carvana,"2026-06-16 19:00:10"
US1475281036,CASY,CASY,"Casey's General Stores","2026-06-16 19:00:10"
US1491231015,CAT,CAT,"Caterpillar Inc.","2026-06-16 19:00:10"
US1508701034,CE,CE,Celanese,"2026-06-16 19:00:10"
US15135B1017,CNC,CNC,"Centene Corporation","2026-06-16 19:00:10"
US15189T1079,CNP,CNP,"CenterPoint Energy","2026-06-16 19:00:10"
US1598641074,CRL,CRL,"Charles River Laboratories","2026-06-16 19:00:10"
US16119P1084,CHTR,CHTR,"Charter Communications","2026-06-16 19:00:10"
US1696561059,CMG,CMG,"Chipotle Mexican Grill","2026-06-16 19:00:10"
US1713401024,CHD,CHD,"Church & Dwight","2026-06-16 19:00:10"
US1717791016,CIEN,CIEN,Ciena,"2026-06-16 19:00:10"
US1720621010,CINF,CINF,"Cincinnati Financial","2026-06-16 19:00:10"
US17275R1023,CSCO,CSCO,Cisco,"2026-06-16 19:00:10"
US1729081035,CTAS,CTAS,Cintas,"2026-06-16 19:00:10"
US1729674242,C,C,Citigroup,"2026-06-16 19:00:10"
US1746101054,CFG,CFG,"Citizens Financial Group","2026-06-16 19:00:10"
US1890541097,CLX,CLX,Clorox,"2026-06-16 19:00:10"
US19247G1076,COHR,COHR,Coherent,"2026-06-16 19:00:10"
US19260U1051,COIN,COIN,Coinbase,"2026-06-16 19:00:10"
US1941621039,CL,CL,Colgate-Palmolive,"2026-06-16 19:00:10"
US1999081045,FIX,FIX,"Comfort Systems USA","2026-06-16 19:00:10"
US2003401070,CMA,CMA,Comerica,"2026-06-16 19:00:10"
US20825C1045,COP,COP,ConocoPhillips,"2026-06-16 19:00:10"
US2091151041,ED,ED,"Consolidated Edison","2026-06-16 19:00:10"
US21037T1097,CEG,CEG,"Constellation Energy","2026-06-16 19:00:10"
US21664A1025,COO,COO,"The Cooper Companies","2026-06-16 19:00:10"
US2172041061,CPRT,CPRT,Copart,"2026-06-16 19:00:10"
US22052L1044,CTVA,CTVA,Corteva,"2026-06-16 19:00:10"
US22160N1090,CSGP,CSGP,"CoStar Group","2026-06-16 19:00:10"
US22788C1053,CRWD,CRWD,CrowdStrike,"2026-06-16 19:00:10"
US2283681060,CCK,CCK,"Crown Holdings","2026-06-16 19:00:10"
US2310211063,CMI,CMI,Cummins,"2026-06-16 19:00:10"
US23331A1097,DHI,DHI,"D.R. Horton","2026-06-16 19:00:10"
US2333311072,DTE,DTE,"DTE Energy","2026-06-16 19:00:10"
US2371941053,DRI,DRI,"Darden Restaurants","2026-06-16 19:00:10"
US23804L1035,DDOG,DDOG,Datadog,"2026-06-16 19:00:10"
US23918K1088,DVA,DVA,"DaVita Inc.","2026-06-16 19:00:10"
US2441991054,DE,DE,"John Deere","2026-06-16 19:00:10"
US24703L2025,DELL,DELL,"Dell Technologies","2026-06-16 19:00:10"
US2473617023,DAL,DAL,"Delta Air Lines","2026-06-16 19:00:10"
US25179M1036,DVN,DVN,"Devon Energy","2026-06-16 19:00:10"
US2521311074,DXCM,DXCM,Dexcom,"2026-06-16 19:00:10"
US25278X1090,FANG,FANG,"Diamondback Energy","2026-06-16 19:00:10"
US2546871060,DIS,DIS,"Walt Disney","2026-06-16 19:00:10"
US2567461080,DLTR,DLTR,"Dollar Tree","2026-06-16 19:00:10"
US25746U1097,DOV,DOV,"Dover Corporation","2026-06-16 19:00:10"
US25754A2015,DPZ,DPZ,Domino's,"2026-06-16 19:00:10"
US26441C2044,DUK,DUK,"Duke Energy","2026-06-16 19:00:10"
US26614N1028,DD,DD,DuPont,"2026-06-16 19:00:10"
US26875P1012,EOG,EOG,"EOG Resources","2026-06-16 19:00:10"
US26884L1098,EQT,EQT,"EQT Corporation","2026-06-16 19:00:10"
US2788651006,ECL,ECL,Ecolab,"2026-06-16 19:00:10"
US2810201077,EIX,EIX,"Edison International","2026-06-16 19:00:10"
US28176E1082,EW,EW,"Edwards Lifesciences","2026-06-16 19:00:10"
US2855121099,EA,EA,"Electronic Arts","2026-06-16 19:00:10"
US29084Q1004,EME,EME,"EMCOR Group","2026-06-16 19:00:10"
US2910111044,EMR,EMR,"Emerson Electric","2026-06-16 19:00:10"
US29364G1031,ETR,ETR,Entergy,"2026-06-16 19:00:10"
US29414B1044,EPAM,EPAM,"EPAM Systems","2026-06-16 19:00:10"
US2944291051,EFX,EFX,Equifax,"2026-06-16 19:00:10"
US29476L1070,EQR,EQR,"Equity Residential","2026-06-16 19:00:10"
US29530P1021,ERIE,ERIE,"Erie Indemnity","2026-06-16 19:00:10"
US2971721029,ESS,ESS,"Essex Property Trust","2026-06-16 19:00:10"
US30034W1062,EVRG,EVRG,Evergy,"2026-06-16 19:00:10"
US30161N1019,EXE,EXE,"Expand Energy","2026-06-16 19:00:10"
US3021301094,EXPD,EXPD,"Expeditors International","2026-06-16 19:00:10"
US30225T1025,EXR,EXR,"Extra Space Storage","2026-06-16 19:00:10"
US3024913036,FMC,FMC,"FMC Corporation","2026-06-16 19:00:10"
US3030751057,FDS,FDS,FactSet,"2026-06-16 19:00:10"
US3032501047,FICO,FICO,"Fair Isaac","2026-06-16 19:00:10"
US3119001044,FAST,FAST,Fastenal,"2026-06-16 19:00:10"
US3137451015,FRT,FRT,"Federal Realty","2026-06-16 19:00:10"
US31428X1063,FDX,FDX,FedEx,"2026-06-16 19:00:10"
US3156161024,FFIV,FFIV,"F5, Inc.","2026-06-16 19:00:10"
US3167731005,FITB,FITB,"Fifth Third Bank","2026-06-16 19:00:10"
US3364331070,FLT,FLT,"Business Fuel Cards (Corpay)","2026-06-16 19:00:10"
US3379321074,FE,FE,FirstEnergy,"2026-06-16 19:00:10"
US34959E1091,FTNT,FTNT,Fortinet,"2026-06-16 19:00:10"
US34959J1084,FTV,FTV,Fortive,"2026-06-16 19:00:10"
US35137L1052,FOXA,FOXA,"Fox Corporation (Class A)","2026-06-16 19:00:10"
US35137L2043,FOX,FOX,"Fox Corporation (Class B)","2026-06-16 19:00:10"
US3546131018,BEN,BEN,"Franklin Templeton","2026-06-16 19:00:10"
US35671D8570,FCX,FCX,Freeport-McMoRan,"2026-06-16 19:00:10"
US36266G1076,GEHC,GEHC,"GE HealthCare","2026-06-16 19:00:10"
US3666511072,IT,IT,Gartner,"2026-06-16 19:00:10"
US3695501086,GD,GD,"General Dynamics","2026-06-16 19:00:10"
US3696043013,GEV,GEV,"GE Vernova","2026-06-16 19:00:10"
US3703341046,GIS,GIS,"General Mills","2026-06-16 19:00:10"
US37045V1008,GM,GM,"General Motors","2026-06-16 19:00:10"
US3746891040,GPC,GPC,"Genuine Parts Company","2026-06-16 19:00:10"
US37940X1028,GPN,GPN,"Global Payments","2026-06-16 19:00:10"
US37959E1029,GL,GL,"Globe Life","2026-06-16 19:00:10"
US3802371076,GNDY,GNDY,GoDaddy,"2026-06-16 19:00:10"
US38141G1040,GS,GS,"Goldman Sachs","2026-06-16 19:00:10"
US3848021040,GWW,GWW,"W. W. Grainger","2026-06-16 19:00:10"
US40412C1018,HCA,HCA,"HCA Healthcare","2026-06-16 19:00:10"
US40434L1052,HPQ,HPQ,"HP Inc.","2026-06-16 19:00:10"
US4165151048,HIG,HIG,"The Hartford","2026-06-16 19:00:10"
US42250P1030,DOC,DOC,"Healthpeak Properties","2026-06-16 19:00:10"
US4262811015,JKHY,JKHY,"Jack Henry & Associates","2026-06-16 19:00:10"
US4278661081,HSY,HSY,"The Hershey Company","2026-06-16 19:00:10"
US43300A2033,HD,HD,"Home Depot","2026-06-16 19:00:10"
US4404521001,HRL,HRL,"Hormel Foods","2026-06-16 19:00:10"
US44107P1049,HST,HST,"Host Hotels & Resorts","2026-06-16 19:00:10"
US4432011082,HWM,HWM,"Howmet Aerospace","2026-06-16 19:00:10"
US4435106079,HUBB,HUBB,"Hubbell Incorporated","2026-06-16 19:00:10"
US4448591028,HUM,HUM,Humana,"2026-06-16 19:00:10"
US4456581077,JBHT,JBHT,"J.B. Hunt","2026-06-16 19:00:10"
US4461501045,HBAN,HBAN,"Huntington Bancshares","2026-06-16 19:00:10"
US4464131063,HII,HII,"Huntington Ingalls Industries","2026-06-16 19:00:10"
US45168D1046,IDXX,IDXX,"IDEXX Laboratories","2026-06-16 19:00:10"
US4553708600,F,F,"Ford Motor Company","2026-06-16 19:00:10"
US45687V1061,IR,IR,"Ingersoll Rand","2026-06-16 19:00:10"
US45841N1072,IBKR,IBKR,"Interactive Brokers","2026-06-16 19:00:10"
US45866F1043,ICE,ICE,"Intercontinental Exchange","2026-06-16 19:00:10"
US4592001014,IBM,IBM,IBM,"2026-06-16 19:00:10"
US4595061015,IFF,IFF,"International Flavors & Fragrances","2026-06-16 19:00:10"
US4601461035,IP,IP,"International Paper","2026-06-16 19:00:10"
US46120E6023,ISRG,ISRG,"Intuitive Surgical","2026-06-16 19:00:10"
US46187W1071,INVH,INVH,"Invitation Homes","2026-06-16 19:00:10"
US46266C1053,IQV,IQV,IQVIA,"2026-06-16 19:00:10"
US46284V1017,IRM,IRM,"Iron Mountain","2026-06-16 19:00:10"
US46625H1005,JPM,JPM,"JPMorgan Chase","2026-06-16 19:00:10"
US4663131039,JBL,JBL,Jabil,"2026-06-16 19:00:10"
US46982L1089,J,J,"Jacobs Solutions","2026-06-16 19:00:10"
US49177J1025,KVUE,KVUE,Kenvue,"2026-06-16 19:00:10"
US49271V1008,KDP,KDP,"Keurig Dr Pepper","2026-06-16 19:00:10"
US4932671088,KEY,KEY,KeyCorp,"2026-06-16 19:00:10"
US49338L1035,KEYS,KEYS,Keysight,"2026-06-16 19:00:10"
US4943681035,KMB,KMB,Kimberly-Clark,"2026-06-16 19:00:10"
US49446R1095,KIM,KIM,"Kimco Realty","2026-06-16 19:00:10"
US49456B1017,KMI,KMI,"Kinder Morgan","2026-06-16 19:00:10"
US5010441013,KR,KR,Kroger,"2026-06-16 19:00:10"
US5024311095,LHX,LHX,L3Harris,"2026-06-16 19:00:10"
US5049221055,LH,LH,Labcorp,"2026-06-16 19:00:10"
US5178341070,LVS,LVS,"Las Vegas Sands","2026-06-16 19:00:10"
US5184391044,EL,EL,"Estée Lauder Companies","2026-06-16 19:00:10"
US5253271028,LDOS,LDOS,Leidos,"2026-06-16 19:00:10"
US5260571048,LEN,LEN,Lennar,"2026-06-16 19:00:10"
US5261071071,LII,LII,"Lennox International","2026-06-16 19:00:10"
US5380341090,LYV,LYV,"Live Nation Entertainment","2026-06-16 19:00:10"
US5398301094,LMT,LMT,"Lockheed Martin","2026-06-16 19:00:10"
US5404241031,L,L,"Loews Corporation","2026-06-16 19:00:10"
US5500211090,LULU,LULU,"Lululemon Athletica","2026-06-16 19:00:10"
US55024U1097,LITE,LITE,Lumentum,"2026-06-16 19:00:10"
US55261F1043,MTB,MTB,"M&T Bank","2026-06-16 19:00:10"
US5529531015,MGM,MGM,"MGM Resorts","2026-06-16 19:00:10"
US55354G1004,MSCI,MSCI,"MSCI Inc.","2026-06-16 19:00:10"
US5717481023,MRSH,MRSH,"Marsh & McLennan","2026-06-16 19:00:10"
US66987P1012,ES,ES,"Eversource Energy","2026-06-16 19:00:10"
US74834L1008,DGX,DGX,"Quest Diagnostics","2026-06-16 19:00:10"
US77313F1066,HOOD,HOOD,"Robinhood Markets","2026-06-16 19:00:10"
US78430Q1013,AOS,AOS,"A. O. Smith","2026-06-16 19:00:10"
US78464A6982,KRE,KRE,"SPDR S&P Regional Banking","2026-06-16 19:00:10"
US79466L3024,CRM,CRM,Salesforce,"2026-06-16 19:00:10"
US89235Q1011,SQ,SQ,"Block, Inc.","2026-06-16 19:00:10"
US9892071054,ZBRA,ZBRA,"Zebra Technologies","2026-06-16 19:00:10"
BMG667211046,NCLH,NCLH,"Norwegian Cruise Line Holdings","2026-06-16 18:51:11"
CH0102993182,TEL,TEL,"TE Connectivity","2026-06-16 18:51:11"
IE000S9YS062,SW,SW,"Smurfit Westrock","2026-06-16 18:51:11"
IE00B58JVZ52,STX,STX,"Seagate Technology","2026-06-16 18:51:11"
IE00BDB64S84,WTW,WTW,"Willis Towers Watson","2026-06-16 18:51:11"
US4062161017,HAL,HAL,Halliburton,"2026-06-16 18:51:11"
US42824C1099,HPE,HPE,"Hewlett Packard Enterprise","2026-06-16 18:51:11"
US45784P1012,PODD,PODD,"Insulet Corporation","2026-06-16 18:51:11"
US4781281010,SJM,SJM,"J.M. Smucker Company (The)","2026-06-16 18:51:11"
US60871R1023,TAP,TAP,"Molson Coors Beverage Company","2026-06-16 18:51:11"
US61174X1090,MNST,MNST,"Monster Beverage","2026-06-16 18:51:11"
US61945C1036,MOS,MOS,"Mosaic Company (The)","2026-06-16 18:51:11"
US6556631008,NDSN,NDSN,"Nordson Corporation","2026-06-16 18:51:11"
US6558441084,NSC,NSC,"Norfolk Southern","2026-06-16 18:51:11"
US6658591044,NTRS,NTRS,"Northern Trust","2026-06-16 18:51:11"
US6687711084,NOC,NOC,"Northrop Grumman","2026-06-16 18:51:11"
US6703461052,NUE,NUE,Nucor,"2026-06-16 18:51:11"
US6745991058,OXY,OXY,"Occidental Petroleum","2026-06-16 18:51:11"
US6821891057,ON,ON,"ON Semiconductor","2026-06-16 18:51:11"
US6852181040,ORLY,ORLY,"OReilly Automotive","2026-06-16 18:51:11"
US69331C1080,PCG,PCG,"PG&E Corporation","2026-06-16 18:51:11"
US6951561090,PKG,PKG,"Packaging Corporation of America","2026-06-16 18:51:11"
US69608A1088,PLTR,PLTR,"Palantir Technologies","2026-06-16 18:51:11"
US7010941042,PH,PH,"Parker Hannifin","2026-06-16 18:51:11"
US7234841010,PNW,PNW,"Pinnacle West Capital","2026-06-16 18:51:11"
US7433151039,PGR,PGR,"Progressive Corporation","2026-06-16 18:51:11"
US74624M1027,RL,RL,"Ralph Lauren Corporation","2026-06-16 18:51:11"
US74955A1051,RVTY,RVTY,Revvity,"2026-06-16 18:51:11"
US7588491032,REG,REG,"Regency Centers","2026-06-16 18:51:11"
US7591EP1011,RF,RF,"Regions Financial Corporation","2026-06-16 18:51:11"
US8085131055,SCHW,SCHW,"Charles Schwab Corporation","2026-06-16 18:51:11"
US8168511090,SRE,SRE,Sempra,"2026-06-16 18:51:11"
US8243481061,SHW,SHW,Sherwin-Williams,"2026-06-16 18:51:11"
US8330341012,SNA,SNA,Snap-on,"2026-06-16 18:51:11"
US84574X1019,SOLV,SOLV,Solventum,"2026-06-16 18:51:11"
US8574771031,STT,STT,"State Street Corporation","2026-06-16 18:51:11"
US8591521005,STE,STE,Steris,"2026-06-16 18:51:11"
US8718291030,SYY,SYY,Sysco,"2026-06-16 18:51:11"
US8760301072,TPR,TPR,"Tapestry, Inc.","2026-06-16 18:51:11"
US87612G1013,TRGP,TRGP,"Targa Resources","2026-06-16 18:51:11"
US8793601058,TDY,TDY,"Teledyne Technologies","2026-06-16 18:51:11"
US88262P1021,TPL,TPL,"Texas Pacific Land Corporation","2026-06-16 18:51:11"
US8932351081,TDG,TDG,"TransDigm Group","2026-06-16 18:51:11"
US89417E1091,TRV,TRV,"Travelers Companies (The)","2026-06-16 18:51:11"
US8962391004,TRMB,TRMB,"Trimble Inc.","2026-06-16 18:51:11"
US9253401031,VRT,VRT,Vertiv,"2026-06-16 18:51:11"
US92556H2067,PSKY,PSKY,"Paramount Skydance Corporation","2026-06-16 18:51:11"
US9293251000,WRB,WRB,"W. R. Berkley Corporation","2026-06-16 18:51:11"
US9344231041,WBD,WBD,"Warner Bros. Discovery","2026-06-16 18:51:11"
US9418481035,WAT,WAT,"Waters Corporation","2026-06-16 18:51:11"
US9581021055,WDC,WDC,"Western Digital","2026-06-16 18:51:11"
US9621661089,WY,WY,Weyerhaeuser,"2026-06-16 18:51:11"
US9694571004,WMB,WMB,"Williams Companies","2026-06-16 18:51:11"
US9078181081,UNP,UNP,"Union Pacific Corporation","2026-06-16 18:28:11"
US92047W1018,VLO,VLO,"Valero Energy","2026-06-16 18:28:11"
US9290421011,VMC,VMC,"Vulcan Materials Company","2026-06-16 18:28:11"
US8425871071,SO,SO,"Southern Company","2026-06-16 18:28:08"
US30231G1022,XOM,XOM,ExxonMobil,"2026-06-16 18:27:40"
US7427181094,PG,PG,"Procter & Gamble","2026-06-16 18:27:26"
US5719032022,MAR,MAR,"Marriott International","2026-06-16 18:27:17"
US5745991068,MAS,MAS,Masco,"2026-06-16 18:27:17"
US57636Q1040,MA,MA,Mastercard,"2026-06-16 18:27:17"
US5825211047,MKC,MKC,"McCormick & Company","2026-06-16 18:27:17"
US5950171042,MCHP,MCHP,"Microchip Technology","2026-06-16 18:27:17"
US6092071563,MDLZ,MDLZ,"Mondelez International","2026-06-16 18:27:17"
US6098391054,MCO,MCO,"Moody's Corporation","2026-06-16 18:27:17"
US8447411088,LUV,LUV,"Southwest Airlines","2026-06-16 18:27:17"
US88579Y1010,MMM,MMM,3M,"2026-06-16 18:27:17"
US15135U1097,COR,COR,Cencora,"2026-06-16 18:26:35"
BM1250141022,BG,BG,"Bunge Global","2026-06-16 18:22:24"
US09260D1072,BX,BX,"Blackstone Inc.","2026-06-16 18:22:24"
BMG2004J1036,CCL,CCL,"Carnival Corporation","2026-06-16 17:05:54"
BMG3223R1088,EG,EG,"Everest Group","2026-06-16 17:05:54"
BMG491BT1088,IVZ,IVZ,Invesco,"2026-06-16 17:05:54"
CA8000541083,SNDK,SNDK,Sandisk,"2026-06-16 17:05:54"
IE0001827041,CRH,CRH,"CRH plc","2026-06-16 17:05:54"
IE000S9YS762,LIN,LIN,"Linde plc","2026-06-16 17:05:54"
IE00BK9ZQ967,TT,TT,"Trane Technologies","2026-06-16 17:05:54"
IE00BLS09M33,PNR,PNR,Pentair,"2026-06-16 17:05:54"
IE00BTN1Y115,MDT,MDT,Medtronic,"2026-06-16 17:05:54"
IE00BY7QL619,JCI,JCI,"Johnson Controls","2026-06-16 17:05:54"
JE00BTDN8H13,APTV,APTV,Aptiv,"2026-06-16 17:05:54"
JP3832370005,NWS,NWS,"News Corp (Class B)","2026-06-16 17:05:54"
LR0008862868,RCL,RCL,"Royal Caribbean Group","2026-06-16 17:05:54"
NL0009434992,LYB,LYB,LyondellBasell,"2026-06-16 17:05:54"
NL0009538784,NXPI,NXPI,"NXP Semiconductors","2026-06-16 17:05:54"
US00206R1023,T,T,AT&T,"2026-06-16 17:05:54"
US0530151036,ADP,ADP,"Automatic Data Processing","2026-06-16 17:05:54"
US05722G1004,BKR,BKR,"Baker Hughes","2026-06-16 17:05:54"
US09073M1045,TECH,TECH,Bio-Techne,"2026-06-16 17:05:54"
US21036P1084,STZ,STZ,"Constellation Brands","2026-06-16 17:05:54"
US2538681030,DLR,DLR,"Digital Realty","2026-06-16 17:05:54"
US3143521058,FDXF,FDXF,"FedEx Freight","2026-06-16 17:05:54"
US3687361044,GNRC,GNRC,Generac,"2026-06-16 17:05:54"
US4432011017,HON,HON,Honeywell,"2026-06-16 17:05:54"
US5732841060,MLM,MLM,"Martin Marietta Materials","2026-06-16 17:05:54"
US59156R1086,MET,MET,MetLife,"2026-06-16 17:05:54"
US5926881054,MTD,MTD,"Mettler Toledo","2026-06-16 17:05:54"
US59522J1034,MAA,MAA,"Mid-America Apartment Communities","2026-06-16 17:05:54"
US60770K1079,MRNA,MRNA,Moderna,"2026-06-16 17:05:54"
US6174464486,MS,MS,"Morgan Stanley","2026-06-16 17:05:54"
US6200763075,MSI,MSI,"Motorola Solutions","2026-06-16 17:05:54"
US6293775085,NRG,NRG,"NRG Energy","2026-06-16 17:05:54"
US6311031081,NDAQ,NDAQ,"Nasdaq, Inc.","2026-06-16 17:05:54"
US64110D1046,NTAP,NTAP,NetApp,"2026-06-16 17:05:54"
US64110L1061,NFLX,NFLX,Netflix,"2026-06-16 17:05:54"
US65473P1057,NI,NI,NiSource,"2026-06-16 17:05:54"
US6795801009,ODFL,ODFL,"Old Dominion","2026-06-16 17:05:54"
US6819191064,OMC,OMC,"Omnicom Group","2026-06-16 17:05:54"
US6826801036,OKE,OKE,Oneok,"2026-06-16 17:05:54"
US68902V1070,OTIS,OTIS,"Otis Worldwide","2026-06-16 17:05:54"
US6934751057,PNC,PNC,"PNC Financial Services","2026-06-16 17:05:54"
US69351T1060,PPL,PPL,"PPL Corporation","2026-06-16 17:05:54"
US69370C1009,PTC,PTC,"PTC Inc.","2026-06-16 17:05:54"
US6937181088,PCAR,PCAR,Paccar,"2026-06-16 17:05:54"
US6974351057,PANW,PANW,"Palo Alto Networks","2026-06-16 17:05:54"
US7043261079,PAYX,PAYX,Paychex,"2026-06-16 17:05:54"
US7181721090,PM,PM,"Philip Morris International","2026-06-16 17:05:54"
US7185461040,PSX,PSX,"Phillips 66","2026-06-16 17:05:54"
US73278L1052,POOL,POOL,"Pool Corporation","2026-06-16 17:05:54"
US74144T1088,TROW,TROW,"T. Rowe Price","2026-06-16 17:05:54"
US74340W1036,PLD,PLD,Prologis,"2026-06-16 17:05:54"
US7443201022,PRU,PRU,"Prudential Financial","2026-06-16 17:05:54"
US7445731067,PEG,PEG,"Public Service Enterprise Group","2026-06-16 17:05:54"
US74460D1090,PSA,PSA,"Public Storage","2026-06-16 17:05:54"
US74762E1029,PWR,PWR,"Quanta Services","2026-06-16 17:05:54"
US7547301090,RJF,RJF,"Raymond James Financial","2026-06-16 17:05:54"
US75513E1010,RTX,RTX,"RTX Corporation","2026-06-16 17:05:54"
US75886F1075,REGN,REGN,"Regeneron Pharmaceuticals","2026-06-16 17:05:54"
US7607591002,RSG,RSG,"Republic Services","2026-06-16 17:05:54"
US7611521078,RMD,RMD,ResMed,"2026-06-16 17:05:54"
US7739031091,ROK,ROK,"Rockwell Automation","2026-06-16 17:05:54"
US7757111049,ROL,ROL,"Rollins, Inc.","2026-06-16 17:05:54"
US7766961061,ROP,ROP,"Roper Technologies","2026-06-16 17:05:54"
US7782961038,ROST,ROST,"Ross Stores","2026-06-16 17:05:54"
US78410G1040,SBAC,SBAC,"SBA Communications","2026-06-16 17:05:54"
US8064071025,HSIC,HSIC,"Henry Schein","2026-06-16 17:05:54"
US81762P1021,NOW,NOW,ServiceNow,"2026-06-16 17:05:54"
US8288061091,SPG,SPG,"Simon Property Group","2026-06-16 17:05:54"
US83088M1027,SWKS,SWKS,"Skyworks Solutions","2026-06-16 17:05:54"
US8545021011,SWK,SWK,"Stanley Black & Decker","2026-06-16 17:05:54"
US8581191009,STLD,STLD,"Steel Dynamics","2026-06-16 17:05:54"
US86800U3023,SMCI,SMCI,Supermicro,"2026-06-16 17:05:54"
US8716071076,SNPS,SNPS,Synopsys,"2026-06-16 17:05:54"
US87165B1035,SYF,SYF,"Synchrony Financial","2026-06-16 17:05:54"
US8725401090,TJX,TJX,"TJX Companies","2026-06-16 17:05:54"
US87256C1018,TKO,TKO,"TKO Group Holdings","2026-06-16 17:05:54"
US8807701029,TER,TER,Teradyne,"2026-06-16 17:05:54"
US8832031012,TXT,TXT,Textron,"2026-06-16 17:05:54"
US88339J1051,TTD,TTD,"Trade Desk (The)","2026-06-16 17:05:54"
US8835561023,TMO,TMO,"Thermo Fisher Scientific","2026-06-16 17:05:54"
US89832Q1094,TFC,TFC,"Truist Financial","2026-06-16 17:05:54"
US9022521051,TYL,TYL,"Tyler Technologies","2026-06-16 17:05:54"
US9024941034,TSN,TSN,"Tyson Foods","2026-06-16 17:05:54"
US9026531049,UDR,UDR,"UDR, Inc.","2026-06-16 17:05:54"
US9029733048,USB,USB,"U.S. Bancorp","2026-06-16 17:05:54"
US90353T1007,UBER,UBER,Uber,"2026-06-16 17:05:54"
US90384S3031,ULTA,ULTA,"Ulta Beauty","2026-06-16 17:05:54"
US9100471096,UAL,UAL,"United Airlines Holdings","2026-06-16 17:05:54"
US9113631090,URI,URI,"United Rentals","2026-06-16 17:05:54"
US9139031002,UHS,UHS,"Universal Health Services","2026-06-16 17:05:54"
US9224751084,VEEV,VEEV,"Veeva Systems","2026-06-16 17:05:54"
US92276F1003,VTR,VTR,Ventas,"2026-06-16 17:05:54"
US92338C1036,VLTO,VLTO,Veralto,"2026-06-16 17:05:54"
US92343E1029,VRSN,VRSN,Verisign,"2026-06-16 17:05:54"
US92556V1061,VTRS,VTRS,Viatris,"2026-06-16 17:05:54"
US9256521090,VICI,VICI,"Vici Properties","2026-06-16 17:05:54"
US92840M1027,VST,VST,"Vistra Corp.","2026-06-16 17:05:54"
US92939U1060,WEC,WEC,"WEC Energy Group","2026-06-16 17:05:54"
US9297401088,WAB,WAB,Wabtec,"2026-06-16 17:05:54"
US9553061055,WST,WST,"West Pharmaceutical Services","2026-06-16 17:05:54"
US9699041011,WSM,WSM,"Williams-Sonoma, Inc.","2026-06-16 17:05:54"
US98138H1014,WDAY,WDAY,"Workday, Inc.","2026-06-16 17:05:54"
US9831341071,WYNN,WYNN,"Wynn Resorts","2026-06-16 17:05:54"
US98419M1009,XYL,XYL,"Xylem Inc.","2026-06-16 17:05:54"
US98978V1035,ZTS,ZTS,Zoetis,"2026-06-16 17:05:54"
US2787681061,SATS,SATS,"EchoStar Corporation","2026-06-16 16:35:23"
US7458671010,PHM,PHM,"PulteGroup Inc.","2026-06-16 16:30:09"
US67066G1040,NVDA,NVDA,"Nvidia Corp","2026-06-16 16:28:51"
US25809K1051,DASH,DASH,"Dash (DoorDash) Inc. Class A","2026-06-16 16:18:37"
US11135F1012,AVGO,AVGO,"Broadcom Inc.","2026-06-16 16:17:39"
US2786421030,EBAY,EBAY,"EBay Inc.","2026-06-16 16:16:40"
US29444U7000,EQIX,EQIX,"Equinix Inc.","2026-06-16 16:15:41"
CH0114405324,GRMN,GRMN,"Garmin Ltd.","2026-06-16 16:14:40"
US3755581036,GILD,GILD,"Gilead Sciences Inc.","2026-06-16 16:13:38"
US00724F1012,ADBE,ADBE,"Adobe Inc.","2026-06-16 16:12:31"
US45337C1027,INCY,INCY,"Incyte Corp.","2026-06-16 16:11:14"
BMG611881019,LBTYA,LBTYA,"Liberty Global plc Class A","2026-06-16 16:09:50"
US5312297550,FWONK,FWONK,"Liberty Media Corp. Formula One","2026-06-16 16:05:55"
US58155Q1031,MCK,MCK,"McKesson Corp.","2026-06-16 16:04:40"
US8318652091,AOS,AOS,"Smith (A.O.) Corp.","2026-06-16 16:02:06"
US8552441094,SBUX,SBUX,"Starbucks Corp.","2026-06-16 15:59:41"
US02079K3059,GOOGL,GOOGL,"Alphabet Inc. Class A","2026-06-16 15:54:59"
US98389B1008,XEL,XEL,"Xcel Energy Inc.","2026-06-16 15:40:07"
US0079031078,AMD,AMD,"Advanced Micro Devices Inc.","2026-06-16 15:39:17"
US0138721065,AA,AA,"Aligned Technology (Altera)","2026-06-16 15:39:17"
US02079K1079,GOOG,GOOG,"Alphabet Inc. Class C","2026-06-16 15:39:17"
US0258161092,AXP,AXP,"American Express Co","2026-06-16 15:39:17"
US0311621009,AMGN,AMGN,"Amgen Inc.","2026-06-16 15:39:17"
US0378331005,AAPL,AAPL,"Apple Inc.","2026-06-16 15:39:17"
US0970231058,BA,BA,"Boeing Co","2026-06-16 15:39:17"
US1266501006,CVS,CVS,"Cisco Systems Inc.","2026-06-16 15:39:17"
US1431301027,KMX,KMX,"Caterpillar Inc.","2026-06-16 15:39:17"
US1667641005,CVX,CVX,"Chevron Corp.","2026-06-16 15:39:17"
US1912161007,KO,KO,"Coca-Cola Co","2026-06-16 15:39:17"
US1924461023,CTSH,CTSH,"Cognizant Technology Solutions","2026-06-16 15:39:17"
US20030N1019,CMCSA,CMCSA,"Comcast Corp. Class A","2026-06-16 15:39:17"
US2058871029,CAG,CAG,"Conagra Brands Inc.","2026-06-16 15:39:17"
US2193501051,GLW,GLW,"Constellation Energy Corp.","2026-06-16 15:39:17"
US22160K1051,COST,COST,"Costco Wholesale Corp.","2026-06-16 15:39:17"
US22822V1017,CCI,CCI,"Crown Castle Inc.","2026-06-16 15:39:17"
US2358511028,DHR,DHR,"Danaher Corp.","2026-06-16 15:39:17"
US2566771059,DG,DG,"Dollar Tree Inc.","2026-06-16 15:39:17"
US2605571031,DOW,DOW,"Dow Inc.","2026-06-16 15:39:17"
US30212P3038,EXPE,EXPE,"Fastenal Co.","2026-06-16 15:39:17"
US30303M1027,META,META,"Meta Platforms Inc. Class A","2026-06-16 15:39:17"
US31620M1062,FIS,FIS,"Fifth Third Bancorp","2026-06-16 15:39:17"
US31847R1023,FAF,FAF,"First Solar Inc.","2026-06-16 15:39:17"
US3377381088,FISV,FISV,"Fiserv Inc.","2026-06-16 15:39:17"
US3696041033,GE,GE,"General Electric Co","2026-06-16 15:39:17"
US4180561072,HAS,HAS,"Hasbro Inc.","2026-06-16 15:39:17"
US4385161066,HON,HON,"Honeywell International Inc.","2026-06-16 15:39:17"
US45167R1041,IEX,IEX,"Idexx Laboratories Inc.","2026-06-16 15:39:17"
US4523081093,ITW,ITW,"Illumina Inc.","2026-06-16 15:39:17"
US4581401001,INTC,INTC,"Intel Corp.","2026-06-16 15:39:17"
US4612021034,INTU,INTU,"Intuitive Surgical Inc.","2026-06-16 15:39:17"
US4781601046,JNJ,JNJ,"Johnson & Johnson","2026-06-16 15:39:17"
US48123V1026,ZD,ZD,"Keurig Dr Pepper Inc.","2026-06-16 15:39:17"
US4824801009,KLAC,KLAC,"KLA Corp.","2026-06-16 15:39:17"
US48251W1045,KKR,KKR,"Lam Research Corp.","2026-06-16 15:39:17"
US5007541064,KHC,KHC,"Kraft Heinz Co.","2026-06-16 15:39:17"
US5324571083,LLY,LLY,"Lilly (Eli) & Co","2026-06-16 15:39:17"
US5486611073,LOW,LOW,"Lululemon Athletica Inc.","2026-06-16 15:39:17"
US56585A1025,MPC,MPC,"Marriott International Class A","2026-06-16 15:39:17"
US5801351017,MCD,MCD,"McDonald's Corp.","2026-06-16 15:39:17"
US58933Y1055,MRK,MRK,"Merck & Co. Inc.","2026-06-16 15:39:17"
US5949181045,MSFT,MSFT,"Microsoft Corp.","2026-06-16 15:39:17"
US5951121038,MU,MU,"Micron Technology Inc.","2026-06-16 15:39:17"
US6092071058,MDLZ,MDLZ,"Mondelez International Inc.","2026-06-16 15:39:17"
US62944T1051,NVR,NVR,"Netease Inc. ADR","2026-06-16 15:39:17"
US6516391066,NEM,NEM,"Newcom Group (Newmont)","2026-06-16 15:39:17"
US65339F1012,NEE,NEE,"NextEra Energy Inc.","2026-06-16 15:39:17"
US6541061031,NKE,NKE,"Nike Inc. Class B","2026-06-16 15:39:17"
US68389X1054,ORCL,ORCL,"O'Reilly Automotive Inc.","2026-06-16 15:39:17"
US6935061076,PPG,PPG,"Paccar Inc.","2026-06-16 15:39:17"
US70450Y1038,PYPL,PYPL,"PayPal Holdings Inc.","2026-06-16 15:39:17"
US7134481081,PEP,PEP,"PepsiCo Inc.","2026-06-16 15:39:17"
US7170811035,PFE,PFE,"Pfizer Inc.","2026-06-16 15:39:17"
US74251V1026,PFG,PFG,"Prudential Financial Inc.","2026-06-16 15:39:17"
US7475251036,QCOM,QCOM,"Qualcomm Inc.","2026-06-16 15:39:17"
US7561091049,O,O,"Realty Income Corp.","2026-06-16 15:39:17"
US78409V1044,SPGI,SPGI,"S&P Global Inc.","2026-06-16 15:39:17"
US8636671013,SYK,SYK,"Stryker Corp.","2026-06-16 15:39:17"
US8679141031,STI,STI,"Sunrun Inc.","2026-06-16 15:39:17"
US8718291078,SYY,SYY,"Sysco Corp.","2026-06-16 15:39:17"
US8725901040,TMUS,TMUS,"T-Mobile US Inc.","2026-06-16 15:39:17"
US87612E1064,TGT,TGT,"Target Corp.","2026-06-16 15:39:17"
US88160R1014,TSLA,TSLA,"Tesla Inc.","2026-06-16 15:39:17"
US8825081040,TXN,TXN,"Texas Instruments Inc.","2026-06-16 15:39:17"
US8923561067,TSCO,TSCO,"Tractor Supply Co.","2026-06-16 15:39:17"
US9113121068,UPS,UPS,"United Parcel Service Class B","2026-06-16 15:39:17"
US91324P1021,UNH,UNH,"UnitedHealth Group Inc.","2026-06-16 15:39:17"
US92343V1044,VZ,VZ,"Verisign Inc.","2026-06-16 15:39:17"
US92345Y1064,VRSK,VRSK,"Verisk Analytics Inc. Class A","2026-06-16 15:39:17"
US92532F1003,VRTX,VRTX,"Vertex Pharmaceuticals Inc.","2026-06-16 15:39:17"
US92826C8394,V,V,"Visa Inc. Class A","2026-06-16 15:39:17"
US9311421039,WMT,WMT,"Walmart Inc.","2026-06-16 15:39:17"
US94106L1098,WM,WM,"Waste Management Inc.","2026-06-16 15:39:17"
US9497461015,WFC,WFC,"Wells Fargo & Co.","2026-06-16 15:39:17"
US95040Q1040,WELL,WELL,"Western Digital Corp.","2026-06-16 15:39:17"
US9884981013,YUM,YUM,"Yum! Brands Inc.","2026-06-16 15:39:17"
US98956P1021,ZBH,ZBH,"Zebra Technologies Corp. Class A","2026-06-16 15:39:17"
US98980L1017,ZM,ZM,"Zoom Video Communications","2026-06-16 15:39:17"
ES0105563003,ANE,ANE.MC,"Acciona Energía","2026-06-16 15:17:14"
ES0105025003,MRL,MRL.MC,"Merlin Properties","2026-06-16 15:14:37"
ES0105027009,LOG,LOG.MC,Logista,"2026-06-16 15:14:37"
ES0105046009,AENA,AENA.MC,Aena,"2026-06-16 15:14:37"
ES0105066007,CLNX,CLNX.MC,"Cellnex Telecom","2026-06-16 15:14:37"
ES0105777017,PUIG,PUIG.MC,"Puig Brands","2026-06-16 15:14:37"
ES0109067019,AMS,AMS.MC,"Amadeus IT Group","2026-06-16 15:14:37"
ES0113211835,BBVA,BBVA.MC,BBVA,"2026-06-16 15:14:37"
ES0113679I37,BKT,BKT.MC,Bankinter,"2026-06-16 15:14:37"
ES0113860A34,SAB,SAB.MC,"Banco Sabadell","2026-06-16 15:14:37"
ES0113900J37,SAN,SAN.MC,"Banco Santander","2026-06-16 15:14:37"
ES0116870314,NTGY,NTGY.MC,"Naturgy Energy Group","2026-06-16 15:14:37"
ES0118594417,IDR,IDR.MC,"Indra Sistemas","2026-06-16 15:14:37"
ES0124244E34,MAP,MAP.MC,Mapfre,"2026-06-16 15:14:37"
ES0125220311,ANA,ANA.MC,Acciona,"2026-06-16 15:14:37"
ES0130670112,ELE,ELE.MC,Endesa,"2026-06-16 15:14:37"
ES0130960018,ENG,ENG.MC,Enagás,"2026-06-16 15:14:37"
ES0132105018,ACX,ACX.MC,Acerinox,"2026-06-16 15:14:37"
ES0137650018,FDR,FDR.MC,Fluidra,"2026-06-16 15:14:37"
ES0140609019,CABK,CABK.MC,CaixaBank,"2026-06-16 15:14:37"
ES0144580Y14,IBE,IBE.MC,Iberdrola,"2026-06-16 15:14:37"
ES0148396007,ITX,ITX.MC,Inditex,"2026-06-16 15:14:37"
ES0157261019,ROVI,ROVI.MC,"Laboratorios Farmacéuticos Rovi","2026-06-16 15:14:37"
ES0165386014,SLR,SLR.MC,"Solaria Energía","2026-06-16 15:14:37"
ES0167050915,ACS,ACS.MC,ACS,"2026-06-16 15:14:37"
ES0171996087,GRF,GRF.MC,Grifols,"2026-06-16 15:14:37"
ES0173093024,RED,RED.MC,Redeia,"2026-06-16 15:14:37"
ES0173516115,REP,REP.MC,Repsol,"2026-06-16 15:14:37"
ES0178430E18,TEF,TEF.MC,Telefónica,"2026-06-16 15:14:37"
ES0180907000,UNI,UNI.MC,"Unicaja Banco","2026-06-16 15:14:37"
ES0182870214,SCYR,SCYR.MC,Sacyr,"2026-06-16 15:14:37"
ES0184262212,VIS,VIS.MC,Viscofan,"2026-06-16 15:14:37"
LU1598757687,MT,MT.AS,ArcelorMittal,"2026-06-16 15:14:37"
NL0015001FS8,FER,FER.MC,Ferrovial,"2026-06-16 15:14:37"
FR0013447729,VRLA,VRLA.PA,VERALLIA,"2026-06-16 14:40:56"
BE0003470755,SOLB,SOLB.BR,SOLVAY,"2026-06-16 14:39:36"
FR0000031577,VIRP,VIRP.PA,VIRBAC,"2026-06-16 14:39:36"
FR0000031775,VCT,VCT.PA,VICAT,"2026-06-16 14:39:36"
FR0000039299,BOL,BOL.PA,BOLLORE,"2026-06-16 14:39:36"
FR0000044448,NEX,NEX.PA,NEXANS,"2026-06-16 14:39:36"
FR0000045072,ACA,ACA.PA,"CREDIT AGRICOLE","2026-06-16 14:39:36"
FR0000050353,FII,FII.PA,LISI,"2026-06-16 14:39:36"
FR0000050809,SOP,SOP.PA,"SOPRA STERIA GROUP","2026-06-16 14:39:36"
FR0000051807,TEP,TEP.PA,TELEPERFORMANCE,"2026-06-16 14:39:36"
FR0000052292,RMS,RMS.PA,"HERMES INTL","2026-06-16 14:39:36"
FR0000053225,MMT,MMT.PA,"METROPOLE TV","2026-06-16 14:39:36"
FR0000054470,UBI,UBI.PA,"UBISOFT ENTERTAIN","2026-06-16 14:39:36"
FR0000054900,TFI,TFI.PA,TF1,"2026-06-16 14:39:36"
FR0000062671,EXA,EXA.PA,"EXAIL TECHNOLOGIES","2026-06-16 14:39:36"
FR0000064578,COV,COV.PA,COVIVIO,"2026-06-16 14:39:36"
FR0000071946,ATE,ATE.PA,ALTEN,"2026-06-16 14:39:36"
FR0000073272,SAF,SAF.PA,SAFRAN,"2026-06-16 14:39:36"
FR0000077919,DEC,DEC.PA,JCDECAUX,"2026-06-16 14:39:36"
FR0000120073,AI,AI.PA,"AIR LIQUIDE","2026-06-16 14:39:36"
FR0000120172,CA,CA.PA,CARREFOUR,"2026-06-16 14:39:36"
FR0000120271,TTE,TTE.PA,TOTALENERGIES,"2026-06-16 14:39:36"
FR0000120321,OR,OR.PA,L'OREAL,"2026-06-16 14:39:36"
FR0000120404,AC,AC.PA,ACCOR,"2026-06-16 14:39:36"
FR0000120503,EN,EN.PA,BOUYGUES,"2026-06-16 14:39:36"
FR0000120578,SAN,SAN.PA,SANOFI,"2026-06-16 14:39:36"
FR0000120628,CS,CS.PA,AXA,"2026-06-16 14:39:36"
FR0000120644,BN,BN.PA,DANONE,"2026-06-16 14:39:36"
FR0000120693,RI,RI.PA,"PERNOD RICARD","2026-06-16 14:39:36"
FR0000120859,NK,NK.PA,IMERYS,"2026-06-16 14:39:36"
FR0000120966,BB,BB.PA,BIC,"2026-06-16 14:39:36"
FR0000121014,MC,MC.PA,LVMH,"2026-06-16 14:39:36"
FR0000121121,RF,RF.PA,EURAZEO,"2026-06-16 14:39:36"
FR0000121147,FRVIA,FRVIA.PA,FORVIA,"2026-06-16 14:39:36"
FR0000121204,MF,MF.PA,WENDEL,"2026-06-16 14:39:36"
FR0000121220,SW,SW.PA,SODEXO,"2026-06-16 14:39:36"
FR0000121329,HO,HO.PA,THALES,"2026-06-16 14:39:36"
FR0000121485,KER,KER.PA,KERING,"2026-06-16 14:39:36"
FR0000121667,EL,EL.PA,ESSILORLUXOTTICA,"2026-06-16 14:39:36"
FR0000121709,SK,SK.PA,S.E.B.,"2026-06-16 14:39:36"
FR0000121964,LI,LI.PA,KLEPIERRE,"2026-06-16 14:39:36"
FR0000121972,SU,SU.PA,"SCHNEIDER ELECTRIC","2026-06-16 14:39:36"
FR0000124141,VIE,VIE.PA,"VEOLIA ENVIRON.","2026-06-16 14:39:36"
FR0000124570,OPM,OPM.PA,OPMOBILITY,"2026-06-16 14:39:36"
FR0000125007,SGO,SGO.PA,"SAINT GOBAIN","2026-06-16 14:39:36"
FR0000125338,CAP,CAP.PA,CAPGEMINI,"2026-06-16 14:39:36"
FR0000125486,DG,DG.PA,VINCI,"2026-06-16 14:39:36"
FR0000127771,VIV,VIV.PA,"VIVENDI SE","2026-06-16 14:39:36"
FR0000130395,RCO,RCO.PA,"REMY COINTREAU","2026-06-16 14:39:36"
FR0000130452,FGR,FGR.PA,EIFFAGE,"2026-06-16 14:39:36"
FR0000130577,PUB,PUB.PA,"PUBLICIS GROUPE SA","2026-06-16 14:39:36"
FR0000130809,GLE,GLE.PA,"SOCIETE GENERALE","2026-06-16 14:39:36"
FR0000131104,BNP,BNP.PA,"BNP PARIBAS ACT.A","2026-06-16 14:39:36"
FR0000131757,ERA,ERA.PA,ERAMET,"2026-06-16 14:39:36"
FR0000131906,RNO,RNO.PA,RENAULT,"2026-06-16 14:39:36"
FR0000133308,ORA,ORA.PA,ORANGE,"2026-06-16 14:39:36"
FR0004024222,ITP,ITP.PA,INTERPARFUMS,"2026-06-16 14:39:36"
FR0004056851,VLA,VLA.PA,VALNEVA,"2026-06-16 14:39:36"
FR0004065605,FR0004065605,FR0004065605.SG,MEDINCELL,"2026-06-16 14:39:36"
FR0004125920,AMUN,AMUN.PA,AMUNDI,"2026-06-16 14:39:36"
FR0005691656,TRI,TRI.PA,TRIGANO,"2026-06-16 14:39:36"
FR0006174348,BVI,BVI.PA,"BUREAU VERITAS","2026-06-16 14:39:36"
FR0010040865,GFC,GFC.PA,GECINA,"2026-06-16 14:39:36"
FR0010112524,NXI,NXI.PA,NEXITY,"2026-06-16 14:39:36"
FR0010208488,ENGI,ENGI.PA,ENGIE,"2026-06-16 14:39:36"
FR0010220475,ALO,ALO.PA,ALSTOM,"2026-06-16 14:39:36"
FR0010221234,ETL,ETL.PA,"EUTELSAT COMMUNIC.","2026-06-16 14:39:36"
FR0010241638,MERY,MERY.PA,MERCIALYS,"2026-06-16 14:39:36"
FR0010259150,IPN,IPN.PA,IPSEN,"2026-06-16 14:39:36"
FR0010282822,VU,VU.PA,Vusion,"2026-06-16 14:39:36"
FR0010307819,LR,LR.PA,LEGRAND,"2026-06-16 14:39:36"
FR0010313833,AKE,AKE.PA,ARKEMA,"2026-06-16 14:39:36"
FR0010340141,ADP,ADP.PA,ADP,"2026-06-16 14:39:36"
FR0010386334,CLARI,CLARI.PA,CLARIANE,"2026-06-16 14:39:36"
FR0010411983,SCR,SCR.PA,"SCOR SE","2026-06-16 14:39:36"
FR0010417345,DBV,DBV.PA,"DBV TECHNOLOGIES","2026-06-16 14:39:36"
FR0010451203,RXL,RXL.PA,REXEL,"2026-06-16 14:39:36"
FR0010481960,ARG,ARG.PA,ARGAN,"2026-06-16 14:39:36"
FR0010533075,GET,GET.PA,"GETLINK SE","2026-06-16 14:39:36"
FR0010667147,COFA,COFA.PA,COFACE,"2026-06-16 14:39:36"
FR0010828137,CARM,CARM.PA,CARMILA,"2026-06-16 14:39:36"
FR0010908533,EDEN,EDEN.PA,EDENRED,"2026-06-16 14:39:36"
FR0010929125,IDL,IDL.PA,"ID LOGISTICS GROUP","2026-06-16 14:39:36"
FR0011341205,NANO,NANO.PA,NANOBIOTIX,"2026-06-16 14:39:36"
FR0011726835,GTT,GTT.PA,GTT,"2026-06-16 14:39:36"
FR0011950732,ELIOR,ELIOR.PA,"ELIOR GROUP","2026-06-16 14:39:36"
FR0012333284,ABVX,ABVX.PA,ABIVAX,"2026-06-16 14:39:36"
FR0012435121,ELIS,ELIS.PA,ELIS,"2026-06-16 14:39:36"
FR0012757854,SPIE,SPIE.PA,SPIE,"2026-06-16 14:39:36"
FR0013154002,DIM,DIM.PA,"SARTORIUS STED BIO","2026-06-16 14:39:36"
FR0013176526,FR,FR.PA,VALEO,"2026-06-16 14:39:36"
FR0013227113,SOI,SOI.PA,SOITEC,"2026-06-16 14:39:36"
FR0013258662,AYV,AYV.PA,AYVENS,"2026-06-16 14:39:36"
FR0013269123,RUI,RUI.PA,RUBIS,"2026-06-16 14:39:36"
FR0013280286,BIM,BIM.PA,BIOMERIEUX,"2026-06-16 14:39:36"
FR0013326246,URW,URW.PA,UNIBAIL-RODAMCO-WE,"2026-06-16 14:39:36"
FR0013451333,FDJU,FDJU.PA,"FDJ UNITED","2026-06-16 14:39:36"
FR0013506730,VK,VK.PA,VALLOUREC,"2026-06-16 14:39:36"
FR0014000MR3,ERF,ERF.PA,"EUROFINS SCIENT.","2026-06-16 14:39:36"
FR0014003TT8,DSY,DSY.PA,"DASSAULT SYSTEMES","2026-06-16 14:39:36"
FR0014004L86,AM,AM.PA,"DASSAULT AVIATION","2026-06-16 14:39:36"
FR001400AJ45,ML,ML.PA,MICHELIN,"2026-06-16 14:39:36"
FR001400J770,AF,AF.PA,"AIR FRANCE -KLM","2026-06-16 14:39:36"
FR001400NLM4,EMEIS,EMEIS.PA,EMEIS,"2026-06-16 14:39:36"
FR001400PVN6,VIRI,VIRI.PA,VIRIDIEN,"2026-06-16 14:39:36"
FR001400Q9V2,EXENS,EXENS.PA,EXOSENS,"2026-06-16 14:39:36"
FR001400X2S4,ATO,ATO.PA,ATOS,"2026-06-16 14:39:36"
FR00140182K6,WLN,WLN.PA,WORLDLINE,"2026-06-16 14:39:36"
LU0088087324,SESG,SESG.PA,SES,"2026-06-16 14:39:36"
LU0569974404,APAM,APAM.AS,APERAM,"2026-06-16 14:39:36"
NL0000226223,STMPA,STMPA.PA,STMICROELECTRONICS,"2026-06-16 14:39:36"
NL0000235190,AIR,AIR.PA,AIRBUS,"2026-06-16 14:39:36"
NL0006294274,ENX,ENX.PA,EURONEXT,"2026-06-16 14:39:36"
NL0014559478,TE,TE.PA,"TECHNIP ENERGIES","2026-06-16 14:39:36"
NL00150001Q9,STLAM,STLAM.PA,"STELLANTIS NV","2026-06-16 14:39:36"
NL0015001W49,PLX,PLX.PA,PLUXEE,"2026-06-16 14:39:36"
1 isin ticker yahoo_code company_name updated_at
2 FR0011184241 ADOC ADOC.PA Adocia 2026-07-02 13:36:06
3 FR00140066X4 ALTHO ALTHO.PA Metavisio 2026-07-02 13:31:23
4 KR7005380001 005380 005380.KS Hyundai Motor Company 2026-07-02 12:40:35
5 KR7005930003 005930 005930.KS Samsung Electronics Co., Ltd. 2026-07-02 11:03:20
6 FR0000039109 SCHP SCHP.PA Seche Environnement 2026-06-17 11:41:00
7 DE000BAY0017 BAYN BAYN.DE Bayer AG 2026-06-17 11:38:00
8 DE000PASM111 P911 P911.DE Porsche AG 2026-06-17 11:38:00
9 DK0062498110 NOVOB NOVO-B.CO Novo Nordisk A/S 2026-06-17 11:38:00
10 FR0000051732 ALTA ALTA.PA Altareit 2026-06-17 11:38:00
11 FR0000073298 ALT ALT.PA Alten 2026-06-17 11:38:00
12 GB0007188757 RIO RIO.L Rio Tinto plc 2026-06-17 11:38:00
13 NL0000009355 UNA UNA.AS Unilever PLC 2026-06-17 11:38:00
14 CH0012005267 NOVN NOVN.SW Novartis AG 2026-06-17 11:35:00
15 CH0038863350 NESN NESN.SW Nestlé SA 2026-06-17 11:35:00
16 DE0007100000 MBG MBG.DE Mercedes-Benz Group 2026-06-17 11:35:00
17 FR0000031122 AIRP AIRP.PA Air France-KLM 2026-06-17 11:35:00
18 FR0000035081 ICAD ICAD.PA Icade 2026-06-17 11:35:00
19 FR0000053381 VLA VLA.PA Valneva SE 2026-06-17 11:35:00
20 FR0010241639 ALM ALM.PA McPhy Energy 2026-06-17 11:35:00
21 GB00BP6MXD84 BP BP.L BP plc 2026-06-17 11:35:00
22 LU1598081501 MT MT.PA ArcelorMittal 2026-06-17 11:35:00
23 NL0015000H23 ASML ASML.AS ASML Holding 2026-06-17 11:35:00
24 FR001400IZY7 CO CO.PA Casino Guichard Perrachon 2026-06-17 11:28:00
25 ES0139140174 COL COL.MC Colonial SFL, SOCIMI, S.A. 2026-06-17 08:00:34
26 ES0177542018 IAG IAG.MC International Consolidated Airlines Group (IAG) 2026-06-17 07:58:31
27 US0000000BTC BTC-USD BTC-USD Bitcoin USD 2026-06-16 19:53:44
28 US000000GOLD GC=F GC=F Gold Ounce 2026-06-16 19:53:44
29 XC0009677409 BRN BZ=F Brent Crude Oil 2026-06-16 19:53:44
30 BMG0450A1053 ACGL ACGL Arch Capital Group 2026-06-16 19:00:10
31 CH0044328745 CB CB Chubb Limited 2026-06-16 19:00:10
32 IE00B4BNMY34 ACN ACN Accenture 2026-06-16 19:00:10
33 IE00B8KQN827 ETN ETN Eaton Corporation 2026-06-16 19:00:10
34 IE00B9699L58 ALLE ALLE Allegion 2026-06-16 19:00:10
35 IE00BLP1HW54 AON AON Aon 2026-06-16 19:00:10
36 JE00BJ1F3079 AMCR AMCR Amcor 2026-06-16 19:00:10
37 US0009041051 ADT ADT ADT Inc. 2026-06-16 19:00:10
38 US0010551028 AFL AFL Aflac 2026-06-16 19:00:10
39 US00130H1059 AES AES AES Corporation 2026-06-16 19:00:10
40 US0017651060 AAL AAL American Airlines Group 2026-06-16 19:00:10
41 US0028241000 ABT ABT Abbott Laboratories 2026-06-16 19:00:10
42 US00287Y1091 ABBV ABBV AbbVie 2026-06-16 19:00:10
43 US00846U1016 A A Agilent Technologies 2026-06-16 19:00:10
44 US0090661010 ABNB ABNB Airbnb 2026-06-16 19:00:10
45 US0091581068 APD APD Air Products and Chemicals 2026-06-16 19:00:10
46 US0097281069 AKAM AKAM Akamai 2026-06-16 19:00:10
47 US0126531013 ALB ALB Albemarle Corporation 2026-06-16 19:00:10
48 US0152711091 ARE ARE Alexandria Real Estate Equities 2026-06-16 19:00:10
49 US0162551016 ALGN ALGN Align Technology 2026-06-16 19:00:10
50 US0188021085 LNT LNT Alliant Energy 2026-06-16 19:00:10
51 US0200021014 ALL ALL Allstate 2026-06-16 19:00:10
52 US02209S1033 MO MO Altria 2026-06-16 19:00:10
53 US0231351067 AMZN AMZN Amazon 2026-06-16 19:00:10
54 US0236081024 AEE AEE Ameren 2026-06-16 19:00:10
55 US0255371017 AEP AEP American Electric Power 2026-06-16 19:00:10
56 US0268747849 AIG AIG American International Group 2026-06-16 19:00:10
57 US03027X1000 AMT AMT American Tower 2026-06-16 19:00:10
58 US0304201033 AWK AWK American Water Works 2026-06-16 19:00:10
59 US03076C1062 AMP AMP Ameriprise Financial 2026-06-16 19:00:10
60 US0311001004 AME AME Ametek 2026-06-16 19:00:10
61 US0320951017 APH APH Amphenol 2026-06-16 19:00:10
62 US0326541051 ADI ADI Analog Devices 2026-06-16 19:00:10
63 US03662Q1058 ANSS ANSS Ansys 2026-06-16 19:00:10
64 US0367521038 ELV ELV Elevance Health 2026-06-16 19:00:10
65 US03743Q1085 APA APA APA Corporation 2026-06-16 19:00:10
66 US03769M1062 APO APO Apollo Global Management 2026-06-16 19:00:10
67 US0382221051 AMAT AMAT Applied Materials 2026-06-16 19:00:10
68 US03831W1080 APP APP AppLovin 2026-06-16 19:00:10
69 US0394831020 ADM ADM Archer-Daniels-Midland 2026-06-16 19:00:10
70 US03990B1017 ARES ARES Ares Management 2026-06-16 19:00:10
71 US0404132054 ANET ANET Arista Networks 2026-06-16 19:00:10
72 US04586V1026 AIZ AIZ Assurant 2026-06-16 19:00:10
73 US0495601058 ATO ATO Atmos Energy 2026-06-16 19:00:10
74 US0527691069 ADSK ADSK Autodesk 2026-06-16 19:00:10
75 US0533321024 AZO AZO AutoZone 2026-06-16 19:00:10
76 US0534841012 AVB AVB AvalonBay Communities 2026-06-16 19:00:10
77 US0536111091 AVY AVY Avery Dennison 2026-06-16 19:00:10
78 US05464C1018 AXON AXON Axon Enterprise 2026-06-16 19:00:10
79 US0584981064 BALL BALL Ball Corporation 2026-06-16 19:00:10
80 US0605051046 BAC BAC Bank of America 2026-06-16 19:00:10
81 US0635761097 AJG AJG Arthur J. Gallagher & Co. 2026-06-16 19:00:10
82 US0640581007 BK BK The Bank of New York Mellon 2026-06-16 19:00:10
83 US0718131099 BAX BAX Baxter International 2026-06-16 19:00:10
84 US0758871014 BDX BDX Becton Dickinson 2026-06-16 19:00:10
85 US0846707026 BRK.B BRK.B Berkshire Hathaway 2026-06-16 19:00:10
86 US0865161014 BBY BBY Best Buy 2026-06-16 19:00:10
87 US09062X1037 BIIB BIIB Biogen 2026-06-16 19:00:10
88 US09290D1019 BLK BLK BlackRock 2026-06-16 19:00:10
89 US09857L1048 BKNG BKNG Booking Holdings 2026-06-16 19:00:10
90 US1011211018 BXP BXP BXP, Inc. 2026-06-16 19:00:10
91 US1011371077 BSX BSX Boston Scientific 2026-06-16 19:00:10
92 US1101221007 BMY BMY Bristol Myers Squibb 2026-06-16 19:00:10
93 US11133T1034 BR BR Broadridge Financial Solutions 2026-06-16 19:00:10
94 US1128071014 LRCX LRCX Lam Research 2026-06-16 19:00:10
95 US1152361010 BRO BRO Brown & Brown 2026-06-16 19:00:10
96 US1156372096 BF.B BF.B Brown-Forman 2026-06-16 19:00:10
97 US12008R1077 BLDR BLDR Builders FirstSource 2026-06-16 19:00:10
98 US12503M1080 CBOE CBOE Cboe Global Markets 2026-06-16 19:00:10
99 US12504L1098 CBRE CBRE CBRE Group 2026-06-16 19:00:10
100 US12514G1085 CDW CDW CDW 2026-06-16 19:00:10
101 US1252691001 CF CF CF Industries 2026-06-16 19:00:10
102 US12541W2098 CHRW CHRW C.H. Robinson 2026-06-16 19:00:10
103 US1255231003 CI CI The Cigna Group 2026-06-16 19:00:10
104 US12572Q1058 CME CME CME Group 2026-06-16 19:00:10
105 US1258961002 CMS CMS CMS Energy 2026-06-16 19:00:10
106 US1264081035 CSX CSX CSX Corporation 2026-06-16 19:00:10
107 US1273871087 CDNS CDNS Cadence Design Systems 2026-06-16 19:00:10
108 US1331311027 CPT CPT Camden Property Trust 2026-06-16 19:00:10
109 US1344291091 CPB CPB Campbell Soup Company 2026-06-16 19:00:10
110 US14040H1059 COF COF Capital One 2026-06-16 19:00:10
111 US14149Y1082 CAH CAH Cardinal Health 2026-06-16 19:00:10
112 US14448C1045 CARR CARR Carrier Global 2026-06-16 19:00:10
113 US1468691027 CVNA CVNA Carvana 2026-06-16 19:00:10
114 US1475281036 CASY CASY Casey's General Stores 2026-06-16 19:00:10
115 US1491231015 CAT CAT Caterpillar Inc. 2026-06-16 19:00:10
116 US1508701034 CE CE Celanese 2026-06-16 19:00:10
117 US15135B1017 CNC CNC Centene Corporation 2026-06-16 19:00:10
118 US15189T1079 CNP CNP CenterPoint Energy 2026-06-16 19:00:10
119 US1598641074 CRL CRL Charles River Laboratories 2026-06-16 19:00:10
120 US16119P1084 CHTR CHTR Charter Communications 2026-06-16 19:00:10
121 US1696561059 CMG CMG Chipotle Mexican Grill 2026-06-16 19:00:10
122 US1713401024 CHD CHD Church & Dwight 2026-06-16 19:00:10
123 US1717791016 CIEN CIEN Ciena 2026-06-16 19:00:10
124 US1720621010 CINF CINF Cincinnati Financial 2026-06-16 19:00:10
125 US17275R1023 CSCO CSCO Cisco 2026-06-16 19:00:10
126 US1729081035 CTAS CTAS Cintas 2026-06-16 19:00:10
127 US1729674242 C C Citigroup 2026-06-16 19:00:10
128 US1746101054 CFG CFG Citizens Financial Group 2026-06-16 19:00:10
129 US1890541097 CLX CLX Clorox 2026-06-16 19:00:10
130 US19247G1076 COHR COHR Coherent 2026-06-16 19:00:10
131 US19260U1051 COIN COIN Coinbase 2026-06-16 19:00:10
132 US1941621039 CL CL Colgate-Palmolive 2026-06-16 19:00:10
133 US1999081045 FIX FIX Comfort Systems USA 2026-06-16 19:00:10
134 US2003401070 CMA CMA Comerica 2026-06-16 19:00:10
135 US20825C1045 COP COP ConocoPhillips 2026-06-16 19:00:10
136 US2091151041 ED ED Consolidated Edison 2026-06-16 19:00:10
137 US21037T1097 CEG CEG Constellation Energy 2026-06-16 19:00:10
138 US21664A1025 COO COO The Cooper Companies 2026-06-16 19:00:10
139 US2172041061 CPRT CPRT Copart 2026-06-16 19:00:10
140 US22052L1044 CTVA CTVA Corteva 2026-06-16 19:00:10
141 US22160N1090 CSGP CSGP CoStar Group 2026-06-16 19:00:10
142 US22788C1053 CRWD CRWD CrowdStrike 2026-06-16 19:00:10
143 US2283681060 CCK CCK Crown Holdings 2026-06-16 19:00:10
144 US2310211063 CMI CMI Cummins 2026-06-16 19:00:10
145 US23331A1097 DHI DHI D.R. Horton 2026-06-16 19:00:10
146 US2333311072 DTE DTE DTE Energy 2026-06-16 19:00:10
147 US2371941053 DRI DRI Darden Restaurants 2026-06-16 19:00:10
148 US23804L1035 DDOG DDOG Datadog 2026-06-16 19:00:10
149 US23918K1088 DVA DVA DaVita Inc. 2026-06-16 19:00:10
150 US2441991054 DE DE John Deere 2026-06-16 19:00:10
151 US24703L2025 DELL DELL Dell Technologies 2026-06-16 19:00:10
152 US2473617023 DAL DAL Delta Air Lines 2026-06-16 19:00:10
153 US25179M1036 DVN DVN Devon Energy 2026-06-16 19:00:10
154 US2521311074 DXCM DXCM Dexcom 2026-06-16 19:00:10
155 US25278X1090 FANG FANG Diamondback Energy 2026-06-16 19:00:10
156 US2546871060 DIS DIS Walt Disney 2026-06-16 19:00:10
157 US2567461080 DLTR DLTR Dollar Tree 2026-06-16 19:00:10
158 US25746U1097 DOV DOV Dover Corporation 2026-06-16 19:00:10
159 US25754A2015 DPZ DPZ Domino's 2026-06-16 19:00:10
160 US26441C2044 DUK DUK Duke Energy 2026-06-16 19:00:10
161 US26614N1028 DD DD DuPont 2026-06-16 19:00:10
162 US26875P1012 EOG EOG EOG Resources 2026-06-16 19:00:10
163 US26884L1098 EQT EQT EQT Corporation 2026-06-16 19:00:10
164 US2788651006 ECL ECL Ecolab 2026-06-16 19:00:10
165 US2810201077 EIX EIX Edison International 2026-06-16 19:00:10
166 US28176E1082 EW EW Edwards Lifesciences 2026-06-16 19:00:10
167 US2855121099 EA EA Electronic Arts 2026-06-16 19:00:10
168 US29084Q1004 EME EME EMCOR Group 2026-06-16 19:00:10
169 US2910111044 EMR EMR Emerson Electric 2026-06-16 19:00:10
170 US29364G1031 ETR ETR Entergy 2026-06-16 19:00:10
171 US29414B1044 EPAM EPAM EPAM Systems 2026-06-16 19:00:10
172 US2944291051 EFX EFX Equifax 2026-06-16 19:00:10
173 US29476L1070 EQR EQR Equity Residential 2026-06-16 19:00:10
174 US29530P1021 ERIE ERIE Erie Indemnity 2026-06-16 19:00:10
175 US2971721029 ESS ESS Essex Property Trust 2026-06-16 19:00:10
176 US30034W1062 EVRG EVRG Evergy 2026-06-16 19:00:10
177 US30161N1019 EXE EXE Expand Energy 2026-06-16 19:00:10
178 US3021301094 EXPD EXPD Expeditors International 2026-06-16 19:00:10
179 US30225T1025 EXR EXR Extra Space Storage 2026-06-16 19:00:10
180 US3024913036 FMC FMC FMC Corporation 2026-06-16 19:00:10
181 US3030751057 FDS FDS FactSet 2026-06-16 19:00:10
182 US3032501047 FICO FICO Fair Isaac 2026-06-16 19:00:10
183 US3119001044 FAST FAST Fastenal 2026-06-16 19:00:10
184 US3137451015 FRT FRT Federal Realty 2026-06-16 19:00:10
185 US31428X1063 FDX FDX FedEx 2026-06-16 19:00:10
186 US3156161024 FFIV FFIV F5, Inc. 2026-06-16 19:00:10
187 US3167731005 FITB FITB Fifth Third Bank 2026-06-16 19:00:10
188 US3364331070 FLT FLT Business Fuel Cards (Corpay) 2026-06-16 19:00:10
189 US3379321074 FE FE FirstEnergy 2026-06-16 19:00:10
190 US34959E1091 FTNT FTNT Fortinet 2026-06-16 19:00:10
191 US34959J1084 FTV FTV Fortive 2026-06-16 19:00:10
192 US35137L1052 FOXA FOXA Fox Corporation (Class A) 2026-06-16 19:00:10
193 US35137L2043 FOX FOX Fox Corporation (Class B) 2026-06-16 19:00:10
194 US3546131018 BEN BEN Franklin Templeton 2026-06-16 19:00:10
195 US35671D8570 FCX FCX Freeport-McMoRan 2026-06-16 19:00:10
196 US36266G1076 GEHC GEHC GE HealthCare 2026-06-16 19:00:10
197 US3666511072 IT IT Gartner 2026-06-16 19:00:10
198 US3695501086 GD GD General Dynamics 2026-06-16 19:00:10
199 US3696043013 GEV GEV GE Vernova 2026-06-16 19:00:10
200 US3703341046 GIS GIS General Mills 2026-06-16 19:00:10
201 US37045V1008 GM GM General Motors 2026-06-16 19:00:10
202 US3746891040 GPC GPC Genuine Parts Company 2026-06-16 19:00:10
203 US37940X1028 GPN GPN Global Payments 2026-06-16 19:00:10
204 US37959E1029 GL GL Globe Life 2026-06-16 19:00:10
205 US3802371076 GNDY GNDY GoDaddy 2026-06-16 19:00:10
206 US38141G1040 GS GS Goldman Sachs 2026-06-16 19:00:10
207 US3848021040 GWW GWW W. W. Grainger 2026-06-16 19:00:10
208 US40412C1018 HCA HCA HCA Healthcare 2026-06-16 19:00:10
209 US40434L1052 HPQ HPQ HP Inc. 2026-06-16 19:00:10
210 US4165151048 HIG HIG The Hartford 2026-06-16 19:00:10
211 US42250P1030 DOC DOC Healthpeak Properties 2026-06-16 19:00:10
212 US4262811015 JKHY JKHY Jack Henry & Associates 2026-06-16 19:00:10
213 US4278661081 HSY HSY The Hershey Company 2026-06-16 19:00:10
214 US43300A2033 HD HD Home Depot 2026-06-16 19:00:10
215 US4404521001 HRL HRL Hormel Foods 2026-06-16 19:00:10
216 US44107P1049 HST HST Host Hotels & Resorts 2026-06-16 19:00:10
217 US4432011082 HWM HWM Howmet Aerospace 2026-06-16 19:00:10
218 US4435106079 HUBB HUBB Hubbell Incorporated 2026-06-16 19:00:10
219 US4448591028 HUM HUM Humana 2026-06-16 19:00:10
220 US4456581077 JBHT JBHT J.B. Hunt 2026-06-16 19:00:10
221 US4461501045 HBAN HBAN Huntington Bancshares 2026-06-16 19:00:10
222 US4464131063 HII HII Huntington Ingalls Industries 2026-06-16 19:00:10
223 US45168D1046 IDXX IDXX IDEXX Laboratories 2026-06-16 19:00:10
224 US4553708600 F F Ford Motor Company 2026-06-16 19:00:10
225 US45687V1061 IR IR Ingersoll Rand 2026-06-16 19:00:10
226 US45841N1072 IBKR IBKR Interactive Brokers 2026-06-16 19:00:10
227 US45866F1043 ICE ICE Intercontinental Exchange 2026-06-16 19:00:10
228 US4592001014 IBM IBM IBM 2026-06-16 19:00:10
229 US4595061015 IFF IFF International Flavors & Fragrances 2026-06-16 19:00:10
230 US4601461035 IP IP International Paper 2026-06-16 19:00:10
231 US46120E6023 ISRG ISRG Intuitive Surgical 2026-06-16 19:00:10
232 US46187W1071 INVH INVH Invitation Homes 2026-06-16 19:00:10
233 US46266C1053 IQV IQV IQVIA 2026-06-16 19:00:10
234 US46284V1017 IRM IRM Iron Mountain 2026-06-16 19:00:10
235 US46625H1005 JPM JPM JPMorgan Chase 2026-06-16 19:00:10
236 US4663131039 JBL JBL Jabil 2026-06-16 19:00:10
237 US46982L1089 J J Jacobs Solutions 2026-06-16 19:00:10
238 US49177J1025 KVUE KVUE Kenvue 2026-06-16 19:00:10
239 US49271V1008 KDP KDP Keurig Dr Pepper 2026-06-16 19:00:10
240 US4932671088 KEY KEY KeyCorp 2026-06-16 19:00:10
241 US49338L1035 KEYS KEYS Keysight 2026-06-16 19:00:10
242 US4943681035 KMB KMB Kimberly-Clark 2026-06-16 19:00:10
243 US49446R1095 KIM KIM Kimco Realty 2026-06-16 19:00:10
244 US49456B1017 KMI KMI Kinder Morgan 2026-06-16 19:00:10
245 US5010441013 KR KR Kroger 2026-06-16 19:00:10
246 US5024311095 LHX LHX L3Harris 2026-06-16 19:00:10
247 US5049221055 LH LH Labcorp 2026-06-16 19:00:10
248 US5178341070 LVS LVS Las Vegas Sands 2026-06-16 19:00:10
249 US5184391044 EL EL Estée Lauder Companies 2026-06-16 19:00:10
250 US5253271028 LDOS LDOS Leidos 2026-06-16 19:00:10
251 US5260571048 LEN LEN Lennar 2026-06-16 19:00:10
252 US5261071071 LII LII Lennox International 2026-06-16 19:00:10
253 US5380341090 LYV LYV Live Nation Entertainment 2026-06-16 19:00:10
254 US5398301094 LMT LMT Lockheed Martin 2026-06-16 19:00:10
255 US5404241031 L L Loews Corporation 2026-06-16 19:00:10
256 US5500211090 LULU LULU Lululemon Athletica 2026-06-16 19:00:10
257 US55024U1097 LITE LITE Lumentum 2026-06-16 19:00:10
258 US55261F1043 MTB MTB M&T Bank 2026-06-16 19:00:10
259 US5529531015 MGM MGM MGM Resorts 2026-06-16 19:00:10
260 US55354G1004 MSCI MSCI MSCI Inc. 2026-06-16 19:00:10
261 US5717481023 MRSH MRSH Marsh & McLennan 2026-06-16 19:00:10
262 US66987P1012 ES ES Eversource Energy 2026-06-16 19:00:10
263 US74834L1008 DGX DGX Quest Diagnostics 2026-06-16 19:00:10
264 US77313F1066 HOOD HOOD Robinhood Markets 2026-06-16 19:00:10
265 US78430Q1013 AOS AOS A. O. Smith 2026-06-16 19:00:10
266 US78464A6982 KRE KRE SPDR S&P Regional Banking 2026-06-16 19:00:10
267 US79466L3024 CRM CRM Salesforce 2026-06-16 19:00:10
268 US89235Q1011 SQ SQ Block, Inc. 2026-06-16 19:00:10
269 US9892071054 ZBRA ZBRA Zebra Technologies 2026-06-16 19:00:10
270 BMG667211046 NCLH NCLH Norwegian Cruise Line Holdings 2026-06-16 18:51:11
271 CH0102993182 TEL TEL TE Connectivity 2026-06-16 18:51:11
272 IE000S9YS062 SW SW Smurfit Westrock 2026-06-16 18:51:11
273 IE00B58JVZ52 STX STX Seagate Technology 2026-06-16 18:51:11
274 IE00BDB64S84 WTW WTW Willis Towers Watson 2026-06-16 18:51:11
275 US4062161017 HAL HAL Halliburton 2026-06-16 18:51:11
276 US42824C1099 HPE HPE Hewlett Packard Enterprise 2026-06-16 18:51:11
277 US45784P1012 PODD PODD Insulet Corporation 2026-06-16 18:51:11
278 US4781281010 SJM SJM J.M. Smucker Company (The) 2026-06-16 18:51:11
279 US60871R1023 TAP TAP Molson Coors Beverage Company 2026-06-16 18:51:11
280 US61174X1090 MNST MNST Monster Beverage 2026-06-16 18:51:11
281 US61945C1036 MOS MOS Mosaic Company (The) 2026-06-16 18:51:11
282 US6556631008 NDSN NDSN Nordson Corporation 2026-06-16 18:51:11
283 US6558441084 NSC NSC Norfolk Southern 2026-06-16 18:51:11
284 US6658591044 NTRS NTRS Northern Trust 2026-06-16 18:51:11
285 US6687711084 NOC NOC Northrop Grumman 2026-06-16 18:51:11
286 US6703461052 NUE NUE Nucor 2026-06-16 18:51:11
287 US6745991058 OXY OXY Occidental Petroleum 2026-06-16 18:51:11
288 US6821891057 ON ON ON Semiconductor 2026-06-16 18:51:11
289 US6852181040 ORLY ORLY O’Reilly Automotive 2026-06-16 18:51:11
290 US69331C1080 PCG PCG PG&E Corporation 2026-06-16 18:51:11
291 US6951561090 PKG PKG Packaging Corporation of America 2026-06-16 18:51:11
292 US69608A1088 PLTR PLTR Palantir Technologies 2026-06-16 18:51:11
293 US7010941042 PH PH Parker Hannifin 2026-06-16 18:51:11
294 US7234841010 PNW PNW Pinnacle West Capital 2026-06-16 18:51:11
295 US7433151039 PGR PGR Progressive Corporation 2026-06-16 18:51:11
296 US74624M1027 RL RL Ralph Lauren Corporation 2026-06-16 18:51:11
297 US74955A1051 RVTY RVTY Revvity 2026-06-16 18:51:11
298 US7588491032 REG REG Regency Centers 2026-06-16 18:51:11
299 US7591EP1011 RF RF Regions Financial Corporation 2026-06-16 18:51:11
300 US8085131055 SCHW SCHW Charles Schwab Corporation 2026-06-16 18:51:11
301 US8168511090 SRE SRE Sempra 2026-06-16 18:51:11
302 US8243481061 SHW SHW Sherwin-Williams 2026-06-16 18:51:11
303 US8330341012 SNA SNA Snap-on 2026-06-16 18:51:11
304 US84574X1019 SOLV SOLV Solventum 2026-06-16 18:51:11
305 US8574771031 STT STT State Street Corporation 2026-06-16 18:51:11
306 US8591521005 STE STE Steris 2026-06-16 18:51:11
307 US8718291030 SYY SYY Sysco 2026-06-16 18:51:11
308 US8760301072 TPR TPR Tapestry, Inc. 2026-06-16 18:51:11
309 US87612G1013 TRGP TRGP Targa Resources 2026-06-16 18:51:11
310 US8793601058 TDY TDY Teledyne Technologies 2026-06-16 18:51:11
311 US88262P1021 TPL TPL Texas Pacific Land Corporation 2026-06-16 18:51:11
312 US8932351081 TDG TDG TransDigm Group 2026-06-16 18:51:11
313 US89417E1091 TRV TRV Travelers Companies (The) 2026-06-16 18:51:11
314 US8962391004 TRMB TRMB Trimble Inc. 2026-06-16 18:51:11
315 US9253401031 VRT VRT Vertiv 2026-06-16 18:51:11
316 US92556H2067 PSKY PSKY Paramount Skydance Corporation 2026-06-16 18:51:11
317 US9293251000 WRB WRB W. R. Berkley Corporation 2026-06-16 18:51:11
318 US9344231041 WBD WBD Warner Bros. Discovery 2026-06-16 18:51:11
319 US9418481035 WAT WAT Waters Corporation 2026-06-16 18:51:11
320 US9581021055 WDC WDC Western Digital 2026-06-16 18:51:11
321 US9621661089 WY WY Weyerhaeuser 2026-06-16 18:51:11
322 US9694571004 WMB WMB Williams Companies 2026-06-16 18:51:11
323 US9078181081 UNP UNP Union Pacific Corporation 2026-06-16 18:28:11
324 US92047W1018 VLO VLO Valero Energy 2026-06-16 18:28:11
325 US9290421011 VMC VMC Vulcan Materials Company 2026-06-16 18:28:11
326 US8425871071 SO SO Southern Company 2026-06-16 18:28:08
327 US30231G1022 XOM XOM ExxonMobil 2026-06-16 18:27:40
328 US7427181094 PG PG Procter & Gamble 2026-06-16 18:27:26
329 US5719032022 MAR MAR Marriott International 2026-06-16 18:27:17
330 US5745991068 MAS MAS Masco 2026-06-16 18:27:17
331 US57636Q1040 MA MA Mastercard 2026-06-16 18:27:17
332 US5825211047 MKC MKC McCormick & Company 2026-06-16 18:27:17
333 US5950171042 MCHP MCHP Microchip Technology 2026-06-16 18:27:17
334 US6092071563 MDLZ MDLZ Mondelez International 2026-06-16 18:27:17
335 US6098391054 MCO MCO Moody's Corporation 2026-06-16 18:27:17
336 US8447411088 LUV LUV Southwest Airlines 2026-06-16 18:27:17
337 US88579Y1010 MMM MMM 3M 2026-06-16 18:27:17
338 US15135U1097 COR COR Cencora 2026-06-16 18:26:35
339 BM1250141022 BG BG Bunge Global 2026-06-16 18:22:24
340 US09260D1072 BX BX Blackstone Inc. 2026-06-16 18:22:24
341 BMG2004J1036 CCL CCL Carnival Corporation 2026-06-16 17:05:54
342 BMG3223R1088 EG EG Everest Group 2026-06-16 17:05:54
343 BMG491BT1088 IVZ IVZ Invesco 2026-06-16 17:05:54
344 CA8000541083 SNDK SNDK Sandisk 2026-06-16 17:05:54
345 IE0001827041 CRH CRH CRH plc 2026-06-16 17:05:54
346 IE000S9YS762 LIN LIN Linde plc 2026-06-16 17:05:54
347 IE00BK9ZQ967 TT TT Trane Technologies 2026-06-16 17:05:54
348 IE00BLS09M33 PNR PNR Pentair 2026-06-16 17:05:54
349 IE00BTN1Y115 MDT MDT Medtronic 2026-06-16 17:05:54
350 IE00BY7QL619 JCI JCI Johnson Controls 2026-06-16 17:05:54
351 JE00BTDN8H13 APTV APTV Aptiv 2026-06-16 17:05:54
352 JP3832370005 NWS NWS News Corp (Class B) 2026-06-16 17:05:54
353 LR0008862868 RCL RCL Royal Caribbean Group 2026-06-16 17:05:54
354 NL0009434992 LYB LYB LyondellBasell 2026-06-16 17:05:54
355 NL0009538784 NXPI NXPI NXP Semiconductors 2026-06-16 17:05:54
356 US00206R1023 T T AT&T 2026-06-16 17:05:54
357 US0530151036 ADP ADP Automatic Data Processing 2026-06-16 17:05:54
358 US05722G1004 BKR BKR Baker Hughes 2026-06-16 17:05:54
359 US09073M1045 TECH TECH Bio-Techne 2026-06-16 17:05:54
360 US21036P1084 STZ STZ Constellation Brands 2026-06-16 17:05:54
361 US2538681030 DLR DLR Digital Realty 2026-06-16 17:05:54
362 US3143521058 FDXF FDXF FedEx Freight 2026-06-16 17:05:54
363 US3687361044 GNRC GNRC Generac 2026-06-16 17:05:54
364 US4432011017 HON HON Honeywell 2026-06-16 17:05:54
365 US5732841060 MLM MLM Martin Marietta Materials 2026-06-16 17:05:54
366 US59156R1086 MET MET MetLife 2026-06-16 17:05:54
367 US5926881054 MTD MTD Mettler Toledo 2026-06-16 17:05:54
368 US59522J1034 MAA MAA Mid-America Apartment Communities 2026-06-16 17:05:54
369 US60770K1079 MRNA MRNA Moderna 2026-06-16 17:05:54
370 US6174464486 MS MS Morgan Stanley 2026-06-16 17:05:54
371 US6200763075 MSI MSI Motorola Solutions 2026-06-16 17:05:54
372 US6293775085 NRG NRG NRG Energy 2026-06-16 17:05:54
373 US6311031081 NDAQ NDAQ Nasdaq, Inc. 2026-06-16 17:05:54
374 US64110D1046 NTAP NTAP NetApp 2026-06-16 17:05:54
375 US64110L1061 NFLX NFLX Netflix 2026-06-16 17:05:54
376 US65473P1057 NI NI NiSource 2026-06-16 17:05:54
377 US6795801009 ODFL ODFL Old Dominion 2026-06-16 17:05:54
378 US6819191064 OMC OMC Omnicom Group 2026-06-16 17:05:54
379 US6826801036 OKE OKE Oneok 2026-06-16 17:05:54
380 US68902V1070 OTIS OTIS Otis Worldwide 2026-06-16 17:05:54
381 US6934751057 PNC PNC PNC Financial Services 2026-06-16 17:05:54
382 US69351T1060 PPL PPL PPL Corporation 2026-06-16 17:05:54
383 US69370C1009 PTC PTC PTC Inc. 2026-06-16 17:05:54
384 US6937181088 PCAR PCAR Paccar 2026-06-16 17:05:54
385 US6974351057 PANW PANW Palo Alto Networks 2026-06-16 17:05:54
386 US7043261079 PAYX PAYX Paychex 2026-06-16 17:05:54
387 US7181721090 PM PM Philip Morris International 2026-06-16 17:05:54
388 US7185461040 PSX PSX Phillips 66 2026-06-16 17:05:54
389 US73278L1052 POOL POOL Pool Corporation 2026-06-16 17:05:54
390 US74144T1088 TROW TROW T. Rowe Price 2026-06-16 17:05:54
391 US74340W1036 PLD PLD Prologis 2026-06-16 17:05:54
392 US7443201022 PRU PRU Prudential Financial 2026-06-16 17:05:54
393 US7445731067 PEG PEG Public Service Enterprise Group 2026-06-16 17:05:54
394 US74460D1090 PSA PSA Public Storage 2026-06-16 17:05:54
395 US74762E1029 PWR PWR Quanta Services 2026-06-16 17:05:54
396 US7547301090 RJF RJF Raymond James Financial 2026-06-16 17:05:54
397 US75513E1010 RTX RTX RTX Corporation 2026-06-16 17:05:54
398 US75886F1075 REGN REGN Regeneron Pharmaceuticals 2026-06-16 17:05:54
399 US7607591002 RSG RSG Republic Services 2026-06-16 17:05:54
400 US7611521078 RMD RMD ResMed 2026-06-16 17:05:54
401 US7739031091 ROK ROK Rockwell Automation 2026-06-16 17:05:54
402 US7757111049 ROL ROL Rollins, Inc. 2026-06-16 17:05:54
403 US7766961061 ROP ROP Roper Technologies 2026-06-16 17:05:54
404 US7782961038 ROST ROST Ross Stores 2026-06-16 17:05:54
405 US78410G1040 SBAC SBAC SBA Communications 2026-06-16 17:05:54
406 US8064071025 HSIC HSIC Henry Schein 2026-06-16 17:05:54
407 US81762P1021 NOW NOW ServiceNow 2026-06-16 17:05:54
408 US8288061091 SPG SPG Simon Property Group 2026-06-16 17:05:54
409 US83088M1027 SWKS SWKS Skyworks Solutions 2026-06-16 17:05:54
410 US8545021011 SWK SWK Stanley Black & Decker 2026-06-16 17:05:54
411 US8581191009 STLD STLD Steel Dynamics 2026-06-16 17:05:54
412 US86800U3023 SMCI SMCI Supermicro 2026-06-16 17:05:54
413 US8716071076 SNPS SNPS Synopsys 2026-06-16 17:05:54
414 US87165B1035 SYF SYF Synchrony Financial 2026-06-16 17:05:54
415 US8725401090 TJX TJX TJX Companies 2026-06-16 17:05:54
416 US87256C1018 TKO TKO TKO Group Holdings 2026-06-16 17:05:54
417 US8807701029 TER TER Teradyne 2026-06-16 17:05:54
418 US8832031012 TXT TXT Textron 2026-06-16 17:05:54
419 US88339J1051 TTD TTD Trade Desk (The) 2026-06-16 17:05:54
420 US8835561023 TMO TMO Thermo Fisher Scientific 2026-06-16 17:05:54
421 US89832Q1094 TFC TFC Truist Financial 2026-06-16 17:05:54
422 US9022521051 TYL TYL Tyler Technologies 2026-06-16 17:05:54
423 US9024941034 TSN TSN Tyson Foods 2026-06-16 17:05:54
424 US9026531049 UDR UDR UDR, Inc. 2026-06-16 17:05:54
425 US9029733048 USB USB U.S. Bancorp 2026-06-16 17:05:54
426 US90353T1007 UBER UBER Uber 2026-06-16 17:05:54
427 US90384S3031 ULTA ULTA Ulta Beauty 2026-06-16 17:05:54
428 US9100471096 UAL UAL United Airlines Holdings 2026-06-16 17:05:54
429 US9113631090 URI URI United Rentals 2026-06-16 17:05:54
430 US9139031002 UHS UHS Universal Health Services 2026-06-16 17:05:54
431 US9224751084 VEEV VEEV Veeva Systems 2026-06-16 17:05:54
432 US92276F1003 VTR VTR Ventas 2026-06-16 17:05:54
433 US92338C1036 VLTO VLTO Veralto 2026-06-16 17:05:54
434 US92343E1029 VRSN VRSN Verisign 2026-06-16 17:05:54
435 US92556V1061 VTRS VTRS Viatris 2026-06-16 17:05:54
436 US9256521090 VICI VICI Vici Properties 2026-06-16 17:05:54
437 US92840M1027 VST VST Vistra Corp. 2026-06-16 17:05:54
438 US92939U1060 WEC WEC WEC Energy Group 2026-06-16 17:05:54
439 US9297401088 WAB WAB Wabtec 2026-06-16 17:05:54
440 US9553061055 WST WST West Pharmaceutical Services 2026-06-16 17:05:54
441 US9699041011 WSM WSM Williams-Sonoma, Inc. 2026-06-16 17:05:54
442 US98138H1014 WDAY WDAY Workday, Inc. 2026-06-16 17:05:54
443 US9831341071 WYNN WYNN Wynn Resorts 2026-06-16 17:05:54
444 US98419M1009 XYL XYL Xylem Inc. 2026-06-16 17:05:54
445 US98978V1035 ZTS ZTS Zoetis 2026-06-16 17:05:54
446 US2787681061 SATS SATS EchoStar Corporation 2026-06-16 16:35:23
447 US7458671010 PHM PHM PulteGroup Inc. 2026-06-16 16:30:09
448 US67066G1040 NVDA NVDA Nvidia Corp 2026-06-16 16:28:51
449 US25809K1051 DASH DASH Dash (DoorDash) Inc. Class A 2026-06-16 16:18:37
450 US11135F1012 AVGO AVGO Broadcom Inc. 2026-06-16 16:17:39
451 US2786421030 EBAY EBAY EBay Inc. 2026-06-16 16:16:40
452 US29444U7000 EQIX EQIX Equinix Inc. 2026-06-16 16:15:41
453 CH0114405324 GRMN GRMN Garmin Ltd. 2026-06-16 16:14:40
454 US3755581036 GILD GILD Gilead Sciences Inc. 2026-06-16 16:13:38
455 US00724F1012 ADBE ADBE Adobe Inc. 2026-06-16 16:12:31
456 US45337C1027 INCY INCY Incyte Corp. 2026-06-16 16:11:14
457 BMG611881019 LBTYA LBTYA Liberty Global plc Class A 2026-06-16 16:09:50
458 US5312297550 FWONK FWONK Liberty Media Corp. Formula One 2026-06-16 16:05:55
459 US58155Q1031 MCK MCK McKesson Corp. 2026-06-16 16:04:40
460 US8318652091 AOS AOS Smith (A.O.) Corp. 2026-06-16 16:02:06
461 US8552441094 SBUX SBUX Starbucks Corp. 2026-06-16 15:59:41
462 US02079K3059 GOOGL GOOGL Alphabet Inc. Class A 2026-06-16 15:54:59
463 US98389B1008 XEL XEL Xcel Energy Inc. 2026-06-16 15:40:07
464 US0079031078 AMD AMD Advanced Micro Devices Inc. 2026-06-16 15:39:17
465 US0138721065 AA AA Aligned Technology (Altera) 2026-06-16 15:39:17
466 US02079K1079 GOOG GOOG Alphabet Inc. Class C 2026-06-16 15:39:17
467 US0258161092 AXP AXP American Express Co 2026-06-16 15:39:17
468 US0311621009 AMGN AMGN Amgen Inc. 2026-06-16 15:39:17
469 US0378331005 AAPL AAPL Apple Inc. 2026-06-16 15:39:17
470 US0970231058 BA BA Boeing Co 2026-06-16 15:39:17
471 US1266501006 CVS CVS Cisco Systems Inc. 2026-06-16 15:39:17
472 US1431301027 KMX KMX Caterpillar Inc. 2026-06-16 15:39:17
473 US1667641005 CVX CVX Chevron Corp. 2026-06-16 15:39:17
474 US1912161007 KO KO Coca-Cola Co 2026-06-16 15:39:17
475 US1924461023 CTSH CTSH Cognizant Technology Solutions 2026-06-16 15:39:17
476 US20030N1019 CMCSA CMCSA Comcast Corp. Class A 2026-06-16 15:39:17
477 US2058871029 CAG CAG Conagra Brands Inc. 2026-06-16 15:39:17
478 US2193501051 GLW GLW Constellation Energy Corp. 2026-06-16 15:39:17
479 US22160K1051 COST COST Costco Wholesale Corp. 2026-06-16 15:39:17
480 US22822V1017 CCI CCI Crown Castle Inc. 2026-06-16 15:39:17
481 US2358511028 DHR DHR Danaher Corp. 2026-06-16 15:39:17
482 US2566771059 DG DG Dollar Tree Inc. 2026-06-16 15:39:17
483 US2605571031 DOW DOW Dow Inc. 2026-06-16 15:39:17
484 US30212P3038 EXPE EXPE Fastenal Co. 2026-06-16 15:39:17
485 US30303M1027 META META Meta Platforms Inc. Class A 2026-06-16 15:39:17
486 US31620M1062 FIS FIS Fifth Third Bancorp 2026-06-16 15:39:17
487 US31847R1023 FAF FAF First Solar Inc. 2026-06-16 15:39:17
488 US3377381088 FISV FISV Fiserv Inc. 2026-06-16 15:39:17
489 US3696041033 GE GE General Electric Co 2026-06-16 15:39:17
490 US4180561072 HAS HAS Hasbro Inc. 2026-06-16 15:39:17
491 US4385161066 HON HON Honeywell International Inc. 2026-06-16 15:39:17
492 US45167R1041 IEX IEX Idexx Laboratories Inc. 2026-06-16 15:39:17
493 US4523081093 ITW ITW Illumina Inc. 2026-06-16 15:39:17
494 US4581401001 INTC INTC Intel Corp. 2026-06-16 15:39:17
495 US4612021034 INTU INTU Intuitive Surgical Inc. 2026-06-16 15:39:17
496 US4781601046 JNJ JNJ Johnson & Johnson 2026-06-16 15:39:17
497 US48123V1026 ZD ZD Keurig Dr Pepper Inc. 2026-06-16 15:39:17
498 US4824801009 KLAC KLAC KLA Corp. 2026-06-16 15:39:17
499 US48251W1045 KKR KKR Lam Research Corp. 2026-06-16 15:39:17
500 US5007541064 KHC KHC Kraft Heinz Co. 2026-06-16 15:39:17
501 US5324571083 LLY LLY Lilly (Eli) & Co 2026-06-16 15:39:17
502 US5486611073 LOW LOW Lululemon Athletica Inc. 2026-06-16 15:39:17
503 US56585A1025 MPC MPC Marriott International Class A 2026-06-16 15:39:17
504 US5801351017 MCD MCD McDonald's Corp. 2026-06-16 15:39:17
505 US58933Y1055 MRK MRK Merck & Co. Inc. 2026-06-16 15:39:17
506 US5949181045 MSFT MSFT Microsoft Corp. 2026-06-16 15:39:17
507 US5951121038 MU MU Micron Technology Inc. 2026-06-16 15:39:17
508 US6092071058 MDLZ MDLZ Mondelez International Inc. 2026-06-16 15:39:17
509 US62944T1051 NVR NVR Netease Inc. ADR 2026-06-16 15:39:17
510 US6516391066 NEM NEM Newcom Group (Newmont) 2026-06-16 15:39:17
511 US65339F1012 NEE NEE NextEra Energy Inc. 2026-06-16 15:39:17
512 US6541061031 NKE NKE Nike Inc. Class B 2026-06-16 15:39:17
513 US68389X1054 ORCL ORCL O'Reilly Automotive Inc. 2026-06-16 15:39:17
514 US6935061076 PPG PPG Paccar Inc. 2026-06-16 15:39:17
515 US70450Y1038 PYPL PYPL PayPal Holdings Inc. 2026-06-16 15:39:17
516 US7134481081 PEP PEP PepsiCo Inc. 2026-06-16 15:39:17
517 US7170811035 PFE PFE Pfizer Inc. 2026-06-16 15:39:17
518 US74251V1026 PFG PFG Prudential Financial Inc. 2026-06-16 15:39:17
519 US7475251036 QCOM QCOM Qualcomm Inc. 2026-06-16 15:39:17
520 US7561091049 O O Realty Income Corp. 2026-06-16 15:39:17
521 US78409V1044 SPGI SPGI S&P Global Inc. 2026-06-16 15:39:17
522 US8636671013 SYK SYK Stryker Corp. 2026-06-16 15:39:17
523 US8679141031 STI STI Sunrun Inc. 2026-06-16 15:39:17
524 US8718291078 SYY SYY Sysco Corp. 2026-06-16 15:39:17
525 US8725901040 TMUS TMUS T-Mobile US Inc. 2026-06-16 15:39:17
526 US87612E1064 TGT TGT Target Corp. 2026-06-16 15:39:17
527 US88160R1014 TSLA TSLA Tesla Inc. 2026-06-16 15:39:17
528 US8825081040 TXN TXN Texas Instruments Inc. 2026-06-16 15:39:17
529 US8923561067 TSCO TSCO Tractor Supply Co. 2026-06-16 15:39:17
530 US9113121068 UPS UPS United Parcel Service Class B 2026-06-16 15:39:17
531 US91324P1021 UNH UNH UnitedHealth Group Inc. 2026-06-16 15:39:17
532 US92343V1044 VZ VZ Verisign Inc. 2026-06-16 15:39:17
533 US92345Y1064 VRSK VRSK Verisk Analytics Inc. Class A 2026-06-16 15:39:17
534 US92532F1003 VRTX VRTX Vertex Pharmaceuticals Inc. 2026-06-16 15:39:17
535 US92826C8394 V V Visa Inc. Class A 2026-06-16 15:39:17
536 US9311421039 WMT WMT Walmart Inc. 2026-06-16 15:39:17
537 US94106L1098 WM WM Waste Management Inc. 2026-06-16 15:39:17
538 US9497461015 WFC WFC Wells Fargo & Co. 2026-06-16 15:39:17
539 US95040Q1040 WELL WELL Western Digital Corp. 2026-06-16 15:39:17
540 US9884981013 YUM YUM Yum! Brands Inc. 2026-06-16 15:39:17
541 US98956P1021 ZBH ZBH Zebra Technologies Corp. Class A 2026-06-16 15:39:17
542 US98980L1017 ZM ZM Zoom Video Communications 2026-06-16 15:39:17
543 ES0105563003 ANE ANE.MC Acciona Energía 2026-06-16 15:17:14
544 ES0105025003 MRL MRL.MC Merlin Properties 2026-06-16 15:14:37
545 ES0105027009 LOG LOG.MC Logista 2026-06-16 15:14:37
546 ES0105046009 AENA AENA.MC Aena 2026-06-16 15:14:37
547 ES0105066007 CLNX CLNX.MC Cellnex Telecom 2026-06-16 15:14:37
548 ES0105777017 PUIG PUIG.MC Puig Brands 2026-06-16 15:14:37
549 ES0109067019 AMS AMS.MC Amadeus IT Group 2026-06-16 15:14:37
550 ES0113211835 BBVA BBVA.MC BBVA 2026-06-16 15:14:37
551 ES0113679I37 BKT BKT.MC Bankinter 2026-06-16 15:14:37
552 ES0113860A34 SAB SAB.MC Banco Sabadell 2026-06-16 15:14:37
553 ES0113900J37 SAN SAN.MC Banco Santander 2026-06-16 15:14:37
554 ES0116870314 NTGY NTGY.MC Naturgy Energy Group 2026-06-16 15:14:37
555 ES0118594417 IDR IDR.MC Indra Sistemas 2026-06-16 15:14:37
556 ES0124244E34 MAP MAP.MC Mapfre 2026-06-16 15:14:37
557 ES0125220311 ANA ANA.MC Acciona 2026-06-16 15:14:37
558 ES0130670112 ELE ELE.MC Endesa 2026-06-16 15:14:37
559 ES0130960018 ENG ENG.MC Enagás 2026-06-16 15:14:37
560 ES0132105018 ACX ACX.MC Acerinox 2026-06-16 15:14:37
561 ES0137650018 FDR FDR.MC Fluidra 2026-06-16 15:14:37
562 ES0140609019 CABK CABK.MC CaixaBank 2026-06-16 15:14:37
563 ES0144580Y14 IBE IBE.MC Iberdrola 2026-06-16 15:14:37
564 ES0148396007 ITX ITX.MC Inditex 2026-06-16 15:14:37
565 ES0157261019 ROVI ROVI.MC Laboratorios Farmacéuticos Rovi 2026-06-16 15:14:37
566 ES0165386014 SLR SLR.MC Solaria Energía 2026-06-16 15:14:37
567 ES0167050915 ACS ACS.MC ACS 2026-06-16 15:14:37
568 ES0171996087 GRF GRF.MC Grifols 2026-06-16 15:14:37
569 ES0173093024 RED RED.MC Redeia 2026-06-16 15:14:37
570 ES0173516115 REP REP.MC Repsol 2026-06-16 15:14:37
571 ES0178430E18 TEF TEF.MC Telefónica 2026-06-16 15:14:37
572 ES0180907000 UNI UNI.MC Unicaja Banco 2026-06-16 15:14:37
573 ES0182870214 SCYR SCYR.MC Sacyr 2026-06-16 15:14:37
574 ES0184262212 VIS VIS.MC Viscofan 2026-06-16 15:14:37
575 LU1598757687 MT MT.AS ArcelorMittal 2026-06-16 15:14:37
576 NL0015001FS8 FER FER.MC Ferrovial 2026-06-16 15:14:37
577 FR0013447729 VRLA VRLA.PA VERALLIA 2026-06-16 14:40:56
578 BE0003470755 SOLB SOLB.BR SOLVAY 2026-06-16 14:39:36
579 FR0000031577 VIRP VIRP.PA VIRBAC 2026-06-16 14:39:36
580 FR0000031775 VCT VCT.PA VICAT 2026-06-16 14:39:36
581 FR0000039299 BOL BOL.PA BOLLORE 2026-06-16 14:39:36
582 FR0000044448 NEX NEX.PA NEXANS 2026-06-16 14:39:36
583 FR0000045072 ACA ACA.PA CREDIT AGRICOLE 2026-06-16 14:39:36
584 FR0000050353 FII FII.PA LISI 2026-06-16 14:39:36
585 FR0000050809 SOP SOP.PA SOPRA STERIA GROUP 2026-06-16 14:39:36
586 FR0000051807 TEP TEP.PA TELEPERFORMANCE 2026-06-16 14:39:36
587 FR0000052292 RMS RMS.PA HERMES INTL 2026-06-16 14:39:36
588 FR0000053225 MMT MMT.PA METROPOLE TV 2026-06-16 14:39:36
589 FR0000054470 UBI UBI.PA UBISOFT ENTERTAIN 2026-06-16 14:39:36
590 FR0000054900 TFI TFI.PA TF1 2026-06-16 14:39:36
591 FR0000062671 EXA EXA.PA EXAIL TECHNOLOGIES 2026-06-16 14:39:36
592 FR0000064578 COV COV.PA COVIVIO 2026-06-16 14:39:36
593 FR0000071946 ATE ATE.PA ALTEN 2026-06-16 14:39:36
594 FR0000073272 SAF SAF.PA SAFRAN 2026-06-16 14:39:36
595 FR0000077919 DEC DEC.PA JCDECAUX 2026-06-16 14:39:36
596 FR0000120073 AI AI.PA AIR LIQUIDE 2026-06-16 14:39:36
597 FR0000120172 CA CA.PA CARREFOUR 2026-06-16 14:39:36
598 FR0000120271 TTE TTE.PA TOTALENERGIES 2026-06-16 14:39:36
599 FR0000120321 OR OR.PA L'OREAL 2026-06-16 14:39:36
600 FR0000120404 AC AC.PA ACCOR 2026-06-16 14:39:36
601 FR0000120503 EN EN.PA BOUYGUES 2026-06-16 14:39:36
602 FR0000120578 SAN SAN.PA SANOFI 2026-06-16 14:39:36
603 FR0000120628 CS CS.PA AXA 2026-06-16 14:39:36
604 FR0000120644 BN BN.PA DANONE 2026-06-16 14:39:36
605 FR0000120693 RI RI.PA PERNOD RICARD 2026-06-16 14:39:36
606 FR0000120859 NK NK.PA IMERYS 2026-06-16 14:39:36
607 FR0000120966 BB BB.PA BIC 2026-06-16 14:39:36
608 FR0000121014 MC MC.PA LVMH 2026-06-16 14:39:36
609 FR0000121121 RF RF.PA EURAZEO 2026-06-16 14:39:36
610 FR0000121147 FRVIA FRVIA.PA FORVIA 2026-06-16 14:39:36
611 FR0000121204 MF MF.PA WENDEL 2026-06-16 14:39:36
612 FR0000121220 SW SW.PA SODEXO 2026-06-16 14:39:36
613 FR0000121329 HO HO.PA THALES 2026-06-16 14:39:36
614 FR0000121485 KER KER.PA KERING 2026-06-16 14:39:36
615 FR0000121667 EL EL.PA ESSILORLUXOTTICA 2026-06-16 14:39:36
616 FR0000121709 SK SK.PA S.E.B. 2026-06-16 14:39:36
617 FR0000121964 LI LI.PA KLEPIERRE 2026-06-16 14:39:36
618 FR0000121972 SU SU.PA SCHNEIDER ELECTRIC 2026-06-16 14:39:36
619 FR0000124141 VIE VIE.PA VEOLIA ENVIRON. 2026-06-16 14:39:36
620 FR0000124570 OPM OPM.PA OPMOBILITY 2026-06-16 14:39:36
621 FR0000125007 SGO SGO.PA SAINT GOBAIN 2026-06-16 14:39:36
622 FR0000125338 CAP CAP.PA CAPGEMINI 2026-06-16 14:39:36
623 FR0000125486 DG DG.PA VINCI 2026-06-16 14:39:36
624 FR0000127771 VIV VIV.PA VIVENDI SE 2026-06-16 14:39:36
625 FR0000130395 RCO RCO.PA REMY COINTREAU 2026-06-16 14:39:36
626 FR0000130452 FGR FGR.PA EIFFAGE 2026-06-16 14:39:36
627 FR0000130577 PUB PUB.PA PUBLICIS GROUPE SA 2026-06-16 14:39:36
628 FR0000130809 GLE GLE.PA SOCIETE GENERALE 2026-06-16 14:39:36
629 FR0000131104 BNP BNP.PA BNP PARIBAS ACT.A 2026-06-16 14:39:36
630 FR0000131757 ERA ERA.PA ERAMET 2026-06-16 14:39:36
631 FR0000131906 RNO RNO.PA RENAULT 2026-06-16 14:39:36
632 FR0000133308 ORA ORA.PA ORANGE 2026-06-16 14:39:36
633 FR0004024222 ITP ITP.PA INTERPARFUMS 2026-06-16 14:39:36
634 FR0004056851 VLA VLA.PA VALNEVA 2026-06-16 14:39:36
635 FR0004065605 FR0004065605 FR0004065605.SG MEDINCELL 2026-06-16 14:39:36
636 FR0004125920 AMUN AMUN.PA AMUNDI 2026-06-16 14:39:36
637 FR0005691656 TRI TRI.PA TRIGANO 2026-06-16 14:39:36
638 FR0006174348 BVI BVI.PA BUREAU VERITAS 2026-06-16 14:39:36
639 FR0010040865 GFC GFC.PA GECINA 2026-06-16 14:39:36
640 FR0010112524 NXI NXI.PA NEXITY 2026-06-16 14:39:36
641 FR0010208488 ENGI ENGI.PA ENGIE 2026-06-16 14:39:36
642 FR0010220475 ALO ALO.PA ALSTOM 2026-06-16 14:39:36
643 FR0010221234 ETL ETL.PA EUTELSAT COMMUNIC. 2026-06-16 14:39:36
644 FR0010241638 MERY MERY.PA MERCIALYS 2026-06-16 14:39:36
645 FR0010259150 IPN IPN.PA IPSEN 2026-06-16 14:39:36
646 FR0010282822 VU VU.PA Vusion 2026-06-16 14:39:36
647 FR0010307819 LR LR.PA LEGRAND 2026-06-16 14:39:36
648 FR0010313833 AKE AKE.PA ARKEMA 2026-06-16 14:39:36
649 FR0010340141 ADP ADP.PA ADP 2026-06-16 14:39:36
650 FR0010386334 CLARI CLARI.PA CLARIANE 2026-06-16 14:39:36
651 FR0010411983 SCR SCR.PA SCOR SE 2026-06-16 14:39:36
652 FR0010417345 DBV DBV.PA DBV TECHNOLOGIES 2026-06-16 14:39:36
653 FR0010451203 RXL RXL.PA REXEL 2026-06-16 14:39:36
654 FR0010481960 ARG ARG.PA ARGAN 2026-06-16 14:39:36
655 FR0010533075 GET GET.PA GETLINK SE 2026-06-16 14:39:36
656 FR0010667147 COFA COFA.PA COFACE 2026-06-16 14:39:36
657 FR0010828137 CARM CARM.PA CARMILA 2026-06-16 14:39:36
658 FR0010908533 EDEN EDEN.PA EDENRED 2026-06-16 14:39:36
659 FR0010929125 IDL IDL.PA ID LOGISTICS GROUP 2026-06-16 14:39:36
660 FR0011341205 NANO NANO.PA NANOBIOTIX 2026-06-16 14:39:36
661 FR0011726835 GTT GTT.PA GTT 2026-06-16 14:39:36
662 FR0011950732 ELIOR ELIOR.PA ELIOR GROUP 2026-06-16 14:39:36
663 FR0012333284 ABVX ABVX.PA ABIVAX 2026-06-16 14:39:36
664 FR0012435121 ELIS ELIS.PA ELIS 2026-06-16 14:39:36
665 FR0012757854 SPIE SPIE.PA SPIE 2026-06-16 14:39:36
666 FR0013154002 DIM DIM.PA SARTORIUS STED BIO 2026-06-16 14:39:36
667 FR0013176526 FR FR.PA VALEO 2026-06-16 14:39:36
668 FR0013227113 SOI SOI.PA SOITEC 2026-06-16 14:39:36
669 FR0013258662 AYV AYV.PA AYVENS 2026-06-16 14:39:36
670 FR0013269123 RUI RUI.PA RUBIS 2026-06-16 14:39:36
671 FR0013280286 BIM BIM.PA BIOMERIEUX 2026-06-16 14:39:36
672 FR0013326246 URW URW.PA UNIBAIL-RODAMCO-WE 2026-06-16 14:39:36
673 FR0013451333 FDJU FDJU.PA FDJ UNITED 2026-06-16 14:39:36
674 FR0013506730 VK VK.PA VALLOUREC 2026-06-16 14:39:36
675 FR0014000MR3 ERF ERF.PA EUROFINS SCIENT. 2026-06-16 14:39:36
676 FR0014003TT8 DSY DSY.PA DASSAULT SYSTEMES 2026-06-16 14:39:36
677 FR0014004L86 AM AM.PA DASSAULT AVIATION 2026-06-16 14:39:36
678 FR001400AJ45 ML ML.PA MICHELIN 2026-06-16 14:39:36
679 FR001400J770 AF AF.PA AIR FRANCE -KLM 2026-06-16 14:39:36
680 FR001400NLM4 EMEIS EMEIS.PA EMEIS 2026-06-16 14:39:36
681 FR001400PVN6 VIRI VIRI.PA VIRIDIEN 2026-06-16 14:39:36
682 FR001400Q9V2 EXENS EXENS.PA EXOSENS 2026-06-16 14:39:36
683 FR001400X2S4 ATO ATO.PA ATOS 2026-06-16 14:39:36
684 FR00140182K6 WLN WLN.PA WORLDLINE 2026-06-16 14:39:36
685 LU0088087324 SESG SESG.PA SES 2026-06-16 14:39:36
686 LU0569974404 APAM APAM.AS APERAM 2026-06-16 14:39:36
687 NL0000226223 STMPA STMPA.PA STMICROELECTRONICS 2026-06-16 14:39:36
688 NL0000235190 AIR AIR.PA AIRBUS 2026-06-16 14:39:36
689 NL0006294274 ENX ENX.PA EURONEXT 2026-06-16 14:39:36
690 NL0014559478 TE TE.PA TECHNIP ENERGIES 2026-06-16 14:39:36
691 NL00150001Q9 STLAM STLAM.PA STELLANTIS NV 2026-06-16 14:39:36
692 NL0015001W49 PLX PLX.PA PLUXEE 2026-06-16 14:39:36
+135
View File
@@ -0,0 +1,135 @@
/* 404 page specific styles - Dark glitch / data terminal theme */
body.page-404 {
background: radial-gradient(circle at top, rgba(13, 117, 255, 0.12), transparent 32%),
linear-gradient(180deg, #06080f 0%, #050611 100%);
color: #e4f0ff;
font-family: 'Inter', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
}
.error-shell {
min-height: calc(100vh - 84px);
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
}
.error-card {
width: min(900px, 100%);
padding: 48px 40px;
border-radius: 28px;
background: rgba(4, 8, 16, 0.94);
border: 1px solid rgba(88, 152, 255, 0.18);
box-shadow: 0 26px 80px rgba(0, 0, 0, 0.45);
overflow: hidden;
position: relative;
}
.error-card::before,
.error-card::after {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
}
.error-card::before {
background: linear-gradient(90deg, rgba(255, 255, 255, 0.04), transparent 40%, rgba(255, 255, 255, 0.04));
transform: skewX(-12deg);
}
.error-card::after {
background-image: radial-gradient(circle at 10% 20%, rgba(3, 155, 255, 0.18), transparent 22%),
radial-gradient(circle at 80% 80%, rgba(63, 185, 255, 0.12), transparent 20%);
}
.error-headline {
margin: 0 0 16px;
font-size: clamp(3rem, 5vw, 6rem);
letter-spacing: -0.08em;
line-height: 0.9;
color: #7df0ff;
text-shadow: 0 0 18px rgba(125, 240, 255, 0.28);
animation: glowPulse 2.5s ease-in-out infinite alternate;
}
.error-subtitle {
margin: 0 0 24px;
color: #b8d3ff;
font-size: 1.05rem;
line-height: 1.8;
letter-spacing: 0.02em;
max-width: 720px;
}
.error-meta {
display: flex;
gap: 16px;
flex-wrap: wrap;
margin-bottom: 32px;
}
.meta-chip {
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(34, 126, 255, 0.18);
border-radius: 999px;
padding: 10px 18px;
font-size: 0.95rem;
color: #c4d6ff;
}
.error-actions {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.button-return {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 14px 26px;
border-radius: 999px;
border: 1px solid rgba(125, 240, 255, 0.5);
background: rgba(26, 34, 60, 0.95);
color: #e5f4ff;
font-size: 0.98rem;
font-weight: 700;
text-decoration: none;
text-transform: uppercase;
letter-spacing: 0.08em;
box-shadow: 0 0 18px rgba(46, 213, 255, 0.12);
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.button-return:hover,
.button-return:focus-visible {
transform: translateY(-2px);
background: rgba(14, 24, 42, 0.98);
box-shadow: 0 0 28px rgba(45, 210, 255, 0.35);
}
@keyframes glowPulse {
0% {
text-shadow: 0 0 18px rgba(125, 240, 255, 0.28), 0 0 40px rgba(125, 240, 255, 0.18);
}
100% {
text-shadow: 0 0 24px rgba(125, 240, 255, 0.55), 0 0 64px rgba(125, 240, 255, 0.25);
}
}
@media (max-width: 720px) {
.error-card {
padding: 32px 22px;
}
.error-headline {
font-size: clamp(2.4rem, 10vw, 4rem);
}
.error-actions {
width: 100%;
}
}
+492
View File
@@ -0,0 +1,492 @@
/* Actions page specific styles - Dark Mode financial UI */
body.actions-page {
--actions-header-height: 76px;
--actions-titlebar-height: 80px;
--actions-form-height: 220px;
--actions-footer-height: 64px;
--actions-gap: 10px;
background: #070a12;
color: #edf2ff;
font-family: 'Inter', 'Segoe UI', Arial, sans-serif;
min-height: 100vh;
display: flex;
flex-direction: column;
margin: 0;
}
body.actions-page header.header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1003;
width: 100%;
}
.actions-header {
position: fixed;
top: var(--actions-header-height);
left: 0;
right: 0;
z-index: 1002;
width: 100%;
padding: 20px;
background: rgba(7, 10, 18, 0.98);
border-bottom: 1px solid rgba(84, 138, 255, 0.14);
}
body.actions-page main.main-content {
flex: 1 0 auto;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: stretch;
min-height: 0;
padding-top: calc(var(--actions-header-height) + var(--actions-titlebar-height) + var(--actions-form-height) + var(--actions-gap));
padding-bottom: calc(var(--actions-footer-height) + 20px);
}
body.actions-page .footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1002;
width: 100%;
}
#formulaire-creation {
position: fixed;
top: calc(var(--actions-header-height) + var(--actions-titlebar-height));
left: 0;
right: 0;
z-index: 1001;
width: 100%;
padding: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.32);
background: rgba(7, 10, 18, 0.98);
}
#formulaire-creation .actions-panel {
margin: 0 auto;
width: min(1200px, 100%);
}
.table-container {
width: min(1200px, 100%);
margin: 0 auto;
padding: 0 20px;
}
.actions-table-wrapper {
height: calc(100vh - var(--actions-header-height) - var(--actions-form-height) - var(--actions-footer-height) - 40px);
overflow-y: auto;
overflow-x: auto;
}
.actions-shell {
width: 100%;
flex: 1 1 auto;
min-height: 0;
padding: 0 20px 28px;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
}
.actions-container {
width: min(1200px, 100%);
margin: 0 auto;
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
gap: 24px;
}
.actions-card {
display: flex;
flex-direction: column;
min-height: 0;
}
.actions-table-wrapper {
overflow-x: auto;
min-height: 0;
}
.actions-card:last-child {
display: flex;
flex-direction: column;
min-height: 0;
}
.actions-table-wrapper {
overflow-x: auto;
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
.actions-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: nowrap;
}
.actions-header .actions-title {
margin: 0;
font-size: clamp(1.8rem, 2.5vw, 2.8rem);
letter-spacing: -0.04em;
white-space: nowrap;
}
.actions-header .action-button {
width: auto;
min-width: 170px;
max-width: 260px;
flex-shrink: 0;
}
.actions-subtitle {
color: #94a7d6;
margin: 4px 0 0;
}
.actions-card,
.actions-panel {
background: rgba(12, 18, 34, 0.96);
border: 1px solid rgba(84, 138, 255, 0.18);
border-radius: 24px;
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.22);
padding: 28px;
}
.actions-panel {
display: grid;
grid-template-columns: 1fr;
gap: 18px;
transition: border-color 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}
.actions-panel.edit-mode {
border-color: rgba(120, 211, 141, 0.35);
box-shadow: 0 28px 90px rgba(46, 160, 95, 0.18);
background: rgba(18, 42, 22, 0.95);
}
.actions-panel label {
display: flex;
flex-direction: column;
gap: 10px;
color: #d3e1ff;
font-size: 0.95rem;
}
.actions-panel input,
.actions-panel select {
background: rgba(15, 22, 41, 0.98);
border: 1px solid rgba(96, 156, 255, 0.18);
border-radius: 14px;
color: #edf2ff;
padding: 14px 16px;
font-size: 1rem;
outline: none;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.actions-panel input:focus,
.actions-panel select:focus {
border-color: rgba(89, 151, 255, 0.65);
box-shadow: 0 0 0 4px rgba(64, 126, 255, 0.14);
}
.actions-panel-footer {
margin-top: 12px !important;
display: grid;
grid-auto-flow: column;
justify-content: end;
gap: 12px;
grid-auto-columns: minmax(140px, max-content);
align-items: center;
}
.btn-action,
.actions-panel-footer button {
width: 90%;
max-width: 190px;
min-width: 120px;
box-sizing: border-box;
height: 46px;
padding: 0 18px;
border-radius: 999px;
white-space: nowrap;
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.95rem;
transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}
.actions-panel-footer button:hover,
.btn-action:hover {
transform: translateY(-1px);
}
.actions-panel-footer button:disabled,
.btn-action:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-action:focus-visible {
outline: 3px solid rgba(94, 154, 255, 0.45);
outline-offset: 2px;
}
.btn-primary {
border: 1px solid rgba(94, 154, 255, 0.35);
background: linear-gradient(135deg, rgba(72, 124, 255, 0.18), rgba(26, 50, 103, 0.95));
color: #f7fbff;
}
.btn-action.update-button,
.btn-primary.update-button {
border-color: rgba(96, 204, 129, 0.35);
background: linear-gradient(135deg, rgba(86, 221, 146, 0.18), rgba(50, 90, 72, 0.95));
}
.btn-cancel {
background: rgba(56, 66, 86, 0.95);
border: 1px solid rgba(99, 110, 133, 0.32);
color: #d7e6ff;
}
.cancel-edit-button {
border-color: rgba(99, 110, 133, 0.32);
}
.actions-table-wrapper {
overflow-x: auto;
max-height: 100%;
}
.actions-table {
width: 100%;
border-collapse: collapse;
min-width: 720px;
}
.actions-table th,
.actions-table td {
padding: 12px 14px;
border-bottom: 1px solid rgba(93, 142, 218, 0.12);
}
.actions-table th {
text-align: left;
font-size: 0.95rem;
color: #c7d4f3;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.actions-table td {
color: #e2ecff;
font-size: 0.96rem;
}
.actions-table th:nth-child(5),
.actions-table td:nth-child(5) {
min-width: 180px;
max-width: 220px;
white-space: nowrap;
}
.actions-table td:nth-child(5) {
overflow: hidden;
text-overflow: ellipsis;
}
.actions-table td .readonly-value {
display: inline-block;
width: 100%;
}
.actions-table td .edit-field {
display: none;
width: 100%;
box-sizing: border-box;
}
.actions-table tr.editing .readonly-value {
display: none;
}
.actions-table tr.editing .edit-field {
display: inline-block;
}
.modal-backdrop {
display: grid;
}
.actions-table tbody tr:hover {
background: rgba(102, 145, 255, 0.08);
}
.edit-action-button,
.action-button,
.cancel-edit-button,
.actions-submit {
width: 100%;
min-height: 41px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 999px;
cursor: pointer;
transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}
.edit-action-button {
height: 38px;
min-height: 38px;
padding: 0 16px;
border: 1px solid rgba(94, 154, 255, 0.35);
background: rgba(22, 45, 96, 0.95);
color: #f7fbff;
font-size: 0.95rem;
font-weight: 700;
}
.action-button,
.cancel-edit-button {
padding: 8px 14px;
border: 1px solid rgba(100, 159, 255, 0.22);
background: rgba(24, 34, 62, 0.98);
color: #d7e6ff;
font-size: 0.9rem;
text-decoration: none;
}
.edit-action-button:hover,
.action-button:hover,
.cancel-edit-button:hover,
.actions-submit:hover {
transform: translateY(-1px);
background: rgba(72, 122, 255, 0.16);
}
.action-form-row {
display: grid;
grid-template-columns: 25% 12.5% 12.5% 50%;
gap: 16px;
align-items: flex-end;
}
.action-form-row label {
margin-bottom: 0;
}
.field-isin {
grid-column: span 1;
}
.field-ticker,
.field-yahoo {
grid-column: span 1;
}
.field-company {
grid-column: span 1;
}
@media (max-width: 1200px) {
.action-form-row {
grid-template-columns: 1fr 1fr;
}
}
@media (max-width: 768px) {
.action-form-row {
grid-template-columns: 1fr;
}
}
.form-error,
#action-form-feedback {
color: #ff7c93;
font-size: 0.92rem;
margin-top: 8px;
}
.modal-backdrop {
position: fixed;
inset: 0;
display: grid;
place-items: center;
background: rgba(4, 8, 20, 0.8);
backdrop-filter: blur(6px);
z-index: 10000;
}
.modal-panel {
width: min(520px, calc(100% - 40px));
background: rgba(10, 14, 28, 0.98);
border: 1px solid rgba(92, 156, 255, 0.22);
border-radius: 24px;
padding: 28px;
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
}
.modal-panel h2 {
margin: 0 0 16px;
font-size: 1.4rem;
color: #eaf4ff;
}
.modal-copy {
margin: 0 0 24px;
color: #b8c9ff;
line-height: 1.7;
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
flex-wrap: wrap;
}
.modal-panel .action-button,
.modal-panel .actions-submit {
min-width: 120px;
}
@media (max-width: 900px) {
.actions-panel {
grid-template-columns: 1fr;
}
.action-form-row {
grid-template-columns: 1fr;
}
}
@media (max-width: 640px) {
.actions-card,
.actions-panel {
padding: 20px;
}
.actions-table th,
.actions-table td {
padding: 12px 10px;
}
}
+257
View File
@@ -0,0 +1,257 @@
body.comptegf-page {
--comptegf-header-height: 76px;
--comptegf-titlebar-height: 80px;
--comptegf-form-height: 260px;
--comptegf-footer-height: 64px;
background: #070a12;
color: var(--text-primary);
}
.comptegf-page {
display: flex;
min-height: 100vh;
}
.comptegf-shell {
width: 100%;
padding: 1rem;
background: transparent;
}
.comptegf-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1rem;
}
.comptegf-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.comptegf-title {
margin: 0;
font-size: 1.8rem;
color: var(--text-primary);
}
.comptegf-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.75rem 1rem;
color: #fff;
background: var(--accent-color);
border-radius: 0.75rem;
text-decoration: none;
transition: background 0.2s ease;
}
.comptegf-button:hover {
background: #1d4ed8;
}
.comptegf-panel,
.comptegf-card {
background: rgba(12, 18, 34, 0.96);
border: 1px solid rgba(84, 138, 255, 0.18);
border-radius: 1rem;
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
padding: 1.25rem;
}
.comptegf-form-row {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 1rem;
align-items: flex-end;
}
.comptegf-form-row label {
display: flex;
flex-direction: column;
gap: 0.5rem;
color: #d3e1ff;
font-size: 0.95rem;
}
.comptegf-form-row input {
width: 100%;
min-height: 2.25rem;
padding: 0.65rem 0.85rem;
border: 1px solid rgba(96, 156, 255, 0.18);
border-radius: 0.75rem;
background: rgba(15, 22, 41, 0.98);
font-size: 0.97rem;
color: #edf2ff;
}
.comptegf-form-row input:focus {
border-color: rgba(89, 151, 255, 0.65);
outline: none;
box-shadow: 0 0 0 4px rgba(64, 126, 255, 0.14);
}
.comptegf-panel-footer {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1rem;
}
.btn-action {
border: none;
cursor: pointer;
border-radius: 0.75rem;
padding: 0.6rem 1rem;
min-height: 38px;
font-weight: 600;
font-size: 0.95rem;
transition: transform 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
background-color: rgba(37, 99, 235, 0.16);
color: #edf2ff;
}
.btn-action:hover {
transform: translateY(-1px);
}
.btn-primary {
background-color: #2563eb;
color: white;
}
.btn-edit {
background-color: #2563eb;
color: white;
}
.btn-cancel {
background-color: rgba(255, 255, 255, 0.08);
color: #edf2ff;
border: 1px solid rgba(255, 255, 255, 0.12);
}
.table-container {
overflow: hidden;
}
.comptegf-table-wrapper {
overflow-x: auto;
}
.comptegf-table {
width: 100%;
border-collapse: collapse;
min-width: 800px;
}
.comptegf-table th,
.comptegf-table td {
padding: 0.75rem 0.85rem;
text-align: left;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.comptegf-table th {
background: rgba(255, 255, 255, 0.04);
color: var(--text-secondary);
font-size: 0.95rem;
text-align: center;
}
.comptegf-table tr.totals-row th,
.comptegf-table tr.totals-row td {
background: rgba(37, 99, 235, 0.12);
color: #edf2ff;
font-weight: 700;
}
.comptegf-table tr.totals-row th.totals-label {
text-align: left;
}
.comptegf-table td.numeric-cell {
text-align: right;
}
.comptegf-table .totals-value {
text-align: right;
}
.comptegf-table tbody td:nth-child(1) {
width: 17%;
}
.comptegf-table tbody td:nth-child(2) {
width: 50%;
}
.comptegf-table tbody td:nth-child(3),
.comptegf-table tbody td:nth-child(4),
.comptegf-table tbody td:nth-child(5) {
width: 11%;
}
.comptegf-table tr:hover {
background: rgba(255, 255, 255, 0.06);
}
.form-error {
margin-top: 1rem;
padding: 0.75rem 1rem;
border-radius: 0.75rem;
background: rgba(248, 113, 113, 0.12);
color: #f8c0c0;
border: 1px solid rgba(248, 113, 113, 0.24);
}
.action-notice {
padding: 1rem 1.25rem;
border-radius: 1rem;
margin-bottom: 1rem;
}
body.comptegf-page .form-error,
body.comptegf-page .action-notice {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.1);
color: var(--text-primary);
}
.action-success {
background: rgba(16, 185, 129, 0.14);
border: 1px solid rgba(16, 185, 129, 0.24);
color: #a7f3d0;
}
.action-error {
background: rgba(248, 113, 113, 0.14);
border: 1px solid rgba(248, 113, 113, 0.24);
color: #fecaca;
}
@media (max-width: 1024px) {
.comptegf-form-row {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 640px) {
.comptegf-form-row {
grid-template-columns: 1fr;
}
.comptegf-header {
flex-direction: column;
align-items: stretch;
}
.comptegf-button {
width: 100%;
}
}
+258
View File
@@ -0,0 +1,258 @@
/* Duplicate of compteGF dark styles but for compteJFG */
body.comptejfg-page {
--comptegf-header-height: 76px;
--comptegf-titlebar-height: 80px;
--comptegf-form-height: 260px;
--comptegf-footer-height: 64px;
background: #070a12;
color: var(--text-primary);
}
.comptejfg-page {
display: flex;
min-height: 100vh;
}
.comptegf-shell {
width: 100%;
padding: 1rem;
background: transparent;
}
.comptegf-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1rem;
}
.comptegf-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.comptegf-title {
margin: 0;
font-size: 1.8rem;
color: var(--text-primary);
}
.comptegf-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.75rem 1rem;
color: #fff;
background: var(--accent-color);
border-radius: 0.75rem;
text-decoration: none;
transition: background 0.2s ease;
}
.comptegf-button:hover {
background: #1d4ed8;
}
.comptegf-panel,
.comptegf-card {
background: rgba(12, 18, 34, 0.96);
border: 1px solid rgba(84, 138, 255, 0.18);
border-radius: 1rem;
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
padding: 1.25rem;
}
.comptegf-form-row {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 1rem;
align-items: flex-end;
}
.comptegf-form-row label {
display: flex;
flex-direction: column;
gap: 0.5rem;
color: #d3e1ff;
font-size: 0.95rem;
}
.comptegf-form-row input {
width: 100%;
min-height: 2.25rem;
padding: 0.65rem 0.85rem;
border: 1px solid rgba(96, 156, 255, 0.18);
border-radius: 0.75rem;
background: rgba(15, 22, 41, 0.98);
font-size: 0.97rem;
color: #edf2ff;
}
.comptegf-form-row input:focus {
border-color: rgba(89, 151, 255, 0.65);
outline: none;
box-shadow: 0 0 0 4px rgba(64, 126, 255, 0.14);
}
.comptegf-panel-footer {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-top: 1rem;
}
.btn-action {
border: none;
cursor: pointer;
border-radius: 0.75rem;
padding: 0.6rem 1rem;
min-height: 38px;
font-weight: 600;
font-size: 0.95rem;
transition: transform 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
background-color: rgba(37, 99, 235, 0.16);
color: #edf2ff;
}
.btn-action:hover {
transform: translateY(-1px);
}
.btn-primary {
background-color: #2563eb;
color: white;
}
.btn-edit {
background-color: #2563eb;
color: white;
}
.btn-cancel {
background-color: rgba(255, 255, 255, 0.08);
color: #edf2ff;
border: 1px solid rgba(255, 255, 255, 0.12);
}
.table-container {
overflow: hidden;
}
.comptegf-table-wrapper {
overflow-x: auto;
}
.comptegf-table {
width: 100%;
border-collapse: collapse;
min-width: 800px;
}
.comptegf-table th,
.comptegf-table td {
padding: 0.75rem 0.85rem;
text-align: left;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.comptegf-table th {
background: rgba(255, 255, 255, 0.04);
color: var(--text-secondary);
font-size: 0.95rem;
text-align: center;
}
.comptegf-table tr.totals-row th,
.comptegf-table tr.totals-row td {
background: rgba(37, 99, 235, 0.12);
color: #edf2ff;
font-weight: 700;
}
.comptegf-table tr.totals-row th.totals-label {
text-align: left;
}
.comptegf-table td.numeric-cell {
text-align: right;
}
.comptegf-table .totals-value {
text-align: right;
}
.comptegf-table tbody td:nth-child(1) {
width: 17%;
}
.comptegf-table tbody td:nth-child(2) {
width: 50%;
}
.comptegf-table tbody td:nth-child(3),
.comptegf-table tbody td:nth-child(4),
.comptegf-table tbody td:nth-child(5) {
width: 11%;
}
.comptegf-table tr:hover {
background: rgba(255, 255, 255, 0.06);
}
.form-error {
margin-top: 1rem;
padding: 0.75rem 1rem;
border-radius: 0.75rem;
background: rgba(248, 113, 113, 0.12);
color: #f8c0c0;
border: 1px solid rgba(248, 113, 113, 0.24);
}
.action-notice {
padding: 1rem 1.25rem;
border-radius: 1rem;
margin-bottom: 1rem;
}
body.comptejfg-page .form-error,
body.comptejfg-page .action-notice {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.1);
color: var(--text-primary);
}
.action-success {
background: rgba(16, 185, 129, 0.14);
border: 1px solid rgba(16, 185, 129, 0.24);
color: #a7f3d0;
}
.action-error {
background: rgba(248, 113, 113, 0.14);
border: 1px solid rgba(248, 113, 113, 0.24);
color: #fecaca;
}
@media (max-width: 1024px) {
.comptegf-form-row {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 640px) {
.comptegf-form-row {
grid-template-columns: 1fr;
}
.comptegf-header {
flex-direction: column;
align-items: stretch;
}
.comptegf-button {
width: 100%;
}
}
+104
View File
@@ -0,0 +1,104 @@
/* Styles pour la page de synchronisation CSV */
body.csv-page {
background: #08101f;
color: #e7eefc;
min-height: 100vh;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
.csv-shell {
min-height: calc(100vh - 120px);
display: flex;
align-items: center;
justify-content: center;
padding: 30px 20px;
}
.csv-card {
width: min(780px, 100%);
background: rgba(12, 18, 32, 0.96);
border: 1px solid rgba(113, 153, 255, 0.16);
border-radius: 22px;
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.28);
padding: 32px;
display: grid;
gap: 28px;
}
.csv-content {
display: grid;
gap: 16px;
}
.csv-card h1 {
margin: 0;
font-size: clamp(1.8rem, 2.5vw, 2.8rem);
letter-spacing: -0.04em;
}
.csv-status {
margin: 0;
font-size: 1rem;
line-height: 1.6;
color: #d3e6ff;
}
.status-ok {
color: #c5f0c7;
}
.status-warning {
color: #ffdab3;
}
.csv-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
flex-wrap: wrap;
}
.btn-action {
border: 1px solid rgba(102, 138, 255, 0.24);
border-radius: 999px;
padding: 12px 18px;
font-weight: 700;
font-size: 0.95rem;
cursor: pointer;
transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
min-width: 110px;
}
.btn-action:hover {
transform: translateY(-1px);
}
.btn-primary {
background: linear-gradient(135deg, rgba(72, 124, 255, 0.16), rgba(34, 46, 88, 0.98));
color: #f7fbff;
border-color: rgba(90, 142, 255, 0.35);
}
.btn-secondary {
background: rgba(24, 32, 58, 0.96);
color: #d7e6ff;
border-color: rgba(118, 143, 190, 0.2);
}
.csv-feedback {
min-height: 24px;
color: #f7b3b3;
font-size: 0.95rem;
}
@media (max-width: 640px) {
.csv-card {
padding: 24px;
}
.csv-actions {
justify-content: center;
}
}
+131
View File
@@ -0,0 +1,131 @@
/* Menu page specific styles - Dark mode modern UI */
body.menu-page {
background: #090b10;
color: #e8effa;
font-family: Inter, 'Segoe UI', sans-serif;
}
.menu-shell {
width: 100%;
display: flex;
justify-content: center;
align-items: stretch;
padding: 20px 8px 40px;
box-sizing: border-box;
}
.menu-card {
width: min(1080px, 100%);
background: rgba(15, 21, 35, 0.98);
border: 1px solid rgba(120, 140, 190, 0.18);
border-radius: 28px;
box-shadow: 0 22px 80px rgba(0, 0, 0, 0.4);
backdrop-filter: blur(18px);
padding: 40px;
}
.menu-card__header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 20px;
margin-bottom: 32px;
}
.menu-card__title {
font-size: clamp(1.8rem, 2.5vw, 2.6rem);
margin: 0;
line-height: 1.05;
letter-spacing: -0.03em;
}
.menu-card__subtitle {
color: #97a3c0;
font-size: 0.95rem;
margin-top: 8px;
}
.menu-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 20px;
}
.menu-button {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 22px 24px;
border-radius: 20px;
border: 1px solid rgba(110, 146, 255, 0.2);
background: linear-gradient(180deg, rgba(15, 23, 45, 0.95), rgba(18, 24, 42, 0.98));
color: #f5f9ff;
text-decoration: none;
transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
min-height: 130px;
}
.menu-button:hover,
.menu-button:focus-visible {
transform: translateY(-3px);
border-color: rgba(91, 132, 255, 0.75);
box-shadow: 0 20px 60px rgba(45, 67, 122, 0.28);
}
.menu-button__content {
display: flex;
flex-direction: column;
gap: 6px;
}
.menu-button__title {
font-size: 1.2rem;
font-weight: 700;
margin: 0;
}
.menu-button__text {
color: #97a3c0;
font-size: 0.95rem;
}
.menu-button__icon {
width: 48px;
height: 48px;
display: grid;
place-items: center;
border-radius: 16px;
background: rgba(87, 132, 255, 0.14);
color: #7fa2ff;
font-size: 1.4rem;
}
.menu-note {
margin-top: 30px;
color: #8090b3;
font-size: 0.95rem;
text-align: center;
}
@media (max-width: 860px) {
.menu-grid {
grid-template-columns: 1fr;
}
.menu-card {
padding: 32px 22px;
}
}
@media (max-width: 520px) {
.menu-card {
padding: 24px 16px;
}
.menu-button {
min-height: 110px;
padding: 18px 18px;
}
}
+410
View File
@@ -0,0 +1,410 @@
:root {
--ordregf-bg: #13161f;
--ordregf-card: #1c2030;
--ordregf-border: rgba(255, 255, 255, 0.08);
--ordregf-text: #f0f2fc;
}
/* Force le plein écran */
.ordregf-page {
background-color: var(--ordregf-bg);
margin: 0;
padding: 0;
}
.ordregf-shell {
width: 100%;
max-width: none;
margin: 0;
padding: 20px;
box-sizing: border-box;
}
.ordregf-card {
background: var(--ordregf-card);
border-radius: 12px;
padding: 20px;
width: 100%;
box-sizing: border-box;
}
/* Tables en pleine largeur */
.ordregf-table,
.ordregf-detail-table {
width: 100% !important;
border-collapse: collapse;
table-layout: auto;
}
/* Alignements entêtes */
.ordregf-table th,
.ordregf-detail-table th {
background: rgba(255, 255, 255, 0.05);
padding: 12px;
text-align: left;
color: #fff;
}
.ordregf-detail-table th {
text-align: center !important;
vertical-align: middle;
}
.ordregf-detail-table td {
padding: 8px;
border-bottom: 1px solid var(--ordregf-border);
}
/* Styles boutons */
.ordregf-edit-button {
padding: 4px 12px;
cursor: pointer;
}
/* Boutons principaux (Créer et Retour) */
.ordregf-btn-menu,
.ordregf-btn-creer {
padding: 10px 24px !important;
border-radius: 50px !important;
border: none !important;
cursor: pointer !important;
font-size: 14px !important;
font-weight: 600 !important;
text-decoration: none !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
transition: background 0.3s ease !important;
color: #ffffff !important;
}
/* Bouton Menu (Bleu) */
.ordregf-btn-menu {
background-color: #1a237e !important;
}
.ordregf-btn-menu:hover {
background-color: #283593 !important;
}
/* Bouton Créer (Vert) */
.ordregf-btn-creer {
background-color: #28a745 !important;
}
.ordregf-btn-creer:hover {
background-color: #218838 !important;
}
/* Styles lignes */
.ordregf-header-style {
background: rgba(255, 255, 255, 0.05) !important;
}
.ordregf-header-style td {
color: #fff !important;
font-weight: 600 !important;
padding: 12px !important;
border-bottom: 2px solid rgba(255, 255, 255, 0.1) !important;
}
.ordregf-detail-row td {
padding: 10px 5px !important;
border-bottom: 1px solid var(--ordregf-border);
color: #e0e0e0;
font-family: monospace;
}
.ordregf-detail-row:hover {
background-color: rgba(255, 255, 255, 0.03);
}
/* Alignement colonnes numériques */
.ordregf-detail-table .text-right {
text-align: right !important;
padding-right: 15px !important;
}
/* Classe commune : force la taille et l'alignement */
.ordregf-btn-petit {
width: 90px; /* Largeur fixe pour tous les petits boutons */
height: 30px; /* Hauteur fixe pour un alignement vertical parfait */
padding: 0 10px; /* Padding horizontal */
font-size: 0.8em;
font-weight: 600;
cursor: pointer;
border: none;
border-radius: 4px;
display: inline-flex; /* Utilise Flexbox pour centrer le texte */
align-items: center; /* Centre verticalement */
justify-content: center; /* Centre horizontalement */
box-sizing: border-box; /* Important : inclut padding/border dans la largeur */
}
/* Couleurs spécifiques */
.ordregf-btn-creer-petit {
background-color: #28a745;
color: white;
}
.ordregf-btn-creer-petit:hover {
background-color: #218838;
}
.ordregf-btn-modifier-petit {
background-color: #1a237e;
color: white;
}
.ordregf-btn-modifier-petit:hover {
background-color: #283593;
}
.ordregf-master-row {
background: linear-gradient(90deg, #001f3f, #004cff) !important;
color: #ffffff;
font-weight: 600;
letter-spacing: 0.3px;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}
/**********************************************************/
/* 1. On nettoie le body */
html,
body {
height: 100%;
margin: 0;
overflow: hidden; /* Empêche le scroll de la page entière */
}
/* 2. On positionne le shell en absolu pour qu'il s'insère entre le header et le footer */
.ordregf-shell {
position: absolute;
top: 80px; /* Hauteur exacte de votre header */
bottom: 50px; /* Hauteur exacte de votre footer */
left: 0;
right: 0;
display: flex;
flex-direction: column;
padding: 10px; /* Un léger espace intérieur pour l'esthétique */
box-sizing: border-box;
}
/* 3. La carte occupe l'espace restant */
.ordregf-card {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden; /* Important pour que le scroll ne sorte pas de la carte */
}
/* 4. C'est ici que le scroll se passe */
.ordregf-table-wrapper {
flex: 1;
overflow-y: auto; /* Active le scroll uniquement ici */
}
/* Important : reset des marges du tableau qui pourraient le pousser */
.ordregf-table {
width: 100%;
margin: 0;
}
.ordregf-btn-petit {
width: 90px;
height: 30px;
padding: 0 10px;
font-size: 0.8em;
font-weight: 600;
cursor: pointer;
border: none;
border-radius: 4px;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition: background 0.2s ease;
}
/* ===========================
MODALES
=========================== */
.ordregf-modal {
width: 520px;
max-width: 92vw;
border: none;
border-radius: 18px;
background: #20263a;
color: white;
padding: 30px;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.45);
animation: popup 0.18s ease-out;
}
.ordregf-modal::backdrop {
background: rgba(0, 0, 0, 0.65);
backdrop-filter: blur(5px);
}
@keyframes popup {
from {
opacity: 0;
transform: translateY(-20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.ordregf-modal h2 {
margin-top: 0;
margin-bottom: 25px;
text-align: center;
font-size: 24px;
font-weight: 600;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 18px;
}
.form-group label {
font-weight: 600;
color: #cfd8ff;
}
.ordregf-modal input,
.ordregf-modal select {
width: 100%;
box-sizing: border-box;
padding: 12px 14px;
border-radius: 10px;
border: 1px solid #3b4668;
background: #151b2d;
color: white;
font-size: 15px;
outline: none;
transition: 0.25s;
}
.ordregf-modal input:focus,
.ordregf-modal select:focus {
border-color: #4d84ff;
box-shadow: 0 0 0 3px rgba(77, 132, 255, 0.25);
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 28px;
}
.modal-actions button {
border: none;
padding: 11px 22px;
border-radius: 10px;
font-weight: 600;
cursor: pointer;
transition: 0.2s;
}
.modal-actions button:first-child {
background: #444b63;
color: white;
}
.modal-actions button:first-child:hover {
background: #59617c;
}
.modal-actions button:last-child {
background: #2dbf5a;
color: white;
}
.modal-actions button:last-child:hover {
background: #27a84f;
}
.form-group .triple {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 10px;
}
#btnRechercher {
margin-top: 10px;
width: 100%;
padding: 12px;
border: none;
border-radius: 10px;
background: #2962ff;
color: white;
font-weight: 600;
cursor: pointer;
}
#btnRechercher:hover {
background: #1d4ed8;
}
dialog.ordregf-modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
width: 520px;
max-width: 90vw;
border: none;
border-radius: 18px;
padding: 30px;
background: #20263a;
color: white;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.45);
}
dialog.ordregf-modal::backdrop {
background: rgba(0, 0, 0, 0.65);
backdrop-filter: blur(5px);
}
+358
View File
@@ -0,0 +1,358 @@
:root {
--ordrejfg-bg: #13161f;
--ordrejfg-card: #1c2030;
--ordrejfg-border: rgba(255, 255, 255, 0.08);
--ordrejfg-text: #f0f2fc;
}
/* Force le plein écran */
.ordrejfg-page {
background-color: var(--ordrejfg-bg);
margin: 0;
padding: 0;
}
.ordrejfg-shell {
width: 100%;
max-width: none;
margin: 0;
padding: 20px;
box-sizing: border-box;
}
.ordrejfg-card {
background: var(--ordrejfg-card);
border-radius: 12px;
padding: 20px;
width: 100%;
box-sizing: border-box;
}
/* Tables en pleine largeur */
.ordrejfg-table,
.ordrejfg-detail-table {
width: 100% !important;
border-collapse: collapse;
table-layout: auto;
}
/* Alignements entêtes */
.ordrejfg-table th,
.ordrejfg-detail-table th {
background: rgba(255, 255, 255, 0.05);
padding: 12px;
text-align: left;
color: #fff;
}
.ordrejfg-detail-table th {
text-align: center !important;
vertical-align: middle;
}
.ordrejfg-detail-table td {
padding: 8px;
border-bottom: 1px solid var(--ordrejfg-border);
}
/* Styles boutons */
.ordrejfg-edit-button {
padding: 4px 12px;
cursor: pointer;
}
/* Boutons principaux (Créer et Retour) */
.ordrejfg-btn-menu,
.ordrejfg-btn-creer {
padding: 10px 24px !important;
border-radius: 50px !important;
border: none !important;
cursor: pointer !important;
font-size: 14px !important;
font-weight: 600 !important;
text-decoration: none !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
transition: background 0.3s ease !important;
color: #ffffff !important;
}
/* Bouton Menu (Bleu) */
.ordrejfg-btn-menu {
background-color: #1a237e !important;
}
.ordrejfg-btn-menu:hover {
background-color: #283593 !important;
}
/* Bouton Créer (Vert) */
.ordrejfg-btn-creer {
background-color: #28a745 !important;
}
.ordrejfg-btn-creer:hover {
background-color: #218838 !important;
}
/* Styles lignes */
.ordrejfg-header-style {
background: rgba(255, 255, 255, 0.05) !important;
}
.ordrejfg-header-style td {
color: #fff !important;
font-weight: 600 !important;
padding: 12px !important;
border-bottom: 2px solid rgba(255, 255, 255, 0.1) !important;
}
.ordrejfg-detail-row td {
padding: 10px 5px !important;
border-bottom: 1px solid var(--ordrejfg-border);
color: #e0e0e0;
font-family: monospace;
}
.ordrejfg-detail-row:hover {
background-color: rgba(255, 255, 255, 0.03);
}
/* Alignement colonnes numériques */
.ordrejfg-detail-table .text-right {
text-align: right !important;
padding-right: 15px !important;
}
/* Classe commune : force la taille et l'alignement */
.ordrejfg-btn-petit {
width: 90px;
height: 30px;
padding: 0 10px;
font-size: 0.8em;
font-weight: 600;
cursor: pointer;
border: none;
border-radius: 4px;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition: background 0.2s ease;
}
/* Couleurs spécifiques */
.ordrejfg-btn-creer-petit {
background-color: #28a745;
color: white;
}
.ordrejfg-btn-creer-petit:hover {
background-color: #218838;
}
.ordrejfg-btn-modifier-petit {
background-color: #1a237e;
color: white;
}
.ordrejfg-btn-modifier-petit:hover {
background-color: #283593;
}
.ordrejfg-master-row {
background: linear-gradient(90deg, #001f3f, #004cff) !important;
color: #ffffff;
font-weight: 600;
letter-spacing: 0.3px;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.08);
}
/**********************************************************/
/* 1. On nettoie le body */
html,
body {
height: 100%;
margin: 0;
overflow: hidden;
}
/* 2. On positionne le shell en absolu pour qu'il s'insère entre le header et le footer */
.ordrejfg-shell {
position: absolute;
top: 80px;
bottom: 50px;
left: 0;
right: 0;
display: flex;
flex-direction: column;
padding: 10px;
box-sizing: border-box;
}
/* 3. La carte occupe l'espace restant */
.ordrejfg-card {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 4. C'est ici que le scroll se passe */
.ordrejfg-table-wrapper {
flex: 1;
overflow-y: auto;
}
.ordrejfg-table {
width: 100%;
margin: 0;
}
/* ===========================
MODALES
=========================== */
.ordrejfg-modal {
width: 520px;
max-width: 92vw;
border: none;
border-radius: 18px;
background: #20263a;
color: white;
padding: 30px;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.45);
animation: popup 0.18s ease-out;
}
.ordrejfg-modal::backdrop {
background: rgba(0, 0, 0, 0.65);
backdrop-filter: blur(5px);
}
@keyframes popup {
from {
opacity: 0;
transform: translateY(-20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.ordrejfg-modal h2 {
margin-top: 0;
margin-bottom: 25px;
text-align: center;
font-size: 24px;
font-weight: 600;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 18px;
}
.form-group label {
font-weight: 600;
color: #cfd8ff;
}
.ordrejfg-modal input,
.ordrejfg-modal select {
width: 100%;
box-sizing: border-box;
padding: 12px 14px;
border-radius: 10px;
border: 1px solid #3b4668;
background: #151b2d;
color: white;
font-size: 15px;
outline: none;
transition: 0.25s;
}
.ordrejfg-modal input:focus,
.ordrejfg-modal select:focus {
border-color: #4d84ff;
box-shadow: 0 0 0 3px rgba(77, 132, 255, 0.25);
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 28px;
}
.modal-actions button {
border: none;
padding: 11px 22px;
border-radius: 10px;
font-weight: 600;
cursor: pointer;
transition: 0.2s;
}
.modal-actions button:first-child {
background: #444b63;
color: white;
}
.modal-actions button:first-child:hover {
background: #59617c;
}
.modal-actions button:last-child {
background: #2dbf5a;
color: white;
}
.modal-actions button:last-child:hover {
background: #27a84f;
}
.form-group .triple {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 10px;
}
#btnRechercher {
margin-top: 10px;
width: 100%;
padding: 12px;
border: none;
border-radius: 10px;
background: #2962ff;
color: white;
font-weight: 600;
cursor: pointer;
}
#btnRechercher:hover {
background: #1d4ed8;
}
dialog.ordrejfg-modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
width: 520px;
max-width: 90vw;
border: none;
border-radius: 18px;
padding: 30px;
background: #20263a;
color: white;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.45);
}
dialog.ordrejfg-modal::backdrop {
background: rgba(0, 0, 0, 0.65);
backdrop-filter: blur(5px);
}
+46 -27
View File
@@ -28,10 +28,14 @@
html {
scroll-behavior: smooth;
min-height: 100%;
height: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
Arial, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
@@ -41,6 +45,15 @@ body {
min-height: 100vh;
}
body > .main-content {
flex: 1 0 auto;
}
main {
flex: 1 0 auto;
width: 100%;
}
.container {
width: 100%;
margin: 0 auto;
@@ -145,25 +158,6 @@ body {
color: #ffffff;
}
.footer {
position: relative;
padding: 2px 20px;
text-align: center;
font-size: 0.85rem;
line-height: 1.1;
min-height: 28px;
display: flex;
align-items: center;
justify-content: center;
}
.footer-logout {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
}
.logo-img {
height: 50px;
width: auto;
@@ -184,11 +178,13 @@ body {
============================================ */
.main-content {
flex: 1;
padding: 40px 20px;
flex: 1 0 auto;
min-height: 0;
padding: 40px 20px 20px;
display: flex;
justify-content: center;
align-items: center;
align-items: flex-start;
width: 100%;
}
.login-container {
@@ -399,13 +395,36 @@ body {
============================================ */
.footer {
display: flex;
align-items: center;
padding: 10px 20px;
background-color: var(--bg-secondary);
border-top: 1px solid var(--border-color);
padding: 20px;
text-align: center;
color: var(--text-secondary);
font-size: 13px;
margin-top: auto;
font-size: 0.85rem;
width: 100%;
}
/* On donne une largeur fixe aux conteneurs latéraux pour forcer le centrage */
#market-clocks,
.logout-container {
flex: 0 0 200px; /* Largeur fixe de 200px pour les deux côtés */
}
#market-clocks {
display: flex;
flex-direction: column;
text-align: left;
}
.footer p {
flex: 1; /* Le texte prend tout l'espace restant */
text-align: center; /* Centre le texte dans cet espace */
}
.footer-logout {
display: block;
text-align: right; /* Aligne le bouton à droite dans son bloc */
}
/* ============================================
+134
View File
@@ -0,0 +1,134 @@
document.addEventListener('DOMContentLoaded', () => {
const actionForm = document.getElementById('action-form');
const actionIsinInput = document.querySelector('input[name="action_isin"]');
const isinInput = document.getElementById('action-isin');
const tickerInput = document.getElementById('action-ticker');
const yahooInput = document.getElementById('action-yahoo_code');
const companyInput = document.getElementById('action-company_name');
const feedbackMessage = document.getElementById('action-form-feedback');
const createButton = document.querySelector('.create-button');
const updateButton = document.querySelector('.update-button');
const cancelEditButton = document.querySelector('.cancel-edit-button');
const actionsPanel = document.querySelector('.actions-panel');
const editActionButtons = document.querySelectorAll('.edit-action-button');
const getExistingActions = () => Array.from(document.querySelectorAll('.action-row')).map((row) => ({
isin: row.dataset.isin || '',
ticker: row.dataset.ticker || '',
yahoo_code: row.dataset.yahoo_code || '',
company_name: row.dataset.company_name || '',
}));
const setFeedback = (message) => {
if (!feedbackMessage) {
return;
}
feedbackMessage.textContent = message;
feedbackMessage.style.display = message ? 'block' : 'none';
};
const validateDuplicateFields = () => {
const existingActions = getExistingActions();
const currentActionIsin = actionIsinInput.value.trim();
const currentIsin = isinInput.value.trim();
const currentTicker = tickerInput.value.trim();
const currentYahoo = yahooInput.value.trim();
const duplicateFields = [];
const isDuplicate = (fieldName, value) => {
if (!value) {
return false;
}
return existingActions.some((entry) => {
if (!entry[fieldName]) {
return false;
}
if (currentActionIsin && entry.isin === currentActionIsin) {
return false;
}
return entry[fieldName].localeCompare(value, undefined, { sensitivity: 'base' }) === 0;
});
};
if (isDuplicate('isin', currentIsin)) {
duplicateFields.push('ISIN');
}
if (isDuplicate('ticker', currentTicker)) {
duplicateFields.push('symbole');
}
if (isDuplicate('yahoo_code', currentYahoo)) {
duplicateFields.push('code Yahoo');
}
if (duplicateFields.length > 0) {
const joined = duplicateFields.join(', ');
setFeedback(`Doublon détecté pour le(s) champ(s) : ${joined}. Veuillez modifier la saisie.`);
createButton.disabled = true;
updateButton.disabled = true;
return false;
}
setFeedback('');
createButton.disabled = false;
updateButton.disabled = false;
return true;
};
const resetFormMode = () => {
actionForm.reset();
actionIsinInput.value = '';
createButton.removeAttribute('disabled');
createButton.hidden = false;
updateButton.hidden = true;
cancelEditButton.hidden = true;
isinInput.removeAttribute('readonly');
isinInput.removeAttribute('disabled');
actionsPanel.classList.remove('edit-mode');
setFeedback('');
};
const setEditMode = (row) => {
const isin = row.dataset.isin || '';
const ticker = row.dataset.ticker || '';
const yahooCode = row.dataset.yahoo_code || '';
const companyName = row.dataset.company_name || '';
actionIsinInput.value = isin;
isinInput.value = isin;
tickerInput.value = ticker;
yahooInput.value = yahooCode;
companyInput.value = companyName;
createButton.setAttribute('disabled', 'disabled');
createButton.hidden = true;
updateButton.hidden = false;
cancelEditButton.hidden = false;
isinInput.setAttribute('readonly', 'readonly');
actionsPanel.classList.add('edit-mode');
validateDuplicateFields();
};
const handleInputChange = () => {
validateDuplicateFields();
};
editActionButtons.forEach((button) => {
button.addEventListener('click', () => {
const row = button.closest('tr');
if (!row) {
return;
}
setEditMode(row);
isinInput.focus();
});
});
[isinInput, tickerInput, yahooInput].forEach((input) => {
input.addEventListener('input', handleInputChange);
});
cancelEditButton.addEventListener('click', resetFormMode);
resetFormMode();
});
+73
View File
@@ -0,0 +1,73 @@
document.addEventListener('DOMContentLoaded', () => {
const compteForm = document.getElementById('comptegf-form');
const compteIdInput = document.querySelector('input[name="comptegf_id"]');
const dateInput = document.getElementById('comptegf-date_operation');
const debitInput = document.getElementById('comptegf-debit');
const creditInput = document.getElementById('comptegf-credit');
const libelleInput = document.getElementById('comptegf-libelle');
const feedbackMessage = document.getElementById('comptegf-form-feedback');
const createButton = document.querySelector('.create-button');
const updateButton = document.querySelector('.update-button');
const cancelEditButton = document.querySelector('.cancel-edit-button');
const panel = document.querySelector('.comptegf-panel');
const editButtons = document.querySelectorAll('.edit-comptegf-button');
const setFeedback = (message) => {
if (!feedbackMessage) {
return;
}
feedbackMessage.textContent = message;
feedbackMessage.style.display = message ? 'block' : 'none';
};
const resetFormMode = () => {
if (!compteForm) {
return;
}
compteForm.reset();
compteIdInput.value = '';
createButton.removeAttribute('disabled');
createButton.hidden = false;
updateButton.hidden = true;
cancelEditButton.hidden = true;
dateInput.removeAttribute('readonly');
setFeedback('');
panel.classList.remove('edit-mode');
};
const setEditMode = (row) => {
const id = row.dataset.id || '';
const dateOperation = row.dataset.date_operation || '';
const debit = row.dataset.debit || '0.00';
const credit = row.dataset.credit || '0.00';
const libelle = row.dataset.libelle || '';
compteIdInput.value = id;
dateInput.value = dateOperation;
debitInput.value = debit;
creditInput.value = credit;
libelleInput.value = libelle;
createButton.setAttribute('disabled', 'disabled');
createButton.hidden = true;
updateButton.hidden = false;
cancelEditButton.hidden = false;
panel.classList.add('edit-mode');
setFeedback('Mode édition activé. Modifiez puis enregistrez.');
};
editButtons.forEach((button) => {
button.addEventListener('click', () => {
const row = button.closest('tr');
if (!row) {
return;
}
setEditMode(row);
libelleInput.focus();
});
});
cancelEditButton.addEventListener('click', resetFormMode);
resetFormMode();
});
+74
View File
@@ -0,0 +1,74 @@
document.addEventListener('DOMContentLoaded', () => {
const compteForm = document.getElementById('comptejfg-form');
const compteIdInput = document.querySelector('input[name="comptejfg_id"]');
const dateInput = document.getElementById('comptejfg-date_operation');
const debitInput = document.getElementById('comptejfg-debit');
const creditInput = document.getElementById('comptejfg-credit');
const libelleInput = document.getElementById('comptejfg-libelle');
const feedbackMessage = document.getElementById('comptejfg-form-feedback');
const createButton = document.querySelector('.create-button');
const updateButton = document.querySelector('.update-button');
const cancelEditButton = document.querySelector('.cancel-edit-button');
const panel = document.querySelector('.comptegf-panel');
const editButtons = document.querySelectorAll('.edit-comptejfg-button');
const setFeedback = (message) => {
if (!feedbackMessage) {
return;
}
feedbackMessage.textContent = message;
feedbackMessage.style.display = message ? 'block' : 'none';
};
const resetFormMode = () => {
if (!compteForm) {
return;
}
compteForm.reset();
compteIdInput.value = '';
createButton.removeAttribute('disabled');
createButton.hidden = false;
updateButton.hidden = true;
cancelEditButton.hidden = true;
dateInput.removeAttribute('readonly');
setFeedback('');
panel.classList.remove('edit-mode');
};
const setEditMode = (row) => {
const id = row.dataset.id || '';
const dateOperation = row.dataset.date_operation || '';
const debit = row.dataset.debit || '0.00';
const credit = row.dataset.credit || '0.00';
const libelle = row.dataset.libelle || '';
compteIdInput.value = id;
dateInput.value = dateOperation;
debitInput.value = debit;
creditInput.value = credit;
libelleInput.value = libelle;
createButton.setAttribute('disabled', 'disabled');
createButton.hidden = true;
updateButton.hidden = false;
cancelEditButton.hidden = false;
dateInput.setAttribute('readonly', 'readonly');
panel.classList.add('edit-mode');
setFeedback('Mode édition activé. Modifiez puis enregistrez.');
};
editButtons.forEach((button) => {
button.addEventListener('click', () => {
const row = button.closest('tr');
if (!row) {
return;
}
setEditMode(row);
libelleInput.focus();
});
});
cancelEditButton.addEventListener('click', resetFormMode);
resetFormMode();
});
+52
View File
@@ -0,0 +1,52 @@
document.addEventListener('DOMContentLoaded', () => {
const updateButton = document.getElementById('csv-update-yes');
const cancelButton = document.getElementById('csv-update-no');
const feedbackElement = document.getElementById('csv-feedback');
if (!updateButton || !cancelButton || !feedbackElement) {
return;
}
const setFeedback = (message, isError = false) => {
feedbackElement.textContent = message;
feedbackElement.style.color = isError ? '#ffb3b3' : '#b8f2b8';
};
updateButton.addEventListener('click', async () => {
updateButton.disabled = true;
cancelButton.disabled = true;
setFeedback('Mise à jour en cours, veuillez patienter...');
try {
const response = await fetch('/php/update_csv.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
},
});
const result = await response.json();
if (!response.ok || !result.success) {
const message = result.message || 'Échec de la mise à jour CSV.';
setFeedback(message, true);
updateButton.disabled = false;
cancelButton.disabled = false;
return;
}
setFeedback(result.message || 'CSV mis à jour avec succès.', false);
setTimeout(() => {
window.location.href = '/php/csv.php';
}, 1200);
} catch (error) {
setFeedback('Erreur réseau lors de la mise à jour CSV.', true);
updateButton.disabled = false;
cancelButton.disabled = false;
}
});
cancelButton.addEventListener('click', () => {
window.location.href = '/php/menu.php';
});
});
+47
View File
@@ -0,0 +1,47 @@
document.addEventListener("DOMContentLoaded", function () {
function updateClocks() {
const now = new Date();
const formatTime = (date) => date.toLocaleTimeString("fr-FR");
// --- PARIS ---
const parisTime = new Date(
now.toLocaleString("en-US", { timeZone: "Europe/Paris" }),
);
const pDay = parisTime.getDay();
const pHour = parisTime.getHours();
const pMin = parisTime.getMinutes();
const isParisOpen =
pDay >= 1 &&
pDay <= 5 &&
pHour >= 9 &&
(pHour < 17 || (pHour === 17 && pMin < 30));
const pEl = document.getElementById("paris-clock");
if (pEl) {
pEl.innerText = "Paris : " + formatTime(parisTime);
pEl.style.color = isParisOpen ? "#28a745" : "#dc3545";
}
// --- NEW-YORK ---
const nyTime = new Date(
now.toLocaleString("en-US", { timeZone: "America/New_York" }),
);
const nyDay = nyTime.getDay();
const nyHour = nyTime.getHours();
const nyMin = nyTime.getMinutes();
const isNyOpen =
nyDay >= 1 &&
nyDay <= 5 &&
nyHour >= 9 &&
(nyHour < 16 || (nyHour === 9 && nyMin >= 30));
const nyEl = document.getElementById("ny-clock");
if (nyEl) {
nyEl.innerText = "New-York : " + formatTime(nyTime);
nyEl.style.color = isNyOpen ? "#28a745" : "#dc3545";
}
}
setInterval(updateClocks, 1000);
updateClocks();
});
+12
View File
@@ -0,0 +1,12 @@
document.addEventListener('DOMContentLoaded', function () {
const menuButtons = document.querySelectorAll('.menu-button[data-target]');
menuButtons.forEach((button) => {
button.addEventListener('click', () => {
const target = button.getAttribute('data-target');
if (target) {
window.location.href = target;
}
});
});
});
+238
View File
@@ -0,0 +1,238 @@
document.addEventListener("DOMContentLoaded", () => {
// =====================================================
// OUTILS MODALES
// =====================================================
function openModal(modal) {
if (!modal) return;
modal.showModal();
// Force le centrage avec le CSS dialog
modal.style.transform = "translate(-50%, -50%)";
}
function closeModal(modal) {
if (!modal) return;
modal.close();
modal.style.transform = "";
}
// Fermeture par clic en dehors de la fenêtre
document.querySelectorAll("dialog").forEach((dialog) => {
dialog.addEventListener("click", (e) => {
const rect = dialog.getBoundingClientRect();
const inside =
e.clientX >= rect.left &&
e.clientX <= rect.right &&
e.clientY >= rect.top &&
e.clientY <= rect.bottom;
if (!inside) {
closeModal(dialog);
}
});
});
// =====================================================
// MODAL CREATION ORDRE
// =====================================================
const modalCreerOrdre = document.getElementById("modalCreerOrdre");
const btnCreer = document.querySelector(".ordregf-btn-creer");
if (modalCreerOrdre && btnCreer) {
btnCreer.addEventListener("click", () => {
openModal(modalCreerOrdre);
});
document.getElementById("btnAnnuler")?.addEventListener("click", () => {
document.getElementById("formCreerOrdre")?.reset();
closeModal(modalCreerOrdre);
const btnValider = document.getElementById("btnValider");
if (btnValider) {
btnValider.disabled = true;
}
});
}
// =====================================================
// RECHERCHE ACTION
// =====================================================
const btnRechercher = document.getElementById("btnRechercher");
btnRechercher?.addEventListener("click", async () => {
const isin = document.getElementById("isinRecherche").value;
if (!isin) {
alert("Veuillez entrer un code ISIN");
return;
}
const response = await fetch(
`/php/api_rechercher_action.php?isin=${encodeURIComponent(isin)}`,
);
const data = await response.json();
if (data.success) {
document.getElementById("Nom").value = data.company_name;
document.getElementById("ticker").value = data.ticker;
document.getElementById("code_yahoo").value = data.yahoo_code;
document.getElementById("btnValider").disabled = false;
} else {
alert("Action non trouvée");
}
});
// =====================================================
// ENREGISTREMENT ORDRE
// =====================================================
document
.getElementById("formCreerOrdre")
?.addEventListener("submit", async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const response = await fetch("/php/api_enregistrer_ordre.php", {
method: "POST",
body: formData,
});
const result = await response.json();
if (result.success) {
location.reload();
} else {
alert(
"Erreur lors de l'enregistrement : " +
(result.message || "Erreur inconnue"),
);
}
});
// =====================================================
// ENREGISTREMENT DETAIL
// =====================================================
document
.getElementById("formCreerDetail")
?.addEventListener("submit", async (e) => {
e.preventDefault();
const response = await fetch("/php/api_enregistrer_detail.php", {
method: "POST",
body: new FormData(e.target),
});
const result = await response.json();
if (result.success) {
location.reload();
} else {
alert(
"Erreur lors de l'enregistrement du détail : " +
(result.message || ""),
);
}
});
// =====================================================
// MODIFICATION DETAIL
// =====================================================
document.addEventListener("click", (e) => {
const button = e.target.closest(".ordregf-btn-modifier-petit");
if (!button) return;
const detail = JSON.parse(button.getAttribute("data-detail"));
const modal = document.getElementById("modalModifierDetail");
if (!modal) return;
document.getElementById("edit_id").value = detail.Id;
document.getElementById("edit_Id_entete").value = detail.Id_entete;
document.getElementById("edit_date").value = detail.Date_op;
document.getElementById("edit_quantite").value = detail.Quantite;
document.getElementById("edit_prix").value = detail.Prix_brut;
document.getElementById("edit_frais_broker").value =
detail.Frais_brocker || 0;
document.getElementById("edit_frais_etat").value = detail.Frais_etat || 0;
document.getElementById("edit_frais_autre").value = detail.Frais_autre || 0;
document.getElementById("edit_type").value = (
detail.Type || ""
).toLowerCase();
document.getElementById("edit_etat").value = (
detail.Etat || ""
).toLowerCase();
document.getElementById("edit_ordre").value = (
detail.Ordre || ""
).toLowerCase();
openModal(modal);
});
// =====================================================
// ENREGISTREMENT MODIFICATION
// =====================================================
document
.getElementById("formModifierDetail")
?.addEventListener("submit", async (e) => {
e.preventDefault();
const response = await fetch("/php/api_modifier_detail.php", {
method: "POST",
body: new FormData(e.target),
});
const result = await response.json();
if (result.success) {
location.reload();
} else {
alert("Erreur : " + result.message);
}
});
//fermer la popup en cliquant à côté
document.querySelectorAll("dialog").forEach((dialog) => {
dialog.addEventListener("click", (e) => {
const rect = dialog.getBoundingClientRect();
const inside =
e.clientX >= rect.left &&
e.clientX <= rect.right &&
e.clientY >= rect.top &&
e.clientY <= rect.bottom;
if (!inside) {
dialog.close();
}
});
});
});
+220
View File
@@ -0,0 +1,220 @@
document.addEventListener("DOMContentLoaded", () => {
// =====================================================
// OUTILS MODALES
// =====================================================
function openModal(modal) {
if (!modal) return;
modal.showModal();
// Force le centrage avec le CSS dialog
modal.style.transform = "translate(-50%, -50%)";
}
function closeModal(modal) {
if (!modal) return;
modal.close();
modal.style.transform = "";
}
// Fermeture par clic en dehors de la fenêtre
document.querySelectorAll("dialog").forEach((dialog) => {
dialog.addEventListener("click", (e) => {
const rect = dialog.getBoundingClientRect();
const inside =
e.clientX >= rect.left &&
e.clientX <= rect.right &&
e.clientY >= rect.top &&
e.clientY <= rect.bottom;
if (!inside) {
closeModal(dialog);
}
});
});
// =====================================================
// MODAL CREATION ORDRE
// =====================================================
const modalCreerOrdre = document.getElementById("modalCreerOrdre");
const btnCreer = document.querySelector(".ordrejfg-btn-creer");
if (modalCreerOrdre && btnCreer) {
btnCreer.addEventListener("click", () => {
openModal(modalCreerOrdre);
});
document.getElementById("btnAnnuler")?.addEventListener("click", () => {
document.getElementById("formCreerOrdre")?.reset();
closeModal(modalCreerOrdre);
const btnValider = document.getElementById("btnValider");
if (btnValider) {
btnValider.disabled = true;
}
});
}
// =====================================================
// RECHERCHE ACTION
// =====================================================
const btnRechercher = document.getElementById("btnRechercher");
btnRechercher?.addEventListener("click", async () => {
const isin = document.getElementById("isinRecherche").value;
if (!isin) {
alert("Veuillez entrer un code ISIN");
return;
}
const response = await fetch(
`/php/api_rechercher_action_jfg.php?isin=${encodeURIComponent(isin)}`,
);
const data = await response.json();
if (data.success) {
document.getElementById("Nom").value = data.company_name;
document.getElementById("ticker").value = data.ticker;
document.getElementById("code_yahoo").value = data.yahoo_code;
document.getElementById("btnValider").disabled = false;
} else {
alert("Action non trouvée");
}
});
// =====================================================
// ENREGISTREMENT ORDRE
// =====================================================
document
.getElementById("formCreerOrdre")
?.addEventListener("submit", async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const response = await fetch("/php/api_enregistrer_ordre_jfg.php", {
method: "POST",
body: formData,
});
const result = await response.json();
if (result.success) {
location.reload();
} else {
alert(
"Erreur lors de l'enregistrement : " +
(result.message || "Erreur inconnue"),
);
}
});
// =====================================================
// ENREGISTREMENT DETAIL
// =====================================================
document
.getElementById("formCreerDetail")
?.addEventListener("submit", async (e) => {
e.preventDefault();
const response = await fetch("/php/api_enregistrer_detail_jfg.php", {
method: "POST",
body: new FormData(e.target),
});
const result = await response.json();
if (result.success) {
location.reload();
} else {
alert(
"Erreur lors de l'enregistrement du détail : " +
(result.message || ""),
);
}
});
// =====================================================
// MODIFICATION DETAIL
// =====================================================
document.addEventListener("click", (e) => {
const button = e.target.closest(".ordrejfg-btn-modifier-petit");
if (!button) return;
const detail = JSON.parse(button.getAttribute("data-detail"));
const modal = document.getElementById("modalModifierDetail");
if (!modal) return;
document.getElementById("edit_id").value = detail.Id;
document.getElementById("edit_Id_entete").value = detail.Id_entete;
document.getElementById("edit_date").value = detail.Date_op;
document.getElementById("edit_quantite").value = detail.Quantite;
document.getElementById("edit_prix").value = detail.Prix_brut;
document.getElementById("edit_frais_broker").value =
detail.Frais_brocker || 0;
document.getElementById("edit_frais_etat").value = detail.Frais_etat || 0;
document.getElementById("edit_frais_autre").value = detail.Frais_autre || 0;
document.getElementById("edit_type").value = (
detail.Type || ""
).toLowerCase();
document.getElementById("edit_etat").value = (
detail.Etat || ""
).toLowerCase();
document.getElementById("edit_ordre").value = (
detail.Ordre || ""
).toLowerCase();
openModal(modal);
});
// =====================================================
// ENREGISTREMENT MODIFICATION
// =====================================================
document
.getElementById("formModifierDetail")
?.addEventListener("submit", async (e) => {
e.preventDefault();
const response = await fetch("/php/api_modifier_detail_jfg.php", {
method: "POST",
body: new FormData(e.target),
});
const result = await response.json();
if (result.success) {
location.reload();
} else {
alert("Erreur : " + result.message);
}
});
});
+24 -10
View File
@@ -1,16 +1,30 @@
<?php
// On envoie explicitement le code d'erreur 404 au navigateur
declare(strict_types=1);
http_response_code(404);
require_once('header.php');
$pageStylesheets = ['/css/404.css'];
$bodyClass = 'page-404';
require_once __DIR__ . '/header.php';
?>
<div style="text-align: center; padding: 50px; color: white;">
<h1>Erreur 404</h1>
<p>Désolé, la page que vous recherchez est introuvable.</p>
<a href="/index.php" style="color: #007bff;">Retour à l'accueil</a>
</div>
<section class="error-shell">
<article class="error-card">
<h1 class="error-headline">404</h1>
<p class="error-subtitle">La transaction est introuvable. Le cours de cette page a chuté et le marché nen veut plus.</p>
<?php
require_once('footer.php');
?>
<div class="error-meta">
<span class="meta-chip">Route : /404</span>
<span class="meta-chip">Status : Page non cotée</span>
<span class="meta-chip">Session : <?= htmlspecialchars((string) ($_SESSION['user_id'] ?? 'invité'), ENT_QUOTES, 'UTF-8') ?></span>
</div>
<div class="error-actions">
<a href="/index.php" class="button-return">Retour à la base</a>
</div>
</article>
</section>
<?php require_once __DIR__ . '/footer.php'; ?>
+159
View File
@@ -0,0 +1,159 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
// Redirection si l'utilisateur n'est pas authentifié.
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
$pageStylesheets = ['/css/actions.css'];
$bodyClass = 'actions-page';
$database = new App\Database\Database();
$actionsManager = new App\Database\ActionsManager($database);
// Traitement du formulaire d'ajout d'une nouvelle action.
$creationMessage = null;
$creationError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action_create'])) {
$newAction = [
'isin' => trim($_POST['isin'] ?? ''),
'ticker' => trim($_POST['ticker'] ?? ''),
'yahoo_code' => trim($_POST['yahoo_code'] ?? ''),
'company_name' => trim($_POST['company_name'] ?? ''),
];
if ($newAction['isin'] === '' || $newAction['ticker'] === '' || $newAction['company_name'] === '') {
$creationError = 'Veuillez remplir tous les champs obligatoires.';
} else {
if ($actionsManager->createAction($newAction)) {
$creationMessage = 'Nouvelle action ajoutée avec succès.';
} else {
$creationError = 'Impossible dajouter laction, veuillez réessayer.';
}
}
}
// Traitement du formulaire de mise à jour d'une action.
$updateMessage = null;
$updateError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action_update'], $_POST['action_isin'])) {
$actionIsin = trim($_POST['action_isin']);
$updateData = [
'ticker' => trim($_POST['ticker'] ?? ''),
'yahoo_code' => trim($_POST['yahoo_code'] ?? ''),
'company_name' => trim($_POST['company_name'] ?? ''),
];
if ($actionIsin === '' || $updateData['ticker'] === '' || $updateData['company_name'] === '') {
$updateError = 'Tous les champs requis doivent être remplis pour mettre à jour cette action.';
} else {
if ($actionsManager->updateAction($actionIsin, $updateData)) {
$updateMessage = 'Action mise à jour avec succès.';
} else {
$updateError = 'Impossible de mettre à jour laction. Vérifiez les données et réessayez.';
}
}
}
$actions = $actionsManager->listActions();
require_once __DIR__ . '/header.php';
?>
<section class="actions-shell">
<div class="actions-container">
<div class="actions-header">
<h1 class="actions-title">Actions financières</h1>
<a href="/php/menu.php" class="action-button">Retour au menu</a>
</div>
<?php if ($creationMessage): ?>
<div class="actions-card action-notice action-success"><?= htmlspecialchars($creationMessage, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($creationError): ?>
<div class="actions-card action-notice action-error"><?= htmlspecialchars($creationError, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($updateMessage): ?>
<div class="actions-card action-notice action-success"><?= htmlspecialchars($updateMessage, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($updateError): ?>
<div class="actions-card action-notice action-error"><?= htmlspecialchars($updateError, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<section class="actions-panel" id="formulaire-creation">
<form id="action-form" method="post" action="" autocomplete="off">
<input type="hidden" name="action_isin" value="">
<div class="action-form-row">
<label class="field-isin">
ISIN
<input id="action-isin" type="text" name="isin" placeholder="Ex. FR0000123456" required>
</label>
<label class="field-ticker">
Symbole
<input id="action-ticker" type="text" name="ticker" placeholder="EXA" required>
</label>
<label class="field-yahoo">
Code Yahoo
<input id="action-yahoo_code" type="text" name="yahoo_code" placeholder="EXA.PA" required>
</label>
<label class="field-company">
Société
<input id="action-company_name" type="text" name="company_name" placeholder="Société Alpha" required>
</label>
</div>
<div id="action-form-feedback" class="form-error" aria-live="polite" style="display:none;"></div>
<div class="actions-panel-footer">
<button type="submit" name="action_create" class="btn-action btn-primary create-button">Créer une action</button>
<button type="submit" name="action_update" class="btn-action btn-primary update-button" hidden>Modifier l'action</button>
<button type="button" class="btn-action btn-cancel cancel-edit-button" hidden>Annuler</button>
</div>
</form>
</section>
<section class="actions-card table-container">
<div class="actions-table-wrapper">
<table class="actions-table">
<thead>
<tr>
<th>ISIN</th>
<th>Symbole</th>
<th>Code Yahoo</th>
<th>Société</th>
<th>Mise à jour</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($actions as $action): ?>
<tr class="action-row"
data-isin="<?= htmlspecialchars((string) $action['isin'], ENT_QUOTES, 'UTF-8') ?>"
data-ticker="<?= htmlspecialchars((string) $action['ticker'], ENT_QUOTES, 'UTF-8') ?>"
data-yahoo_code="<?= htmlspecialchars((string) $action['yahoo_code'], ENT_QUOTES, 'UTF-8') ?>"
data-company_name="<?= htmlspecialchars((string) $action['company_name'], ENT_QUOTES, 'UTF-8') ?>"
>
<td><?= htmlspecialchars((string) $action['isin'], ENT_QUOTES, 'UTF-8') ?></td>
<td><?= htmlspecialchars((string) $action['ticker'], ENT_QUOTES, 'UTF-8') ?></td>
<td><?= htmlspecialchars((string) $action['yahoo_code'], ENT_QUOTES, 'UTF-8') ?></td>
<td><?= htmlspecialchars((string) $action['company_name'], ENT_QUOTES, 'UTF-8') ?></td>
<td><?= htmlspecialchars((string) $action['updated_at'], ENT_QUOTES, 'UTF-8') ?></td>
<td>
<button type="button" class="btn-action btn-edit edit-action-button">Modifier</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</div>
</section>
<script src="/js/actions.js" defer></script>
<?php require_once __DIR__ . '/footer.php'; ?>
+22
View File
@@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/db.php';
$db = (new App\Database\Database())->getConnection();
$stmt = $db->prepare("INSERT INTO ordreGF_pied
(Id_entete, Date_op, Quantite, Prix_brut, Frais_brocker, Frais_etat, Frais_autre, Ordre, Type, Etat)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$success = $stmt->execute([
$_POST['Id_entete'],
$_POST['Date_op'],
$_POST['Quantite'],
$_POST['Prix_brut'],
$_POST['Frais_brocker'],
$_POST['Frais_etat'],
$_POST['Frais_autre'],
$_POST['Ordre'],
$_POST['Type'],
$_POST['Etat']
]);
echo json_encode(['success' => $success]);
+27
View File
@@ -0,0 +1,27 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/db.php';
$db = (new App\Database\Database())->getConnection();
// Insertion dans la table ordreJFG_pied
$sql = "INSERT INTO ordreJFG_pied (Id_entete, Date_op, Quantite, Prix_brut, Frais_brocker, Frais_etat, Frais_autre, Ordre, Type, Etat)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $db->prepare($sql);
$success = $stmt->execute([
$_POST['Id_entete'],
$_POST['Date_op'],
$_POST['Quantite'],
$_POST['Prix_brut'],
$_POST['Frais_brocker'],
$_POST['Frais_etat'],
$_POST['Frais_autre'],
$_POST['Ordre'],
$_POST['Type'],
$_POST['Etat']
]);
echo json_encode(['success' => $success]);
+10
View File
@@ -0,0 +1,10 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/db.php';
$db = (new App\Database\Database())->getConnection();
$stmt = $db->prepare("INSERT INTO ordreGF (isin, Nom, ticker, code_yahoo) VALUES (?, ?, ?, ?)");
$success = $stmt->execute([$_POST['isin'], $_POST['Nom'], $_POST['ticker'], $_POST['code_yahoo']]);
echo json_encode(['success' => $success]);
+12
View File
@@ -0,0 +1,12 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/db.php';
$db = (new App\Database\Database())->getConnection();
// Insertion dans la table ordreJFG
$stmt = $db->prepare("INSERT INTO ordreJFG (isin, Nom, ticker, code_yahoo) VALUES (?, ?, ?, ?)");
$success = $stmt->execute([$_POST['isin'], $_POST['Nom'], $_POST['ticker'], $_POST['code_yahoo']]);
echo json_encode(['success' => $success]);
+46
View File
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db.php';
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$db = (new App\Database\Database())->getConnection();
$sql = "UPDATE ordreGF_pied SET
Date_op = :date,
Quantite = :qte,
Prix_brut = :prix,
Frais_brocker = :f_b,
Frais_etat = :f_e,
Frais_autre = :f_a,
Ordre = :ordre,
Type = :type,
Etat = :etat
WHERE Id = :id";
$stmt = $db->prepare($sql);
$stmt->execute([
':date' => $_POST['Date_op'],
':qte' => $_POST['Quantite'],
':prix' => $_POST['Prix_brut'],
':f_b' => $_POST['Frais_brocker'],
':f_e' => $_POST['Frais_etat'],
':f_a' => $_POST['Frais_autre'],
':ordre' => $_POST['Ordre'],
':type' => $_POST['Type'],
':etat' => $_POST['Etat'],
':id' => $_POST['id']
]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db.php';
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$db = (new App\Database\Database())->getConnection();
// Mise à jour de la table ordreJFG_pied
$sql = "UPDATE ordreJFG_pied SET
Date_op = :date,
Quantite = :qte,
Prix_brut = :prix,
Frais_brocker = :f_b,
Frais_etat = :f_e,
Frais_autre = :f_a,
Ordre = :ordre,
Type = :type,
Etat = :etat
WHERE Id = :id";
$stmt = $db->prepare($sql);
$stmt->execute([
':date' => $_POST['Date_op'],
':qte' => $_POST['Quantite'],
':prix' => $_POST['Prix_brut'],
':f_b' => $_POST['Frais_brocker'],
':f_e' => $_POST['Frais_etat'],
':f_a' => $_POST['Frais_autre'],
':ordre' => $_POST['Ordre'],
':type' => $_POST['Type'],
':etat' => $_POST['Etat'],
':id' => $_POST['id']
]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/db.php';
header('Content-Type: application/json');
$db = (new App\Database\Database())->getConnection();
// Récupération des données POST
$id = $_POST['id'];
$nom = $_POST['nom'];
$ticker = $_POST['ticker'];
try {
$stmt = $db->prepare("UPDATE ordreGF SET nom = ?, ticker = ? WHERE id = ?");
$stmt->execute([$nom, $ticker, $id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
+20
View File
@@ -0,0 +1,20 @@
<?php
require_once __DIR__ . '/db.php';
header('Content-Type: application/json');
$db = (new App\Database\Database())->getConnection();
// Récupération des données POST
$id = $_POST['id'];
$nom = $_POST['nom'];
$ticker = $_POST['ticker'];
try {
// Mise à jour de la table ordreJFG
$stmt = $db->prepare("UPDATE ordreJFG SET Nom = ?, ticker = ? WHERE ID = ?");
$stmt->execute([$nom, $ticker, $id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
+9
View File
@@ -0,0 +1,9 @@
<?php
require_once __DIR__ . '/db.php';
$isin = $_GET['isin'] ?? '';
$db = (new App\Database\Database())->getConnection();
$stmt = $db->prepare("SELECT * FROM actions WHERE isin = ?");
$stmt->execute([$isin]);
$action = $stmt->fetch(PDO::FETCH_ASSOC);
echo json_encode($action ? ['success' => true, ...$action] : ['success' => false]);
+12
View File
@@ -0,0 +1,12 @@
<?php
require_once __DIR__ . '/db.php';
$isin = $_GET['isin'] ?? '';
$db = (new App\Database\Database())->getConnection();
// Si vous avez aussi une table actions_jfg spécifique, remplacez 'actions' par 'actions_jfg'
$stmt = $db->prepare("SELECT * FROM actions WHERE isin = ?");
$stmt->execute([$isin]);
$action = $stmt->fetch(PDO::FETCH_ASSOC);
echo json_encode($action ? ['success' => true, ...$action] : ['success' => false]);
+179
View File
@@ -0,0 +1,179 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
// Redirection si l'utilisateur n'est pas authentifié.
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
$pageStylesheets = ['/css/compteGF.css'];
$bodyClass = 'comptegf-page';
$database = new App\Database\Database();
$compteGFManager = new App\Database\CompteGFManager($database);
$creationMessage = null;
$creationError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['comptegf_create'])) {
$newEntry = [
'date_operation' => trim($_POST['date_operation'] ?? ''),
'debit' => trim($_POST['debit'] ?? '0.00'),
'credit' => trim($_POST['credit'] ?? '0.00'),
'libelle' => trim($_POST['libelle'] ?? ''),
];
if ($newEntry['date_operation'] === '' || $newEntry['libelle'] === '') {
$creationError = 'Veuillez remplir la date et le libellé.';
} else {
if ($compteGFManager->createCompteGF($newEntry)) {
$creationMessage = 'Nouvelle écriture ajoutée avec succès.';
} else {
$creationError = 'Impossible dajouter l’écriture, veuillez réessayer.';
}
}
}
$updateMessage = null;
$updateError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['comptegf_update'], $_POST['comptegf_id'])) {
$entryId = (int) $_POST['comptegf_id'];
$updateData = [
'date_operation' => trim($_POST['date_operation'] ?? ''),
'debit' => trim($_POST['debit'] ?? '0.00'),
'credit' => trim($_POST['credit'] ?? '0.00'),
'libelle' => trim($_POST['libelle'] ?? ''),
];
if ($entryId <= 0 || $updateData['date_operation'] === '' || $updateData['libelle'] === '') {
$updateError = 'Tous les champs requis doivent être remplis pour mettre à jour cette écriture.';
} else {
if ($compteGFManager->updateCompteGF($entryId, $updateData)) {
$updateMessage = 'Écriture mise à jour avec succès.';
} else {
$updateError = 'Impossible de mettre à jour l’écriture. Vérifiez les données et réessayez.';
}
}
}
$entries = $compteGFManager->listCompteGF();
$totalCredit = 0.0;
$totalDebit = 0.0;
foreach ($entries as $entry) {
$totalCredit += (float) $entry['credit'];
$totalDebit += (float) $entry['debit'];
}
require_once __DIR__ . '/header.php';
?>
<section class="comptegf-shell">
<div class="comptegf-container">
<div class="comptegf-header">
<h1 class="comptegf-title">Compte GF</h1>
<a href="/php/menu.php" class="comptegf-button">Retour au menu</a>
</div>
<?php if ($creationMessage): ?>
<div class="comptegf-card action-notice action-success"><?= htmlspecialchars($creationMessage, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($creationError): ?>
<div class="comptegf-card action-notice action-error"><?= htmlspecialchars($creationError, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($updateMessage): ?>
<div class="comptegf-card action-notice action-success"><?= htmlspecialchars($updateMessage, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($updateError): ?>
<div class="comptegf-card action-notice action-error"><?= htmlspecialchars($updateError, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<section class="comptegf-panel" id="formulaire-creation">
<form id="comptegf-form" method="post" action="" autocomplete="off">
<input type="hidden" name="comptegf_id" value="">
<div class="comptegf-form-row">
<label class="field-date_operation">
Date opération
<input id="comptegf-date_operation" type="date" name="date_operation" required>
</label>
<label class="field-libelle">
Libellé
<input id="comptegf-libelle" type="text" name="libelle" placeholder="Description" required>
</label>
<label class="field-credit">
Crédit
<input id="comptegf-credit" type="number" name="credit" step="0.01" min="0" value="0.00" required>
</label>
<label class="field-debit">
Débit
<input id="comptegf-debit" type="number" name="debit" step="0.01" min="0" value="0.00" required>
</label>
</div>
<div id="comptegf-form-feedback" class="form-error" aria-live="polite" style="display:none;"></div>
<div class="comptegf-panel-footer">
<button type="submit" name="comptegf_create" class="btn-action btn-primary create-button">Créer une écriture</button>
<button type="submit" name="comptegf_update" class="btn-action btn-primary update-button" hidden>Modifier l'écriture</button>
<button type="button" class="btn-action btn-cancel cancel-edit-button" hidden>Annuler</button>
</div>
</form>
</section>
<section class="comptegf-card table-container">
<div class="comptegf-table-wrapper">
<table class="comptegf-table">
<thead>
<tr class="totals-row">
<th colspan="2" class="totals-label">Totaux :</th>
<th class="numeric-cell totals-value"><?= htmlspecialchars(number_format($totalCredit, 2, ',', ' '), ENT_QUOTES, 'UTF-8') ?></th>
<th class="numeric-cell totals-value"><?= htmlspecialchars(number_format($totalDebit, 2, ',', ' '), ENT_QUOTES, 'UTF-8') ?></th>
<th class="numeric-cell totals-value"><?= htmlspecialchars(number_format($totalCredit - $totalDebit, 2, ',', ' '), ENT_QUOTES, 'UTF-8') ?></th>
</tr>
<tr>
<th>Date opération</th>
<th>Libellé</th>
<th>Crédit</th>
<th>Débit</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($entries as $entry): ?>
<?php
$formattedDate = $entry['date_operation'];
if (!empty($entry['date_operation'])) {
$dateTime = DateTime::createFromFormat('Y-m-d', $entry['date_operation']);
if ($dateTime !== false) {
$formattedDate = $dateTime->format('d/m/Y');
}
}
?>
<tr class="comptegf-row"
data-id="<?= htmlspecialchars((string) $entry['id'], ENT_QUOTES, 'UTF-8') ?>"
data-date_operation="<?= htmlspecialchars((string) $entry['date_operation'], ENT_QUOTES, 'UTF-8') ?>"
data-debit="<?= htmlspecialchars((string) $entry['debit'], ENT_QUOTES, 'UTF-8') ?>"
data-credit="<?= htmlspecialchars((string) $entry['credit'], ENT_QUOTES, 'UTF-8') ?>"
data-libelle="<?= htmlspecialchars((string) $entry['libelle'], ENT_QUOTES, 'UTF-8') ?>"
>
<td><?= htmlspecialchars((string) $formattedDate, ENT_QUOTES, 'UTF-8') ?></td>
<td><?= htmlspecialchars((string) $entry['libelle'], ENT_QUOTES, 'UTF-8') ?></td>
<td class="numeric-cell"><?= htmlspecialchars((string) $entry['credit'], ENT_QUOTES, 'UTF-8') ?></td>
<td class="numeric-cell"><?= htmlspecialchars((string) $entry['debit'], ENT_QUOTES, 'UTF-8') ?></td>
<td>
<button type="button" class="btn-action btn-edit edit-comptegf-button">Modifier</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</div>
</section>
<script src="/js/compteGF.js" defer></script>
<?php require_once __DIR__ . '/footer.php';
+179
View File
@@ -0,0 +1,179 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
// Redirection si l'utilisateur n'est pas authentifié.
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
$pageStylesheets = ['/css/compteJFG.css'];
$bodyClass = 'comptejfg-page';
$database = new App\Database\Database();
$compteJFGManager = new App\Database\CompteJFGManager($database);
$creationMessage = null;
$creationError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['comptejfg_create'])) {
$newEntry = [
'date_operation' => trim($_POST['date_operation'] ?? ''),
'debit' => trim($_POST['debit'] ?? '0.00'),
'credit' => trim($_POST['credit'] ?? '0.00'),
'libelle' => trim($_POST['libelle'] ?? ''),
];
if ($newEntry['date_operation'] === '' || $newEntry['libelle'] === '') {
$creationError = 'Veuillez remplir la date et le libellé.';
} else {
if ($compteJFGManager->createCompteJFG($newEntry)) {
$creationMessage = 'Nouvelle écriture ajoutée avec succès.';
} else {
$creationError = 'Impossible dajouter l’écriture, veuillez réessayer.';
}
}
}
$updateMessage = null;
$updateError = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['comptejfg_update'], $_POST['comptejfg_id'])) {
$entryId = (int) $_POST['comptejfg_id'];
$updateData = [
'date_operation' => trim($_POST['date_operation'] ?? ''),
'debit' => trim($_POST['debit'] ?? '0.00'),
'credit' => trim($_POST['credit'] ?? '0.00'),
'libelle' => trim($_POST['libelle'] ?? ''),
];
if ($entryId <= 0 || $updateData['date_operation'] === '' || $updateData['libelle'] === '') {
$updateError = 'Tous les champs requis doivent être remplis pour mettre à jour cette écriture.';
} else {
if ($compteJFGManager->updateCompteJFG($entryId, $updateData)) {
$updateMessage = 'Écriture mise à jour avec succès.';
} else {
$updateError = 'Impossible de mettre à jour l’écriture. Vérifiez les données et réessayez.';
}
}
}
$entries = $compteJFGManager->listCompteJFG();
$totalCredit = 0.0;
$totalDebit = 0.0;
foreach ($entries as $entry) {
$totalCredit += (float) $entry['credit'];
$totalDebit += (float) $entry['debit'];
}
require_once __DIR__ . '/header.php';
?>
<section class="comptegf-shell">
<div class="comptegf-container">
<div class="comptegf-header">
<h1 class="comptegf-title">Compte JFG</h1>
<a href="/php/menu.php" class="comptegf-button">Retour au menu</a>
</div>
<?php if ($creationMessage): ?>
<div class="comptegf-card action-notice action-success"><?= htmlspecialchars($creationMessage, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($creationError): ?>
<div class="comptegf-card action-notice action-error"><?= htmlspecialchars($creationError, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($updateMessage): ?>
<div class="comptegf-card action-notice action-success"><?= htmlspecialchars($updateMessage, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($updateError): ?>
<div class="comptegf-card action-notice action-error"><?= htmlspecialchars($updateError, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<section class="comptegf-panel" id="formulaire-creation">
<form id="comptejfg-form" method="post" action="" autocomplete="off">
<input type="hidden" name="comptejfg_id" value="">
<div class="comptegf-form-row">
<label class="field-date_operation">
Date opération
<input id="comptejfg-date_operation" type="date" name="date_operation" required>
</label>
<label class="field-libelle">
Libellé
<input id="comptejfg-libelle" type="text" name="libelle" placeholder="Description" required>
</label>
<label class="field-credit">
Crédit
<input id="comptejfg-credit" type="number" name="credit" step="0.01" min="0" value="0.00" required>
</label>
<label class="field-debit">
Débit
<input id="comptejfg-debit" type="number" name="debit" step="0.01" min="0" value="0.00" required>
</label>
</div>
<div id="comptejfg-form-feedback" class="form-error" aria-live="polite" style="display:none;"></div>
<div class="comptegf-panel-footer">
<button type="submit" name="comptejfg_create" class="btn-action btn-primary create-button">Créer une écriture</button>
<button type="submit" name="comptejfg_update" class="btn-action btn-primary update-button" hidden>Modifier l'écriture</button>
<button type="button" class="btn-action btn-cancel cancel-edit-button" hidden>Annuler</button>
</div>
</form>
</section>
<section class="comptegf-card table-container">
<div class="comptegf-table-wrapper">
<table class="comptegf-table">
<thead>
<tr class="totals-row">
<th colspan="2" class="totals-label">Totaux :</th>
<th class="numeric-cell totals-value"><?= htmlspecialchars(number_format($totalCredit, 2, ',', ' '), ENT_QUOTES, 'UTF-8') ?></th>
<th class="numeric-cell totals-value"><?= htmlspecialchars(number_format($totalDebit, 2, ',', ' '), ENT_QUOTES, 'UTF-8') ?></th>
<th class="numeric-cell totals-value"><?= htmlspecialchars(number_format($totalCredit - $totalDebit, 2, ',', ' '), ENT_QUOTES, 'UTF-8') ?></th>
</tr>
<tr>
<th>Date opération</th>
<th>Libellé</th>
<th>Crédit</th>
<th>Débit</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($entries as $entry): ?>
<?php
$formattedDate = $entry['date_operation'];
if (!empty($entry['date_operation'])) {
$dateTime = DateTime::createFromFormat('Y-m-d', $entry['date_operation']);
if ($dateTime !== false) {
$formattedDate = $dateTime->format('d/m/Y');
}
}
?>
<tr class="comptegf-row"
data-id="<?= htmlspecialchars((string) $entry['id'], ENT_QUOTES, 'UTF-8') ?>"
data-date_operation="<?= htmlspecialchars((string) $entry['date_operation'], ENT_QUOTES, 'UTF-8') ?>"
data-debit="<?= htmlspecialchars((string) $entry['debit'], ENT_QUOTES, 'UTF-8') ?>"
data-credit="<?= htmlspecialchars((string) $entry['credit'], ENT_QUOTES, 'UTF-8') ?>"
data-libelle="<?= htmlspecialchars((string) $entry['libelle'], ENT_QUOTES, 'UTF-8') ?>"
>
<td><?= htmlspecialchars((string) $formattedDate, ENT_QUOTES, 'UTF-8') ?></td>
<td><?= htmlspecialchars((string) $entry['libelle'], ENT_QUOTES, 'UTF-8') ?></td>
<td class="numeric-cell"><?= htmlspecialchars((string) $entry['credit'], ENT_QUOTES, 'UTF-8') ?></td>
<td class="numeric-cell"><?= htmlspecialchars((string) $entry['debit'], ENT_QUOTES, 'UTF-8') ?></td>
<td>
<button type="button" class="btn-action btn-edit edit-comptejfg-button">Modifier</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</section>
</div>
</section>
<script src="/js/compteJFG.js" defer></script>
<?php require_once __DIR__ . '/footer.php';
+125
View File
@@ -0,0 +1,125 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
use App\Database\Database;
use App\Database\ActionsManager;
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
$pageStylesheets = ['/css/csv.css'];
$pageScripts = ['/js/csv.js'];
$bodyClass = 'csv-page';
$database = new Database();
$actionsManager = new ActionsManager($database);
$csvFilePath = __DIR__ . '/../assets/csv/actions.csv';
$csvRecords = [];
$csvReadError = null;
$csvExists = is_readable($csvFilePath);
if ($csvExists) {
$handle = fopen($csvFilePath, 'r');
if ($handle === false) {
$csvExists = false;
$csvReadError = 'Impossible de lire le fichier CSV.';
} else {
$header = fgetcsv($handle);
while (($row = fgetcsv($handle)) !== false) {
if (count($row) < 4) {
continue;
}
$isin = trim((string) ($row[0] ?? ''));
if ($isin === '') {
continue;
}
$csvRecords[$isin] = [
'ticker' => trim((string) ($row[1] ?? '')),
'yahoo_code' => trim((string) ($row[2] ?? '')),
'company_name' => trim((string) ($row[3] ?? '')),
];
}
fclose($handle);
}
}
$actions = $actionsManager->listActions();
$differences = [];
foreach ($actions as $action) {
$isin = trim((string) ($action['isin'] ?? ''));
if ($isin === '') {
continue;
}
$expected = [
'ticker' => trim((string) ($action['ticker'] ?? '')),
'yahoo_code' => trim((string) ($action['yahoo_code'] ?? '')),
'company_name' => trim((string) ($action['company_name'] ?? '')),
];
if (!isset($csvRecords[$isin])) {
$differences[] = ['isin' => $isin, 'reason' => 'absent'];
continue;
}
$csvRow = $csvRecords[$isin];
foreach ($expected as $field => $value) {
if ($csvRow[$field] !== $value) {
$differences[] = ['isin' => $isin, 'reason' => $field];
break;
}
}
}
$csvReady = $csvExists && empty($differences);
if ($csvReadError !== null) {
$statusMessage = 'Impossible de vérifier le fichier actions.csv : ' . $csvReadError;
} elseif ($csvReady) {
$statusMessage = 'Le fichier actions.csv est à jour.';
} else {
$statusMessage = 'Le fichier actions.csv peut être mis à jour.';
if ($csvExists) {
$statusMessage .= ' ' . count($differences) . ' différence(s) détectée(s).';
}
}
require_once __DIR__ . '/header.php';
?>
<section class="csv-shell">
<div class="csv-card">
<div class="csv-content">
<h1>Synchronisation CSV</h1>
<p class="csv-status <?= $csvReady ? 'status-ok' : 'status-warning' ?>"><?= htmlspecialchars($statusMessage, ENT_QUOTES, 'UTF-8') ?></p>
</div>
<div class="csv-actions">
<?php if ($csvReady): ?>
<a href="/php/menu.php" class="btn-action btn-primary">Retour au menu</a>
<?php else: ?>
<button id="csv-update-yes" type="button" class="btn-action btn-primary">Mettre à jour</button>
<button id="csv-update-no" type="button" class="btn-action btn-secondary">Retour au menu</button>
<?php endif; ?>
<?php if ($csvExists): ?>
<a id="csv-download-link" href="/php/download_csv.php" class="btn-action btn-secondary">Télécharger CSV</a>
<?php endif; ?>
</div>
<div id="csv-feedback" class="csv-feedback" role="status" aria-live="polite"></div>
</div>
</section>
<script src="/js/csv.js"></script>
<?php require_once __DIR__ . '/footer.php';
+267
View File
@@ -71,6 +71,68 @@ class Database
}
}
/**
* Class CompteJFGManager
*
* Opérations CRUD sur la table `compteJFG`.
*/
class CompteJFGManager
{
private PDO $connection;
public function __construct(Database $database)
{
$this->connection = $database->getConnection();
}
public function listCompteJFG(): array
{
$statement = $this->connection->query(
'SELECT id, date_operation, debit, credit, libelle, updated_at
FROM compteJFG
ORDER BY date_operation DESC, id DESC'
);
return $statement->fetchAll();
}
public function createCompteJFG(array $data): bool
{
$statement = $this->connection->prepare(
'INSERT INTO compteJFG (date_operation, debit, credit, libelle, created_at, updated_at)
VALUES (:date_operation, :debit, :credit, :libelle, NOW(), NOW())'
);
$statement->bindValue(':date_operation', $data['date_operation'], PDO::PARAM_STR);
$statement->bindValue(':debit', $data['debit'], PDO::PARAM_STR);
$statement->bindValue(':credit', $data['credit'], PDO::PARAM_STR);
$statement->bindValue(':libelle', $data['libelle'], PDO::PARAM_STR);
return $statement->execute();
}
public function updateCompteJFG(int $id, array $data): bool
{
$statement = $this->connection->prepare(
'UPDATE compteJFG
SET date_operation = :date_operation,
debit = :debit,
credit = :credit,
libelle = :libelle,
updated_at = NOW()
WHERE id = :id'
);
$statement->bindValue(':date_operation', $data['date_operation'], PDO::PARAM_STR);
$statement->bindValue(':debit', $data['debit'], PDO::PARAM_STR);
$statement->bindValue(':credit', $data['credit'], PDO::PARAM_STR);
$statement->bindValue(':libelle', $data['libelle'], PDO::PARAM_STR);
$statement->bindValue(':id', $id, PDO::PARAM_INT);
return $statement->execute();
}
}
/**
* Class LoginManager
*
@@ -364,3 +426,208 @@ class LoginManager
return $statement->execute();
}
}
/**
* Class ActionsManager
*
* Opérations CRUD sur la table `actions`.
*/
class ActionsManager
{
private PDO $connection;
public function __construct(Database $database)
{
$this->connection = $database->getConnection();
}
/**
* Retourne toutes les actions.
*
* @return array
*/
public function listActions(): array
{
$statement = $this->connection->query(
'SELECT isin, ticker, yahoo_code, company_name, updated_at
FROM actions
ORDER BY updated_at DESC'
);
return $statement->fetchAll();
}
/**
* Exporte toutes les actions vers un fichier CSV.
*
* @param string $filePath
* @return bool
*/
public function exportActionsToCsv(string $filePath): bool
{
$actions = $this->listActions();
$directory = dirname($filePath);
if (!is_dir($directory) && !mkdir($directory, 0755, true) && !is_dir($directory)) {
return false;
}
$handle = fopen($filePath, 'w');
if ($handle === false) {
return false;
}
$header = ['isin', 'ticker', 'yahoo_code', 'company_name', 'updated_at'];
if (fputcsv($handle, $header) === false) {
fclose($handle);
return false;
}
foreach ($actions as $action) {
if (fputcsv($handle, [
$action['isin'],
$action['ticker'],
$action['yahoo_code'],
$action['company_name'],
$action['updated_at'],
]) === false) {
fclose($handle);
return false;
}
}
fclose($handle);
return true;
}
/**
* Retourne une action par son ISIN.
*
* @param string $isin
* @return array|null
*/
public function getActionByIsin(string $isin): ?array
{
$statement = $this->connection->prepare(
'SELECT isin, ticker, yahoo_code, company_name, updated_at
FROM actions
WHERE isin = :isin'
);
$statement->bindValue(':isin', $isin, PDO::PARAM_STR);
$statement->execute();
$result = $statement->fetch();
return $result === false ? null : $result;
}
/**
* Crée une nouvelle action.
*
* @param array $data
* @return bool
*/
public function createAction(array $data): bool
{
$statement = $this->connection->prepare(
'INSERT INTO actions (isin, ticker, yahoo_code, company_name, updated_at)
VALUES (:isin, :ticker, :yahoo_code, :company_name, NOW())'
);
$statement->bindValue(':isin', $data['isin'], PDO::PARAM_STR);
$statement->bindValue(':ticker', $data['ticker'], PDO::PARAM_STR);
$statement->bindValue(':yahoo_code', $data['yahoo_code'], PDO::PARAM_STR);
$statement->bindValue(':company_name', $data['company_name'], PDO::PARAM_STR);
return $statement->execute();
}
/**
* Met à jour une action.
*
* @param string $isin
* @param array $data
* @return bool
*/
public function updateAction(string $isin, array $data): bool
{
$statement = $this->connection->prepare(
'UPDATE actions
SET ticker = :ticker,
yahoo_code = :yahoo_code,
company_name = :company_name,
updated_at = NOW()
WHERE isin = :isin'
);
$statement->bindValue(':ticker', $data['ticker'], PDO::PARAM_STR);
$statement->bindValue(':yahoo_code', $data['yahoo_code'], PDO::PARAM_STR);
$statement->bindValue(':company_name', $data['company_name'], PDO::PARAM_STR);
$statement->bindValue(':isin', $isin, PDO::PARAM_STR);
return $statement->execute();
}
}
/**
* Class CompteGFManager
*
* Opérations CRUD sur la table `compteGF`.
*/
class CompteGFManager
{
private PDO $connection;
public function __construct(Database $database)
{
$this->connection = $database->getConnection();
}
public function listCompteGF(): array
{
$statement = $this->connection->query(
'SELECT id, date_operation, debit, credit, libelle, updated_at
FROM compteGF
ORDER BY date_operation DESC, id DESC'
);
return $statement->fetchAll();
}
public function createCompteGF(array $data): bool
{
$statement = $this->connection->prepare(
'INSERT INTO compteGF (date_operation, debit, credit, libelle, created_at, updated_at)
VALUES (:date_operation, :debit, :credit, :libelle, NOW(), NOW())'
);
$statement->bindValue(':date_operation', $data['date_operation'], PDO::PARAM_STR);
$statement->bindValue(':debit', $data['debit'], PDO::PARAM_STR);
$statement->bindValue(':credit', $data['credit'], PDO::PARAM_STR);
$statement->bindValue(':libelle', $data['libelle'], PDO::PARAM_STR);
return $statement->execute();
}
public function updateCompteGF(int $id, array $data): bool
{
$statement = $this->connection->prepare(
'UPDATE compteGF
SET date_operation = :date_operation,
debit = :debit,
credit = :credit,
libelle = :libelle,
updated_at = NOW()
WHERE id = :id'
);
$statement->bindValue(':date_operation', $data['date_operation'], PDO::PARAM_STR);
$statement->bindValue(':debit', $data['debit'], PDO::PARAM_STR);
$statement->bindValue(':credit', $data['credit'], PDO::PARAM_STR);
$statement->bindValue(':libelle', $data['libelle'], PDO::PARAM_STR);
$statement->bindValue(':id', $id, PDO::PARAM_INT);
return $statement->execute();
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
$csvFilePath = __DIR__ . '/../assets/csv/actions.csv';
if (!is_readable($csvFilePath)) {
http_response_code(404);
echo 'Fichier CSV introuvable.';
exit;
}
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="actions.csv"');
header('Content-Length: ' . (string) filesize($csvFilePath));
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
readfile($csvFilePath);
exit;
+18 -5
View File
@@ -1,9 +1,22 @@
</main>
<footer class="footer">
<?php if (isset($_SESSION['user_id'])): ?>
<a class="logout-button footer-logout" href="/php/menu.php?action=logout">Se déconnecter</a>
<?php endif; ?>
<!-- 1. Les horloges en premier (elles seront à gauche) -->
<div id="market-clocks">
<div id="paris-clock">Paris : --:--:--</div>
<div id="ny-clock">New-York : --:--:--</div>
</div>
<!-- 2. Le texte au milieu -->
<p>&copy; 2026 - Jean-François GIRAUD - Positions en bourse - Tous droits réservés</p>
<!-- 3. Le bouton tout à droite (grâce à la classe footer-logout) -->
<?php if (isset($_SESSION['user_id'])): ?>
<a class="logout-button footer-logout" href="/php/logout.php">Se déconnecter</a>
<?php endif; ?>
<!-- Appel du script JS (placé à la fin) -->
<script src="/js/footer.js"></script>
</footer>
</body>
</html>
</body>
</html>
+9 -2
View File
@@ -1,13 +1,20 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bourse - Page d'Accueil</title>
<title>Bourse</title>
<link rel="stylesheet" href="/css/style.css">
<?php if (!empty($pageStylesheets) && is_array($pageStylesheets)): ?>
<?php foreach ($pageStylesheets as $sheet): ?>
<link rel="stylesheet" href="<?= htmlspecialchars($sheet, ENT_QUOTES, 'UTF-8') ?>">
<?php endforeach; ?>
<?php endif; ?>
<link rel="shortcut icon" href="/assets/images/favicon.png" type="image/x-icon">
</head>
<body>
<body class="<?= !empty($bodyClass) ? htmlspecialchars($bodyClass, ENT_QUOTES, 'UTF-8') : '' ?>">
<header class="header">
<div class="container">
<div class="logo">
+14
View File
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
// Destroy the PHP session and clear the session cookie.
session_unset();
session_destroy();
setcookie(session_name(), '', time() - 42000, '/');
// Redirect to the public login/home page.
header('Location: https://giraud-finance.com');
exit;
+65 -22
View File
@@ -4,40 +4,83 @@ declare(strict_types=1);
require_once __DIR__ . '/session.php';
// Logout action
if (isset($_GET['action']) && $_GET['action'] === 'logout') {
session_unset();
session_destroy();
setcookie(session_name(), '', time() - 42000, '/');
header('Location: ../index.php');
exit;
}
// Require login
// Si l'utilisateur n'est pas connecté, redirection vers l'accueil.
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
// Ajoute le CSS spécifique à cette page et une classe body dédiée.
$pageStylesheets = ['/css/menu.css'];
$bodyClass = 'menu-page';
require_once __DIR__ . '/header.php';
?>
<div class="login-container">
<div class="login-box">
<h2 class="login-title">Espace utilisateur</h2>
<section class="menu-shell">
<article class="menu-card">
<header class="menu-card__header">
<div>
<h2 class="menu-card__title">Espace de gestion</h2>
<p class="menu-card__subtitle">Accédez aux fonctions clés de l'application financière.</p>
</div>
<span class="menu-card__badge">v1.0</span>
</header>
<p>Session ID : <?php echo htmlspecialchars(session_id(), ENT_QUOTES, 'UTF-8'); ?></p>
<p>User ID : <?php echo htmlspecialchars((string)($_SESSION['user_id'] ?? ''), ENT_QUOTES, 'UTF-8'); ?></p>
<p>Login : <?php echo htmlspecialchars((string)($_SESSION['user_login'] ?? ''), ENT_QUOTES, 'UTF-8'); ?></p>
<p>Nom : <?php echo htmlspecialchars((string)($_SESSION['user_name'] ?? ''), ENT_QUOTES, 'UTF-8'); ?></p>
<p>Dernière activité (timestamp) : <?php echo htmlspecialchars((string)time(), ENT_QUOTES, 'UTF-8'); ?></p>
<p>Adresse IP : <?php echo htmlspecialchars($_SERVER['REMOTE_ADDR'] ?? '', ENT_QUOTES, 'UTF-8'); ?></p>
<form name="menu" class="menu-grid" action="#" method="post" autocomplete="off" novalidate>
<button type="button" class="menu-button" data-target="/php/ordreGF.php">
<div class="menu-button__content">
<span class="menu-button__title">Ordre GF</span>
<span class="menu-button__text">Voir et modifier les ordres GF</span>
</div>
<span class="menu-button__icon">⇄</span>
</button>
<div style="margin-top:16px;">
<a class="btn-submit" href="menu.php?action=logout" style="display:inline-block;text-decoration:none;">Se déconnecter</a>
<button type="button" class="menu-button" data-target="/php/ordreJFG.php">
<div class="menu-button__content">
<span class="menu-button__title">Ordre JFG</span>
<span class="menu-button__text">Voir et modifier les ordres JFG</span>
</div>
<span class="menu-button__icon">⇄</span>
</button>
<button type="button" class="menu-button" data-target="/php/compteGF.php">
<div class="menu-button__content">
<span class="menu-button__title">Compte GF</span>
<span class="menu-button__text">Voir et modifier le compte GF</span>
</div>
<span class="menu-button__icon">💼</span>
</button>
<button type="button" class="menu-button" data-target="/php/compteJFG.php">
<div class="menu-button__content">
<span class="menu-button__title">Compte JFG</span>
<span class="menu-button__text">Voir et modifier le compte JFG</span>
</div>
<span class="menu-button__icon">💼</span>
</button>
<button type="button" class="menu-button" data-target="/php/actions.php">
<div class="menu-button__content">
<span class="menu-button__title">Actions</span>
<span class="menu-button__text">Créer, voir et modifier les actions</span>
</div>
<span class="menu-button__icon">⚡</span>
</button>
<button type="button" class="menu-button" data-target="/php/csv.php">
<div class="menu-button__content">
<span class="menu-button__title">CSV</span>
<span class="menu-button__text">Importer / exporter les actions</span>
</div>
<span class="menu-button__icon">📁</span>
</button>
</form>
<p class="menu-note">Giraud Finance : Accès sécurisé. Veillez à fermer votre session après chaque utilisation.</p>
</article>
</section>
<script src="/js/menu.js" defer></script>
<?php require_once __DIR__ . '/footer.php'; ?>
+370
View File
@@ -0,0 +1,370 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
/*A supprimer quand la page fonctionnera correctement*/
ini_set('display_errors', 1);
error_reporting(E_ALL);
/**************************************************** */
$pageStylesheets = ['/css/ordreGF.css'];
$bodyClass = 'ordregf-page';
$database = new App\Database\Database();
$connection = $database->getConnection();
function fetchOrdreGF(PDO $connection): array
{
$stmt = $connection->query('SELECT * FROM `ordreGF` ORDER BY `ID` DESC');
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
function fetchOrdreGFPied(PDO $connection, string $masterId): array
{
$stmt = $connection->prepare('SELECT * FROM `ordreGF_pied` WHERE `Id_entete` = :masterId ORDER BY `Id` ASC');
$stmt->execute([':masterId' => $masterId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
$ordres = fetchOrdreGF($connection);
require_once __DIR__ . '/header.php';
?>
<section class="ordregf-shell">
<div class="ordregf-card">
<header class="ordregf-card-header" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 28px;">
<h1 class="ordregf-title">Gestion des ordres GF</h1>
<div style="display: flex; gap: 10px;">
<button type="button" class="ordregf-btn-creer" onclick="document.getElementById('modalCreerOrdre').showModal();">Créer un ordre</button>
<button type="button" class="ordregf-btn-menu" onclick="window.location.href='/php/menu.php';">Retour au menu</button>
</div>
</header>
<div class="ordregf-table-wrapper">
<table class="ordregf-table">
<tbody>
<?php foreach ($ordres as $ordre): ?>
<?php
$details = fetchOrdreGFPied($connection, (string)$ordre['ID']);
$totalQ = 0;
// Détection d'un ordre annulé
$isCanceled = false;
foreach ($details as $d) {
if (strtolower($d['Etat'] ?? '') === 'annulé') {
$isCanceled = true;
break;
}
}
// 1. Calcul du total des quantités actives
foreach ($details as $d) {
if (strtolower($d['Etat'] ?? '') === 'actif') {
$q = (int)($d['Quantite'] ?? 0);
$oType = strtolower($d['Ordre'] ?? '');
$tOp = strtolower($d['Type'] ?? '');
$signe = ($tOp === 'long') ? ($oType === 'achat' ? 1 : -1) : ($oType === 'achat' ? -1 : 1);
$totalQ += ($q * $signe);
}
}
// 2. Calcul Plus-Value et Mise à jour statut
$plusvalue = 0.0000;
if ($isCanceled) {
$plusvalue = 0;
if ((float)$ordre['PlusValue'] != 0) {
$connection->prepare(
"UPDATE ordreGF SET PlusValue = 0 WHERE ID = ?"
)->execute([$ordre['ID']]);
$ordre['PlusValue'] = 0;
}
}
$isSold = (!$isCanceled && $totalQ === 0 && count($details) > 0);
if ($isSold) {
foreach ($details as $detail) {
$qte = (int)$detail['Quantite'];
$fraisDetail = (float)$detail['Frais_brocker'] + (float)$detail['Frais_etat'] + (float)$detail['Frais_autre'];
$oType = strtolower($detail['Ordre']);
$prixNet = ($oType === 'vente') ? (float)$detail['Prix_brut'] - $fraisDetail : (float)$detail['Prix_brut'] + $fraisDetail;
$tOp = strtolower($detail['Type']);
$signePV = ($oType === 'vente') ? 1 : -1;
$plusvalue += ($qte * $prixNet * $signePV);
}
$plusvalue = round($plusvalue, 4);
// Mise à jour de la plus-value uniquement si nécessaire
if (abs((float)$ordre['PlusValue'] - $plusvalue) > 0.0001) {
$connection->prepare(
"UPDATE ordreGF SET PlusValue = ? WHERE ID = ?"
)->execute([$plusvalue, $ordre['ID']]);
$ordre['PlusValue'] = $plusvalue;
}
// Si la quantité totale est à zéro, toutes les lignes actives passent en soldé
$connection->prepare(
"UPDATE ordreGF_pied
SET Etat = 'soldé'
WHERE Id_entete = ?
AND Etat = 'actif'"
)->execute([$ordre['ID']]);
// Recharge les données après modification
$details = fetchOrdreGFPied($connection, (string)$ordre['ID']);
}
// Désactivation si ordre soldé ou annulé
$isDisabled = $isCanceled || abs((float)$ordre['PlusValue']) > 0.0001;
$disabledAttr = $isDisabled
? 'disabled style="opacity:0.5; cursor:not-allowed;"'
: '';
?>
<tr class="ordregf-master-row ordregf-header-style">
<td colspan="11" style="font-weight: bold; font-size: 1.1em; color: #fff;">
<?php echo htmlspecialchars((string)$ordre['isin']) . ' --- ' . htmlspecialchars((string)$ordre['Nom']) . ' ( ' . htmlspecialchars((string)$ordre['ticker']) . ' )'; ?>
</td>
</tr>
<tr class="ordregf-detail-block">
<td colspan="11">
<table class="ordregf-detail-table">
<thead>
<tr>
<th>Date</th>
<th>Qté</th>
<th>Prix Brut</th>
<th>Frais</th>
<th>Prix Net</th>
<th>Eng. Brut</th>
<th>Eng. Net</th>
<th>Ordre</th>
<th>Type</th>
<th>Etat</th>
<th style="text-align: right;"><button type="button" class="ordregf-btn-creer-petit ordregf-btn-petit" <?= $disabledAttr ?> onclick="document.getElementById('Id_entete_detail').value='<?= $ordre['ID'] ?>'; document.getElementById('modalCreerDetail').showModal();">Créer</button></th>
</tr>
</thead>
<tbody>
<?php
$engaBrut = 0;
$engaNet = 0;
foreach ($details as $detail):
$qte = (int)($detail['Quantite'] ?? 0);
$prix = (float)($detail['Prix_brut'] ?? 0);
$frais = (float)($detail['Frais_brocker'] ?? 0) + (float)($detail['Frais_etat'] ?? 0) + (float)($detail['Frais_autre'] ?? 0);
$ordreType = strtolower($detail['Ordre'] ?? '');
$prixNet = ($ordreType === 'vente') ? $prix - $frais : $prix + $frais;
$date = !empty($detail['Date_op']) ? date('d/m/Y', strtotime($detail['Date_op'])) : '--/--/----';
if (strtolower($detail['Etat'] ?? '') === 'actif') {
$mult = (strtolower($detail['Type'] ?? '') === 'long' ? 1 : -1) * (strtolower($detail['Ordre'] ?? '') === 'achat' ? 1 : -1);
$engaBrut += ($qte * $prix) * $mult;
$engaNet += ($qte * $prixNet) * $mult;
}
?>
<tr>
<td><?= htmlspecialchars($date) ?></td>
<td class="text-right"><?= $qte ?></td>
<td class="text-right"><?= number_format($prix, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($frais, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($prixNet, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($qte * $prix, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($qte * $prixNet, 3, ',', ' ') ?></td>
<td style="text-align: center"><?= htmlspecialchars($detail['Ordre'] ?? '') ?></td>
<td style="text-align: center"><?= htmlspecialchars($detail['Type'] ?? '') ?></td>
<td style="text-align: center"><?= htmlspecialchars($detail['Etat'] ?? '') ?></td>
<td style="text-align: center"><button type=" button" class="ordregf-btn-petit ordregf-btn-modifier-petit" <?= $disabledAttr ?> data-detail='<?= htmlspecialchars(json_encode($detail), ENT_QUOTES, 'UTF-8') ?>'>Modifier</button></td>
</tr>
<?php endforeach; ?>
<?php if ($isDisabled): ?>
<tr style="background-color: rgba(255, 255, 255, 0.08); font-weight: bold;">
<td colspan="6" style="text-align: right;">Plus value :</td>
<td style="color: <?= (float)$ordre['PlusValue'] < 0 ? 'red' : 'green' ?>;"><?= number_format((float)$ordre['PlusValue'], 3, ',', ' ') ?></td>
<td colspan="4"></td>
</tr>
<?php else: ?>
<tr style="background-color: rgba(255, 255, 255, 0.08); font-weight: bold;">
<td style="text-align: right;">TOTAL :</td>
<td class="text-right"><?= number_format($totalQ, 0, ',', ' ') ?></td>
<?php if ($totalQ == 0): ?>
<td class="text-right">0</td>
<td class="text-right">0</td>
<td class="text-right">0</td>
<?php else: ?>
<td class="text-right"><?= number_format($engaBrut / $totalQ, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($engaNet / $totalQ - $engaBrut / $totalQ, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($engaNet / $totalQ, 3, ',', ' ') ?></td>
<?php endif; ?>
<td class="text-right"><?= number_format($engaBrut, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($engaNet, 3, ',', ' ') ?></td>
<td colspan="4"></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</section>
<!-- Modals -->
<dialog id="modalCreerOrdre" class="ordregf-modal">
<form id="formCreerOrdre">
<h2>Créer un nouvel ordre</h2>
<div class="form-group">
<label>ISIN</label>
<input type="text" id="isinRecherche" name="isin" required>
<button type="button" id="btnRechercher">Rechercher</button>
</div>
<div class="form-group">
<label>Nom :</label>
<input type="text" name="Nom" id="Nom" readonly>
</div>
<div class="form-group">
<label>Ticker :</label>
<input type="text" name="ticker" id="ticker" readonly>
</div>
<div class="form-group">
<label>Code Yahoo :</label>
<input type="text" name="code_yahoo" id="code_yahoo" readonly>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button type="button" id="btnAnnuler">Annuler</button>
<button type="submit" id="btnValider" disabled>Valider</button>
</div>
</form>
</dialog>
<dialog id="modalCreerDetail" class="ordregf-modal">
<form id="formCreerDetail">
<input type="hidden" name="Id_entete" id="Id_entete_detail">
<h2>Ajouter un mouvement</h2>
<div class="form-group">
<label>Date :</label>
<input type="date" name="Date_op" required>
</div>
<div class="form-group">
<label>Quantité :</label>
<input type="number" name="Quantite" required>
</div>
<div class="form-group">
<label>Prix Brut :</label>
<input type="number" step="0.0001" name="Prix_brut" required>
</div>
<div class="form-group">
<label>Frais</label>
<div class="triple">
<input type="number" step="0.0001" name="Frais_brocker" placeholder="Broker">
<input type="number" step="0.0001" name="Frais_etat" placeholder="État">
<input type="number" step="0.0001" name="Frais_autre" placeholder="Autre">
</div>
</div>
<div class="form-group">
<label>Ordre (Achat/Vente) :</label>
<select name="Ordre">
<option value="achat">achat</option>
<option value="vente">vente</option>
</select>
</div>
<div class="form-group">
<label>Type (Long/Short) :</label>
<select name="Type">
<option value="long">long</option>
<option value="short">short</option>
</select>
</div>
<div class="form-group">
<label>Etat :</label>
<select name="Etat">
<option value="actif">actif</option>
<option value="annulé">annulé</option>
</select>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button type="button" onclick="document.getElementById('modalCreerDetail').close()">Annuler</button>
<button type="submit">Valider</button>
</div>
</form>
</dialog>
<dialog id="modalModifierDetail" class="ordregf-modal">
<form id="formModifierDetail">
<input type="hidden" name="id" id="edit_id">
<input type="hidden" name="Id_entete" id="edit_Id_entete">
<h2>Modifier le mouvement</h2>
<div class="form-group">
<label>Date :</label>
<input type="date" name="Date_op" id="edit_date" required>
</div>
<div class="form-group">
<label>Quantité :</label>
<input type="number" name="Quantite" id="edit_quantite" required>
</div>
<div class="form-group">
<label>Prix Brut :</label>
<input type="number" step="0.0001" name="Prix_brut" id="edit_prix" required>
</div>
<div class="form-group">
<label>Frais</label>
<div class="triple">
<input type="number" step="0.0001" name="Frais_brocker" id="edit_frais_broker" placeholder="Broker">
<input type="number" step="0.0001" name="Frais_etat" id="edit_frais_etat" placeholder="État">
<input type="number" step="0.0001" name="Frais_autre" id="edit_frais_autre" placeholder="Autre">
</div>
</div>
<div class="form-group">
<label>Ordre :</label>
<select name="Ordre" id="edit_ordre">
<option value="achat">achat</option>
<option value="vente">vente</option>
</select>
</div>
<div class="form-group">
<label>Type :</label>
<select name="Type" id="edit_type">
<option value="long">long</option>
<option value="short">short</option>
</select>
</div>
<div class="form-group">
<label>Etat :</label>
<select name="Etat" id="edit_etat">
<option value="actif">actif</option>
<option value="annulé">annulé</option>
</select>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button type="button" onclick="document.getElementById('modalModifierDetail').close()">Annuler</button>
<button type="submit">Enregistrer</button>
</div>
</form>
</dialog>
<script src="/js/ordreGF.js" defer></script>
<?php require_once __DIR__ . '/footer.php'; ?>
+337
View File
@@ -0,0 +1,337 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
if (empty($_SESSION['user_id'])) {
header('Location: ../index.php');
exit;
}
/*A supprimer quand la page fonctionnera correctement*/
ini_set('display_errors', 1);
error_reporting(E_ALL);
/**************************************************** */
$pageStylesheets = ['/css/ordreJFG.css'];
$bodyClass = 'ordrejfg-page';
$database = new App\Database\Database();
$connection = $database->getConnection();
function fetchOrdreJFG(PDO $connection): array
{
$stmt = $connection->query('SELECT * FROM `ordreJFG` ORDER BY `ID` DESC');
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
function fetchOrdreJFGPied(PDO $connection, string $masterId): array
{
$stmt = $connection->prepare('SELECT * FROM `ordreJFG_pied` WHERE `Id_entete` = :masterId ORDER BY `Id` ASC');
$stmt->execute([':masterId' => $masterId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}
$ordres = fetchOrdreJFG($connection);
require_once __DIR__ . '/header.php';
?>
<section class="ordrejfg-shell">
<div class="ordrejfg-card">
<header class="ordrejfg-card-header" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 28px;">
<h1 class="ordrejfg-title">Gestion des ordres JFG</h1>
<div style="display: flex; gap: 10px;">
<button type="button" class="ordrejfg-btn-creer" onclick="document.getElementById('modalCreerOrdre').showModal();">Créer un ordre</button>
<button type="button" class="ordrejfg-btn-menu" onclick="window.location.href='/php/menu.php';">Retour au menu</button>
</div>
</header>
<div class="ordrejfg-table-wrapper">
<table class="ordrejfg-table">
<tbody>
<?php foreach ($ordres as $ordre): ?>
<?php
$details = fetchOrdreJFGPied($connection, (string)$ordre['ID']);
$totalQ = 0;
// Détection d'un ordre annulé
$isCanceled = false;
foreach ($details as $d) {
if (strtolower($d['Etat'] ?? '') === 'annulé') {
$isCanceled = true;
break;
}
}
// 1. Calcul du total des quantités actives
foreach ($details as $d) {
if (strtolower($d['Etat'] ?? '') === 'actif') {
$q = (int)($d['Quantite'] ?? 0);
$oType = strtolower($d['Ordre'] ?? '');
$tOp = strtolower($d['Type'] ?? '');
$signe = ($tOp === 'long') ? ($oType === 'achat' ? 1 : -1) : ($oType === 'achat' ? -1 : 1);
$totalQ += ($q * $signe);
}
}
// 2. Calcul Plus-Value et Mise à jour statut
$plusvalue = 0.0000;
if ($isCanceled) {
$plusvalue = 0;
if ((float)$ordre['PlusValue'] != 0) {
$connection->prepare("UPDATE ordreJFG SET PlusValue = 0 WHERE ID = ?")->execute([$ordre['ID']]);
$ordre['PlusValue'] = 0;
}
}
$isSold = (!$isCanceled && $totalQ === 0 && count($details) > 0);
if ($isSold) {
foreach ($details as $detail) {
$qte = (int)$detail['Quantite'];
$fraisDetail = (float)$detail['Frais_brocker'] + (float)$detail['Frais_etat'] + (float)$detail['Frais_autre'];
$oType = strtolower($detail['Ordre']);
$prixNet = ($oType === 'vente') ? (float)$detail['Prix_brut'] - $fraisDetail : (float)$detail['Prix_brut'] + $fraisDetail;
$tOp = strtolower($detail['Type']);
$signePV = ($oType === 'vente') ? 1 : -1;
$plusvalue += ($qte * $prixNet * $signePV);
}
$plusvalue = round($plusvalue, 4);
if (abs((float)$ordre['PlusValue'] - $plusvalue) > 0.0001) {
$connection->prepare("UPDATE ordreJFG SET PlusValue = ? WHERE ID = ?")->execute([$plusvalue, $ordre['ID']]);
$ordre['PlusValue'] = $plusvalue;
}
$connection->prepare("UPDATE ordreJFG_pied SET Etat = 'soldé' WHERE Id_entete = ? AND Etat = 'actif'")->execute([$ordre['ID']]);
$details = fetchOrdreJFGPied($connection, (string)$ordre['ID']);
}
$isDisabled = $isCanceled || abs((float)$ordre['PlusValue']) > 0.0001;
$disabledAttr = $isDisabled ? 'disabled style="opacity:0.5; cursor:not-allowed;"' : '';
?>
<tr class="ordrejfg-master-row ordrejfg-header-style">
<td colspan="11" style="font-weight: bold; font-size: 1.1em; color: #fff;">
<?php echo htmlspecialchars((string)$ordre['isin']) . ' --- ' . htmlspecialchars((string)$ordre['Nom']) . ' ( ' . htmlspecialchars((string)$ordre['ticker']) . ' )'; ?>
</td>
</tr>
<tr class="ordrejfg-detail-block">
<td colspan="11">
<table class="ordrejfg-detail-table">
<thead>
<tr>
<th>Date</th>
<th>Qté</th>
<th>Prix Brut</th>
<th>Frais</th>
<th>Prix Net</th>
<th>Eng. Brut</th>
<th>Eng. Net</th>
<th>Ordre</th>
<th>Type</th>
<th>Etat</th>
<th style="text-align: right;"><button type="button" class="ordrejfg-btn-creer-petit ordrejfg-btn-petit" <?= $disabledAttr ?> onclick="document.getElementById('Id_entete_detail').value='<?= $ordre['ID'] ?>'; document.getElementById('modalCreerDetail').showModal();">Créer</button></th>
</tr>
</thead>
<tbody>
<?php
$engaBrut = 0;
$engaNet = 0;
foreach ($details as $detail):
$qte = (int)($detail['Quantite'] ?? 0);
$prix = (float)($detail['Prix_brut'] ?? 0);
$frais = (float)($detail['Frais_brocker'] ?? 0) + (float)($detail['Frais_etat'] ?? 0) + (float)($detail['Frais_autre'] ?? 0);
$ordreType = strtolower($detail['Ordre'] ?? '');
$prixNet = ($ordreType === 'vente') ? $prix - $frais : $prix + $frais;
$date = !empty($detail['Date_op']) ? date('d/m/Y', strtotime($detail['Date_op'])) : '--/--/----';
if (strtolower($detail['Etat'] ?? '') === 'actif') {
$mult = (strtolower($detail['Type'] ?? '') === 'long' ? 1 : -1) * (strtolower($detail['Ordre'] ?? '') === 'achat' ? 1 : -1);
$engaBrut += ($qte * $prix) * $mult;
$engaNet += ($qte * $prixNet) * $mult;
}
?>
<tr>
<td><?= htmlspecialchars($date) ?></td>
<td class="text-right"><?= $qte ?></td>
<td class="text-right"><?= number_format($prix, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($frais, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($prixNet, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($qte * $prix, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($qte * $prixNet, 3, ',', ' ') ?></td>
<td style="text-align: center"><?= htmlspecialchars($detail['Ordre'] ?? '') ?></td>
<td style="text-align: center"><?= htmlspecialchars($detail['Type'] ?? '') ?></td>
<td style="text-align: center"><?= htmlspecialchars($detail['Etat'] ?? '') ?></td>
<td style="text-align: center"><button type="button" class="ordrejfg-btn-petit ordrejfg-btn-modifier-petit" <?= $disabledAttr ?> data-detail='<?= htmlspecialchars(json_encode($detail), ENT_QUOTES, 'UTF-8') ?>'>Modifier</button></td>
</tr>
<?php endforeach; ?>
<tr style="background-color: rgba(255, 255, 255, 0.08); font-weight: bold;">
<?php if ($isDisabled): ?>
<td colspan="6" style="text-align: right;">Plus value :</td>
<td style="color: <?= (float)$ordre['PlusValue'] < 0 ? 'red' : 'green' ?>;"><?= number_format((float)$ordre['PlusValue'], 3, ',', ' ') ?></td>
<td colspan="4"></td>
<?php else: ?>
<td style="text-align: right;">TOTAL :</td>
<td class="text-right"><?= number_format($totalQ, 0, ',', ' ') ?></td>
<?php if ($totalQ == 0): ?>
<td colspan="3" class="text-right">0</td>
<?php else: ?>
<td class="text-right"><?= number_format($engaBrut / $totalQ, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($engaNet / $totalQ - $engaBrut / $totalQ, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($engaNet / $totalQ, 3, ',', ' ') ?></td>
<?php endif; ?>
<td class="text-right"><?= number_format($engaBrut, 3, ',', ' ') ?></td>
<td class="text-right"><?= number_format($engaNet, 3, ',', ' ') ?></td>
<td colspan="4"></td>
<?php endif; ?>
</tr>
</tbody>
</table>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</section>
<dialog id="modalCreerOrdre" class="ordrejfg-modal">
<form id="formCreerOrdre">
<h2>Créer un nouvel ordre</h2>
<div class="form-group">
<label>ISIN</label>
<input type="text" id="isinRecherche" name="isin" required>
<button type="button" id="btnRechercher">Rechercher</button>
</div>
<div class="form-group">
<label>Nom :</label>
<input type="text" name="Nom" id="Nom" readonly>
</div>
<div class="form-group">
<label>Ticker :</label>
<input type="text" name="ticker" id="ticker" readonly>
</div>
<div class="form-group">
<label>Code Yahoo :</label>
<input type="text" name="code_yahoo" id="code_yahoo" readonly>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button type="button" id="btnAnnuler">Annuler</button>
<button type="submit" id="btnValider" disabled>Valider</button>
</div>
</form>
</dialog>
<dialog id="modalCreerDetail" class="ordrejfg-modal">
<form id="formCreerDetail">
<input type="hidden" name="Id_entete" id="Id_entete_detail">
<h2>Ajouter un mouvement</h2>
<div class="form-group">
<label>Date :</label>
<input type="date" name="Date_op" required>
</div>
<div class="form-group">
<label>Quantité :</label>
<input type="number" name="Quantite" required>
</div>
<div class="form-group">
<label>Prix Brut :</label>
<input type="number" step="0.0001" name="Prix_brut" required>
</div>
<div class="form-group">
<label>Frais</label>
<div class="triple">
<input type="number" step="0.0001" name="Frais_brocker" placeholder="Broker">
<input type="number" step="0.0001" name="Frais_etat" placeholder="État">
<input type="number" step="0.0001" name="Frais_autre" placeholder="Autre">
</div>
</div>
<div class="form-group">
<label>Ordre (Achat/Vente) :</label>
<select name="Ordre">
<option value="achat">achat</option>
<option value="vente">vente</option>
</select>
</div>
<div class="form-group">
<label>Type (Long/Short) :</label>
<select name="Type">
<option value="long">long</option>
<option value="short">short</option>
</select>
</div>
<div class="form-group">
<label>Etat :</label>
<select name="Etat">
<option value="actif">actif</option>
<option value="annulé">annulé</option>
</select>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button type="button" onclick="document.getElementById('modalCreerDetail').close()">Annuler</button>
<button type="submit">Valider</button>
</div>
</form>
</dialog>
<dialog id="modalModifierDetail" class="ordrejfg-modal">
<form id="formModifierDetail">
<input type="hidden" name="id" id="edit_id">
<input type="hidden" name="Id_entete" id="edit_Id_entete">
<h2>Modifier le mouvement</h2>
<div class="form-group">
<label>Date :</label>
<input type="date" name="Date_op" id="edit_date" required>
</div>
<div class="form-group">
<label>Quantité :</label>
<input type="number" name="Quantite" id="edit_quantite" required>
</div>
<div class="form-group">
<label>Prix Brut :</label>
<input type="number" step="0.0001" name="Prix_brut" id="edit_prix" required>
</div>
<div class="form-group">
<label>Frais</label>
<div class="triple">
<input type="number" step="0.0001" name="Frais_brocker" id="edit_frais_broker" placeholder="Broker">
<input type="number" step="0.0001" name="Frais_etat" id="edit_frais_etat" placeholder="État">
<input type="number" step="0.0001" name="Frais_autre" id="edit_frais_autre" placeholder="Autre">
</div>
</div>
<div class="form-group">
<label>Ordre :</label>
<select name="Ordre" id="edit_ordre">
<option value="achat">achat</option>
<option value="vente">vente</option>
</select>
</div>
<div class="form-group">
<label>Type :</label>
<select name="Type" id="edit_type">
<option value="long">long</option>
<option value="short">short</option>
</select>
</div>
<div class="form-group">
<label>Etat :</label>
<select name="Etat" id="edit_etat">
<option value="actif">actif</option>
<option value="annulé">annulé</option>
</select>
</div>
<div class="modal-actions" style="margin-top: 20px;">
<button type="button" onclick="document.getElementById('modalModifierDetail').close()">Annuler</button>
<button type="submit">Enregistrer</button>
</div>
</form>
</dialog>
<script src="/js/ordreJFG.js" defer></script>
<?php require_once __DIR__ . '/footer.php'; ?>
+43
View File
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/session.php';
require_once __DIR__ . '/db.php';
use App\Database\Database;
use App\Database\ActionsManager;
header('Content-Type: application/json; charset=UTF-8');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['success' => false, 'message' => 'Méthode non autorisée.']);
exit;
}
if (empty($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['success' => false, 'message' => 'Authentification requise.']);
exit;
}
$database = new Database();
$actionsManager = new ActionsManager($database);
$csvFilePath = __DIR__ . '/../assets/csv/actions.csv';
try {
$success = $actionsManager->exportActionsToCsv($csvFilePath);
if (!$success) {
http_response_code(500);
echo json_encode(['success' => false, 'message' => 'Impossible de générer le fichier CSV.']);
exit;
}
echo json_encode(['success' => true, 'message' => 'Fichier CSV mis à jour avec succès.']);
exit;
} catch (Throwable $exception) {
http_response_code(500);
echo json_encode(['success' => false, 'message' => 'Erreur interne : ' . $exception->getMessage()]);
exit;
}
+120 -4
View File
@@ -1,6 +1,7 @@
.
├── assets
│   ├── csv
│   │   ├── actions.csv
│   │   ├── autre.csv
│   │   ├── ibex35.csv
│   │   ├── nasdaq100.csv
@@ -9,18 +10,133 @@
│   └── images
│   ├── favicon.png
│   └── GFBlancLogo.png
├── composer.json
├── composer.lock
├── css
│   ├── 404.css
│   ├── actions.css
│   ├── compteGF.css
│   ├── compteJFG.css
│   ├── csv.css
│   ├── menu.css
│   └── style.css
├── .htaccess
├── index.php
├── js
│   ├── actions.js
│   ├── compteGF.js
│   ├── compteJFG.js
│   ├── csv.js
│   └── menu.js
├── php
│   ├── 404.php
│   ├── actions.php
│   ├── compteGF.php
│   ├── compteJFG.php
│   ├── csv.php
│   ├── db.php
│   ├── download_csv.php
│   ├── footer.php
│   ├── forgot_password.php
│   ├── header.php
│   ├── login_process.php
│   ├── logout.php
│   ├── menu.php
│   ── session.php
│   ── register.php
│   ├── reset_password.php
│   ├── session.php
│   └── update_csv.php
├── structure.txt
└── structur.txt
└── vendor
├── autoload.php
├── composer
│   ├── autoload_classmap.php
│   ├── autoload_namespaces.php
│   ├── autoload_psr4.php
│   ├── autoload_real.php
│   ├── autoload_static.php
│   ├── ClassLoader.php
│   ├── installed.json
│   ├── installed.php
│   ├── InstalledVersions.php
│   ├── LICENSE
│   └── platform_check.php
└── phpmailer
└── phpmailer
├── COMMITMENT
├── composer.json
├── get_oauth_token.php
├── language
│   ├── phpmailer.lang-af.php
│   ├── phpmailer.lang-ar.php
│   ├── phpmailer.lang-as.php
│   ├── phpmailer.lang-az.php
│   ├── phpmailer.lang-ba.php
│   ├── phpmailer.lang-be.php
│   ├── phpmailer.lang-bg.php
│   ├── phpmailer.lang-bn.php
│   ├── phpmailer.lang-ca.php
│   ├── phpmailer.lang-cs.php
│   ├── phpmailer.lang-da.php
│   ├── phpmailer.lang-de.php
│   ├── phpmailer.lang-el.php
│   ├── phpmailer.lang-eo.php
│   ├── phpmailer.lang-es.php
│   ├── phpmailer.lang-et.php
│   ├── phpmailer.lang-fa.php
│   ├── phpmailer.lang-fi.php
│   ├── phpmailer.lang-fo.php
│   ├── phpmailer.lang-fr.php
│   ├── phpmailer.lang-gl.php
│   ├── phpmailer.lang-he.php
│   ├── phpmailer.lang-hi.php
│   ├── phpmailer.lang-hr.php
│   ├── phpmailer.lang-hu.php
│   ├── phpmailer.lang-hy.php
│   ├── phpmailer.lang-id.php
│   ├── phpmailer.lang-it.php
│   ├── phpmailer.lang-ja.php
│   ├── phpmailer.lang-ka.php
│   ├── phpmailer.lang-ko.php
│   ├── phpmailer.lang-ku.php
│   ├── phpmailer.lang-lt.php
│   ├── phpmailer.lang-lv.php
│   ├── phpmailer.lang-mg.php
│   ├── phpmailer.lang-mn.php
│   ├── phpmailer.lang-ms.php
│   ├── phpmailer.lang-nb.php
│   ├── phpmailer.lang-nl.php
│   ├── phpmailer.lang-pl.php
│   ├── phpmailer.lang-pt_br.php
│   ├── phpmailer.lang-pt.php
│   ├── phpmailer.lang-ro.php
│   ├── phpmailer.lang-ru.php
│   ├── phpmailer.lang-si.php
│   ├── phpmailer.lang-sk.php
│   ├── phpmailer.lang-sl.php
│   ├── phpmailer.lang-sr_latn.php
│   ├── phpmailer.lang-sr.php
│   ├── phpmailer.lang-sv.php
│   ├── phpmailer.lang-tl.php
│   ├── phpmailer.lang-tr.php
│   ├── phpmailer.lang-uk.php
│   ├── phpmailer.lang-ur.php
│   ├── phpmailer.lang-vi.php
│   ├── phpmailer.lang-zh_cn.php
│   └── phpmailer.lang-zh.php
├── LICENSE
├── README.md
├── SECURITY.md
├── SMTPUTF8.md
├── src
│   ├── DSNConfigurator.php
│   ├── Exception.php
│   ├── OAuth.php
│   ├── OAuthTokenProvider.php
│   ├── PHPMailer.php
│   ├── POP3.php
│   └── SMTP.php
└── VERSION
7 directories, 17 files
13 directories, 125 files
tree > structure.txt