mirror of
https://github.com/frappe/books.git
synced 2024-12-22 10:58:59 +00:00
fix: shift serial number creation to Transfer
This commit is contained in:
parent
4384e32706
commit
6869ca9652
@ -2,16 +2,10 @@ import { ListViewSettings } from 'fyo/model/types';
|
||||
import { getTransactionStatusColumn } from 'models/helpers';
|
||||
import { PurchaseReceiptItem } from './PurchaseReceiptItem';
|
||||
import { StockTransfer } from './StockTransfer';
|
||||
import { createSerialNumbers } from './helpers';
|
||||
|
||||
export class PurchaseReceipt extends StockTransfer {
|
||||
items?: PurchaseReceiptItem[];
|
||||
|
||||
override async afterSubmit(): Promise<void> {
|
||||
await super.afterSubmit();
|
||||
await createSerialNumbers(this);
|
||||
}
|
||||
|
||||
static getListViewSettings(): ListViewSettings {
|
||||
return {
|
||||
columns: [
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Fyo, t } from 'fyo';
|
||||
import type { Doc } from 'fyo/model/doc';
|
||||
import {
|
||||
Action,
|
||||
DefaultMap,
|
||||
@ -20,13 +19,13 @@ import { SerialNumber } from './SerialNumber';
|
||||
import { StockMovementItem } from './StockMovementItem';
|
||||
import { Transfer } from './Transfer';
|
||||
import {
|
||||
createSerialNumbers,
|
||||
canValidateSerialNumber,
|
||||
getSerialNumberFromDoc,
|
||||
updateSerialNumbers,
|
||||
validateBatch,
|
||||
validateSerialNumber,
|
||||
validateSerialNumber
|
||||
} from './helpers';
|
||||
import { MovementType, MovementTypeEnum, SerialNumberStatus } from './types';
|
||||
import { MovementType, MovementTypeEnum } from './types';
|
||||
|
||||
export class StockMovement extends Transfer {
|
||||
name?: string;
|
||||
@ -66,7 +65,6 @@ export class StockMovement extends Transfer {
|
||||
|
||||
async afterSubmit(): Promise<void> {
|
||||
await super.afterSubmit();
|
||||
await createSerialNumbers(this);
|
||||
await updateSerialNumbers(this, false);
|
||||
}
|
||||
|
||||
@ -147,7 +145,12 @@ export class StockMovement extends Transfer {
|
||||
}
|
||||
|
||||
async function validateSerialNumberStatus(doc: StockMovement) {
|
||||
for (const serialNumber of getSerialNumberFromDoc(doc)) {
|
||||
for (const { serialNumber, item } of getSerialNumberFromDoc(doc)) {
|
||||
const cannotValidate = !(await canValidateSerialNumber(item, serialNumber));
|
||||
if (cannotValidate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const snDoc = await doc.fyo.doc.getDoc(
|
||||
ModelNameEnum.SerialNumber,
|
||||
serialNumber
|
||||
@ -161,35 +164,26 @@ async function validateSerialNumberStatus(doc: StockMovement) {
|
||||
|
||||
if (doc.movementType === 'MaterialReceipt' && status !== 'Inactive') {
|
||||
throw new ValidationError(
|
||||
t`Active Serial Number ${serialNumber} cannot be used for Material Issue`
|
||||
t`Non Inactive Serial Number ${serialNumber} cannot be used for Material Receipt`
|
||||
);
|
||||
}
|
||||
|
||||
if (doc.movementType === 'MaterialIssue' && status !== 'Active') {
|
||||
validateMaterialIssueSerialNumber(serialNumber, status);
|
||||
throw new ValidationError(
|
||||
t`Inactive Serial Number ${serialNumber} cannot be used for Material Issue`
|
||||
t`Non Active Serial Number ${serialNumber} cannot be used for Material Issue`
|
||||
);
|
||||
}
|
||||
|
||||
if (doc.movementType === 'MaterialTransfer' && status !== 'Active') {
|
||||
throw new ValidationError(
|
||||
t`Non Active Serial Number ${serialNumber} cannot be used for Material Transfer`
|
||||
);
|
||||
}
|
||||
|
||||
if (item.fromLocation && status !== 'Active') {
|
||||
throw new ValidationError(
|
||||
t`Non Active Serial Number ${serialNumber} cannot be used as Manufacture raw material`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function validateMaterialReceiptSerialNumber(
|
||||
serialNumber: string,
|
||||
status: string
|
||||
) {
|
||||
if (status === 'Inactive') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async function validateMaterialIssueSerialNumber(
|
||||
serialNumber: string,
|
||||
status: SerialNumberStatus
|
||||
) {
|
||||
if (status === 'Active') {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ValidationError(t`Serial Number ${serialNumber} is not Active.`);
|
||||
}
|
||||
|
@ -15,8 +15,9 @@ import { Money } from 'pesa';
|
||||
import { safeParseFloat } from 'utils/index';
|
||||
import { StockMovement } from './StockMovement';
|
||||
import { MovementTypeEnum } from './types';
|
||||
import { TransferItem } from './TransferItem';
|
||||
|
||||
export class StockMovementItem extends Doc {
|
||||
export class StockMovementItem extends TransferItem {
|
||||
name?: string;
|
||||
item?: string;
|
||||
fromLocation?: string;
|
||||
@ -30,10 +31,12 @@ export class StockMovementItem extends Doc {
|
||||
|
||||
rate?: Money;
|
||||
amount?: Money;
|
||||
parentdoc?: StockMovement;
|
||||
|
||||
batch?: string;
|
||||
serialNumber?: string;
|
||||
|
||||
parentdoc?: StockMovement;
|
||||
|
||||
get isIssue() {
|
||||
return this.parentdoc?.movementType === MovementTypeEnum.MaterialIssue;
|
||||
}
|
||||
|
@ -17,15 +17,16 @@ import { addItem, getLedgerLinkAction, getNumberSeries } from 'models/helpers';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { Money } from 'pesa';
|
||||
import { TargetField } from 'schemas/types';
|
||||
import { SerialNumber } from './SerialNumber';
|
||||
import { StockTransferItem } from './StockTransferItem';
|
||||
import { Transfer } from './Transfer';
|
||||
import {
|
||||
canValidateSerialNumber,
|
||||
getSerialNumberFromDoc,
|
||||
updateSerialNumbers,
|
||||
validateBatch,
|
||||
validateSerialNumber,
|
||||
} from './helpers';
|
||||
import { SerialNumber } from './SerialNumber';
|
||||
|
||||
export abstract class StockTransfer extends Transfer {
|
||||
name?: string;
|
||||
@ -311,7 +312,12 @@ export abstract class StockTransfer extends Transfer {
|
||||
}
|
||||
|
||||
async function validateSerialNumberStatus(doc: StockTransfer) {
|
||||
for (const serialNumber of getSerialNumberFromDoc(doc)) {
|
||||
for (const { serialNumber, item } of getSerialNumberFromDoc(doc)) {
|
||||
const cannotValidate = !(await canValidateSerialNumber(item, serialNumber));
|
||||
if (cannotValidate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const snDoc = await doc.fyo.doc.getDoc(
|
||||
ModelNameEnum.SerialNumber,
|
||||
serialNumber
|
||||
|
@ -12,8 +12,9 @@ import { ModelNameEnum } from 'models/types';
|
||||
import { Money } from 'pesa';
|
||||
import { safeParseFloat } from 'utils/index';
|
||||
import { StockTransfer } from './StockTransfer';
|
||||
import { TransferItem } from './TransferItem';
|
||||
|
||||
export class StockTransferItem extends Doc {
|
||||
export class StockTransferItem extends TransferItem {
|
||||
item?: string;
|
||||
location?: string;
|
||||
|
||||
@ -25,8 +26,10 @@ export class StockTransferItem extends Doc {
|
||||
|
||||
rate?: Money;
|
||||
amount?: Money;
|
||||
|
||||
description?: string;
|
||||
hsnCode?: number;
|
||||
|
||||
batch?: string;
|
||||
serialNumber?: string;
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { Transactional } from 'models/Transactional/Transactional';
|
||||
import { StockManager } from './StockManager';
|
||||
import { SMTransferDetails } from './types';
|
||||
import type { SMTransferDetails } from './types';
|
||||
import type { TransferItem } from './TransferItem';
|
||||
import { createSerialNumbers } from './helpers';
|
||||
|
||||
export abstract class Transfer extends Transactional {
|
||||
date?: Date;
|
||||
items?: TransferItem[];
|
||||
|
||||
async beforeSubmit(): Promise<void> {
|
||||
await super.beforeSubmit();
|
||||
@ -13,6 +16,7 @@ export abstract class Transfer extends Transactional {
|
||||
|
||||
async afterSubmit(): Promise<void> {
|
||||
await super.afterSubmit();
|
||||
await createSerialNumbers(this);
|
||||
const transferDetails = this._getTransferDetails();
|
||||
await this._getStockManager().createTransfers(transferDetails);
|
||||
}
|
||||
|
21
models/inventory/TransferItem.ts
Normal file
21
models/inventory/TransferItem.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import type { Transfer } from './Transfer';
|
||||
import type { Money } from 'pesa';
|
||||
|
||||
export class TransferItem extends Doc {
|
||||
item?: string;
|
||||
|
||||
unit?: string;
|
||||
transferUnit?: string;
|
||||
quantity?: number;
|
||||
transferQuantity?: number;
|
||||
unitConversionFactor?: number;
|
||||
|
||||
rate?: Money;
|
||||
amount?: Money;
|
||||
|
||||
batch?: string;
|
||||
serialNumber?: string;
|
||||
|
||||
parentdoc?: Transfer;
|
||||
}
|
@ -8,8 +8,9 @@ import type { StockMovement } from './StockMovement';
|
||||
import type { StockMovementItem } from './StockMovementItem';
|
||||
import type { StockTransfer } from './StockTransfer';
|
||||
import type { StockTransferItem } from './StockTransferItem';
|
||||
import { Transfer } from './Transfer';
|
||||
import { TransferItem } from './TransferItem';
|
||||
import type { SerialNumberStatus } from './types';
|
||||
import type { PurchaseReceipt } from './PurchaseReceipt';
|
||||
|
||||
export async function validateBatch(
|
||||
doc: StockMovement | StockTransfer | Invoice
|
||||
@ -171,14 +172,17 @@ export function getSerialNumberFromDoc(doc: StockTransfer | StockMovement) {
|
||||
}
|
||||
|
||||
return doc.items
|
||||
.map((item) => getSerialNumbers(item.serialNumber ?? ''))
|
||||
.map((item) =>
|
||||
getSerialNumbers(item.serialNumber ?? '').map((serialNumber) => ({
|
||||
serialNumber,
|
||||
item,
|
||||
}))
|
||||
)
|
||||
.flat()
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
export async function createSerialNumbers(
|
||||
doc: PurchaseReceipt | StockMovement
|
||||
) {
|
||||
export async function createSerialNumbers(doc: Transfer) {
|
||||
const items = doc.items ?? [];
|
||||
const serialNumberCreateList = items
|
||||
.map((item) => {
|
||||
@ -208,7 +212,7 @@ export async function createSerialNumbers(
|
||||
}
|
||||
}
|
||||
|
||||
function isSerialNumberIncoming(item: StockTransferItem | StockMovementItem) {
|
||||
function isSerialNumberIncoming(item: TransferItem) {
|
||||
if (item.parentdoc?.schemaName === ModelNameEnum.Shipment) {
|
||||
return false;
|
||||
}
|
||||
@ -220,6 +224,17 @@ function isSerialNumberIncoming(item: StockTransferItem | StockMovementItem) {
|
||||
return !!item.toLocation && !item.fromLocation;
|
||||
}
|
||||
|
||||
export async function canValidateSerialNumber(
|
||||
item: StockTransferItem | StockMovementItem,
|
||||
serialNumber: string
|
||||
) {
|
||||
if (!isSerialNumberIncoming(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return await item.fyo.db.exists(ModelNameEnum.SerialNumber, serialNumber);
|
||||
}
|
||||
|
||||
export async function updateSerialNumbers(
|
||||
doc: StockTransfer | StockMovement,
|
||||
isCancel: boolean
|
||||
|
@ -29,6 +29,7 @@
|
||||
"label": "Status",
|
||||
"fieldtype": "Select",
|
||||
"default": "Inactive",
|
||||
"readOnly": true,
|
||||
"options": [
|
||||
{
|
||||
"value": "Inactive",
|
||||
|
Loading…
Reference in New Issue
Block a user