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.
46 lines
5.0 KiB
Java
46 lines
5.0 KiB
Java
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;
|
|
});}
|
|
}
|