/************************************************************************ MeOS - Orienteering Software Copyright (C) 2009-2017 Melin Software HB This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Melin Software HB - software@melin.nu - www.melin.nu Eksoppsvägen 16, SE-75646 UPPSALA, Sweden ************************************************************************/ #pragma once #include #include #include class oEvent; class xmlobject; typedef vector xmlList; class xmlparser; class gdioutput; class oRunner; class oClub; class oTeam; class oCourse; class oControl; class oClass; class oDataInterface; class oDataConstInterface; class oAbstractRunner; struct RunnerWDBEntry; class RunnerDB; typedef oRunner * pRunner; typedef oClass * pClass; typedef oClub * pClub; typedef oTeam * pTeam; typedef oCourse *pCourse; class IOF30Interface { oEvent &oe; int cachedStageNumber; int entrySourceId; bool splitLateFee; bool useGMT; // Use GMT when exporting // Export teams as individual bool teamsAsIndividual; // Unroll course loops bool unrollLoops; // Include data on stage number bool includeStageRaceInfo; void operator=(const IOF30Interface &); struct LegInfo { int maxRunners; int minRunners; LegInfo() : maxRunners(1), minRunners(1) {} void setMinRunners(int nr) {minRunners = max(minRunners, nr); maxRunners = max(maxRunners, nr);} void setMaxRunners(int nr) {maxRunners = max(maxRunners, nr);} }; struct FeeInfo { double fee; double taxable; double percentage; // Eventor / OLA stupidity wstring currency; wstring fromTime; wstring toTime; wstring fromBirthDate; wstring toBirthDate; bool includes(const FeeInfo &fo) const { if (toBirthDate != fo.toBirthDate || fromBirthDate != fo.fromBirthDate) return false; if (!includeFrom(fromTime, fo.fromTime)) return false; if (!includeTo(toTime, fo.toTime)) return false; /*if (!includeFrom(fromBirthDate, fo.fromBirthDate)) return false; if (!includeTo(toBirthDate, fo.toBirthDate)) return false;*/ return true; } void add(FeeInfo &fi); wstring getDateKey() const {return fromTime + L" - " + toTime;} FeeInfo() : fee(0), taxable(0), percentage(0) {} const bool operator<(const FeeInfo &fi) const { return fee < fi.fee || (fee == fi.fee && taxable < fi.taxable); } private: bool includeFrom(const wstring &a, const wstring &b) const { if ( a > b || (b.empty() && !a.empty()) ) return false; return true; } bool includeTo(const wstring &a, const wstring &b) const { if ( (!a.empty() && a < b) || (b.empty() && !a.empty()) ) return false; return true; } }; struct FeeStatistics { double fee; double lateFactor; }; vector feeStatistics; static void getAgeLevels(const vector &fees, const vector &ix, int &normalIx, int &redIx, wstring &youthLimit, wstring &seniorLimit); bool matchStageFilter(const set &stageFilter, const xmlList &races); void readEvent(gdioutput &gdi, const xmlobject &xo, map > &teamClassConfig); pRunner readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam team, const map > &teamClassConfig, const set &stageFilter, map > > &personId2TeamLeg); pRunner readPerson(gdioutput &gdi, const xmlobject &xo); pClub readOrganization(gdioutput &gdi, const xmlobject &xo, bool saveToDB); pClass readClass(const xmlobject &xo, map > &teamClassConfig); pTeam readTeamEntry(gdioutput &gdi, xmlobject &xTeam, const set &stageFilter, map > &bibPatterns, const map > &teamClassConfig, map > > &personId2TeamLeg); pRunner readPersonStart(gdioutput &gdi, pClass pc, xmlobject &xo, pTeam team, const map > &teamClassConfig); pTeam readTeamStart(gdioutput &gdi, pClass pc, xmlobject &xTeam, map > &bibPatterns, const map > &teamClassConfig); pTeam getCreateTeam(gdioutput &gdi, const xmlobject &xTeam, bool &newTeam); static int getIndexFromLegPos(int leg, int legorder, const vector &setup); void prescanEntry(xmlobject & xo, set& stages); void setupClassConfig(int classId, const xmlobject &xTeam, map > &teamClassConfig); void setupRelayClasses(const map > &teamClassConfig); void setupRelayClass(pClass pc, const vector &teamClassConfig); int parseISO8601Time(const xmlobject &xo); wstring getCurrentTime() const; static void getNationality(const xmlobject &xCountry, oDataInterface &di); static void getAmount(const xmlobject &xAmount, double &amount, wstring ¤cy); static void getAssignedFee(const xmlobject &xFee, double &fee, double &paid, double &taxable, double &percentage, wstring ¤cy); static void getFee(const xmlobject &xFee, FeeInfo &fee); static void getFeeAmounts(const xmlobject &xFee, double &fee, double &taxable, double &percentage, wstring ¤cy); void writeFees(xmlparser &xml, const oRunner &r) const; void writeAmount(xmlparser &xml, const char *tag, int amount) const; void writeAssignedFee(xmlparser &xml, const oAbstractRunner &tr, int paidForCard) const; void writeRentalCardService(xmlparser &xml, int cardFee, bool paid) const; void getProps(vector &props) const; void writeClassResult(xmlparser &xml, const oClass &c, const vector &r, const vector &t); void writeClass(xmlparser &xml, const oClass &c); void writeCourse(xmlparser &xml, const oCourse &c); void writePersonResult(xmlparser &xml, const oRunner &r, bool includeCourse, bool teamMember, bool hasInputTime); void writeTeamResult(xmlparser &xml, const oTeam &t, bool hasInputTime); void writeResult(xmlparser &xml, const oRunner &rPerson, const oRunner &rResultCarrier, bool includeCourse, bool includeRaceNumber, bool teamMember, bool hasInputTime); void writePerson(xmlparser &xml, const oRunner &r); void writeClub(xmlparser &xml, const oClub &c, bool writeExtended) const; void getRunnersToUse(const pClass cls, vector &rToUse, vector &tToUse, int leg, bool includeUnknown) const; void writeClassStartList(xmlparser &xml, const oClass &c, const vector &r, const vector &t); void writePersonStart(xmlparser &xml, const oRunner &r, bool includeCourse, bool teamMember); void writeTeamStart(xmlparser &xml, const oTeam &t); void writeStart(xmlparser &xml, const oRunner &r, bool includeCourse, bool includeRaceNumber, bool teamMember); pCourse haveSameCourse(const vector &r) const; void writeLegOrder(xmlparser &xml, const oRunner &r) const; // Returns zero if no stage number int getStageNumber(); bool readXMLCompetitorDB(const xmlobject &xCompetitor); void writeXMLCompetitorDB(xmlparser &xml, const RunnerWDBEntry &rde) const; int getStartIndex(const wstring &startId); bool readControl(const xmlobject &xControl); pCourse readCourse(const xmlobject &xcrs); void readCourseGroups(xmlobject xClassCourse, vector< vector > &crs); void bindClassCourse(oClass &pc, const vector< vector > &crs); static wstring constructCourseName(const xmlobject &xcrs); static wstring constructCourseName(const wstring &family, const wstring &name); void classAssignmentObsolete(gdioutput &gdi, xmlList &xAssignment, const map &courses, const map > &coursesFamilies); void classCourseAssignment(gdioutput &gdi, xmlList &xAssignment, const map &courses, const map > &coursesFamilies); void personCourseAssignment(gdioutput &gdi, xmlList &xAssignment, const map &courses); void teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment, const map &courses); void assignTeamCourse(gdioutput &gdi, oTeam &t, xmlList &xAssignment, const map &courses); pCourse findCourse(gdioutput &gdi, const map &courses, xmlobject &xPAssignment); wstring writeControl(xmlparser &xml, const oControl &c, set &writtenId); void writeCourseInfo(xmlparser &xml, const oCourse &c); void writeFullCourse(xmlparser &xml, const oCourse &c, const map &ctrlId2ExportId); public: IOF30Interface(oEvent *oe, bool forceSplitFee); virtual ~IOF30Interface() {} void readEventList(gdioutput &gdi, xmlobject &xo); /** Scan the entry list to find specification of stage numbers*/ void prescanEntryList(xmlobject & xo, set& definedStages); void readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNonexisting, const set &stageFilter, int &entRead, int &entFail, int &entRemoved); void readStartList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail); void readClassList(gdioutput &gdi, xmlobject &xo, int &entRead, int &entFail); void readCompetitorList(gdioutput &gdi, const xmlobject &xo, int &personCount); void readClubList(gdioutput &gdi, const xmlobject &xo, int &clubCount); void readCourseData(gdioutput &gdi, const xmlobject &xo, bool updateClasses, int &courseCount, int &entFail); void writeResultList(xmlparser &xml, const set &classes, int leg, bool useUTC, bool teamsAsIndividual, bool unrollLoops, bool includeStageInfo); void writeStartList(xmlparser &xml, const set &classes, bool useUTC, bool teamsAsIndividual, bool includeStageInfo); void writeEvent(xmlparser &xml); void writeCourses(xmlparser &xml); void writeRunnerDB(const RunnerDB &db, xmlparser &xml) const; void writeClubDB(const RunnerDB &db, xmlparser &xml) const; };