Erweitere VoTiAn NG um Fachfunktionen und verbessere die Listenoberfläche
Ergänze Auftragsbearbeitung, Disposition, Stammdaten, Kunden- und Transporteurportale, Lagerverwaltung, Abrechnung, Exporte und Statistik. Füge Kontoeinstellungen, Mitteilungen, Automatikdienste und Betriebsstatus sowie die zugehörigen Tests und PHP-Abgleichsdokumentation hinzu. Vergrößere die persönlichen Auftragslisten auf einheitliche Höhen und richte Statusanzeigen sowie die Ranking-Vorschau-Steuerelemente bündig aus. Validierung: 44 Frontendtests und Produktionsbuild erfolgreich. Backend funktional unverändert gegenüber dem vollständigen Lauf mit 1.624 erfolgreichen und drei übersprungenen Tests. Layout im Browser und lokale Bereitstellung geprüft.
This commit is contained in:
1 parent
363bc27c26
commit
781a2b82dc
1165 files changed
+74986
-1028
No files matched your search
@@ -0,0 +1,45 @@
|
||||
package de.stadtbote.votian;
|
||||
|
||||
import de.stadtbote.votian.database.DatabaseService;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.time.*;
|
||||
import java.util.*;
|
||||
import static de.stadtbote.votian.AdminSupport.*;
|
||||
import static de.stadtbote.votian.LegacyMapping.*;
|
||||
import static de.stadtbote.votian.OrderEntryService.fields;
|
||||
|
||||
/** The standard PHP rollcard within the courier's released vehicle/day/job scope. */
|
||||
@RestController
|
||||
@RequestMapping("/api/courier-portal/disposition/rollcard")
|
||||
class CourierDispositionRollcard {
|
||||
final DatabaseService db;final BusinessSupport support;
|
||||
CourierDispositionRollcard(DatabaseService db,BusinessSupport support){this.db=db;this.support=support;}
|
||||
@GetMapping Map<String,Object> get(Authentication a,@RequestParam long vehicle,@RequestParam LocalDate day,@RequestParam(defaultValue="ALL") String selection){return view(ApiController.user(a),vehicle,day,selection);}
|
||||
@GetMapping("/pdf") org.springframework.http.ResponseEntity<byte[]> pdf(Authentication a,@RequestParam long vehicle,@RequestParam LocalDate day,@RequestParam(defaultValue="ALL") String selection,@RequestParam String revision){
|
||||
var data=view(ApiController.user(a),vehicle,day,selection);if(!Objects.equals(data.get("revision"),revision))throw VehicleDisposition.conflict();
|
||||
return org.springframework.http.ResponseEntity.ok().header("Cache-Control","no-store").header("Content-Disposition","attachment; filename=Rollkarte-"+vehicle+"-"+day+".pdf").contentType(org.springframework.http.MediaType.APPLICATION_PDF).body(VehicleRollcardPdf.create(data));
|
||||
}
|
||||
@SuppressWarnings("unchecked") Map<String,Object> view(LegacyUser u,long vehicle,LocalDate day,String selection){return db.readTransaction(()->{
|
||||
if(vehicle<=0)throw bad("Fahrzeug fehlt.");VehicleDisposition.date(day);if(selection==null||!Set.of("ALL","RESERVED","ACCEPTED").contains(selection))throw bad("Ungültige Rollkartenauswahl.");
|
||||
var board=new CourierDisposition(db,support);long courier=board.courier(u);var scope=board.view(u,day,0,vehicle);var vehicles=(List<Map<String,Object>>)scope.get("rows");if(vehicles.size()!=1)throw CourierPortal.denied();var row=vehicles.getFirst();
|
||||
var allowed=((List<Map<String,Object>>)row.get("jobs")).stream().map(j->id(j,"id")).toList();
|
||||
var jobs=List.<Map<String,Object>>of();
|
||||
if(!allowed.isEmpty()){
|
||||
String reserved="(j.jb_status IN (9,0) AND j.jb_offer=0 AND EXISTS (SELECT 1 FROM vehicledisposition d WHERE d.crvh_id=? AND d.jb_id=j.jb_id AND d.vhd_timeslot>=? AND d.vhd_timeslot<?))";
|
||||
String accepted="(j.jb_status=1 AND j.jb_ordertime>=? AND j.jb_ordertime<? AND EXISTS (SELECT 1 FROM courier c WHERE c.cr_id=j.cr_id AND c.cr_sid=? AND c.cr_sid<>''))";
|
||||
var args=new ArrayList<Object>(allowed);args.add(mandator(db,u));String clause;
|
||||
if(selection.equals("RESERVED")){clause=reserved;args.addAll(List.of(vehicle,day.toString(),day.plusDays(1).toString()));}
|
||||
else if(selection.equals("ACCEPTED")){clause=accepted;args.addAll(List.of(day,day.plusDays(1),text(row,"sid")));}
|
||||
else {clause="("+reserved+" OR "+accepted+")";args.addAll(List.of(vehicle,day.toString(),day.plusDays(1).toString(),day,day.plusDays(1),text(row,"sid")));}
|
||||
jobs=db.queryForList("SELECT j.jb_id,j.jb_id_parent,j.jb_ordertime,j.jb_status,j.jb_service,j.jb_totalprice,csc.cs_id,csc.csc_name,cs.cs_eid AS customer_label FROM job j JOIN costcenter csc ON csc.csc_id=j.csc_id_related JOIN customer cs ON cs.cs_id=csc.cs_id WHERE j.jb_id IN ("+CourierPortal.placeholders(allowed.size())+") AND (j.jb_storno IS NULL OR j.jb_storno IN (0,1,3)) AND j.jb_timeunits>0 AND cs.hq_id IN (SELECT hq_id FROM mandatorheadquarters GROUP BY hq_id HAVING COUNT(*)=1 AND MAX(md_id)=?) AND "+clause+" ORDER BY CASE WHEN j.jb_status=1 THEN 1 ELSE 0 END,TIME(j.jb_ordertime),j.jb_id LIMIT 301",args.toArray());
|
||||
if(jobs.size()>300)throw bad("Mehr als 300 Aufträge auf der Rollkarte. Bitte die Auswahl eingrenzen.");
|
||||
}
|
||||
var cards=new VehicleRollcards(db);var warnings=new LinkedHashSet<String>();warnings.add("Die Rollkarte enthält ausschließlich die für Ihren Zugang freigegebenen Aufträge dieses Fahrzeugs.");
|
||||
String format=cards.parameter("MASK_DISPOSITION_FUNCTIONNAME_CARTAGE_NOTE",u.headquartersId());if(format.isBlank())format=cards.parameter("MASK_DISPOSITION_FUNCTIONNAME_CARTAGE_NOTE",0);
|
||||
if(!format.isBlank()&&!Set.of("getCartageNote","getServiceCartageNote").contains(format))warnings.add("Für diese Niederlassung ist ein besonderes PHP-Rollkartenformat eingerichtet. Diese Vorschau verwendet die Standardrollkarte; zusätzliche Felder des Sonderformats sind nicht enthalten.");
|
||||
var parents=new HashSet<>(allowed);var v=fields("crvh_id",vehicle,"crvh_sid",text(row,"sid"),"crvh_vh_sign",text(row,"registration"));
|
||||
var result=cards.document(u,vehicle,day,selection,v,jobs,parents,warnings);
|
||||
if(board.courier(u)!=courier)throw CourierPortal.denied();return result;
|
||||
});}
|
||||
}
|
||||
Reference in new issue
Block a user