gea-program 0.45.0__tar.gz → 0.46.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gea_program-0.45.0 → gea_program-0.46.0}/PKG-INFO +13 -1
- {gea_program-0.45.0 → gea_program-0.46.0}/README.md +12 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/__init__.py +1 -1
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/__main__.py +58 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/acceptance_tests.py +152 -0
- gea_program-0.46.0/gea/help/invoice-check.md +15 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/helplib.py +2 -1
- gea_program-0.46.0/gea/invoice_check.py +786 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/service.py +27 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/web/app.html +31 -1
- {gea_program-0.45.0 → gea_program-0.46.0}/gea_program.egg-info/PKG-INFO +13 -1
- {gea_program-0.45.0 → gea_program-0.46.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/pyproject.toml +1 -1
- {gea_program-0.45.0 → gea_program-0.46.0}/LICENSE +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/alerts.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/backup.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/bench.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/blind_harness.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog_map.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/catalog_register.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/certificates.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/cli.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/client_reports.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/config_versioning.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/conformance.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/control_room.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/correlation.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/dashboard.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/declarations.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/deviation.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/dlis.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/dnp3.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/doctor.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/dossier.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/drill_string.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/earth_model.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/economics.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/ed25519.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/edr.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/elevation.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/etp.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/example_register_map.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/fat_sat.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/files.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/follower.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/forward_model.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/friction_priors.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/gamma.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/geodesy.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/hartip.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/alarms.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/alerts.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/backup.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/catalog.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/charts.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/conformance.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/control-room.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/data-in.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/declare.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/dlis.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/doctor.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/dossier.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/drift.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/economics.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/edr.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/etp.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/files.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/historian.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/instruments.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/interval.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/map.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/month-end.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/notifications.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/opseis.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/osdu.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/patches.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/quality.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/report-history.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/seismic.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/setup.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/simulation.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/site.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/sites.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/slip.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/soak.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/sra.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/start.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/structure.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/tools.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/transients.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/vibration.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/well-report.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/help/well3d.md +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/housekeeping.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/interval.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/jobs.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/live_ports.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/loadtest.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/modbus.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/model_card.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/month_end.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/notify.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/opcua_port.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/operator_app.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/osdu.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/pad_summary.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/patches.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/pdf_report.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/penetrator.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/permits.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/piwebapi.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/ports.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/ppdm.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/project.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/quakeml.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reconciler.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/report_history.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/sample_record.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/sbom.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seedlink.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/segy.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_array.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_film.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_response.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_track.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/series_cache.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/service_life.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/shapefile.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/shell.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/shut_in.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/simulation.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/site_map.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/sla_report.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/slip.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/soak.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/sra.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/store_forward.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/strata_join.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/structure.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/supervisor.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/survey_view.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/telemetry.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/tool_library.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/transient.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/vibration.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/well3d.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/well_assembler.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/well_report.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/wits0.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/witsml.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea/workspace.py +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/setup.cfg +0 -0
- {gea_program-0.45.0 → gea_program-0.46.0}/tests/test_acceptance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.46.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -648,6 +648,18 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
|
|
|
648
648
|
itself; `gea help seedlink`. A TexNet station is served by EarthScope at
|
|
649
649
|
`rtserve.iris.washington.edu:18000`, network `TX`.
|
|
650
650
|
|
|
651
|
+
### The invoice cross-check
|
|
652
|
+
|
|
653
|
+
The drilling contractor's daywork invoice, day by day, against the daily
|
|
654
|
+
drilling reports and the drilling record, at the contract's terms as the
|
|
655
|
+
operator declares them: hours billed against hours reported, standby billed
|
|
656
|
+
at the operating rate, rig repair past the allowance, a trip or a circulation
|
|
657
|
+
the recorder never saw, a depth or footage overstated, an amount that is not
|
|
658
|
+
quantity times price, a day billed with no report. Each day AGREES, is in
|
|
659
|
+
QUESTION or DIFFERS, with the dollars in question and the line each comes
|
|
660
|
+
from; a client report with its PDF. The **Invoice check** tab, `gea
|
|
661
|
+
invoice-check`, `gea help invoice-check`.
|
|
662
|
+
|
|
651
663
|
### The lateral, the printable reports, the daily summary and the key
|
|
652
664
|
|
|
653
665
|
An earthquake near a well with a directional survey is measured from the
|
|
@@ -609,6 +609,18 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
|
|
|
609
609
|
itself; `gea help seedlink`. A TexNet station is served by EarthScope at
|
|
610
610
|
`rtserve.iris.washington.edu:18000`, network `TX`.
|
|
611
611
|
|
|
612
|
+
### The invoice cross-check
|
|
613
|
+
|
|
614
|
+
The drilling contractor's daywork invoice, day by day, against the daily
|
|
615
|
+
drilling reports and the drilling record, at the contract's terms as the
|
|
616
|
+
operator declares them: hours billed against hours reported, standby billed
|
|
617
|
+
at the operating rate, rig repair past the allowance, a trip or a circulation
|
|
618
|
+
the recorder never saw, a depth or footage overstated, an amount that is not
|
|
619
|
+
quantity times price, a day billed with no report. Each day AGREES, is in
|
|
620
|
+
QUESTION or DIFFERS, with the dollars in question and the line each comes
|
|
621
|
+
from; a client report with its PDF. The **Invoice check** tab, `gea
|
|
622
|
+
invoice-check`, `gea help invoice-check`.
|
|
623
|
+
|
|
612
624
|
### The lateral, the printable reports, the daily summary and the key
|
|
613
625
|
|
|
614
626
|
An earthquake near a well with a directional survey is measured from the
|
|
@@ -590,6 +590,24 @@ def main(argv=None) -> int:
|
|
|
590
590
|
p_dz.add_argument("--actor", type=str, default="cli")
|
|
591
591
|
p_dz.add_argument("--json", action="store_true")
|
|
592
592
|
|
|
593
|
+
p_iv = sub.add_parser("invoice-check", help="the drilling contractor's daywork invoice, day by day, against the daily drilling reports and the drilling record, at the contract's terms")
|
|
594
|
+
p_iv.add_argument("--workspace", type=str, default=None)
|
|
595
|
+
p_iv.add_argument("--well", type=str, default=None)
|
|
596
|
+
p_iv.add_argument("--template", type=str, default=None, choices=["ddr", "invoice"], help="print the headings a file needs")
|
|
597
|
+
p_iv.add_argument("--attach-ddr", type=str, default=None, help="a daily drilling report (CSV)")
|
|
598
|
+
p_iv.add_argument("--attach-invoice", type=str, default=None, help="an invoice (CSV)")
|
|
599
|
+
p_iv.add_argument("--source", type=str, default="", help="with --attach-*: where the file came from")
|
|
600
|
+
p_iv.add_argument("--terms-source", type=str, default=None, help="declare the contract's terms: where they came from")
|
|
601
|
+
p_iv.add_argument("--day-start", type=str, default="06:00")
|
|
602
|
+
p_iv.add_argument("--report-date", type=str, default="start", choices=["start", "end"])
|
|
603
|
+
for k_ in ("operating", "standby", "repair", "moving", "force-majeure"):
|
|
604
|
+
p_iv.add_argument(f"--{k_}", type=float, default=None, help=f"the {k_.replace('-', ' ')} day rate, USD")
|
|
605
|
+
p_iv.add_argument("--repair-hours-job", type=float, default=None)
|
|
606
|
+
p_iv.add_argument("--repair-hours-month", type=float, default=None)
|
|
607
|
+
p_iv.add_argument("--write", action="store_true", help="write the client report")
|
|
608
|
+
p_iv.add_argument("--actor", type=str, default="cli")
|
|
609
|
+
p_iv.add_argument("--json", action="store_true")
|
|
610
|
+
|
|
593
611
|
p_ps = sub.add_parser("pad-summary", help="the daily pad summary: what changed since the last one, what is due, what is still missing - one page, kept in report history; the service writes it each day and sends it through the notification rules")
|
|
594
612
|
p_ps.add_argument("--workspace", type=str, required=True)
|
|
595
613
|
p_ps.add_argument("--send", action="store_true", help="also hand it to the notification rules (the event pad.summary)")
|
|
@@ -2338,6 +2356,46 @@ def main(argv=None) -> int:
|
|
|
2338
2356
|
print(f" {os.path.join(ws.reports_dir, e['path'])}")
|
|
2339
2357
|
print(f" key fingerprint {e['fingerprint']}")
|
|
2340
2358
|
return 0
|
|
2359
|
+
elif a.cmd == "invoice-check":
|
|
2360
|
+
import json as _json
|
|
2361
|
+
from . import invoice_check as _IC
|
|
2362
|
+
from .cli import _safe_stdout
|
|
2363
|
+
from .workspace import Workspace, WorkspaceError
|
|
2364
|
+
_safe_stdout()
|
|
2365
|
+
if a.template:
|
|
2366
|
+
print(_IC.template(a.template), end="")
|
|
2367
|
+
return 0
|
|
2368
|
+
if not a.workspace:
|
|
2369
|
+
raise SystemExit("invoice-check: give --workspace C:\\site (or --template ddr)")
|
|
2370
|
+
try:
|
|
2371
|
+
ws = Workspace(a.workspace)
|
|
2372
|
+
if a.terms_source is not None:
|
|
2373
|
+
t_ = _IC.set_terms(ws, a.actor, a.terms_source, a.day_start, a.report_date,
|
|
2374
|
+
{"operating": a.operating, "standby": a.standby, "repair": a.repair, "moving": a.moving, "force_majeure": a.force_majeure},
|
|
2375
|
+
a.repair_hours_job, a.repair_hours_month)
|
|
2376
|
+
print("terms kept: " + ", ".join(f"{k} {v:,.2f} USD/day" for k, v in t_["rates_usd_per_day"].items()) + f"; report day from {t_['day_start']}")
|
|
2377
|
+
return 0
|
|
2378
|
+
wid = a.well or (ws.wells()[0]["id"] if ws.wells() else None)
|
|
2379
|
+
if wid is None:
|
|
2380
|
+
raise SystemExit("invoice-check: the workspace has no wells")
|
|
2381
|
+
for kind, f_ in (("ddr", a.attach_ddr), ("invoice", a.attach_invoice)):
|
|
2382
|
+
if f_:
|
|
2383
|
+
with open(f_, "rb") as fh:
|
|
2384
|
+
r_ = _IC.attach(ws, a.actor, wid, kind, os.path.basename(f_), fh.read(), a.source)
|
|
2385
|
+
print(f"attached {r_['name']}: {r_['lines']} line(s)" + (f", {len(r_['errors'])} not read" if r_['errors'] else ""))
|
|
2386
|
+
if a.attach_ddr or a.attach_invoice:
|
|
2387
|
+
return 0
|
|
2388
|
+
if a.write:
|
|
2389
|
+
r_ = _IC.write_report(ws, wid, __version__, a.actor)
|
|
2390
|
+
print(f"wrote {r_['report_id']} ({r_['status']}): {r_['paths']['html']}")
|
|
2391
|
+
if r_['paths'].get('pdf'):
|
|
2392
|
+
print(f" printable: {r_['paths']['pdf']}")
|
|
2393
|
+
return 0
|
|
2394
|
+
r = _IC.check(ws, wid)
|
|
2395
|
+
except (KeyError, ValueError, OSError, WorkspaceError) as e:
|
|
2396
|
+
raise SystemExit(f"invoice-check: {e.args[0] if e.args else e}")
|
|
2397
|
+
print(_json.dumps(r, default=str) if a.json else _IC.text(r))
|
|
2398
|
+
return 0
|
|
2341
2399
|
elif a.cmd == "pad-summary":
|
|
2342
2400
|
import json as _json
|
|
2343
2401
|
from . import pad_summary as _PS
|
|
@@ -10610,6 +10610,157 @@ def section_cn_four(tmp: str) -> None:
|
|
|
10610
10610
|
+ (f" [failed: {', '.join(failed5)}]" if failed5 else ""))
|
|
10611
10611
|
|
|
10612
10612
|
|
|
10613
|
+
def section_co_invoice_check(tmp: str) -> None:
|
|
10614
|
+
"""Section CO - the invoice cross-check: the daily drilling report and the invoice read by their headings in
|
|
10615
|
+
whatever order and spelling a form uses, a file that is neither refused with the headings it needs; a labelled
|
|
10616
|
+
scene of five report days with seven planted differences - a day billed twice, repair past the allowance at the
|
|
10617
|
+
operating rate, a trip the record shows never happened, standby billed at the operating rate, a depth and footage
|
|
10618
|
+
overstated, an amount that is not quantity times price, a day billed with no report and nothing on the record -
|
|
10619
|
+
each found with the dollars it puts in question; the same days billed and reported correctly agree; the report
|
|
10620
|
+
with its PDF; the API, the CLI, the tab and the help page."""
|
|
10621
|
+
import http.cookiejar
|
|
10622
|
+
import subprocess as _sp
|
|
10623
|
+
import urllib.request
|
|
10624
|
+
import urllib.error
|
|
10625
|
+
import base64 as _b64
|
|
10626
|
+
from . import __version__
|
|
10627
|
+
from . import client_reports as CR
|
|
10628
|
+
from . import helplib as H
|
|
10629
|
+
from . import invoice_check as IC
|
|
10630
|
+
from . import pdf_report as PDF
|
|
10631
|
+
from .workspace import Workspace
|
|
10632
|
+
from .service import Service, Users
|
|
10633
|
+
pkg = Path(__file__).parent
|
|
10634
|
+
d = Path(tmp, "co"); d.mkdir()
|
|
10635
|
+
|
|
10636
|
+
# -- CO1 reading the files ---------------------------------------------------------------------------------------
|
|
10637
|
+
t_ddr, t_inv = IC.read_ddr(IC.template("ddr")), IC.read_invoice(IC.template("invoice"))
|
|
10638
|
+
odd = IC.read_ddr("Rpt Date;Start Time;End Time;IADC Code;Operations;MD From;MD To\n07/01/2026;0600;1800;2 - Drilling;Drill ahead;9500;10,100\n"
|
|
10639
|
+
"07/01/2026;1800;0600;33;Standby - waiting on orders;10100;10100\nnot a date;0600;0700;2;x;1;2\n")
|
|
10640
|
+
span = IC.read_invoice("Period From,Period To,Charge,Qty,UOM,Rate,Ext Amount\n2026-07-01,2026-07-03,Stand-by rate,3,day,25000,75000\n"
|
|
10641
|
+
"2026-07-04,2026-07-04,Mobilization,1,lot,50000,50000\n")
|
|
10642
|
+
try:
|
|
10643
|
+
IC.read_ddr("Name,Value\na,1\n")
|
|
10644
|
+
refused = ""
|
|
10645
|
+
except ValueError as e:
|
|
10646
|
+
refused = str(e)
|
|
10647
|
+
c1 = {
|
|
10648
|
+
"templates": len(t_ddr["lines"]) == 2 and t_ddr["lines"][0]["code"] == 2 and t_ddr["lines"][1]["hours"] == 12 and len(t_inv["lines"]) == 2
|
|
10649
|
+
and t_inv["lines"][1]["kind"] == "standby" and t_inv["lines"][1]["hours"] == 12,
|
|
10650
|
+
"odd": len(odd["lines"]) == 2 and odd["lines"][0]["date"] == "2026-07-01" and odd["lines"][0]["hours"] == 12 and odd["lines"][1]["hours"] == 12
|
|
10651
|
+
and odd["lines"][0]["depth_to_ft"] == 10100 and odd["lines"][1]["standby"] and len(odd["errors"]) == 1 and "row 4" in odd["errors"][0],
|
|
10652
|
+
"span": span["lines"][0]["kind"] == "standby" and span["lines"][0]["price"] == 25000 and span["lines"][0]["to"] == "2026-07-03" and span["lines"][0]["hours"] == 72
|
|
10653
|
+
and span["lines"][1]["kind"] == "moving",
|
|
10654
|
+
"refused": "Date column" in refused and "--template ddr" in refused,
|
|
10655
|
+
}
|
|
10656
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
10657
|
+
ok(not failed1,
|
|
10658
|
+
"CO1 the files read by their headings: the templates; a semicolon report with its own headings, times without colons, a code with its "
|
|
10659
|
+
"name, a standby line, a row that does not read named and the rest kept; an invoice span of days at a 'Rate' that is a price; a file "
|
|
10660
|
+
"that is neither refused with the headings it needs" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
10661
|
+
|
|
10662
|
+
# -- CO2 the cross-check ---------------------------------------------------------------------------------------------
|
|
10663
|
+
F = IC.selftest_files(str(d))
|
|
10664
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad CO", actor="tester")
|
|
10665
|
+
w = ws.add_well_file(F["edr"], display="INV-1", actor="tester")
|
|
10666
|
+
r_none = IC.check(ws, w["id"])
|
|
10667
|
+
IC.set_terms(ws, "tester", "test daywork contract, Exhibit A", "06:00", "start", {"operating": 30000, "standby": 25000, "repair": 0}, None, 2)
|
|
10668
|
+
r_nofiles = IC.check(ws, w["id"])
|
|
10669
|
+
IC.attach(ws, "tester", w["id"], "ddr", "ddr.csv", F["ddr"].encode(), "test reports")
|
|
10670
|
+
IC.attach(ws, "tester", w["id"], "invoice", "inv.csv", F["invoice"].encode(), "test invoice 1")
|
|
10671
|
+
r = IC.check(ws, w["id"])
|
|
10672
|
+
D = {x["date"]: x for x in r["days"]}
|
|
10673
|
+
fd = lambda dk: {f["check"]: f for f in D[dk]["findings"]}
|
|
10674
|
+
c2 = {
|
|
10675
|
+
"states": r_none["status"] == "NO TERMS" and r_nofiles["status"] == "NO FILES" and r["status"] == "DIFFERS"
|
|
10676
|
+
and [D[k]["status"] for k in sorted(D)] == ["DIFFERS", "DIFFERS", "DIFFERS", "DIFFERS", "QUESTION"],
|
|
10677
|
+
"day1": set(fd("2026-07-01")) == {"OVER 24 H", "BILLED TWICE"} and fd("2026-07-01")["OVER 24 H"]["usd_in_question"] == 30000
|
|
10678
|
+
and abs(D["2026-07-01"]["record"]["drilling_h"] - 18) < 0.2 and D["2026-07-01"]["record"]["quiet_h"] < 0.2,
|
|
10679
|
+
"day2": fd("2026-07-02")["REPAIR OVER ALLOWANCE"]["usd_in_question"] == 2500 and "14:00-16:00" in fd("2026-07-02")["LINE VS RECORD"]["detail"]
|
|
10680
|
+
and fd("2026-07-02")["LINE VS RECORD"]["ref"] == "ddr.csv row 6" and "DRILLING HOURS" not in fd("2026-07-02"),
|
|
10681
|
+
"day3": abs(fd("2026-07-03")["STANDBY AT OPERATING"]["usd_in_question"] - 4166.67) < 0.01 and fd("2026-07-03")["QUIET ON THE RECORD"]["severity"] == "QUESTION",
|
|
10682
|
+
"day4": fd("2026-07-04")["ARITHMETIC"]["usd_in_question"] == 1000 and "7,600" in fd("2026-07-04")["DEPTH"]["detail"] and "1,200" in fd("2026-07-04")["FOOTAGE"]["detail"],
|
|
10683
|
+
"day5": set(fd("2026-07-05")) == {"NO REPORT", "NOT IN THE RECORD"},
|
|
10684
|
+
"totals": r["totals"]["usd_in_question"] == 37666.67 and r["totals"]["billed_checked_usd"] == 181000 and r["totals"]["billed_usd"] == 185200
|
|
10685
|
+
and [x["description"] for x in r["other_lines"]] == ["Fuel (diesel)"] and set(r["record"]["channels"]) == {"drilling flag", "pump output", "rotary", "bit depth"},
|
|
10686
|
+
}
|
|
10687
|
+
# the same days billed and reported as they happened
|
|
10688
|
+
ws2 = Workspace.create(str(d / "ws2"), "Pad CO2", actor="tester")
|
|
10689
|
+
w2 = ws2.add_well_file(F["edr"], display="INV-2", actor="tester")
|
|
10690
|
+
IC.set_terms(ws2, "tester", "test daywork contract", "06:00", "start", {"operating": 30000, "standby": 25000, "repair": 0}, None, 2)
|
|
10691
|
+
ddr_ok = F["ddr"].replace("2026-07-02,14:00,16:00,2,6,Trip out", "2026-07-02,14:00,16:00,2,7,Service rig").replace("6200,7600", "6200,7400")
|
|
10692
|
+
inv_ok = ("Date,Rate Type,Quantity,Unit,Unit Price,Amount\n2026-07-01,Operating day rate,1,day,30000,30000\n"
|
|
10693
|
+
"2026-07-02,Operating day rate,22,hour,1250,27500\n2026-07-02,Repair rate,2,hour,0,0\n"
|
|
10694
|
+
"2026-07-03,Standby rate,20,hour,1041.6667,20833.33\n2026-07-03,Operating day rate,4,hour,1250,5000\n2026-07-04,Operating day rate,1,day,30000,30000\n")
|
|
10695
|
+
IC.attach(ws2, "tester", w2["id"], "ddr", "ddr.csv", ddr_ok.encode(), "test reports")
|
|
10696
|
+
IC.attach(ws2, "tester", w2["id"], "invoice", "inv.csv", inv_ok.encode(), "test invoice 2")
|
|
10697
|
+
r2 = IC.check(ws2, w2["id"])
|
|
10698
|
+
c2["clean"] = r2["status"] == "AGREES" and r2["totals"]["agrees"] == 4 and r2["totals"]["usd_in_question"] == 0 and r2["findings"] == []
|
|
10699
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
10700
|
+
ok(not failed2,
|
|
10701
|
+
"CO2 the cross-check: no terms, then no files, said so; five report days against the record - a day billed twice, 2 h of repair past "
|
|
10702
|
+
"a 2 h allowance at the operating rate (2,500.00), a trip the record shows never moved, 20 h of standby billed at the operating rate "
|
|
10703
|
+
"(4,166.67) with the quiet hours a question, an overstated depth and footage, an amount 1,000.00 over quantity times price, a day "
|
|
10704
|
+
"billed with no report and nothing on the record; 37,666.67 in question; the fuel listed, not checked; the same days billed and "
|
|
10705
|
+
"reported as they happened agree, the standby hours explaining the quiet" + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
10706
|
+
|
|
10707
|
+
# -- CO3 the report, the API, the CLI, the tab, the help -----------------------------------------------------------
|
|
10708
|
+
rep = IC.write_report(ws, w["id"], __version__, "tester")
|
|
10709
|
+
rd = PDF.read(Path(rep["paths"]["pdf"]).read_bytes())
|
|
10710
|
+
html_ = Path(rep["paths"]["html"]).read_text(encoding="utf-8")
|
|
10711
|
+
Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
|
|
10712
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
10713
|
+
base_url = svc.url.rstrip("/")
|
|
10714
|
+
|
|
10715
|
+
def opener(name, pw_):
|
|
10716
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
10717
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
10718
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
10719
|
+
return o
|
|
10720
|
+
|
|
10721
|
+
def call(o, method, path, body=None):
|
|
10722
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
10723
|
+
if method == "POST":
|
|
10724
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
10725
|
+
try:
|
|
10726
|
+
with o.open(rq, timeout=120) as rr_:
|
|
10727
|
+
return rr_.status, json.loads(rr_.read())
|
|
10728
|
+
except urllib.error.HTTPError as e:
|
|
10729
|
+
return e.code, json.loads(e.read())
|
|
10730
|
+
try:
|
|
10731
|
+
V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
10732
|
+
s_g, gj = call(V, "GET", "/api/invoice-check?well=" + w["id"])
|
|
10733
|
+
s_bad, _ = call(V, "GET", "/api/invoice-check?well=nope")
|
|
10734
|
+
s_vt, _ = call(V, "POST", "/api/invoice-check/terms", {"source": "x", "operating": 1})
|
|
10735
|
+
s_ot, otj = call(O, "POST", "/api/invoice-check/terms", {"source": "contract B", "day_start": "06:00", "operating": 30000, "standby": 25000, "repair": 0, "repair_hours_per_month": 2})
|
|
10736
|
+
s_ob, _ = call(O, "POST", "/api/invoice-check/terms", {"source": "contract B", "day_start": "6am", "operating": 30000})
|
|
10737
|
+
s_oa, oaj = call(O, "POST", "/api/invoice-check/attach", {"well_id": w["id"], "kind": "invoice", "filename": "inv2.csv", "source": "invoice 2",
|
|
10738
|
+
"content_b64": _b64.b64encode(IC.template("invoice").encode()).decode()})
|
|
10739
|
+
s_ow, owj = call(O, "POST", "/api/invoice-check/write", {"well_id": w["id"]})
|
|
10740
|
+
s_or, _ = call(O, "POST", "/api/invoice-check/remove", {"file": oaj.get("file", "")})
|
|
10741
|
+
finally:
|
|
10742
|
+
svc.stop()
|
|
10743
|
+
cli_t = _sp.run([sys.executable, "-m", "gea", "invoice-check", "--template", "invoice"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
10744
|
+
cli_c = _sp.run([sys.executable, "-m", "gea", "invoice-check", "--workspace", wsp, "--well", w["id"]], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
10745
|
+
cli_w = _sp.run([sys.executable, "-m", "gea", "invoice-check", "--workspace", wsp, "--well", w["id"], "--write"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
10746
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
10747
|
+
c3 = {
|
|
10748
|
+
"report": rd["ok"] and rep["status"] == "DIFFERS" and "Invoice cross-check - INV-1" in rd["text"][0] and "37,666.67" in html_ and "REPAIR OVER ALLOWANCE" in html_
|
|
10749
|
+
and not CR.forbidden_terms(html_),
|
|
10750
|
+
"api": s_g == 200 and gj["check"]["totals"]["usd_in_question"] == 37666.67 and s_bad == 404 and s_vt == 403 and s_ot == 200 and otj["source"] == "contract B"
|
|
10751
|
+
and s_ob == 400 and s_oa == 200 and oaj["lines"] == 2 and s_ow == 200 and owj["report_id"].startswith("INV-") and s_or == 200,
|
|
10752
|
+
"cli": cli_t.returncode == 0 and "Rate Type" in cli_t.stdout and cli_c.returncode == 0 and "REPAIR OVER ALLOWANCE" in cli_c.stdout and "37,666.67" in cli_c.stdout
|
|
10753
|
+
and cli_w.returncode == 0 and "printable:" in cli_w.stdout,
|
|
10754
|
+
"page": all(x in page_src for x in ("VIEWS.invoices", "['#/invoices', 'Invoice check']", "/api/invoice-check/attach", "ivTerms")),
|
|
10755
|
+
"help": any(t[0] == "invoice-check" for t in H.INDEX) and not H.check("invoice-check") and H.VIEW_TOPIC.get("invoices") == "invoice-check",
|
|
10756
|
+
}
|
|
10757
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
10758
|
+
ok(not failed3,
|
|
10759
|
+
"CO3 the report (with its PDF) and the check on the API (anyone signed in reads it; only an operator declares terms, attaches, "
|
|
10760
|
+
"removes or writes; a start hour that is not one refused), the CLI (a template, the check, the report written), the tab and the help page"
|
|
10761
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
10762
|
+
|
|
10763
|
+
|
|
10613
10764
|
def main() -> int:
|
|
10614
10765
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
10615
10766
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -10705,6 +10856,7 @@ def main() -> int:
|
|
|
10705
10856
|
section_cl_history_and_dossier(tmp)
|
|
10706
10857
|
section_cm_watch_and_alerts(tmp)
|
|
10707
10858
|
section_cn_four(tmp)
|
|
10859
|
+
section_co_invoice_check(tmp)
|
|
10708
10860
|
if _FAILS:
|
|
10709
10861
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
10710
10862
|
for f in _FAILS:
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# The invoice cross-check
|
|
2
|
+
|
|
3
|
+
> The drilling contractor's daywork invoice, day by day, against the daily drilling reports and the drilling record, at the contract's terms as the operator declares them: each day AGREES, is in QUESTION, or DIFFERS, with the dollars each difference puts in question and the line it comes from.
|
|
4
|
+
|
|
5
|
+
**The command**: the **Invoice check** tab. Choose the well; declare the contract's terms once (where they came from, the hour the report day starts on the rig's clock and whether a report is dated by the day it starts or ends, the day rates - operating, and standby, repair, moving and force majeure where the contract has them - and the repair allowance in hours a job and a month); attach the daily drilling reports and the invoice as CSV files, each with its source. **Write the report** writes the client report with its PDF. From a terminal: `gea invoice-check --workspace C:\site --well W` prints the check; `--terms-source "..." --day-start 06:00 --operating 30000 --standby 25000 --repair 0 --repair-hours-month 24` declares the terms; `--attach-ddr FILE --source "..."` and `--attach-invoice FILE --source "..."` attach; `--write` writes the report; `--template ddr` or `--template invoice` prints the headings it reads.
|
|
6
|
+
|
|
7
|
+
**The files**: saved from a spreadsheet as CSV and read by their headings. A daily drilling report: one row per line of the time breakdown - Date (the report's), Hours (or From and To), Code (the IADC operation code) or Activity, and Depth From and Depth To where it has them. An invoice: one row per charge - Date (or From and To for a span), Rate Type (operating, standby, repair, moving, force majeure; anything else - fuel, rentals - is listed and not checked), Quantity, Unit (day or hour), and Unit Price or Amount.
|
|
8
|
+
|
|
9
|
+
**The checks**: the report's lines add up to 24 hours; hours reported drilling (code 2) against the record's hours on bottom making hole; the day's end depth and footage against the record's; a line coded drilling, reaming, circulating or trips over a span the record shows the pumps off, the rotary still and the bit still; a repair line over a span the record shows the rig working; more than 24 hours billed in a day, a day billed twice, billed with no report or nothing in the record; standby hours (code 33, or an activity that says standby or waiting on the operator's orders) billed at the operating rate; rig repair (code 8) past the allowance billed at the operating rate (IADC daywork contract, paragraph 4.4); a unit price that is not the contract's rate for its kind; quantity times price that is not the amount; and, as a question, a day billed at the operating rate on which the record shows the rig quiet six hours or more beyond the hours billed at standby, repair or force majeure.
|
|
10
|
+
|
|
11
|
+
**What it writes**: the files and their index in `economics\invoices\`, the terms in `economics\invoices\terms.json`, the audit lines `invoice.terms`, `invoice.attach`, `invoice.remove`, `report.invoice_check`, and the report in `reports\wells\<well>\invoice_check.*` (PDF, HTML, markdown, JSON), kept in report history.
|
|
12
|
+
|
|
13
|
+
**The number to check**: a day's dollars in question against its finding - the hours times the difference between the two rates, over 24; the record's hours against the well's charts for the same report day.
|
|
14
|
+
|
|
15
|
+
**What this page will not call a measurement**: what is owed - the contract and the parties decide; this sets three accounts side by side at the terms as declared. The clocks - the report's and the recorder's are taken to be the rig's same clock. Quiet time on the recorder - waiting on cement, rigging up and repairs within the allowance are operating time with the pumps off, so quiet is a question, not a difference. A charge that is not a day rate.
|
|
@@ -54,6 +54,7 @@ INDEX: List[tuple] = [
|
|
|
54
54
|
('report-history', 'Report history', 'every version of every client report kept in a dated folder with its SHA-256, when the next one replaces it'),
|
|
55
55
|
('pad-summary', 'The daily pad summary', 'one page each morning - what changed since the last one, what is due, what is still missing - kept in report history and sent through the notification rules'),
|
|
56
56
|
('dossier', 'The signed dossier', "a well's or the pad's reports, declarations, audit log and source hashes in one zip signed with the site's Ed25519 key, with a checker anyone can run without GEA"),
|
|
57
|
+
('invoice-check', 'The invoice cross-check', "the drilling contractor's daywork invoice, day by day, against the daily drilling reports and the drilling record at the contract's terms: hours, rates, standby, the repair allowance, depth and footage, with the dollars each difference puts in question"),
|
|
57
58
|
('economics', 'Economics', 'each well\'s days, footage and cost by the operator\'s own declared rates, against the EIA oil and gas spot prices while it was drilled, and any series the site imports'),
|
|
58
59
|
('well3d', 'The well in 3D', 'each well\'s path from its directional survey, set among the mapped formation surfaces and contours with its picks, coloured by what was measured along it, and the drill string replayed from the record; the Volve field shipped as the worked example'),
|
|
59
60
|
('charts', 'The charts', 'a well\'s channels stacked on one axis with a linked cursor, zoom and pan from every sample, time or depth for a drilling recorder, the depth events marked, and the drilling progress of every well'),
|
|
@@ -84,7 +85,7 @@ REQUIRED_LINES = ('**The command**', '**What it writes**', '**The number to chec
|
|
|
84
85
|
VIEW_TOPIC: Dict[str, str] = {
|
|
85
86
|
'home': 'start', 'wells': 'data-in', 'well': 'drift', 'live': 'patches', 'patch': 'patches', 'files': 'files', 'alarms': 'alarms',
|
|
86
87
|
'approvals': 'well-tests', 'config': 'site', 'reports': 'drift', 'verify': 'start', 'survey': 'data-in', 'jobs': 'site',
|
|
87
|
-
'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
|
|
88
|
+
'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'invoices': 'invoice-check', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
|