create branch dev and commit code
This commit is contained in:
parent
3b70cc9fe8
commit
ea68fa5cc4
44 changed files with 12421 additions and 214 deletions
162
src/lib/core/utils/productCode.ts
Normal file
162
src/lib/core/utils/productCode.ts
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
import { get } from 'svelte/store';
|
||||
import { existingProductCodes } from '../stores/sheetStore';
|
||||
|
||||
// Country code mapping (country short from Android -> 2-digit product code prefix)
|
||||
// Country short is read from /sdcard/coffeevending/country/short
|
||||
export const countryCodeMap: Record<string, string> = {
|
||||
// Thailand
|
||||
THAI: '12',
|
||||
tha: '12',
|
||||
// Malaysia
|
||||
MYS: '12',
|
||||
mys: '12',
|
||||
// Indonesia
|
||||
IDR: '13',
|
||||
idr: '13',
|
||||
// Australia
|
||||
AUS: '51',
|
||||
aus: '51',
|
||||
// Singapore
|
||||
SGP: '52',
|
||||
sgp: '52',
|
||||
SG: '52', // obsolete
|
||||
// UAE Dubai
|
||||
UAE_DUBAI: '53',
|
||||
uae_dubai: '53',
|
||||
dubai: '53',
|
||||
// Hong Kong
|
||||
HKG: '54',
|
||||
hkg: '54',
|
||||
// UK
|
||||
GBR: '55',
|
||||
gbr: '55',
|
||||
// Romania
|
||||
ROU: '56',
|
||||
rou: '56',
|
||||
// Latvia
|
||||
LVA: '57',
|
||||
lva: '57',
|
||||
// Estonia
|
||||
EST: '58',
|
||||
est: '58',
|
||||
// Lithuania
|
||||
LTU: '59',
|
||||
ltu: '59',
|
||||
// USA Pepsi (uses Thai prefix)
|
||||
USA_PEPSI: '12',
|
||||
usa_pepsi: '12',
|
||||
// Counter machines
|
||||
counter01: '19'
|
||||
};
|
||||
|
||||
// Temperature codes
|
||||
export const tempCodes: Record<TempType, string> = {
|
||||
hot: '01',
|
||||
cold: '02',
|
||||
blend: '03'
|
||||
};
|
||||
|
||||
// Category/Drink type codes
|
||||
export const categoryOptions = [
|
||||
{ value: '01', label: 'Coffee V1' },
|
||||
{ value: '21', label: 'Coffee V2' },
|
||||
{ value: '02', label: 'Tea' },
|
||||
{ value: '03', label: 'Milk' },
|
||||
{ value: '04', label: 'Whey' },
|
||||
{ value: '05', label: 'Soda & Other' }
|
||||
] as const;
|
||||
|
||||
export type TempType = 'hot' | 'cold' | 'blend';
|
||||
export type CategoryCode = (typeof categoryOptions)[number]['value'];
|
||||
|
||||
/**
|
||||
* Get all existing product code suffixes (last 4 digits)
|
||||
* @param category - Optional category code to filter by (e.g., '01' for Coffee V1)
|
||||
*/
|
||||
export function getExistingCodeSuffixes(category?: string): Set<string> {
|
||||
const codes = get(existingProductCodes);
|
||||
|
||||
if (category) {
|
||||
// Filter codes by category (2nd segment: XX-[category]-XX-XXXX)
|
||||
return new Set(
|
||||
[...codes]
|
||||
.filter((code) => {
|
||||
const parts = code.split('-');
|
||||
return parts[1] === category;
|
||||
})
|
||||
.map((code) => code.split('-')[3])
|
||||
);
|
||||
}
|
||||
|
||||
return new Set([...codes].map((code) => code.split('-')[3]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate next suffix by finding max existing + 1 for a specific category
|
||||
* @param category - Optional category code to find max within (e.g., '01' for Coffee V1)
|
||||
*/
|
||||
export function generateNextSuffix(category?: string): string {
|
||||
const suffixes = getExistingCodeSuffixes(category);
|
||||
let maxSuffix = 0;
|
||||
|
||||
for (const suffix of suffixes) {
|
||||
const num = parseInt(suffix, 10);
|
||||
if (!isNaN(num) && num > maxSuffix) {
|
||||
maxSuffix = num;
|
||||
}
|
||||
}
|
||||
|
||||
const nextSuffix = maxSuffix + 1;
|
||||
|
||||
if (nextSuffix > 9999) {
|
||||
throw new Error('Product code suffix exceeded 9999');
|
||||
}
|
||||
|
||||
return String(nextSuffix).padStart(4, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a complete product code
|
||||
* @param country - Country code (e.g., 'tha')
|
||||
* @param category - Category code (e.g., '01' for Coffee V1)
|
||||
* @param temp - Temperature type ('hot', 'cold', 'blend')
|
||||
* @param suffix - Optional specific suffix, otherwise auto-generate
|
||||
* @returns Product code like '12-01-01-0006'
|
||||
*/
|
||||
export function generateProductCode(
|
||||
country: string,
|
||||
category: string,
|
||||
temp: TempType,
|
||||
suffix?: string
|
||||
): string {
|
||||
const countryCode = countryCodeMap[country] || '99';
|
||||
const tempCode = tempCodes[temp];
|
||||
const codeSuffix = suffix ?? generateNextSuffix();
|
||||
|
||||
return `${countryCode}-${category}-${tempCode}-${codeSuffix}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a product code already exists
|
||||
*/
|
||||
export function isProductCodeExists(code: string): boolean {
|
||||
const codes = get(existingProductCodes);
|
||||
return codes.has(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique product code (auto-retry if exists)
|
||||
*/
|
||||
export function generateUniqueProductCode(
|
||||
country: string,
|
||||
category: string,
|
||||
temp: TempType
|
||||
): string {
|
||||
const code = generateProductCode(country, category, temp);
|
||||
|
||||
if (isProductCodeExists(code)) {
|
||||
throw new Error(`Product code already exists: ${code}`);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue