Warenwirtschaft: AP-33a Bestell-Abwicklung — Nav „Bestellungen" + Fulfillment-Board
Neuer Nav-Punkt „Bestellungen" (Abwicklung + API-Bestellungen als Unterpunkte). Board für Versand-Mitarbeiter (copyreader): 4 Filter-Kacheln (heute eingegangen / zu konfektionieren / versandfertig / heute versendet), Packliste je Bestellung (Sets mit Komponenten), Dokumente (Rechnung/Lieferschein/Kombi-Download über eigene copyreader-Route, Erstellen ohne Mailversand; API-Bestellungen verlinken die externe Rechnung), Aktionen Konfektioniert/Versendet (nur vorwärts, Storno bleibt Verkäufe/admin). Versandfertig-Regel per Kundenentscheid: Rechnung sofort, Vorkasse nach Zahlungseingang, API immer (ShoppingOrder::isReadyToShip()). Statuswechsel-Logik in OrderStatusService extrahiert (Verkäufe-Modal + Board teilen Transaktion/Lock/Margin-Folgen/AP-13-Abzug). Kundenentscheid Punkt 3: Board-Statuswechsel setzt shipped_status_locked — die Bestell-Detailseiten ändern den Status dann nicht mehr automatisch (offen → in Bearbeitung). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
f1eb5fbc7f
commit
a367d851f6
9 changed files with 818 additions and 71 deletions
|
|
@ -2,16 +2,14 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Setting;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Services\CustomerPriority;
|
||||
use App\Services\Invoice;
|
||||
use App\Services\OrderStatusService;
|
||||
use App\Services\Payment;
|
||||
use App\Services\PaymentService;
|
||||
use App\Services\ProductStockService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Request;
|
||||
|
||||
|
|
@ -46,7 +44,8 @@ class SalesController extends Controller
|
|||
{
|
||||
|
||||
$ShoppingOrder = ShoppingOrder::find($id);
|
||||
if ($ShoppingOrder->shipped == 0) {
|
||||
// AP-33: kein Auto-Wechsel mehr, wenn der Status über die WaWi gesetzt wurde
|
||||
if ($ShoppingOrder->shipped == 0 && ! $ShoppingOrder->shipped_status_locked) {
|
||||
$ShoppingOrder->shipped = 1;
|
||||
$ShoppingOrder->save();
|
||||
}
|
||||
|
|
@ -209,7 +208,7 @@ class SalesController extends Controller
|
|||
public function usersDetail($id)
|
||||
{
|
||||
$ShoppingOrder = ShoppingOrder::find($id);
|
||||
if($ShoppingOrder->shipped === 0){
|
||||
if($ShoppingOrder->shipped === 0 && ! $ShoppingOrder->shipped_status_locked){
|
||||
$ShoppingOrder->shipped = 1;
|
||||
$ShoppingOrder->save();
|
||||
}
|
||||
|
|
@ -291,7 +290,7 @@ class SalesController extends Controller
|
|||
public function customersDetail($id)
|
||||
{
|
||||
$ShoppingOrder = ShoppingOrder::find($id);
|
||||
if($ShoppingOrder->shipped === 0){
|
||||
if($ShoppingOrder->shipped === 0 && ! $ShoppingOrder->shipped_status_locked){
|
||||
$ShoppingOrder->shipped = 1;
|
||||
$ShoppingOrder->save();
|
||||
}
|
||||
|
|
@ -429,67 +428,7 @@ class SalesController extends Controller
|
|||
]);
|
||||
|
||||
if ($data['action'] === 'store_shipped') {
|
||||
// Statuswechsel + Margin-/Provisionsfolgen atomar; Lock gegen Doppelklick/zweiten Tab
|
||||
DB::transaction(function () use ($data) {
|
||||
$shopping_order = ShoppingOrder::query()->lockForUpdate()->findOrFail($data['id']);
|
||||
$shopping_order->shipped = (int) $data['shipped'];
|
||||
$shopping_order->save();
|
||||
// handel Promotion Product and credit by storno
|
||||
Payment::handelUserPromotionOrder($shopping_order);
|
||||
Payment::handelUserShopOrder($shopping_order);
|
||||
|
||||
if ($shopping_order->getAPIShippedType() === 'sent' || $shopping_order->getAPIShippedType() === 'close') {
|
||||
if (! $shopping_order->shipped_at) {
|
||||
$shopping_order->shipped_at = now();
|
||||
$shopping_order->save();
|
||||
// is shipped set pending_to
|
||||
if ($shopping_order->shopping_order_margin) {
|
||||
if ($shopping_order->shopping_order_margin->hasPartnerCommission()) {
|
||||
$days = Setting::getContentBySlug('pending_partner_commissions_in_days');
|
||||
$days = $days ? $days : 20;
|
||||
$partner_commission_pending_to = $shopping_order->shipped_at;
|
||||
$partner_commission_pending_to->addDays($days);
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = $partner_commission_pending_to;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
} else {
|
||||
$days = Setting::getContentBySlug('pending_order_margins_in_days');
|
||||
$days = $days ? $days : 20;
|
||||
$margin_pending_to = $shopping_order->shipped_at;
|
||||
$margin_pending_to->addDays($days);
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = $margin_pending_to;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$shopping_order->shipped_at = null;
|
||||
$shopping_order->save();
|
||||
if ($shopping_order->shopping_order_margin) {
|
||||
// zurücksetzen der pending_to
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}
|
||||
if ($shopping_order->getAPIShippedType() === 'cancel') {
|
||||
if ($shopping_order->shopping_order_margin) {
|
||||
$shopping_order->shopping_order_margin->cancellation = true;
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
} else {
|
||||
if ($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->cancellation) {
|
||||
$shopping_order->shopping_order_margin->cancellation = false;
|
||||
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->margin_pending_to = null;
|
||||
$shopping_order->shopping_order_margin->save();
|
||||
}
|
||||
}
|
||||
|
||||
// AP-13: Verkaufs-Abgänge (Produktbestand) mit dem neuen Versandstatus abgleichen
|
||||
app(ProductStockService::class)->syncSaleStock($shopping_order, auth()->id());
|
||||
});
|
||||
app(OrderStatusService::class)->setShipped((int) $data['id'], (int) $data['shipped'], auth()->id());
|
||||
}
|
||||
|
||||
/* txaction ändern
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue