Spaces:
Sleeping
Sleeping
Commit
·
5654237
1
Parent(s):
6a73dca
First commit application to vinhngba2704/multimodal-image-audio
Browse files- .env +6 -0
- app.py +100 -0
- modules/audio_process.py +118 -0
- modules/image_process.py +128 -0
- modules/mapping.py +67 -0
- modules/normalization.py +18 -0
- modules/saving.py +29 -0
- modules/transformation.py +62 -0
- requirements.txt +14 -0
- resources/cloud_vision_ai_key.json +13 -0
- resources/employee.json +566 -0
- resources/merchant.json +0 -0
- resources/normalization_rule.json +3 -0
- resources/product.json +0 -0
- resources/unit.json +8 -0
.env
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MODEL_NAME=gemini-1.5-flash
|
| 2 |
+
MERCHANT_JSON_PATH=resources/merchant.json
|
| 3 |
+
PRODUCT_JSON_PATH=resources/product.json
|
| 4 |
+
UNIT_JSON_PATH=resources/unit.json
|
| 5 |
+
EMPLOYEE_JSON_PATH=resources/employee.json
|
| 6 |
+
NORMALIZATION_RULE_PATH=resources/normalization_rule.json
|
app.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import os
|
| 3 |
+
import json
|
| 4 |
+
from zipfile import ZipFile
|
| 5 |
+
from io import BytesIO
|
| 6 |
+
|
| 7 |
+
# Initialized Modules
|
| 8 |
+
from modules.image_process import image_process
|
| 9 |
+
from modules.audio_process import audio_process
|
| 10 |
+
from modules.transformation import json_to_dms_excel
|
| 11 |
+
# from modules.saving import saving_json, saving_excel
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
# Streamlit app
|
| 15 |
+
st.title("TOOL NHẬP ĐƠN HÀNG TỰ ĐỘNG")
|
| 16 |
+
|
| 17 |
+
# Add a text input for employee code
|
| 18 |
+
employee_code = st.text_input("Nhập mã nhân viên của bạn:", placeholder="Administrator", max_chars=20)
|
| 19 |
+
|
| 20 |
+
# Add a button to confirm the input
|
| 21 |
+
if st.button("Xác nhận mã nhân viên"):
|
| 22 |
+
if employee_code == "":
|
| 23 |
+
st.error("Vui lòng nhập mã nhân viên trước khi xác nhận.")
|
| 24 |
+
else:
|
| 25 |
+
st.success(f"Mã nhân viên của bạn là: {employee_code}")
|
| 26 |
+
|
| 27 |
+
st.write("Tải lên folder chứa hình ảnh đơn hàng (dưới dạng file Zip).")
|
| 28 |
+
|
| 29 |
+
# File uploader for ZIP file
|
| 30 |
+
uploaded_file = st.file_uploader("Tải file Zip chứa hình ảnh đơn hàng", type=["zip"])
|
| 31 |
+
|
| 32 |
+
if uploaded_file is not None:
|
| 33 |
+
# Extract ZIP file
|
| 34 |
+
with ZipFile(uploaded_file) as zip_file:
|
| 35 |
+
zip_file.extractall("temp_invoices")
|
| 36 |
+
|
| 37 |
+
# Collect image and audio files
|
| 38 |
+
all_files = zip_file.namelist()
|
| 39 |
+
# Image files
|
| 40 |
+
image_files = [os.path.join("temp_invoices", file) for file in all_files if file.lower().endswith((".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".webp"))]
|
| 41 |
+
# Audio files
|
| 42 |
+
audio_files = [os.path.join("temp_invoices", file) for file in all_files if file.lower().endswith((".mp3", ".wav", ".m4a", ".flac"))]
|
| 43 |
+
|
| 44 |
+
if not image_files and not audio_files:
|
| 45 |
+
st.error("Không có file hình ảnh và/hoặc file âm thanh hợp lệ trong thư mục file Zip.")
|
| 46 |
+
else:
|
| 47 |
+
st.write(f"Tìm thấy file {len(image_files)} ảnh và {len(audio_files)} file âm thanh trong thư mục.")
|
| 48 |
+
|
| 49 |
+
order_counter = 1 # Initialize the order ID counter
|
| 50 |
+
results = {}
|
| 51 |
+
|
| 52 |
+
# Process image files
|
| 53 |
+
for i, image_path in enumerate(image_files, start=1):
|
| 54 |
+
st.write(f"Processing image{i}/{len(image_files)}: {os.path.basename(image_path)}")
|
| 55 |
+
try:
|
| 56 |
+
content = image_process(image_path= image_path, order_id= order_counter)
|
| 57 |
+
results[f"image_file_{i}"] = content
|
| 58 |
+
order_counter += 1
|
| 59 |
+
except Exception as e:
|
| 60 |
+
st.error(f"Error processing {image_path}: {e}")
|
| 61 |
+
|
| 62 |
+
# Process audio files
|
| 63 |
+
for i, audio_path in enumerate(audio_files, start=1):
|
| 64 |
+
st.write(f"Processing audio{i}/{len(audio_files)}: {os.path.basename(audio_path)}")
|
| 65 |
+
try:
|
| 66 |
+
content = audio_process(audio_path= audio_path, order_id= order_counter)
|
| 67 |
+
results[f"audio_file_{i}"] = content
|
| 68 |
+
order_counter += 1
|
| 69 |
+
except Exception as e:
|
| 70 |
+
st.error(f"Error processing {audio_path}: {e}")
|
| 71 |
+
|
| 72 |
+
# Display the results
|
| 73 |
+
st.write("OCR Results:")
|
| 74 |
+
st.json(results)
|
| 75 |
+
|
| 76 |
+
# Allow user to download the results as a JSON file
|
| 77 |
+
json_data = json.dumps(results, indent=4)
|
| 78 |
+
st.download_button(
|
| 79 |
+
label="Tải file kết quả ở dạng JSON",
|
| 80 |
+
data=json_data,
|
| 81 |
+
file_name="invoice_results.json",
|
| 82 |
+
mime="application/json"
|
| 83 |
+
)
|
| 84 |
+
# Allow user to download the results as Excel file
|
| 85 |
+
# Convert results to Excel format
|
| 86 |
+
df = json_to_dms_excel(results, employee_code)
|
| 87 |
+
|
| 88 |
+
# Allow user to preview excel file before downloading
|
| 89 |
+
st.subheader("Xem trước dữ liệu Excel:")
|
| 90 |
+
st.dataframe(df.head())
|
| 91 |
+
|
| 92 |
+
excel_buffer = BytesIO()
|
| 93 |
+
df.to_excel(excel_buffer, index=False)
|
| 94 |
+
excel_buffer.seek(0)
|
| 95 |
+
st.download_button(
|
| 96 |
+
label="Tải file theo template Excel từ DMS",
|
| 97 |
+
data=excel_buffer,
|
| 98 |
+
file_name="invoice_results.xlsx",
|
| 99 |
+
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
| 100 |
+
)
|
modules/audio_process.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import whisper
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
+
import os
|
| 4 |
+
from rapidfuzz import process, fuzz
|
| 5 |
+
import pandas as pd
|
| 6 |
+
import json
|
| 7 |
+
import google.generativeai as genai
|
| 8 |
+
import re
|
| 9 |
+
|
| 10 |
+
# Initialized Modules
|
| 11 |
+
from modules.mapping import mapping_employee, mapping_merchant, mapping_product, mapping_unit
|
| 12 |
+
|
| 13 |
+
load_dotenv()
|
| 14 |
+
# Trancribe Model: Whisper
|
| 15 |
+
transcribe_model = whisper.load_model("turbo")
|
| 16 |
+
# Load the Gemini model
|
| 17 |
+
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
|
| 18 |
+
MODEL_NAME = os.getenv("MODEL_NAME")
|
| 19 |
+
genai.configure(api_key=GEMINI_API_KEY)
|
| 20 |
+
# Gemini Model
|
| 21 |
+
LLM_model = genai.GenerativeModel(MODEL_NAME)
|
| 22 |
+
|
| 23 |
+
# Line Split Function
|
| 24 |
+
def line():
|
| 25 |
+
print("=" * 30)
|
| 26 |
+
|
| 27 |
+
# Audio to raw text
|
| 28 |
+
def process_audio(audio_path, transcribe_model):
|
| 29 |
+
try:
|
| 30 |
+
transcript = transcribe_model.transcribe(audio_path)
|
| 31 |
+
return transcript["text"]
|
| 32 |
+
except Exception as e:
|
| 33 |
+
print(f"Trancribe failed: {e}")
|
| 34 |
+
return ""
|
| 35 |
+
|
| 36 |
+
# Parsing audio-text
|
| 37 |
+
def parse_audio_text(text, extract_model):
|
| 38 |
+
prompt = f"""
|
| 39 |
+
Dưới đây là nội dung hóa đơn bằng tiếng Việt. Hãy trích xuất tên đại lý mua (seller), tên đại lý bán (buyer), tên sản phẩm (product_name), đơn vị tính (unit), số lượng theo từng đơn hàng (quantity), ngày đặt hàng (order_date).
|
| 40 |
+
|
| 41 |
+
Văn bản:
|
| 42 |
+
{text}
|
| 43 |
+
|
| 44 |
+
Trả về kết quả dạng JSON:
|
| 45 |
+
{{
|
| 46 |
+
"order_1": {{
|
| 47 |
+
"seller": "...",
|
| 48 |
+
"buyer": "...",
|
| 49 |
+
"product_name": "...",
|
| 50 |
+
"unit": "...",
|
| 51 |
+
"quantity": "...",
|
| 52 |
+
"order_date": "..."
|
| 53 |
+
}},
|
| 54 |
+
...
|
| 55 |
+
}}
|
| 56 |
+
"""
|
| 57 |
+
response = extract_model.generate_content(prompt)
|
| 58 |
+
|
| 59 |
+
try:
|
| 60 |
+
content = response.text
|
| 61 |
+
# Use regex to extract the JSON part
|
| 62 |
+
match = re.search(r"\{[\s\S]*\}", content)
|
| 63 |
+
if match:
|
| 64 |
+
json_str = match.group(0)
|
| 65 |
+
extracted_json = json.loads(json_str)
|
| 66 |
+
return list(extracted_json.values()) # List of orders
|
| 67 |
+
else:
|
| 68 |
+
raise ValueError("No valid JSON found in Gemini output")
|
| 69 |
+
|
| 70 |
+
except Exception as e:
|
| 71 |
+
print("Failed to parse JSON from LLM response:", e)
|
| 72 |
+
return []
|
| 73 |
+
|
| 74 |
+
# Audio Handling Function
|
| 75 |
+
def audio_process(audio_path, order_id):
|
| 76 |
+
print(f"Start process audio file: {os.path.basename(audio_path)}")
|
| 77 |
+
line()
|
| 78 |
+
|
| 79 |
+
# Audio to Text
|
| 80 |
+
raw_text = process_audio(
|
| 81 |
+
audio_path=audio_path,
|
| 82 |
+
transcribe_model=transcribe_model
|
| 83 |
+
)
|
| 84 |
+
print(f"Transcript is done. Transcription: {raw_text}")
|
| 85 |
+
line()
|
| 86 |
+
|
| 87 |
+
# Text to JSON
|
| 88 |
+
extracted_information = parse_audio_text(
|
| 89 |
+
text=raw_text,
|
| 90 |
+
extract_model=LLM_model
|
| 91 |
+
)
|
| 92 |
+
print(f"Extracted Information.")
|
| 93 |
+
line()
|
| 94 |
+
|
| 95 |
+
# Mapping
|
| 96 |
+
merchant_mapped_data = mapping_merchant(
|
| 97 |
+
information=extracted_information,
|
| 98 |
+
json_path=os.getenv("MERCHANT_JSON_PATH"),
|
| 99 |
+
normalization_rule=os.getenv("NORMALIZATION_RULE_PATH")
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
unit_merchant_mapped_data = mapping_unit(
|
| 103 |
+
information=merchant_mapped_data,
|
| 104 |
+
json_path=os.getenv("UNIT_JSON_PATH"),
|
| 105 |
+
normalization_rule=os.getenv("NORMALIZATION_RULE_PATH")
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
# Skipping employee and product mapping
|
| 109 |
+
processed_data = unit_merchant_mapped_data
|
| 110 |
+
|
| 111 |
+
# Assign order id
|
| 112 |
+
for item in processed_data:
|
| 113 |
+
item["order_id"] = order_id
|
| 114 |
+
|
| 115 |
+
print(f"Successfully mapped data (merchant + unit).")
|
| 116 |
+
line()
|
| 117 |
+
|
| 118 |
+
return processed_data
|
modules/image_process.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from dotenv import load_dotenv
|
| 2 |
+
import os
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import json
|
| 5 |
+
from google.cloud import vision
|
| 6 |
+
import google.generativeai as genai
|
| 7 |
+
from google.oauth2 import service_account
|
| 8 |
+
import re
|
| 9 |
+
|
| 10 |
+
# Initialized Modules
|
| 11 |
+
from modules.mapping import mapping_employee, mapping_merchant, mapping_product, mapping_unit
|
| 12 |
+
|
| 13 |
+
load_dotenv()
|
| 14 |
+
# Load the credential for Cloud-Vision-API model
|
| 15 |
+
service_account_info_str = os.getenv("GOOGLE_APPLICATION_CREDENTIALS_JSON")
|
| 16 |
+
service_account_info = json.loads(service_account_info_str)
|
| 17 |
+
CREDENTIALS = service_account.Credentials.from_service_account_info(service_account_info)
|
| 18 |
+
# Load the Gemini model
|
| 19 |
+
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
|
| 20 |
+
MODEL_NAME = os.getenv("MODEL_NAME")
|
| 21 |
+
genai.configure(api_key=GEMINI_API_KEY)
|
| 22 |
+
|
| 23 |
+
# Gemini Model
|
| 24 |
+
LLM_model = genai.GenerativeModel(MODEL_NAME)
|
| 25 |
+
|
| 26 |
+
# Line Split Function
|
| 27 |
+
def line():
|
| 28 |
+
print("=" * 30)
|
| 29 |
+
|
| 30 |
+
# Image to raw text
|
| 31 |
+
def process_ocr(image_path):
|
| 32 |
+
try:
|
| 33 |
+
client = vision.ImageAnnotatorClient(credentials=CREDENTIALS)
|
| 34 |
+
|
| 35 |
+
with open(image_path, "rb") as image_file:
|
| 36 |
+
content = image_file.read()
|
| 37 |
+
|
| 38 |
+
image = vision.Image(content=content)
|
| 39 |
+
response = client.document_text_detection(image=image)
|
| 40 |
+
|
| 41 |
+
# Extract detected text
|
| 42 |
+
texts = response.text_annotations
|
| 43 |
+
return texts[0].description if texts else ""
|
| 44 |
+
except Exception as e:
|
| 45 |
+
print(f"OCR failed: {e}")
|
| 46 |
+
return ""
|
| 47 |
+
|
| 48 |
+
# Parsing image-text
|
| 49 |
+
def parse_image_text(text, extract_model):
|
| 50 |
+
prompt = f"""
|
| 51 |
+
Dưới đây là nội dung hóa đơn bằng tiếng Việt. Hãy trích xuất tên đại lý mua (seller), tên đại lý bán (buyer), tên sản phẩm (product_name), đơn vị tính (unit), số lượng theo từng đơn hàng (quantity), ngày đặt hàng (order_date).
|
| 52 |
+
|
| 53 |
+
Văn bản:
|
| 54 |
+
{text}
|
| 55 |
+
|
| 56 |
+
Trả về kết quả dạng JSON:
|
| 57 |
+
{{
|
| 58 |
+
"order_1": {{
|
| 59 |
+
"seller": "...",
|
| 60 |
+
"buyer": "...",
|
| 61 |
+
"product_name": "...",
|
| 62 |
+
"unit": "...",
|
| 63 |
+
"quantity": "...",
|
| 64 |
+
"order_date": "..."
|
| 65 |
+
}},
|
| 66 |
+
...
|
| 67 |
+
}}
|
| 68 |
+
"""
|
| 69 |
+
response = extract_model.generate_content(prompt)
|
| 70 |
+
|
| 71 |
+
try:
|
| 72 |
+
content = response.text
|
| 73 |
+
# Use regex to extract the JSON part
|
| 74 |
+
match = re.search(r"\{[\s\S]*\}", content)
|
| 75 |
+
if match:
|
| 76 |
+
json_str = match.group(0)
|
| 77 |
+
extracted_json = json.loads(json_str)
|
| 78 |
+
return list(extracted_json.values()) # List of orders
|
| 79 |
+
else:
|
| 80 |
+
raise ValueError("No valid JSON found in Gemini output")
|
| 81 |
+
|
| 82 |
+
except Exception as e:
|
| 83 |
+
print("Failed to parse JSON from LLM response:", e)
|
| 84 |
+
return []
|
| 85 |
+
|
| 86 |
+
# Image Handling Function
|
| 87 |
+
def image_process(image_path, order_id):
|
| 88 |
+
print(f"Start process image file: {os.path.basename(image_path)}")
|
| 89 |
+
line()
|
| 90 |
+
|
| 91 |
+
# Image to Text
|
| 92 |
+
raw_text = process_ocr(image_path=image_path)
|
| 93 |
+
print(f"Successfully extract raw text. Text: {raw_text}")
|
| 94 |
+
line()
|
| 95 |
+
|
| 96 |
+
# Text to JSON
|
| 97 |
+
extracted_information = parse_image_text(
|
| 98 |
+
text=raw_text,
|
| 99 |
+
extract_model=LLM_model
|
| 100 |
+
)
|
| 101 |
+
print(f"Extracted Information.")
|
| 102 |
+
line()
|
| 103 |
+
|
| 104 |
+
# Mapping
|
| 105 |
+
merchant_mapped_data = mapping_merchant(
|
| 106 |
+
information=extracted_information,
|
| 107 |
+
json_path=os.getenv("MERCHANT_JSON_PATH"),
|
| 108 |
+
normalization_rule=os.getenv("NORMALIZATION_RULE_PATH")
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
unit_merchant_mapped_data = mapping_unit(
|
| 112 |
+
information=merchant_mapped_data,
|
| 113 |
+
json_path=os.getenv("UNIT_JSON_PATH"),
|
| 114 |
+
normalization_rule=os.getenv("NORMALIZATION_RULE_PATH")
|
| 115 |
+
)
|
| 116 |
+
|
| 117 |
+
# Skipping employee and product mapping
|
| 118 |
+
processed_data = unit_merchant_mapped_data
|
| 119 |
+
|
| 120 |
+
# Assign order id
|
| 121 |
+
for item in processed_data:
|
| 122 |
+
item["order_id"] = order_id
|
| 123 |
+
|
| 124 |
+
print(f"Successfully mapped data (merchant + unit).")
|
| 125 |
+
line()
|
| 126 |
+
|
| 127 |
+
return processed_data
|
| 128 |
+
|
modules/mapping.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
from rapidfuzz import process, fuzz
|
| 3 |
+
|
| 4 |
+
# Initialized Modules
|
| 5 |
+
from modules.normalization import normalization
|
| 6 |
+
|
| 7 |
+
# Mapping merchant
|
| 8 |
+
def mapping_merchant(information, json_path, normalization_rule):
|
| 9 |
+
# Load from merchant JSON file
|
| 10 |
+
with open(json_path, "r", encoding="utf-8") as f:
|
| 11 |
+
name_id_dict = json.load(f)
|
| 12 |
+
|
| 13 |
+
# Create cached normalized dictionary
|
| 14 |
+
normalized_cached_map = {normalization(text= k, normalization_rule= normalization_rule): v for k, v in name_id_dict.items()}
|
| 15 |
+
name_list = list(normalized_cached_map.keys())
|
| 16 |
+
|
| 17 |
+
for item in information:
|
| 18 |
+
# Match seller
|
| 19 |
+
seller_name = normalization(text= item["seller"], normalization_rule= normalization_rule)
|
| 20 |
+
seller_match, seller_score, _ = process.extractOne(seller_name, name_list, scorer= fuzz.token_sort_ratio)
|
| 21 |
+
if seller_score >= 80:
|
| 22 |
+
item["seller_id"] = normalized_cached_map[seller_match]
|
| 23 |
+
else:
|
| 24 |
+
item["seller_id"] = None
|
| 25 |
+
|
| 26 |
+
# Match buyer
|
| 27 |
+
buyer_name = normalization(text= item["buyer"], normalization_rule= normalization_rule)
|
| 28 |
+
buyer_match, buyer_score, _ = process.extractOne(buyer_name, name_list, scorer= fuzz.token_sort_ratio)
|
| 29 |
+
if buyer_score >= 80:
|
| 30 |
+
item["buyer_id"] = normalized_cached_map[buyer_match]
|
| 31 |
+
else:
|
| 32 |
+
item["buyer_id"] = None
|
| 33 |
+
|
| 34 |
+
return information
|
| 35 |
+
|
| 36 |
+
# Mapping unit
|
| 37 |
+
def mapping_unit(information, json_path, normalization_rule):
|
| 38 |
+
# Load from unit JSON file
|
| 39 |
+
with open(json_path, "r", encoding="utf-8") as f:
|
| 40 |
+
unit_id_dict = json.load(f)
|
| 41 |
+
|
| 42 |
+
# Create cached normalized dictionary
|
| 43 |
+
normalized_cached_map = {normalization(text= k, normalization_rule= normalization_rule): v for k, v in unit_id_dict.items()}
|
| 44 |
+
unit_list = list(normalized_cached_map.keys())
|
| 45 |
+
|
| 46 |
+
for item in information:
|
| 47 |
+
# Match unit
|
| 48 |
+
unit = normalization(text= item["unit"], normalization_rule= normalization_rule)
|
| 49 |
+
unit_match, unit_score, _ = process.extractOne(unit, unit_list, scorer= fuzz.token_sort_ratio)
|
| 50 |
+
if unit_score >= 80:
|
| 51 |
+
item["unit_id"] = normalized_cached_map[unit_match]
|
| 52 |
+
else:
|
| 53 |
+
item["unit_id"] = None
|
| 54 |
+
|
| 55 |
+
return information
|
| 56 |
+
|
| 57 |
+
# Mapping employee
|
| 58 |
+
def mapping_employee(information, json_path, normalization_rule):
|
| 59 |
+
# Load from employee JSON file
|
| 60 |
+
with open(json_path, "r", encoding="utf-8") as f:
|
| 61 |
+
employee_id_dict = json.load(f)
|
| 62 |
+
|
| 63 |
+
# Mapping product
|
| 64 |
+
def mapping_product(information, json_path, normalization_rule):
|
| 65 |
+
# Load from product JSON file
|
| 66 |
+
with open(json_path, "r", encoding="utf-8") as f:
|
| 67 |
+
product_id_dict = json.load(f)
|
modules/normalization.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
|
| 3 |
+
# Normalize the key before mapping
|
| 4 |
+
def normalization(text, normalization_rule):
|
| 5 |
+
# Load normalization rule:
|
| 6 |
+
with open(normalization_rule, "r", encoding="utf-8") as f:
|
| 7 |
+
replace_dict = json.load(f)
|
| 8 |
+
|
| 9 |
+
# Lowercase the text
|
| 10 |
+
text = text.lower()
|
| 11 |
+
# Replace the words
|
| 12 |
+
for old, new in replace_dict.items():
|
| 13 |
+
text = text.replace(old.lower(), new.lower())
|
| 14 |
+
# # Remove diacritics
|
| 15 |
+
# text = unicodedata.normalize('NFD', text)
|
| 16 |
+
# text = ''.join(c for c in text if unicodedata.category(c) != 'Mn')
|
| 17 |
+
|
| 18 |
+
return text.strip()
|
modules/saving.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import pandas as pd
|
| 4 |
+
|
| 5 |
+
# Write the json result
|
| 6 |
+
def saving_json(data, json_path: str):
|
| 7 |
+
try:
|
| 8 |
+
# Ensure the directory exists
|
| 9 |
+
os.makedirs(os.path.dirname(json_path), exist_ok=True)
|
| 10 |
+
|
| 11 |
+
# Write the data to the JSON file
|
| 12 |
+
with open(json_path, "w", encoding="utf-8") as f:
|
| 13 |
+
json.dump(data, f, ensure_ascii=False, indent=4)
|
| 14 |
+
|
| 15 |
+
print(f"Data successfully saved to: {json_path}")
|
| 16 |
+
except Exception as e:
|
| 17 |
+
print(f"Failed to save JSON file. Error: {e}")
|
| 18 |
+
|
| 19 |
+
def saving_excel(data: pd.DataFrame, excel_path: str):
|
| 20 |
+
try:
|
| 21 |
+
# Ensure the directory exists
|
| 22 |
+
os.makedirs(os.path.dirname(excel_path), exist_ok=True)
|
| 23 |
+
|
| 24 |
+
# Save DataFrame to Excel file
|
| 25 |
+
data.to_excel(excel_path, index=False)
|
| 26 |
+
|
| 27 |
+
print(f"Data successfully saved to: {excel_path}")
|
| 28 |
+
except Exception as e:
|
| 29 |
+
print(f"Failed to save Excel file. Error: {e}")
|
modules/transformation.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
|
| 3 |
+
# JSON to Excel Template
|
| 4 |
+
def json_to_dms_excel(res, employee_code=""):
|
| 5 |
+
columns = [
|
| 6 |
+
"STT *",
|
| 7 |
+
"Số thứ tự đơn hàng *",
|
| 8 |
+
"Mã nhân viên kinh doanh *",
|
| 9 |
+
"Tên nhân viên kinh doanh",
|
| 10 |
+
"Mã tự sinh đại lý mua *",
|
| 11 |
+
"Tên đại lý mua",
|
| 12 |
+
"Mã tự sinh đại lý bán *",
|
| 13 |
+
"Tên đại lý bán",
|
| 14 |
+
"Ngày đặt hàng *",
|
| 15 |
+
"Ngày giao hàng",
|
| 16 |
+
"Ghi chú",
|
| 17 |
+
"Sửa giá bán *",
|
| 18 |
+
"Chiết khấu tổng đơn hàng (%)",
|
| 19 |
+
"Mã sản phẩm *",
|
| 20 |
+
"Tên sản phẩm",
|
| 21 |
+
"Mã đơn vị tính *",
|
| 22 |
+
"Là sản phẩm? *",
|
| 23 |
+
"Số lượng *",
|
| 24 |
+
"Giá bán (bao gồm VAT)"
|
| 25 |
+
]
|
| 26 |
+
|
| 27 |
+
rows = []
|
| 28 |
+
idx = 1
|
| 29 |
+
|
| 30 |
+
for _, orders in res.items():
|
| 31 |
+
for order in orders:
|
| 32 |
+
row = {col: '' for col in columns} # Initialize all columns with empty string
|
| 33 |
+
|
| 34 |
+
row["STT *"] = idx
|
| 35 |
+
row["Số thứ tự đơn hàng *"] = order.get("order_id", idx)
|
| 36 |
+
row["Mã nhân viên kinh doanh *"] = employee_code
|
| 37 |
+
row["Tên nhân viên kinh doanh"] = order.get("saler", "")
|
| 38 |
+
row["Mã tự sinh đại lý mua *"] = order.get("buyer_id", "")
|
| 39 |
+
row["Tên đại lý mua"] = order.get("buyer", "")
|
| 40 |
+
row["Mã tự sinh đại lý bán *"] = order.get("seller_id", "")
|
| 41 |
+
row["Tên đại lý bán"] = order.get("seller", "")
|
| 42 |
+
row["Ngày đặt hàng *"] = order.get("order_date", "")
|
| 43 |
+
row["Ngày giao hàng"] = order.get("delivery_date", "")
|
| 44 |
+
row["Ghi chú"] = order.get("note", "")
|
| 45 |
+
row["Sửa giá bán *"] = order.get("change_price", "")
|
| 46 |
+
row["Chiết khấu tổng đơn hàng (%)"] = order.get("discount", "")
|
| 47 |
+
row["Mã sản phẩm *"] = order.get("product_id", "")
|
| 48 |
+
row["Tên sản phẩm"] = order.get("product_name", "")
|
| 49 |
+
row["Mã đơn vị tính *"] = order.get("unit_id", "")
|
| 50 |
+
row["Là sản phẩm? *"] = "Sản phẩm bán"
|
| 51 |
+
row["Số lượng *"] = order.get("quantity", "")
|
| 52 |
+
rows.append(row)
|
| 53 |
+
idx += 1
|
| 54 |
+
|
| 55 |
+
df = pd.DataFrame(rows, columns=columns)
|
| 56 |
+
|
| 57 |
+
# Create "End" row, first column is "End", other is blank like in the excel template
|
| 58 |
+
end_row = pd.DataFrame([["End"] + [""] * df.shape[1] - 1], columns= df.columns)
|
| 59 |
+
|
| 60 |
+
df = pd.concat([df, end_row], ignore_index= True)
|
| 61 |
+
|
| 62 |
+
return df
|
requirements.txt
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
git+https://github.com/openai/whisper.git
|
| 2 |
+
ffmpeg
|
| 3 |
+
transformers
|
| 4 |
+
accelerate
|
| 5 |
+
python-dotenv
|
| 6 |
+
rapidfuzz
|
| 7 |
+
openpyxl
|
| 8 |
+
python-dotenv
|
| 9 |
+
huggingface_hub
|
| 10 |
+
google-generativeai
|
| 11 |
+
pandas
|
| 12 |
+
google-cloud-vision
|
| 13 |
+
google-auth
|
| 14 |
+
streamlit
|
resources/cloud_vision_ai_key.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"type": "service_account",
|
| 3 |
+
"project_id": "gen-lang-client-0680794503",
|
| 4 |
+
"private_key_id": "3f1d0c6b365a57afc5f11e5627d8cd00a5436c23",
|
| 5 |
+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBKbnDskM5Ht1w\ngKUZsMvlkSFWI3INBHntrY1sTvBZnVBs0xq2NIIAnhamMAtIqBt0bYk1qNzZd/y3\nlCo59Ogla4edbZ6XaLn7lBj0qHi2j9m2IleFfRXvtSIkFueOHmbG3qUYQpSoIQMI\ngu376o5YasuBiIPvQbHiG58/30UB8DSzM+aTPfGBKv52hVRsP9U4stZ6X8H+AKoy\nH0PQyrhMBozBGdeqQO3x3LBRmWL8AM/f7Nc9yUcpO/H9C/roTWrTMH4tSAufC0Qj\nnojDSatQZQ3SEXI6R5C8K8y0VnyhGD92++2BrjK8BkQrMtSTF6g7LomFkF6sJuv5\nvY6cxMhRAgMBAAECggEAEx1jRKUKAfJhTMDDlcc+ZiP2feUEDvBidc1hhquecpUe\ntaYuU9mJA9v2YdEJ93wAkNpGDwlRfDO4znHbETaAbTOMOAf2VFqzYjHwRkW7Aas6\nisuF3a/Ye+AbgMwYyKI5iXR+4ee0zkPLXmGWgKy1aV/Sw6lpZO5wq+9lKEJFPJZc\nbf8I5QI91W+fG9qYE15H5AOO+XGsgKv+gHFh2xfmZ4eJI1d1/VJWrCpmHHa4WtJZ\nYxBDOY9qqYICSTR7wYwYRhSdX3vrErfppJDIVzQlHDseV80Bc6YoIX7QSzygWrR0\nV6Ob/meSYhuH+RQXaoCyZ59pF8pR+w4mENu6OuLQAQKBgQDz0za9DMQnn/HMSZrb\n+lNFBZFV2G63FiEE3yJTSFSC3MCDPSd1dNPEDJ9Oh0AfhWv/ieyHVmGS7VuqwMMD\n7ANQFlhkS5xXc9qN+Liq1SytCFpEZEzVbeaCYNNBvuJbeAI8yiB/qCk6+Zocflbs\n9Sj1Aa7oXbl1ZYyckNi8r8Tz+wKBgQDKzueghglBXb6zaByhk/0r5gwfERLpwrI0\naYTZTcLH+8akdFge3K03bZ5YQaG0dHl9YqxGQMZGMoinootLlu1LtFXcCRfrK35U\nM4n9MZ7SsAh5himCqtDNNnCuxcklSsp4F7N/CIlbloE7EnzwF+2PG1JWjjsoOLPz\nPQiXxR23IwKBgEDB8iHXyCk2A8RcMDMIkyEbz3PbXdxmljJzCOzRoxB2jPLORTKe\n6reBGraCmXdFul9ORHHVcWjSfawmMiVSg7a7mJJaupVHgd5/FpzYrVrvgvnzIaz1\n2Wj7SmCF0By3DPEURflhskGllVbH/1JD8rLP1aKFcgJKDERw+/9xN4ANAoGBAJrJ\nbalrg3bbOKgvBuMfUvQFQS0Y1+mHyoEMI/PCUK5XcFWl4nezj5SlWlwbw3I6D1tu\nSvPXjjyXZwsimNPZXkUQXxNv8Uxwxps3NtMC4ygEaINvrRDolDJ7oWcS16FZwswD\nsuB6wHMhnIJcavTIHmzBuocLSQU6ucUkyQEk1bgnAoGATz+x4X9FLz6e/tVHnBJ5\nXG1EfenUJMLQCVsDq6ine/n5Mz+2ngsOu2b8W6PGNabisfCE0e/xJM/TYw5jJ9vf\nYHf0+4h4BWKom4vlQHb/FgZXzS85oPJ7kY9IGzpWa2A0IKFBHabD9roT3tDYv9Qq\nBfT1Cl41UTsqYre+nDGNX/c=\n-----END PRIVATE KEY-----\n",
|
| 6 |
+
"client_email": "vision-api-sa@gen-lang-client-0680794503.iam.gserviceaccount.com",
|
| 7 |
+
"client_id": "104243194869318851804",
|
| 8 |
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
| 9 |
+
"token_uri": "https://oauth2.googleapis.com/token",
|
| 10 |
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
| 11 |
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/vision-api-sa%40gen-lang-client-0680794503.iam.gserviceaccount.com",
|
| 12 |
+
"universe_domain": "googleapis.com"
|
| 13 |
+
}
|
resources/employee.json
ADDED
|
@@ -0,0 +1,566 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
" Nguyễn Tuấn Vũ": "TG.VuNT",
|
| 3 |
+
"Ngô Sỹ Kiên": "TV01.KienNS",
|
| 4 |
+
"Huỳnh Hiếu Nghĩa": "TG.NghiaHH",
|
| 5 |
+
"Cao Hoàng Hải": "HCM.HaiCH",
|
| 6 |
+
"Phạm Ngọc Đệ": "HCM.DePN",
|
| 7 |
+
"Dương Quốc Hưng": "PN.HungDQ",
|
| 8 |
+
"Trần Bảo Ngân": "HCM.NganTB",
|
| 9 |
+
"Trần Việt Hoàng": "NT.HoangTV",
|
| 10 |
+
"Hồ Xuân Thuận": "TV01.ThuanHX",
|
| 11 |
+
"Trần Xuân Mạnh": "TV01.ManhTX",
|
| 12 |
+
"La Mạnh Toàn": "TV02.ToanLM",
|
| 13 |
+
"Ngô Tiến Thành": "TV02.ThanhNT",
|
| 14 |
+
"Trần Mạnh Hùng": "TV01.HungTM",
|
| 15 |
+
"Lê Vũ Duy": "TT2.DuyLV",
|
| 16 |
+
"Nguyễn Đức Tuấn": "TT2.TuanND",
|
| 17 |
+
"Phan Thanh Tâm": "TG.TamPT",
|
| 18 |
+
"Ngô Minh Đẳng": "TG.DangNM",
|
| 19 |
+
"Nguyễn Văn Giám": "RD.GiamNV",
|
| 20 |
+
"Nguyễn Ngọc Nghĩa": "RD.NghiaNN",
|
| 21 |
+
"Đinh Hồng Dương": "TV02.DuongDH",
|
| 22 |
+
"Đoàn Nguyễn Huy Hoàng": "TN.HoangDNH",
|
| 23 |
+
"Ngô Thanh Bình": "DN.BinhNT",
|
| 24 |
+
"Đặng Huỳnh Nam Anh": "DN.AnhDHN",
|
| 25 |
+
"Lưu Liên Thảo": "TMDT.ThaoLL",
|
| 26 |
+
"Bùi Thị Anh Thư": "BH.ThuBTA",
|
| 27 |
+
"Đỗ Nam Anh": "TV01.AnhDN",
|
| 28 |
+
"Châu Hoài Duy": "TG.DuyCH",
|
| 29 |
+
"Nguyễn Diệu Linh": "TV03.LinhND",
|
| 30 |
+
"Bùi Thị Linh Chi": "TMDT.ChiBTL",
|
| 31 |
+
"Nguyễn Thị Bích Ngọc": "TMDT.NgocNTB",
|
| 32 |
+
"Lê Việt Hòa": "PR.HoaLV",
|
| 33 |
+
"Nguyễn Văn Hùng": "CT.HungNV",
|
| 34 |
+
"Dương Văn Phúc": "DN.PhucDV",
|
| 35 |
+
"Đào Ngô Bích Hồng": "RD.hongDNB",
|
| 36 |
+
"Lê Văn Thành": "RD.thanhlv",
|
| 37 |
+
"Đào Văn Phú": "Xled.phudv",
|
| 38 |
+
"Nguyễn Xuân Dũng": "TN.DungNX",
|
| 39 |
+
"Trần Bình Minh": "TMDT.MinhTB",
|
| 40 |
+
"Võ Thành Long": "HCM.LongVT",
|
| 41 |
+
"Nguyễn Tuấn Dũng": "TV02.DungNT",
|
| 42 |
+
"Trang GS": "Tv01.TrangtestGS",
|
| 43 |
+
"Nguyễn Minh Tâm": "TG.TamNM",
|
| 44 |
+
"Thái Phi Châu": "NT.ChauTP",
|
| 45 |
+
"Đào Khắc Khương": "TV02.KhuongDK",
|
| 46 |
+
"Nguyễn Viết Luận": "NT.LuanNV",
|
| 47 |
+
"Phạm Minh Đức": "TMDT.Ducpm",
|
| 48 |
+
"DLUQ_CN_TN_GiaBao": "DLUQ_CN_TN_GiaBao",
|
| 49 |
+
"DLUQ_CN_NT_Khangan": "DLUQ_CN_NT_Khangan",
|
| 50 |
+
"DLUQ_V2_SHome": "DLUQ_V2_SHome",
|
| 51 |
+
"DLUQ_V2_HN_A Hoàng": "DLUQ_V2_HN_TBD15",
|
| 52 |
+
"Cập nhật SP 1": "TMDT.SanPham1",
|
| 53 |
+
"Vũ Văn Quang": "TV03.QuangVV",
|
| 54 |
+
"Đỗ Thị Lý": "QLHT.LyDT",
|
| 55 |
+
"Trần Đăng Khoa": "HCM.KhoaTD",
|
| 56 |
+
"Huỳnh Công Hải": "TN.HaiHC",
|
| 57 |
+
"Đặng Hồng Phúc": "HCM.PhucDH",
|
| 58 |
+
"Dương Lý Đức": "CT.DucDL",
|
| 59 |
+
"Phan Đăng Phú": "TN.PhuPD",
|
| 60 |
+
"DLUQ_CN_HCM_ACT": "DLUQ_CN_HCM_ACT",
|
| 61 |
+
"DLUQ_CN_BH_BRVT": "DLUQ_CN_BH_BRVT",
|
| 62 |
+
"DLUQ_CN_BH_BT_HienHau": "DLUQ_CN_BH_BT_HienHau",
|
| 63 |
+
"DLUQ_CN_BH_BP_DuongHa": "DLUQ_CN_BH_BP_DuongHa",
|
| 64 |
+
"DLUQ_CN_BH_BD_SongThang": "DLUQ_CN_BH_BD_SongThang",
|
| 65 |
+
"DLUQ_CN_BH_DN_VinhQuang": "DLUQ_CN_BH_DN_VinhQuang",
|
| 66 |
+
"DLUQ_CN_TG_TruongXuan": "DLUQ_CN_TG_TruongXuan",
|
| 67 |
+
"DLUQ_CN_TN_ThanhMai": "DLUQ_CN_TN_ThanhMai",
|
| 68 |
+
"DLUQ_CN_DN_NhatBich": "DLUQ_CN_DN_NhatBich",
|
| 69 |
+
"DLUQ_V3_HN": "DLUQ_V3_HN",
|
| 70 |
+
"DLUQ_V3_PT_Saka": "DLUQ_V3_PT_Saka",
|
| 71 |
+
"DLUQ_V2_HN_Smartree": "DLUQ_V2_HN_Smartree",
|
| 72 |
+
"DLUQ_V2_HN_QuangTuan": "DLUQ_V2_HN_QuangTuan",
|
| 73 |
+
"DLUQ_V2_HN_Kingsway": "DLUQ_V2_HN_Kingsway",
|
| 74 |
+
"DLUQ_V1_TH_NgaSang": "DLUQ_V1_TH_NgaSang",
|
| 75 |
+
"DLUQ_V1_TH_NhatThinh": "DLUQ_V1_TH_NhatThinh",
|
| 76 |
+
"DLUQ_V1_TH_LuongThuy": "DLUQ_V1_TH_LuongThuy",
|
| 77 |
+
"Phạm Anh Thơ": "TV01.ThoPA",
|
| 78 |
+
"Nguyễn Kim Long": "TV02.LongNK",
|
| 79 |
+
"Bùi Quang Tiến": "BH.TienBQ",
|
| 80 |
+
"Đồng Văn Quảng": "BH.QuangDV",
|
| 81 |
+
"Nguyễn Thị Thu Phong": "HCM.PhongNTT",
|
| 82 |
+
"Phạm Mạnh Tùng": "BH.TungPM",
|
| 83 |
+
"Nguyễn Thị Ngọc Châm": "CT.ChamNTN",
|
| 84 |
+
"Trần Thị Thu Hiền": "TN.HienTTT",
|
| 85 |
+
"Nguyễn Thị Thu Phương": "NT.PhuongNTT",
|
| 86 |
+
"Lê Thị Thạo": "DN.ThaoLT",
|
| 87 |
+
"Nguyễn Ngọc Bảo Thiện": "TG.ThienNNB",
|
| 88 |
+
"Nguyễn Văn Phong (V3)": "TV03.PhongNV",
|
| 89 |
+
"App Dịch vụ": "appdv",
|
| 90 |
+
"Nguyễn Đình Quốc Trung": "TN.TrungNDQ",
|
| 91 |
+
"Đoàn Thị Thanh Thảo": "NCTT.ThaoDT",
|
| 92 |
+
"Đỗ Hải Triều": "NCTT.TrieuDH",
|
| 93 |
+
"Nguyễn Trọng Nghĩa": "CT.NghiaNT",
|
| 94 |
+
"Nguyễn Văn Huy": "TV03.HuyNV",
|
| 95 |
+
"Admin Test": "Admintest",
|
| 96 |
+
"TMDT.TrangDT": "TMDT.trangdt",
|
| 97 |
+
"Vũ Đức Cường": "TMDT.Cuongvd",
|
| 98 |
+
"Tài khoản giám sát test app đại lý 02": "TK.GS.TESTAPPDAILY02",
|
| 99 |
+
"Tài khoản giám sát test app đại lý 01": "TK.GS.TESTAPPDAILY01",
|
| 100 |
+
"Tài khoản test app đại lý 02": "TK.TESTAPPDAILY02",
|
| 101 |
+
"Tài khoản test app đại lý 01": "TK.TESTAPPDAILY01",
|
| 102 |
+
"Hoàng Phú Thừa": "TN.ThuaHP",
|
| 103 |
+
"Vũ Nguyễn Quỳnh Nga": "PR.NgaLVQ",
|
| 104 |
+
"Nguyễn Đình Thiện": "TN.ThienND",
|
| 105 |
+
"SangDV": "C4LED.SangDV1",
|
| 106 |
+
"Dien97": "C4LED.Dien97",
|
| 107 |
+
"HuyND": "C4LED.HuyND",
|
| 108 |
+
"HoangND": "C4LED.HoangND",
|
| 109 |
+
"HungTM": "C4LED.HungTM",
|
| 110 |
+
"Lê Anh Dũng": "FPT.dungla15",
|
| 111 |
+
"Lê Ngọc Tú": "TMDT.tunl",
|
| 112 |
+
"Phạm Hồng Nhung": "TMDT.nhungph",
|
| 113 |
+
"ThauTho_Admin_CN_BH": "ThauTho_Admin_CN_BH",
|
| 114 |
+
"ThauTho_Admin_CN_TG": "ThauTho_Admin_CN_TG",
|
| 115 |
+
"ThauTho_Admin_CN_CT": "ThauTho_Admin_CN_CT",
|
| 116 |
+
"ThauTho_Admin_CN_HCM": "ThauTho_Admin_CN_HCM",
|
| 117 |
+
"ThauTho_Admin_V3": "ThauTho_Admin_V3",
|
| 118 |
+
"ThauTho_Admin_V2": "ThauTho_Admin_V2",
|
| 119 |
+
"ThauTho_Admin_V1": "ThauTho_Admin_V1",
|
| 120 |
+
"Bùi Thị Mỹ Tiên": "CT.TienBTM",
|
| 121 |
+
"Hà Đình Thi": "TV03.ThiHD",
|
| 122 |
+
"Lã Mạnh Toán": "TV01.ToanLM",
|
| 123 |
+
"Nguyễn Thị Hoa": "RD.HoaNT",
|
| 124 |
+
"Nguyệt VTS": "vts.nguyetta",
|
| 125 |
+
"ThauTho_Call": "ThauTho_Call",
|
| 126 |
+
"ThauTho_CV": "ThauTho_CV",
|
| 127 |
+
"ThauTho_Admin": "ThauTho_Admin",
|
| 128 |
+
"Chu Thị Khuyên": "KT.KhuyenCT",
|
| 129 |
+
"Lê Văn Từ": "HCM.TuLV",
|
| 130 |
+
"Nguyễn Hà Nhật Thanh": "NT.ThanhNHN",
|
| 131 |
+
"Nguyễn Văn Bi": "NT.BiNV",
|
| 132 |
+
"Nguyễn Thành Long": "TV01.LongNT",
|
| 133 |
+
"Nguyễn Thành Nhân": "TG.NhanNT",
|
| 134 |
+
"Đỗ Văn Thuận": "TV02.ThuanDV",
|
| 135 |
+
"Bùi Tứ Trực": "BH.TrucBT",
|
| 136 |
+
"Đặng Hồng Kiên": "TV03.KienDH",
|
| 137 |
+
"Huỳnh Kinh Kha": "CT.KhaHK",
|
| 138 |
+
"Hoàng Trọng Công": "BH.CongHT",
|
| 139 |
+
"Lê Thu Hà": "xk.halt",
|
| 140 |
+
"Hoàng Trung Kiên": "TV02.KienHT",
|
| 141 |
+
"Ngô Văn Cương": "TV01.CuongNV",
|
| 142 |
+
"Nguyễn Huy Phúc Đạt": "datnhp",
|
| 143 |
+
"Hoàng Ngọc Minh Huy": "HCM.HuyHNM",
|
| 144 |
+
"Support": "support.it",
|
| 145 |
+
"Nguyễn Phương Lâm": "BH.LamNP",
|
| 146 |
+
"Nguyễn Trọng Hiếu": "hieunt.pntt",
|
| 147 |
+
"Trần Vinh Quy": "C4LED.QuyTV",
|
| 148 |
+
"Đinh Văn Sáng": "C4LED.SangDV",
|
| 149 |
+
"report": "report.ecom",
|
| 150 |
+
"Ralli Smart IOT": "RalliSmart",
|
| 151 |
+
"Nguyễn Khắc Quý": "TV03.QuyNK",
|
| 152 |
+
"Bùi Quang Thái": "HCM.ThaiBQ",
|
| 153 |
+
"Võ Nhật Hào": "NCTT.HaoVN",
|
| 154 |
+
"Mạc Kế Minh": "TT2.MinhMK",
|
| 155 |
+
"Võ Văn Duy": "TT2.DuyVV",
|
| 156 |
+
"Mai Bảo Linh": "RD.LinhMB",
|
| 157 |
+
"Bùi Trần Bảo Linh": "RD.LinhBTB",
|
| 158 |
+
"Nguyễn Lê Lâm": "TT2.LamNL",
|
| 159 |
+
"Trần Nghiệp Đoàn": "RD.DoanTN",
|
| 160 |
+
"Đặng Hồ Đắc Trung": "TT2.TrungDHD",
|
| 161 |
+
"Lê Nam Thành": "PPMN.ThanhLN",
|
| 162 |
+
"Nguyễn Thị Hồng Liên": "RD.LienNTH",
|
| 163 |
+
"NCTT.QT": "NCTT",
|
| 164 |
+
"Trần Thị Loan": "KH.LoanTT",
|
| 165 |
+
"Nguyễn Duy Ngọc": "BH.NgocND",
|
| 166 |
+
"Hà Minh Khang": "TN.KhangHM",
|
| 167 |
+
"Nguyễn Thắng Lợi": "TN.LoiNT",
|
| 168 |
+
"K Văn Diu": "TN.DiuKV",
|
| 169 |
+
"Nguyễn Thanh Thiện": "TT4.ThienNT",
|
| 170 |
+
"Dư Chấn Hưng": "TT4.HungDC",
|
| 171 |
+
"Trần Phạm Diệu Linh": "RD.LinhTPD",
|
| 172 |
+
"Nguyễn Hoàng Hà": "NCTT.HaNH",
|
| 173 |
+
"Hoàng Thị Hường": "PTT.HuongHT",
|
| 174 |
+
"HienHT": "HienHT",
|
| 175 |
+
"Nguyễn Hoàng Gia": "HCM.GiaNH",
|
| 176 |
+
"Phan Tuấn Vũ": "CT.VuPT",
|
| 177 |
+
"Nguyễn Hải": "DN.HaiN",
|
| 178 |
+
"Quách Tiến Đạt": "CT.DatQT",
|
| 179 |
+
"Trần Văn Cường": "TV03.CuongTV",
|
| 180 |
+
"Phạm Đức Long": "TV03.LongPD",
|
| 181 |
+
"Nguyễn Ngọc Tuấn Minh": "NCTT.MinhNNT",
|
| 182 |
+
"Lại Phi Hùng": "NT.HungLP",
|
| 183 |
+
"Dương Văn Trung (TMDT)": "TMDT.TrungDV",
|
| 184 |
+
"Ngô Hải Đường": "CT.DuongNH",
|
| 185 |
+
"Vũ Thị Tuyết": "gdv.tuyetvt",
|
| 186 |
+
"Nguyễn Tiến Thành": "NT.ThanhNT",
|
| 187 |
+
"Phùng Quốc Khánh": "TMDT.khanhpq",
|
| 188 |
+
"Kiều Thanh Dương": "C4LED.duongkt",
|
| 189 |
+
"Vũ Thế Song": "TV02.SongVT",
|
| 190 |
+
"Nguyễn Quang Long": "TV02.LongNQ",
|
| 191 |
+
"Nguyễn Văn Phong": "Tv01.PhongNV",
|
| 192 |
+
"Giảng Công Tràng": "CT.TrangGC",
|
| 193 |
+
"Trần Ngọc Minh": "TV01.MinhTN",
|
| 194 |
+
"Test05": "test05",
|
| 195 |
+
"Hà Văn Quy": "TV01.QuyHV",
|
| 196 |
+
"Nguyễn Quang Huy": "TV03.HuyNQ",
|
| 197 |
+
"Lâm Minh Phúc": "BH.PhucLM",
|
| 198 |
+
"Mai Tiến Huy": "BH.HuyMT",
|
| 199 |
+
"KIM VĂN VINH": "RD.VinhKV",
|
| 200 |
+
"Nguyễn Văn Trường": "DN.TruongNV",
|
| 201 |
+
"Huỳnh Thắng Lợi": "TN.LoiHT",
|
| 202 |
+
"Lê Bá Sơn": "TN.SonLB",
|
| 203 |
+
"Vũ Quang Trung": "TV03.TrungVQ",
|
| 204 |
+
"Nguyễn Văn Sang": "TV03.SangNV",
|
| 205 |
+
"Nguyễn Hoài Nam": "TV02.NamNH",
|
| 206 |
+
"Tạ Quang Dướng": "HCM.DuongTQ",
|
| 207 |
+
"Nguyễn Hoài Thương": "CT.ThuongNH",
|
| 208 |
+
"Nguyễn Xuân Vinh": "TG.VinhNX",
|
| 209 |
+
"Đặng Văn Ninh": "HCM.NinhDV",
|
| 210 |
+
"Trần Nhân Kha": "HCM.KhaTN",
|
| 211 |
+
"Lê Thanh Thảo": "TN.ThaoLT",
|
| 212 |
+
"Hiệp": "hiep",
|
| 213 |
+
"nule": "nule",
|
| 214 |
+
"Nguyễn Thanh Đông": "BH.DongNT",
|
| 215 |
+
"Vũ Mai Phương": "xk.phuongmv",
|
| 216 |
+
"Quách Ngọc Ánh": "xk.anhqn",
|
| 217 |
+
"Phạm Yến Ngọc": "xk.ngocpy",
|
| 218 |
+
"Lê Kim Thành": "TV02.ThanhLK",
|
| 219 |
+
"Bùi Gia Thế": "TV03.TheBG",
|
| 220 |
+
"Nguyễn Hải Đăng (CT)": "TV02.DangNH1",
|
| 221 |
+
"Hoàng Trung Kiên TT1": "TT1.KienHT",
|
| 222 |
+
"Nguyễn Trung Hiếu": "TT1.HieuNT",
|
| 223 |
+
"Lê Chí Bảo": "TG.BaoLC",
|
| 224 |
+
"Đinh Xuân Đạo": "DN.DaoDX",
|
| 225 |
+
"Nguyễn Hải Ninh": "DN.NinhNH",
|
| 226 |
+
"Nguyễn Trọng Tuấn": "RD.TuanNT",
|
| 227 |
+
"Trần Đình Hinh": "RD.HinhTD",
|
| 228 |
+
"Phạm Anh Dũng": "RD.DungPA",
|
| 229 |
+
"Nguyễn Văn Trinh": "RD.TrinhNV",
|
| 230 |
+
"Trần Đức Thắng": "RD.ThangTD",
|
| 231 |
+
"Đặng Văn Ba": "RD.BaDV",
|
| 232 |
+
"Nguyễn Thị Thu Hương": "RD.HuongNTT",
|
| 233 |
+
"Nguyễn Đăng Chuyên": "TV02.ChuyenND",
|
| 234 |
+
"Trần Tùng Lâm": "TV02.LamTT",
|
| 235 |
+
"Lê Văn Nam Trường": "NCTT.TruongLVN",
|
| 236 |
+
"Phạm Duy Đức": "NCTT.DucPD",
|
| 237 |
+
"Trần Thị Diễm": "CT.diemtt",
|
| 238 |
+
"Nguyễn Minh Thư": "MN.thumn",
|
| 239 |
+
"Phạm Thị Thu": "tn.thupt",
|
| 240 |
+
"Đỗ Phượng": "BH1.phuongdo",
|
| 241 |
+
"Nguyễn Bá Huy": "tmdt.huynb",
|
| 242 |
+
"Sầm Mạnh Sơn": "TV03.SonSM",
|
| 243 |
+
"Nguyễn Hoàng Long (CT)": "TV03.LongNH",
|
| 244 |
+
"Hoàng Văn Tiến": "BH.TienHV",
|
| 245 |
+
"Huỳnh Đức Toàn": "BH.ToanHD",
|
| 246 |
+
"Phòng Kế hoạch - Xem đơn": "kh.xem",
|
| 247 |
+
"Phòng Kế hoạch - Xử lý đơn": "kh.xuly",
|
| 248 |
+
"Truyền thống V3 - Xem đơn OH": "tv03.xemdon",
|
| 249 |
+
"Truyền thống V3 - Tạo đơn OH": "tv03.taodon",
|
| 250 |
+
"Truyền thống V2 - Xem đơn OH": "tv02.xemdon",
|
| 251 |
+
"Truyền thống V2 - Tạo đơn OH": "tv02.taodon",
|
| 252 |
+
"Truyền thống V1 - Xem đơn OH": "tv01.xemdon",
|
| 253 |
+
"Truyền thống V1 - Tạo đơn OH": "tv01.taodon",
|
| 254 |
+
"Tây Nguyên - Xem đơn OH": "tn.xemdon",
|
| 255 |
+
"Tây Nguyên - Tạo đơn OH": "tn.taodon",
|
| 256 |
+
"Tiền Giang - Xem đơn OH": "tg.xemdon",
|
| 257 |
+
"Tiền Giang - Tạo đơn OH": "tg.taodon",
|
| 258 |
+
"Nha Trang - Xem đơn OH": "nt.xemdon",
|
| 259 |
+
"Nha Trang - Tạo đơn OH": "nt.taodon",
|
| 260 |
+
"Đà Nẵng - Xem đơn OH": "dn.xemdon",
|
| 261 |
+
"Đà Nẵng - Tạo đơn OH": "dn.taodon",
|
| 262 |
+
"Biên Hòa - Xem đơn OH": "bh.xemdon",
|
| 263 |
+
"Biên Hòa - Tạo đơn OH": "bh.taodon",
|
| 264 |
+
"Cần Thơ - Xem đơn OH": "ct.xemdon",
|
| 265 |
+
"Cần Thơ - Tạo đơn OH": "ct.taodon",
|
| 266 |
+
"Hồ Chí Minh - Xem đơn OH": "hcm.xemdon",
|
| 267 |
+
"Hồ Chí Minh - Tạo đơn OH": "hcm.taodon",
|
| 268 |
+
"Nguyễn Văn Vũ": "TV02.VuNV",
|
| 269 |
+
"Phan Văn Đạt": "TV02.DatPV",
|
| 270 |
+
"Phạm Hải": "TT4.HaiP",
|
| 271 |
+
"Khuất Thị Sâm": "QLHT.SamKT",
|
| 272 |
+
"Nguyễn Hoàng Kiên": "XLED.kiennh",
|
| 273 |
+
"Nguyễn Xuân Tùng": "TV03.TungNX",
|
| 274 |
+
"Nguyễn Hồng Sơn": "HCM.SonNH",
|
| 275 |
+
"Hoàng Quốc Việt": "TV03.VietHQ",
|
| 276 |
+
"Đào Thị Nhung": "TV02.NhungDT",
|
| 277 |
+
"Vũ Tuấn Dũng": "TV01.DungVT",
|
| 278 |
+
"Nguyễn Anh Quang": "TV01.QuangNA",
|
| 279 |
+
"Ngô Đức Hoài": "TT1.HoaiND",
|
| 280 |
+
"Huỳnh Tống": "DN.TongH",
|
| 281 |
+
"Trần Tuấn Dương": "tmdt.duongtt",
|
| 282 |
+
"Lê Thị Trang": "rd.tranglt",
|
| 283 |
+
"Vũ Duy Hải": "rd.haivd",
|
| 284 |
+
"Trần Thị Hiền": "HCM.HienTT",
|
| 285 |
+
"Nguyễn Mai Anh": "xk.anhnm",
|
| 286 |
+
"Nguyễn Thanh Hóa": "TG.HoaNT",
|
| 287 |
+
"Trần Việt Dũng": "TV03.DungTV",
|
| 288 |
+
"R&D_NV1": "R&D.NV1",
|
| 289 |
+
"Kiều Thanh Ly": "C4LED.lykt",
|
| 290 |
+
"Đào Phú Hội": "DN.HoiDP",
|
| 291 |
+
"Lê Tuấn Anh": "GDV_anhlt",
|
| 292 |
+
"Phạm Hải Nam": "BH.NamPH",
|
| 293 |
+
"Bùi Hưng": "TV02.HungB",
|
| 294 |
+
"Đoàn Giang Nam": "TV03.NamDG",
|
| 295 |
+
"Nguyễn Đình Quý": "TV03.QuyND",
|
| 296 |
+
"Nguyễn Văn Duy": "TV03.DuyNV",
|
| 297 |
+
"Hoàng Văn Tín": "BH.TinHV",
|
| 298 |
+
"Trần Anh Quân": "HCM.QuanTA",
|
| 299 |
+
"Nguyễn Quyết Chiến": "CT.ChienNQ",
|
| 300 |
+
"Nguyễn Ngọc Hải": "NT.HaiNN",
|
| 301 |
+
"Hoàng Văn Huân": "bh.huanhv",
|
| 302 |
+
"Sơn Đại": "CT.DaiS",
|
| 303 |
+
"Chu Thị Ngọc Diệp": "c4led.diepctn",
|
| 304 |
+
"Nguyễn Thị Thanh": "c4led.thanhnt",
|
| 305 |
+
"Kiều Hoài Trung (CTDA)": "CT.TrungKH",
|
| 306 |
+
"Trần Viết Hùng": "TV01.HungTV",
|
| 307 |
+
"Đõ Thị Hồng Nhung": "TMDT.Nhungdth",
|
| 308 |
+
"Phạm Quang Tiến": "TMDT.Tienpq",
|
| 309 |
+
"Lê Hồng Ánh": "TMDT.Anhlh",
|
| 310 |
+
"Đinh Thị Yến": "TMDT.Yendt",
|
| 311 |
+
"Phan Thanh Tâm (TMĐT)": "TMDT.Tampt",
|
| 312 |
+
"trangnt": "TTKDCS.trangnt",
|
| 313 |
+
"Trang nguyễn": "TN.trangnt",
|
| 314 |
+
"trang nguyễn": "QTHT.trangnt",
|
| 315 |
+
"trangnt175": "TV02.trang",
|
| 316 |
+
"nguyễn Trang V1": "TV01.trangnt",
|
| 317 |
+
"Nguyễn Trang": "CT.Trangnt",
|
| 318 |
+
"nguyễn Trang": "TT3.Trangnt",
|
| 319 |
+
"trang nguỹen": "HCM.trangnt",
|
| 320 |
+
"Nguyễn Trang QLBH2": "QLBH2.trangnt",
|
| 321 |
+
"Nguyễn Trang QLBH": "QLBH1.trangnt",
|
| 322 |
+
"Nguyễn Thu Trang": "gdv.trangthunt",
|
| 323 |
+
"Hằng TMĐT": "tmdt.hangntt",
|
| 324 |
+
"Hà Đức Trung": "DN.TrungHD",
|
| 325 |
+
"Nguyễn Ngọc Hiền": "TG.Hiennn",
|
| 326 |
+
"Nguyễn Tấn Thành": "TG.Thanhnt",
|
| 327 |
+
"Lê Văn Duy": "TN.Duylv",
|
| 328 |
+
"Khúc Minh Thu": "qlht.thukm",
|
| 329 |
+
"Nguyễn Hữu Thắng": "KST.Thangnh",
|
| 330 |
+
"Lê Hùng Quân": "KST.Quanlh",
|
| 331 |
+
"Phạm Tuấn Thành": "TT1.Thanhpt",
|
| 332 |
+
"Trần Thu Trang": "xk.trangtt",
|
| 333 |
+
"Nguyễn Thị Thu Trà": "xk.trantt",
|
| 334 |
+
"Lê Thúy Hạnh": "xk.hanhlt",
|
| 335 |
+
"Lê Hà My": "xk.mylh",
|
| 336 |
+
"Chu Thị Trang": "xk.trangct",
|
| 337 |
+
"Đỗ Đức Đại": "xk.daidd",
|
| 338 |
+
"Đỗ Huyền Trang": "xk.trangdh",
|
| 339 |
+
"Vũ Thị Nguyên": "xk.nguyenvt",
|
| 340 |
+
"Nguyễn Thùy Dung": "xk.dungnt",
|
| 341 |
+
"Trần Trung Hiếu": "xk.hieutt",
|
| 342 |
+
"Đinh Thị Vân": "xk.vandt",
|
| 343 |
+
"Đỗ Việt Tùng": "xk.tungdv",
|
| 344 |
+
"Phạm Đức Tuấn": "xk.tuanpd",
|
| 345 |
+
"Nguyễn Thanh Xuân": "xk.xuannt",
|
| 346 |
+
"Nguyễn Đoàn Thanh": "xk.thanhnd",
|
| 347 |
+
"Hoàng Ngọc Anh": "TV01.Anhhn",
|
| 348 |
+
"Nguyễn Tiến Dũng": "NCTT.Dungnt",
|
| 349 |
+
"Đào Xuân Dũng": "TT2.DungDX",
|
| 350 |
+
"Nguyễn Thế Kỳ Nam": "dn.namntk",
|
| 351 |
+
"Nguyễn Đắc Hùng": "TT1.hungnd",
|
| 352 |
+
"Biên tập nội dung SAMS": "SAMS",
|
| 353 |
+
"Lê Tấn Phát": "TV02.PhatLT",
|
| 354 |
+
"Trần Văn Tiến": "gdv_tientv",
|
| 355 |
+
"Nguyễn Tuấn Tân": "TMDT.Tannt",
|
| 356 |
+
"Kiều Thanh Loan": "gdv_loankt",
|
| 357 |
+
"Bùi Ngọc Thu": "gdv_thubn",
|
| 358 |
+
"Nguyễn Thuỳ Trang": "gdv_trangnt",
|
| 359 |
+
"Lê Thị Thuý Hiền": "C4LED.HienLTT",
|
| 360 |
+
"Nguyễn Văn Diễn": "gdv_diennv",
|
| 361 |
+
"Đặng Quỳnh Trang": "hoasao02",
|
| 362 |
+
"Nguyễn Thị Minh Hoa": "hoasao01",
|
| 363 |
+
"Nguyễn Văn Tỉnh": "TN.TinhNV",
|
| 364 |
+
"Đặng Thanh Hải": "BH.HaiDT",
|
| 365 |
+
"Ngô Thị kim Oanh": "NT.OanhNTK",
|
| 366 |
+
"Võ Thị Kim Anh": "TG.AnhVTK",
|
| 367 |
+
"Phạm Vũ Thiện": "TT1.ThienPV",
|
| 368 |
+
"Chu Minh Quân": "TT1.QuanCM",
|
| 369 |
+
"Lê Việt Hùng": "TT1.HungLV",
|
| 370 |
+
"Lã Thị Hải Yến": "PPMB.YenLTH",
|
| 371 |
+
"Nguyễn Lê Thăng": "PPMB.ThangNL",
|
| 372 |
+
"Tôn Nữ Thanh Thiện": "PPMN.ThienTNT",
|
| 373 |
+
"Lê Minh Tuấn": "PPMN.TuanLM",
|
| 374 |
+
"Đào Thị Ngát": "QLHT.NgatDT",
|
| 375 |
+
"Nguyễn thị Kim Ngân": "KH.NganNTK",
|
| 376 |
+
"Khúc Chí Tùng": "KH.TungKC",
|
| 377 |
+
"Quách Thành Chương": "KH.ChuongQT",
|
| 378 |
+
"Nguyễn Văn Thảo": "C4LED.ThaoNV",
|
| 379 |
+
"Lê Ngọc Lâm": "C4LED.LamLN",
|
| 380 |
+
"Lê Đức Anh": "C4LED.AnhLD",
|
| 381 |
+
"Nguyễn Triệu Sơn": "C4LED.SonNT",
|
| 382 |
+
"Trần Thanh Hải": "TV03.HaiTT",
|
| 383 |
+
"Lương Phước Tạo": "CT.TaoLP",
|
| 384 |
+
"Mai Việt Bình": "TV03.BinhMV",
|
| 385 |
+
"Xuong": "Xuong",
|
| 386 |
+
"C4LED": "C4LED",
|
| 387 |
+
"Trangnt": "CRM.Trangnt",
|
| 388 |
+
"Nguyễn Phi Long": "TV03.LongNP",
|
| 389 |
+
"Võ Tòng Bá": "CT.BaVT",
|
| 390 |
+
"Trần Nhật Tuấn": "tv03.tuantn",
|
| 391 |
+
"Nguyễn Văn Thiện": "dn.thiennv",
|
| 392 |
+
"Mai Phúc Huy": "HCM.HuyMP",
|
| 393 |
+
"Huỳnh Thị Bích Thúy": "TMDT.ThuyHTB",
|
| 394 |
+
"Nguyễn Ngọc Thiện": "TT3.ThienNN",
|
| 395 |
+
"Nguyễn Trọng Phan": "TV02.PhanNT",
|
| 396 |
+
"Phạm Đắc Quyết": "TV02.QuyetPD",
|
| 397 |
+
"Bùi Văn Minh": "HCM.MinhBV",
|
| 398 |
+
"Vũ Thế Hiếu": "TMDT.hieuvt",
|
| 399 |
+
"Võ Trần Chánh": "BH.ChanhVT",
|
| 400 |
+
"test02": "test02",
|
| 401 |
+
"Nguyễn Văn Minh": "TV03.MinhNV",
|
| 402 |
+
"Lê Tuấn Anh (TMDT)": "TMDT.AnhLT",
|
| 403 |
+
"Phạm Minh Thảo": "TG.ThaoPM",
|
| 404 |
+
"Trần Viết Bình": "TT3.BinhTV",
|
| 405 |
+
"Lượng Phú Thấp": "NT.ThapLP",
|
| 406 |
+
"Đỗ Trường Giang": "TV03.GiangDT",
|
| 407 |
+
"Hà Quân Hiệu": "TV03.HieuHQ",
|
| 408 |
+
"Lương Quang Thắng": "TV02.ThangLQ",
|
| 409 |
+
"Nguyễn Thế Công": "TV02.CongNT",
|
| 410 |
+
"Vũ Đức Khoa": "TV02.KhoaVD",
|
| 411 |
+
"Đào Văn Thảo": "TV02.ThaoDV",
|
| 412 |
+
"Ngô Huy Xuân": "TV02.XuanNH",
|
| 413 |
+
"Hồ Sỹ Dũng": "TV01.DungHS",
|
| 414 |
+
"Lê Văn Linh": "TV01.LinhLV",
|
| 415 |
+
"Trần Bá Tăng": "TV01.TangTB",
|
| 416 |
+
"Trần Tiến Dương": "TV01.DuongTT",
|
| 417 |
+
"Phạm Văn Anh": "TV02.Anhpv",
|
| 418 |
+
"Nguyễn Quốc Dũng": "TT2.DungNQ",
|
| 419 |
+
"Võ Quang Thiện": "TT2.ThienVQ",
|
| 420 |
+
"Nguyễn Hoàng Nam": "TG.NamNH",
|
| 421 |
+
"Nguyễn Hồng Đăng": "TG.DangNH",
|
| 422 |
+
"Nguyễn Thành Khương": "NT.KhuongNT",
|
| 423 |
+
"Ngô Quốc Huy": "NT.HuyNQ",
|
| 424 |
+
"Phan Tấn Linh": "NT.LinhPT",
|
| 425 |
+
"Bùi Vĩnh Nguyên": "HCM.NguyenBV",
|
| 426 |
+
"Trần Phú Cường": "HCM.CuongTP",
|
| 427 |
+
"Trần Ngọc Trọng": "HCM.TrongTN",
|
| 428 |
+
"Nguyễn Thụy Hồng Đô": "HCM.DoNTH",
|
| 429 |
+
"Vũ Hồng Vân": "DN.VanVH",
|
| 430 |
+
"Tống Phước Anh Duy": "DN.DuyTPA",
|
| 431 |
+
"Thái Thành Trung": "DN.TrungTT",
|
| 432 |
+
"Lê Trúc": "DN.TrucLe",
|
| 433 |
+
"Nguyễn Trọng Nguyễn": "CT.NguyenNT",
|
| 434 |
+
"Nguyễn Đức Phục": "CT.PhucND",
|
| 435 |
+
"Lý Văn Bình": "CT.BinhLV",
|
| 436 |
+
"Đào Thị Thu Hường": "BH.HuongDTT",
|
| 437 |
+
"Lưu văn Tuấn": "BH.TuanLV",
|
| 438 |
+
"Vũ Thanh Tuấn": "BH.TuanVT",
|
| 439 |
+
"Nguyễn Hữu Duyên": "BH.DuyenNH",
|
| 440 |
+
"Nguyễn Văn Quyết": "TV02.QuyetNV",
|
| 441 |
+
"Nguyễn Hải Đăng": "TV02.DangNH",
|
| 442 |
+
"Nguyễn Duy Quang": "HCM.QuangND",
|
| 443 |
+
"Trần Phước Huy": "DN.HuyTP",
|
| 444 |
+
"Nguyễn Long Thái": "rd.thainl",
|
| 445 |
+
"App Reviewer": "app.reviewer",
|
| 446 |
+
"Nguyễn Anh Đức": "rd.ducna",
|
| 447 |
+
"Hoàng Thanh Thủy": "ppmb.thuyht",
|
| 448 |
+
"Trần Mạnh Dũng": "TV02.DungTM",
|
| 449 |
+
"Nguyễn Duy Hải": "tv02.haind",
|
| 450 |
+
"Trần Văn Nhân": "TV03.NhanTV",
|
| 451 |
+
"Trần Lê Mạnh": "TV03.ManhTL",
|
| 452 |
+
"Hà Tùng Lâm": "TV03.LamHT",
|
| 453 |
+
"Nguyễn Hồng Hoàng": "TV03.HoangNH",
|
| 454 |
+
"Trần Thanh Hiếu": "TV03.HieuTT",
|
| 455 |
+
"Lê Chính Cương": "TV03.CuongLC",
|
| 456 |
+
"Ngô Pháp Anh": "TV03.AnhNP",
|
| 457 |
+
"Trần Minh Việt": "TV02.VietTM",
|
| 458 |
+
"Ngô Quang Vấn": "TV02.VanNQ",
|
| 459 |
+
"Đinh Trọng Uẩn": "TV02.UanDT",
|
| 460 |
+
"Phạm Tiến Tùy": "TV02.TuyPT",
|
| 461 |
+
"Đỗ Văn Tùng": "TV02.TungDV",
|
| 462 |
+
"Dương Quốc Trung": "TV02.TrungDQ",
|
| 463 |
+
"Nguyễn Văn Thế": "TV02.TheNV",
|
| 464 |
+
"Ngô Ngọc Thanh": "TV02.ThanhNN",
|
| 465 |
+
"Nguyễn Văn Rinh": "TV02.RinhNV",
|
| 466 |
+
"Nguyễn Văn Quynh": "TV02.QuynhNV",
|
| 467 |
+
"Đinh Văn Quyết": "TV02.QuyetDV",
|
| 468 |
+
"Trần Văn Long": "TV02.LongTV",
|
| 469 |
+
"Văn Tiến Lợi": "TV02.LoiVT",
|
| 470 |
+
"Vũ Văn Khởi": "TV02.KhoiVV",
|
| 471 |
+
"Trần Văn Đồng": "TV02.DongTV",
|
| 472 |
+
"Nguyễn Văn Cương": "TV02.CuongNV",
|
| 473 |
+
"Nguyễn Ngọc Anh": "TV02.AnhNN",
|
| 474 |
+
"Đỗ Tuấn Anh": "TV02.AnhDT",
|
| 475 |
+
"Nguyễn Minh Toàn": "TV01.ToanNM",
|
| 476 |
+
"Bùi Văn Thọ": "TV01.ThoBV",
|
| 477 |
+
"Bùi Tất Thành": "TV01.ThanhBT",
|
| 478 |
+
"Nguyễn Hồng Lĩnh": "TV01.LinhNH",
|
| 479 |
+
"Đoàn Văn Liêu": "TV01.LieuDV",
|
| 480 |
+
"Nguyễn Văn Lập": "TV01.LapNV",
|
| 481 |
+
"Đỗ Văn Khởi": "TV01.KhoiDV",
|
| 482 |
+
"Đỗ Hưng Hà": "TV01.HaDH",
|
| 483 |
+
"Bùi Văn Hùng": "TV01.HungBV",
|
| 484 |
+
"Lê Minh Hiếu": "TV01.HieuLM",
|
| 485 |
+
"Tạ Văn Dương": "TV01.DuongTV",
|
| 486 |
+
"Dương Quốc Chung": "TV01.ChungDQ",
|
| 487 |
+
"Vũ Thái Bình": "TV01.BinhVT",
|
| 488 |
+
"Nguyễn Anh Toàn": "TN.ToanNA",
|
| 489 |
+
"Nguyễn Lương Sự": "TN.SuNL",
|
| 490 |
+
"Đàm Nguyễn Vi Nhân": "TN.NhanDV",
|
| 491 |
+
"Nguyễn Anh Minh": "TN.MinhNA",
|
| 492 |
+
"Nguyễn Văn Hoàng": "TN.HoangNV",
|
| 493 |
+
"Đinh Song Hào": "TN.HaoDS",
|
| 494 |
+
"Bùi Hồ Vũ": "TG.VuBH",
|
| 495 |
+
"Nguyễn Ngọc Tú": "TG.TuNN",
|
| 496 |
+
"Phạm Minh Tuấn": "TG.TuanPM",
|
| 497 |
+
"Nguyễn Anh Tuấn": "TG.TuanNA",
|
| 498 |
+
"Võ Minh Trường": "TG.TruongVM",
|
| 499 |
+
"Phan Minh Trí": "TG.TriPM",
|
| 500 |
+
"Huỳnh Kim Phát": "TG.PhatHK",
|
| 501 |
+
"Phan Văn Hiếu": "TG.HieuPV",
|
| 502 |
+
"Nguyễn Văn Đồi": "TG.DoiNV",
|
| 503 |
+
"Võ Trường An": "TG.AnVT",
|
| 504 |
+
"Quản lý BH1": "PPMB.QLBH1",
|
| 505 |
+
"Nguyễn Ngọc Anh Tú": "NT.TuNNA",
|
| 506 |
+
"Trần Ngọc Sơn": "NT.SonTN",
|
| 507 |
+
"Nguyễn Thái Huy": "NT.HuyNT",
|
| 508 |
+
"Lê Hoài Bảo": "NT.BaoLH",
|
| 509 |
+
"Lương Minh Tuyển": "NCTT.TuyenLM",
|
| 510 |
+
"Trần Xuân Tùng": "NCTT.TungTX",
|
| 511 |
+
"Phạm Đoàn Thắng": "NCTT.ThangPD",
|
| 512 |
+
"Trần Quốc Phong": "NCTT.PhongTQ",
|
| 513 |
+
"Trần Xuân Chính": "NCTT.ChinhTX",
|
| 514 |
+
"Nguyễn Văn Quí": "CT.QuiNV",
|
| 515 |
+
"Trần Trung Liệt": "CT.LietTT",
|
| 516 |
+
"Nguyễn Văn Bé Hai": "CT.HaiNVB",
|
| 517 |
+
"Quản Minh Hoàng Việt": "HCM.VietQMH",
|
| 518 |
+
"Đặng Mạnh Vĩ": "HCM.ViDM",
|
| 519 |
+
"Phan Thanh Tú": "HCM.TuPT",
|
| 520 |
+
"Nguyễn Hoàng Tú": "HCM.TuNH",
|
| 521 |
+
"Nguyễn Trọng Minh Trường": "HCM.TruongNTM",
|
| 522 |
+
"Trần Đức Trọng": "HCM.TrongTD",
|
| 523 |
+
"Nguyễn Hoàng Thiện": "HCM.ThienNH",
|
| 524 |
+
"Huỳnh Ngọc Thành": "HCM.ThanhHN",
|
| 525 |
+
"Đỗ Tiến Quang": "HCM.QuangDT",
|
| 526 |
+
"Phạm Hoàng Minh": "HCM.MinhPH",
|
| 527 |
+
"Nguyễn Văn Luận": "HCM.LuanNV",
|
| 528 |
+
"Nguyễn Sĩ Long": "HCM.LongNS",
|
| 529 |
+
"Nguyễn Minh Đạt": "HCM.DatNM",
|
| 530 |
+
"Nguyễn Văn Binh": "HCM.BinhNV",
|
| 531 |
+
"Ngô Quang Vinh": "DN.VinhNQ",
|
| 532 |
+
"Dương Trung": "DN.TrungDuong",
|
| 533 |
+
"Trần Hồ Bảo Toàn": "DN.ToanTHB",
|
| 534 |
+
"Lê Minh Toàn": "DN.ToanLM",
|
| 535 |
+
"Nguyễn Quý": "DN.QuyN",
|
| 536 |
+
"Phan Thế Phú": "TT2.PhuPT",
|
| 537 |
+
"Nguyễn Thành Nam (TT2)": "TT2.NamNT",
|
| 538 |
+
"Lê Đình Nam": "DN.NamLD",
|
| 539 |
+
"Vương Văn Linh": "DN.LinhVV",
|
| 540 |
+
"Trần Như Lành": "DN.LanhTN",
|
| 541 |
+
"Nguyễn Văn Lâm": "DN.LamNV",
|
| 542 |
+
"Nguyễn Đức Khánh": "DN.KhanhND",
|
| 543 |
+
"Nguyễn Văn Cả": "DN.CaNV",
|
| 544 |
+
"Nguyễn Văn Bình": "DN.BinhNV",
|
| 545 |
+
"Đặng Phạm Minh Trung": "CT.TrungDPM",
|
| 546 |
+
"Nguyễn Trung Thảo": "CT.ThaoNT",
|
| 547 |
+
"Huỳnh Vỉnh Nông": "CT.NongHV",
|
| 548 |
+
"Nguyễn Tuấn Anh": "CT.AnhNT",
|
| 549 |
+
"Nguyễn Xuân Thương": "BH.ThuongNX",
|
| 550 |
+
"Dương Quốc Nguyên": "BH.NguyenDQ",
|
| 551 |
+
"Đinh Xuân Ngọc": "BH.NgocDX",
|
| 552 |
+
"Đặng Hải Nam": "BH.NamDH",
|
| 553 |
+
"Phạm Thành Minh": "BH.MinhPT",
|
| 554 |
+
"Phạm Anh Linh": "BH.LinhPA",
|
| 555 |
+
"Nguyễn Quốc Hậu": "BH.HauNQ",
|
| 556 |
+
"Bùi Đức Hạo": "BH.HaoBD",
|
| 557 |
+
"Nguyễn Phạm Duy": "BH.DuyNP",
|
| 558 |
+
"Bùi Nguyên Dũng": "BH.DungBN",
|
| 559 |
+
"Nguyễn Thế Đoàn": "BH.DoanNT",
|
| 560 |
+
"Vũ Thái An": "BH.AnVT",
|
| 561 |
+
"Đặng Ngọc Anh": "BH.AnhDN",
|
| 562 |
+
"Nguyễn Xuân Trường": "CT.TruongNX",
|
| 563 |
+
"Mai Văn An": "CT.AnMV",
|
| 564 |
+
"Test 01": "Test01",
|
| 565 |
+
"Administrator": "Administrator"
|
| 566 |
+
}
|
resources/merchant.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
resources/normalization_rule.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cửa hàng": "ch"
|
| 3 |
+
}
|
resources/product.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
resources/unit.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"Mét": "M",
|
| 3 |
+
"Bộ": "Bo",
|
| 4 |
+
"Cuộn": "Cuon",
|
| 5 |
+
"Chiếc": "Chiec",
|
| 6 |
+
"Thùng 10": "Thung10",
|
| 7 |
+
"Cái": "Cai"
|
| 8 |
+
}
|