This commit is contained in:
seb
2026-10-14 00:10:50 +02:00
parent f6cb3d3e35
commit 56a86fc005
6 changed files with 148 additions and 12 deletions

View File

@@ -32,6 +32,8 @@ import PeopleIcon from '@mui/icons-material/People';
import LocalShippingIcon from '@mui/icons-material/LocalShipping';
import TuneIcon from '@mui/icons-material/Tune';
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
import RequestQuoteIcon from '@mui/icons-material/RequestQuote';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import BackendError from './BackendError';
import { company, number as numberApi } from '../api';
import authAutomat, { bootstrapAuthMe } from '../automats/authAutomat';
@@ -49,18 +51,22 @@ const NUMBER_SCHEMES = [
{ type: 'entity', label: 'Kundennummer', icon: PeopleIcon },
{ type: 'delivery', label: 'Lieferschein', icon: LocalShippingIcon },
{ type: 'adjustment', label: 'Bestandskorrektur', icon: TuneIcon },
{ type: 'quote', label: 'Angebot', icon: RequestQuoteIcon },
{ type: 'order', label: 'Bestellung', icon: ShoppingCartIcon },
];
const PRESETS = [
{
id: 'standard',
label: 'Standard',
hint: 'Klassische Kürzel (ART-, KD-, LS-, KORR-)',
hint: 'Klassische Kürzel (ART-, KD-, LS-, KORR-, ANG-, AUF-)',
values: {
sku: { prefix: 'ART-', padding: 6, next: 1 },
entity: { prefix: 'KD-', padding: 6, next: 1001 },
delivery: { prefix: 'LS-', padding: 6, next: 1 },
adjustment: { prefix: 'KORR-', padding: 5, next: 1 },
quote: { prefix: 'ANG-', padding: 6, next: 1 },
order: { prefix: 'AUF-', padding: 6, next: 1 },
},
},
{
@@ -72,28 +78,34 @@ const PRESETS = [
entity: { prefix: '', padding: 5, next: 20001 },
delivery: { prefix: '', padding: 5, next: 30001 },
adjustment: { prefix: '', padding: 5, next: 90001 },
quote: { prefix: '', padding: 5, next: 40001 },
order: { prefix: '', padding: 5, next: 50001 },
},
},
{
id: 'compact',
label: 'Kurzkürzel',
hint: 'Einbuchstabige Präfixe (A-, K-, L-, B-)',
hint: 'Einbuchstabige Präfixe (A-, K-, L-, B-, AG-, AU-)',
values: {
sku: { prefix: 'A-', padding: 5, next: 1 },
entity: { prefix: 'K-', padding: 5, next: 1001 },
delivery: { prefix: 'L-', padding: 5, next: 1 },
adjustment: { prefix: 'B-', padding: 5, next: 1 },
quote: { prefix: 'AG-', padding: 5, next: 1 },
order: { prefix: 'AU-', padding: 5, next: 1 },
},
},
{
id: 'international',
label: 'International',
hint: 'Englische Kürzel (SKU-, C-, DEL-, ADJ-)',
hint: 'Englische Kürzel (SKU-, C-, DEL-, ADJ-, Q-, ORD-)',
values: {
sku: { prefix: 'SKU-', padding: 5, next: 1 },
entity: { prefix: 'C-', padding: 5, next: 1001 },
delivery: { prefix: 'DEL-', padding: 5, next: 1 },
adjustment: { prefix: 'ADJ-', padding: 4, next: 1 },
quote: { prefix: 'Q-', padding: 5, next: 1 },
order: { prefix: 'ORD-', padding: 5, next: 1 },
},
},
];

View File

@@ -29,6 +29,7 @@ import {
apiFor,
parseNum,
} from './manifestConfig';
import { ensureDocumentNumber, getNextDocumentNumber } from '../../utils/documentNumber';
class ManifestForm extends PureComponent {
constructor(props) {
@@ -125,8 +126,11 @@ class ManifestForm extends PureComponent {
}
});
if (this.props.mode === 'edit') void this.loadEdit();
else void this.loadPartiesOnly();
if (this.props.mode === 'edit') {
void this.loadEdit();
} else {
void this.loadPartiesOnly();
}
}
componentDidUpdate(prevProps) {
@@ -664,6 +668,7 @@ class ManifestForm extends PureComponent {
attachments: this.state.attachments,
},
{
kind: cfg.kind,
partyField: cfg.partyField,
requireAtLeastOne,
externalNumber: cfg.externalNumber,

View File

@@ -344,9 +344,9 @@ class ManifestHeader extends PureComponent {
<SingleLineTextEdit
size="small"
label="Nummer"
value={number}
disabled={saving || pdfUploading || useExternalNumber}
onChange={onNumberChange}
value={number || ''}
disabled
placeholder="–"
sx={{
flex: { xs: '1 1 100%', sm: '1 1 120px' },
minWidth: { sm: 100 },

View File

@@ -475,6 +475,7 @@ export class OrderList extends PureComponent {
this.state = {
items: orderAutomat.getItems(),
unfilteredTotal: orderAutomat.state.unfilteredTotal ?? 0,
filterKey: orderAutomat.getFilterKey?.() ?? '',
partiesById: {},
busyId: null,
};
@@ -494,6 +495,7 @@ export class OrderList extends PureComponent {
this.unsub = orderAutomat.subscribe(this, (state) => ({
items: state.items,
unfilteredTotal: state.unfilteredTotal ?? 0,
filterKey: orderAutomat.getFilterKey(state),
}));
void this.loadParties();
}
@@ -583,7 +585,7 @@ export class OrderList extends PureComponent {
}
render() {
const { items, unfilteredTotal, partiesById, busyId } = this.state;
const { items, unfilteredTotal, filterKey, partiesById, busyId } = this.state;
rowContext.partiesById = partiesById;
rowContext.busyId = busyId;
@@ -615,6 +617,7 @@ export class OrderList extends PureComponent {
reserveBottom={32}
minPageSize={8}
minHeight={0}
resetKey={filterKey}
items={items || []}
totalCount={items ? items.length : 0}
unfilteredTotal={unfilteredTotal}

View File

@@ -12,6 +12,7 @@ import orderAutomat from '../../automats/orderAutomat';
import { getArticle } from '../../automats/artikelAutomat';
import { selectCompanyTaxrate } from '../../automats/companyAutomat';
import { netFromGross } from '../../utils/price';
import { ensureDocumentNumber, getNextDocumentNumber } from '../../utils/documentNumber';
import {
GREEN_PANEL,
ORANGE_PANEL,
@@ -444,7 +445,7 @@ export function collectFilesForUpload(attachments = [], { onlyNew = false } = {}
*/
export async function buildManifestBody(
form,
{ partyField, requireAtLeastOne, externalNumber: useExternalNumber },
{ partyField, requireAtLeastOne, externalNumber: useExternalNumber, kind },
) {
const date = form.date;
if (!date) throw new Error('Datum fehlt.');
@@ -460,8 +461,11 @@ export async function buildManifestBody(
lines: buildLines(form.lines, { requireAtLeastOne }),
};
} else {
const number = String(form.number ?? '').trim();
if (!number) throw new Error('Nummer fehlt.');
let number = String(form.number ?? '').trim();
if (!number) {
number = await ensureDocumentNumber(kind || (partyField === 'entityId' ? 'quote' : 'doc'));
}
if (!number) throw new Error('Nummer konnte nicht ermittelt werden.');
body = {
number,
date,