Erweitere VoTiAn NG um Auftrags-, Stamm- und Verwaltungsfunktionen
Ergänzt Auftragserfassung und -bearbeitung, Unternehmerbelege, Stornos, Lagerkorrekturen, Stammdaten, Abrechnung, CRM, Formulare, Berichte und Preisverwaltung auf Basis der aktuellen PHP-Anwendung. Enthält Integrations- und Oberflächentests sowie dokumentierte Abgleiche und Prüfstände.
This commit is contained in:
1 parent
42c87282ee
commit
363bc27c26
190 files changed
+14815
-1857
No files matched your search
@@ -0,0 +1,47 @@
|
||||
package de.stadtbote.votian;
|
||||
import de.stadtbote.votian.database.DatabaseService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.*;
|
||||
import java.time.*;
|
||||
import java.time.format.*;
|
||||
import static de.stadtbote.votian.AdminSupport.*;
|
||||
import static de.stadtbote.votian.LegacyMapping.*;
|
||||
import static de.stadtbote.votian.OrderEntryService.fields;
|
||||
import static de.stadtbote.votian.CrmScope.marks;
|
||||
|
||||
/** Category 15, matching the PHP Bewertung form and its persisted value formats. */
|
||||
@Service
|
||||
class EvaluationService extends MetafieldRecords {
|
||||
static final DateTimeFormatter DATE=DateTimeFormatter.ofPattern("dd.MM.uuuu").withResolverStyle(ResolverStyle.STRICT);
|
||||
EvaluationService(DatabaseService db,FormAdministration forms,MessageAdministration messages){super(db,forms,messages,15);}
|
||||
void access(LegacyUser u){u.require(0);u.require(8);}
|
||||
Map<String,Object> options(LegacyUser u){return fields("headquarters",headquarters(u),"currentHeadquarters",u.headquartersId());}
|
||||
List<Map<String,Object>> lookup(LegacyUser u,long hq,String kind,String q){checked(u,hq);if(q==null)q="";if(q.length()>100)throw bad("Suchbegriff ist zu lang.");String search="%"+q.replace("\\","\\\\").replace("%","\\%").replace("_","\\_")+"%";
|
||||
return switch(kind){
|
||||
case "customer" -> db.queryForList("SELECT cs.cs_id AS id,cs.cs_eid AS value,CONCAT_WS(' · ',cs.cs_eid,cmp.cmp_comp,cmp.cmp_comp2) AS label FROM customer cs JOIN company cmp ON cmp.cmp_id=cs.cmp_id WHERE cs.hq_id=? AND (cs.cs_eid LIKE ? OR cmp.cmp_comp LIKE ?) ORDER BY cs.cs_eid LIMIT 100",hq,search,search);
|
||||
case "courier" -> {u.require(1);yield db.queryForList("SELECT cr.cr_id AS id,cr.cr_eid AS value,CONCAT_WS(' · ',cr.cr_eid,cmp.cmp_comp) AS label FROM courier cr JOIN company cmp ON cmp.cmp_id=cr.cmp_id WHERE cr.hq_id=? AND (cr.cr_eid LIKE ? OR cmp.cmp_comp LIKE ?) ORDER BY cr.cr_eid LIMIT 100",hq,search,search);}
|
||||
case "vehicle" -> {u.require(1);yield db.queryForList("SELECT cv.crvh_id AS id,cv.crvh_sid AS value,cv.crvh_sid AS label FROM couriervehicle cv JOIN courier cr ON cr.cr_id=cv.cr_id WHERE cr.hq_id=? AND cv.crvh_sid LIKE ? ORDER BY cv.crvh_sid LIMIT 100",hq,search);}
|
||||
case "vehicleType" -> db.queryForList("SELECT mt_sort AS id,mt_sort AS value,mt_value AS label FROM metatype WHERE mt_type='vehicletype' ORDER BY mt_sort");
|
||||
case "group" -> {var hqs=headquarters(u).stream().map(r->id(r,"id")).toList();var args=new ArrayList<Object>(List.of(mandator(db,u)));args.addAll(hqs);args.add(search);yield db.queryForList("SELECT grp_id AS id,grp_id AS value,grp_name AS label FROM groups WHERE md_id=? AND (hq_id=0 OR hq_id IN ("+marks(hqs.size())+")) AND grp_name LIKE ? ORDER BY grp_name LIMIT 100",args.toArray());}
|
||||
case "branch" -> db.queryForList("SELECT br_id AS id,br_id AS value,br_name AS label FROM branch WHERE br_name LIKE ? ORDER BY br_name LIMIT 100",search);
|
||||
default -> throw bad("Unbekannte Bewertungsauswahl.");
|
||||
};
|
||||
}
|
||||
String validateValue(LegacyUser u,long hq,Map<String,Object> def,String value){String type=text(def,"type"),v=value.strip();if(v.isEmpty())return "";switch(type){
|
||||
case "date_begin","date_end","date" -> {parseDate(v);return v;}
|
||||
case "checkboxes_hq" -> {if(!v.matches("[0-9]+(,[0-9]+)*"))throw bad("Ungültige Niederlassungsauswahl.");var allowed=headquarters(u).stream().map(r->Long.toString(id(r,"id"))).toList();var requested=Arrays.stream(v.split(",")).distinct().toList();if(!allowed.containsAll(requested))throw bad("Niederlassung nicht freigegeben.");return String.join(",",requested);}
|
||||
case "button:cs:cs_eid" -> {one(db.queryForList("SELECT cs_id FROM customer WHERE hq_id=? AND cs_eid=?",hq,v));return v;}
|
||||
case "button:cr:cr_eid" -> {u.require(1);one(db.queryForList("SELECT cr_id FROM courier WHERE hq_id=? AND cr_eid=?",hq,v));return v;}
|
||||
case "select:crvh:crvh_sid" -> {u.require(1);if(db.queryForList("SELECT cv.crvh_id FROM couriervehicle cv JOIN courier cr ON cr.cr_id=cv.cr_id WHERE cr.hq_id=? AND cv.crvh_sid=?",hq,v).isEmpty())throw bad("Fahrzeug nicht gefunden.");return v;}
|
||||
case "select:vht" -> {one(db.queryForList("SELECT mt_sort FROM metatype WHERE mt_type='vehicletype' AND mt_sort=?",number(v)));return v;}
|
||||
case "select:grp" -> {var hqs=headquarters(u).stream().map(r->id(r,"id")).toList();var args=new ArrayList<Object>(List.of(number(v),mandator(db,u)));args.addAll(hqs);one(db.queryForList("SELECT grp_id FROM groups WHERE grp_id=? AND md_id=? AND (hq_id=0 OR hq_id IN ("+marks(hqs.size())+"))",args.toArray()));return v;}
|
||||
case "select:br" -> {one(db.queryForList("SELECT br_id FROM branch WHERE br_id=?",number(v)));return v;}
|
||||
default -> throw bad(text(def,"label")+": Nicht unterstützter Bewertungsfeldtyp.");
|
||||
}}
|
||||
static long number(String v){try{long n=Long.parseLong(v);if(n<0)throw new NumberFormatException();return n;}catch(NumberFormatException e){throw bad("Ungültiger Auswahlwert.");}}
|
||||
static LocalDate parseDate(String v){try{return LocalDate.parse(v,DATE);}catch(DateTimeParseException e){throw bad("Ungültiges Datum (TT.MM.JJJJ).");}}
|
||||
void validateValues(List<Map<String,Object>> defs,Map<Long,String> values){LocalDate begin=null,end=null;for(var d:defs){String v=values.get(id(d,"id"));if(v==null||v.isBlank())continue;if(text(d,"type").equals("date_begin"))begin=parseDate(v);if(text(d,"type").equals("date_end"))end=parseDate(v);}if(begin!=null&&end!=null&&end.isBefore(begin))throw bad("Das Enddatum liegt vor dem Beginn.");}
|
||||
@Override Map<String,Object> rendering(LegacyUser u,long hq,long object){var result=super.rendering(u,hq,object);var data=new LinkedHashMap<>((Map<String,Object>)result.get("data"));var values=new LinkedHashMap<>((Map<Long,String>)data.get("values"));var defs=(List<Map<String,Object>>)result.get("definitions");for(var def:defs){long field=id(def,"id");String type=text(def,"type"),v=values.getOrDefault(field,"");if(v.isBlank())continue;if(type.equals("checkboxes_hq")){var names=headquarters(u).stream().collect(java.util.stream.Collectors.toMap(r->Long.toString(id(r,"id")),r->text(r,"label")));values.put(field,Arrays.stream(v.split(",")).map(x->names.getOrDefault(x,x)).collect(java.util.stream.Collectors.joining(", ")));}}
|
||||
data.put("values",values);result.put("data",data);return result;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user