package de.stadtbote.votian; import de.stadtbote.votian.database.DatabaseService; import java.util.*; import static de.stadtbote.votian.AdminSupport.*; import static de.stadtbote.votian.LegacyMapping.*; import static de.stadtbote.votian.OrderEntryService.fields; /** Classic jobs2 photo quantities; independent of the external workflow service. */ final class CustomerEntryPhotos { record Requirement(int station,int minimum,int maximum){} final DatabaseService db; CustomerEntryPhotos(DatabaseService db){this.db=db;} List> settings(long customer){return db.queryForList("SELECT par_id,par_key,md_id,hq_id,emp_id,par_value FROM parameter WHERE par_key IN (?,?) ORDER BY par_key,par_id",ExtrasCustomerSettings.photoKey(customer),ExtrasCustomerSettings.rangeKey(customer));} long cashCustomer(long payer){if(payer<=0)return 0;var rows=db.queryForList("SELECT cs_id FROM costcenter WHERE csc_id=?",payer);return rows.size()==1?id(rows.getFirst(),"cs_id"):0;} List revisionBasis(long customer,long cashPayer){var basis=new ArrayList();var own=settings(customer);if(!own.isEmpty())basis.add(own);long cash=cashCustomer(cashPayer);if(cash>0&&cash!=customer){var rows=settings(cash);if(!rows.isEmpty()){basis.add(cash);basis.add(rows);}}return basis;} ExtrasCustomerSettings.Values config(long customer){var rows=settings(customer).stream().map(r->{var next=new LinkedHashMap<>(r);if(text(r,"par_key").equals(ExtrasCustomerSettings.rangeKey(customer))&&text(r,"par_value").isBlank())next.put("par_value","1|1");return (Map)next;}).toList();return ExtrasCustomerSettings.decode(ExtrasCustomerSettings.Type.PHOTO,customer,rows);} List plan(CustomerEntryAccess.State state,CustomerOrderEntry.Draft draft){ var own=config(state.customer());boolean systemCash=draft.payment()==OrderEntryModels.Payment.CASH&&!state.cashPayerSelect(); var initial=systemCash?config(cashCustomer(state.cashPayer())):own; return plan(draft.stops().size(),initial,own,systemCash?draft.cashStop():null); } static List plan(int stations,ExtrasCustomerSettings.Values initial,ExtrasCustomerSettings.Values own,Integer cashStop){ var result=new ArrayList(); for(int i=1;i=cashStop?own:initial;if(config.mode()!=null&&(config.mode()==2||config.mode()==3))result.add(new Requirement(i+1,config.minimum(),config.maximum()));} return List.copyOf(result); } void created(long job,List plan){ if(plan.isEmpty())return; var stops=db.queryForList("SELECT tr_id,tr_sort FROM tour WHERE jb_id=? ORDER BY tr_sort,tr_id",job); for(var r:plan){var matching=stops.stream().filter(t->id(t,"tr_sort")==r.station()).toList();if(matching.size()!=1)throw bad("Die Fotoanforderung kann keiner eindeutigen Station zugeordnet werden.");long station=id(matching.getFirst(),"tr_id"); if(!db.queryForList("SELECT gdc_id FROM genericdatacontainer WHERE gdc_obj_type='tr' AND gdc_obj_id=? AND gdc_gen_fieldname='tr_photo'",station).isEmpty())throw bad("Die Station besitzt bereits eine Fotoanforderung."); db.insert("genericdatacontainer",fields("gdc_obj_type","tr","gdc_obj_id",station,"gdc_gen_fieldname","tr_photo","gdc_content",r.minimum()+"|"+r.maximum(),"gdc_context",Long.toString(job))); } } }