commit af07bbc36bf4509df82531544bd2cf23459eb4b8 Author: sebastian Date: Tue Mar 17 16:22:20 2026 -0500 Configuracion final de back con serve diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e308772 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Entorno virtual +venv/ +ENV/ +env/ +.venv/ + +# Archivos de configuración del entorno +.env +*.env + +# Python cache +__pycache__/ +*.py[cod] +*$py.class + +# Logs y archivos temporales +*.log +*.sqlite3 +*.db +*.DS_Store +*.egg-info/ +*.egg + +# IDEs y editores +.vscode/ +.idea/ +*.sublime-project +*.sublime-workspace + +# Otros +*.pyc \ No newline at end of file diff --git a/Back_comercial_iko/README.md b/Back_comercial_iko/README.md new file mode 100644 index 0000000..e69de29 diff --git a/Back_comercial_iko/app/comercial/Main_comercial.py b/Back_comercial_iko/app/comercial/Main_comercial.py new file mode 100644 index 0000000..ff983a8 --- /dev/null +++ b/Back_comercial_iko/app/comercial/Main_comercial.py @@ -0,0 +1,16 @@ +from fastapi import APIRouter +from Back_comercial_iko.services.Comercial_service import ComercialService +from Back_comercial_iko.core.Response import ApiResponse +from Back_comercial_iko.core.HttpStatus import HttpStatus + + +router = APIRouter(prefix="/comercial", tags=["Comercial"]) + +@router.post("/create-project") +def create_project(data: dict): + try: + service = ComercialService() + result = service.create_project_commercial(data) + return ApiResponse.success(result,"Proyecto creado",HttpStatus.CREATED) + except Exception as e: + return ApiResponse.error(str(e),HttpStatus.NOT_FOUND) \ No newline at end of file diff --git a/Back_comercial_iko/core/Auth.py b/Back_comercial_iko/core/Auth.py new file mode 100644 index 0000000..676a1b2 --- /dev/null +++ b/Back_comercial_iko/core/Auth.py @@ -0,0 +1,48 @@ +import jwt +from datetime import datetime, timedelta +from typing import Dict, Any +from core.Config import settings + + +class TokenManager: + """ + Handles token generation and validation + """ + + @classmethod + def generate(cls, payload: Dict[str, Any]) -> str: + data = cls._add_expiration(payload) + + return jwt.encode( + data, + settings.token_secret_key, + algorithm=settings.token_algorithm + ) + + @classmethod + def verify(cls, token: str) -> Dict[str, Any]: + + try: + return jwt.decode( + token, + settings.token_secret_key, + algorithms=[settings.token_algorithm] + ) + + except jwt.ExpiredSignatureError: + raise ValueError("Token expired") + + except jwt.InvalidTokenError: + raise ValueError("Invalid token") + + @classmethod + def _add_expiration(cls, payload: Dict[str, Any]) -> Dict[str, Any]: + + expiration = datetime.utcnow() + timedelta( + minutes=settings.token_expire_minutes + ) + + data = payload.copy() + data["exp"] = expiration + + return data \ No newline at end of file diff --git a/Back_comercial_iko/core/Config.py b/Back_comercial_iko/core/Config.py new file mode 100644 index 0000000..73dbea3 --- /dev/null +++ b/Back_comercial_iko/core/Config.py @@ -0,0 +1,15 @@ +from pydantic_settings import BaseSettings + + +class Settings(BaseSettings): + + token_secret_key: str + token_algorithm: str + token_expire_minutes: int + + class Config: + env_file = ".env" + extra = "ignore" + + +settings = Settings() \ No newline at end of file diff --git a/Back_comercial_iko/core/ExceptionHandler.py b/Back_comercial_iko/core/ExceptionHandler.py new file mode 100644 index 0000000..6647f5d --- /dev/null +++ b/Back_comercial_iko/core/ExceptionHandler.py @@ -0,0 +1,16 @@ +from fastapi.responses import JSONResponse +from fastapi.exceptions import RequestValidationError +from fastapi import Request +from Back_comercial_iko.core.HttpStatus import HttpStatus + + +async def validation_exception_handler(request: Request, exc: RequestValidationError): + + return JSONResponse( + status_code=HttpStatus.BAD_REQUEST, + content={ + "success": False, + "message": "Formato de request inválido", + "error_code": "INVALID_JSON" + } + ) \ No newline at end of file diff --git a/Back_comercial_iko/core/HttpStatus.py b/Back_comercial_iko/core/HttpStatus.py new file mode 100644 index 0000000..abbc8f5 --- /dev/null +++ b/Back_comercial_iko/core/HttpStatus.py @@ -0,0 +1,14 @@ +class HttpStatus: + """ + Common HTTP status codes used in the API + """ + OK = 200 + CREATED = 201 + NO_CONTENT = 204 + BAD_REQUEST = 400 + UNAUTHORIZED = 401 + FORBIDDEN = 403 + NOT_FOUND = 404 + CONFLICT = 409 + UNPROCESSABLE_ENTITY = 422 + INTERNAL_SERVER_ERROR = 500 \ No newline at end of file diff --git a/Back_comercial_iko/core/Response.py b/Back_comercial_iko/core/Response.py new file mode 100644 index 0000000..82092b2 --- /dev/null +++ b/Back_comercial_iko/core/Response.py @@ -0,0 +1,53 @@ +from fastapi.responses import JSONResponse +from typing import Any, Optional +from Back_comercial_iko.core.HttpStatus import HttpStatus + + +class ApiResponse: + + @staticmethod + def success( + data: Optional[Any] = None, + message: str = "Success", + status_code: int = HttpStatus.OK + ): + + return JSONResponse( + status_code=status_code, + content={ + "success": True, + "message": message, + "data": data + } + ) + + @staticmethod + def error( + message: str, + status_code: int = HttpStatus.BAD_REQUEST, + data: Optional[Any] = None + ): + + return JSONResponse( + status_code=status_code, + content={ + "success": False, + "message": message, + "data": data + } + ) + + @staticmethod + def exception( + exception: Exception, + status_code: int = HttpStatus.INTERNAL_SERVER_ERROR + ): + + return JSONResponse( + status_code=status_code, + content={ + "success": False, + "message": str(exception), + "data": None + } + ) \ No newline at end of file diff --git a/Back_comercial_iko/core/SocieteNotFoundException.py b/Back_comercial_iko/core/SocieteNotFoundException.py new file mode 100644 index 0000000..0278f94 --- /dev/null +++ b/Back_comercial_iko/core/SocieteNotFoundException.py @@ -0,0 +1,10 @@ +class SocieteNotFoundException(Exception): + def __init__(self, societe_name=None, extra_msg=None): + base_message = "Societe not found" + if societe_name: + base_message += f": '{societe_name}'" + if extra_msg: + base_message += f" - {extra_msg}" + + self.message = base_message + super().__init__(self.message) \ No newline at end of file diff --git a/Back_comercial_iko/core/validators/Email_validator.py b/Back_comercial_iko/core/validators/Email_validator.py new file mode 100644 index 0000000..00fdaa7 --- /dev/null +++ b/Back_comercial_iko/core/validators/Email_validator.py @@ -0,0 +1,13 @@ +import re + +class EmailValidator: + + EMAIL_REGEX = r"^[\w\.-]+@[\w\.-]+\.\w+$" + + @staticmethod + def validate(email: str) -> bool: + + if not email: + return False + + return re.match(EmailValidator.EMAIL_REGEX, email) is not None \ No newline at end of file diff --git a/Back_comercial_iko/core/validators/Field_validator.py b/Back_comercial_iko/core/validators/Field_validator.py new file mode 100644 index 0000000..a8dabee --- /dev/null +++ b/Back_comercial_iko/core/validators/Field_validator.py @@ -0,0 +1,7 @@ +class FieldValidator: + + @staticmethod + def required(value, field_name: str): + + if value is None or value == "": + raise ValueError(f"{field_name} es obligatorio") \ No newline at end of file diff --git a/Back_comercial_iko/database/Database.py b/Back_comercial_iko/database/Database.py new file mode 100644 index 0000000..a859453 --- /dev/null +++ b/Back_comercial_iko/database/Database.py @@ -0,0 +1,25 @@ +import os +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from dotenv import load_dotenv + +load_dotenv() + +class Database: + + def __init__(self): + self.user = os.getenv("DB_USER") + self.password = os.getenv("DB_PASSWORD") + self.server = os.getenv("DB_HOST") + self.port = os.getenv("DB_PORT") + self.database = os.getenv("DB_NAME") + self.engine = self.getconnection() + + def getconnection(self): + return create_engine( + "mysql+pymysql://{0}:{1}@{2}/{3}".format(self.user, self.password, self.server, self.database) + ) + + def setConnection(self): + session = sessionmaker(bind=self.engine) + return session() \ No newline at end of file diff --git a/Back_comercial_iko/main.py b/Back_comercial_iko/main.py new file mode 100644 index 0000000..9cbf29b --- /dev/null +++ b/Back_comercial_iko/main.py @@ -0,0 +1,9 @@ +from fastapi import FastAPI +from fastapi.exceptions import RequestValidationError +from Back_comercial_iko.core.ExceptionHandler import validation_exception_handler +from Back_comercial_iko.app.comercial.Main_comercial import router as comercial_router + +app = FastAPI() + +app.include_router(comercial_router) +app.add_exception_handler(RequestValidationError, validation_exception_handler) \ No newline at end of file diff --git a/Back_comercial_iko/models/Projet_extrafields_model.py b/Back_comercial_iko/models/Projet_extrafields_model.py new file mode 100644 index 0000000..c66d69e --- /dev/null +++ b/Back_comercial_iko/models/Projet_extrafields_model.py @@ -0,0 +1,24 @@ +from sqlalchemy import Column, Integer, String, Date, TIMESTAMP +from sqlalchemy.ext.declarative import declarative_base +from datetime import datetime + +Base = declarative_base() + +class ProjetExtrafieldsModel(Base): + __tablename__ = "llx_projet_extrafields" + + ROWID = Column(Integer, primary_key=True, autoincrement=True, nullable=False) + TMS = Column(TIMESTAMP, nullable=True) + FK_OBJECT = Column(Integer, nullable=False) + IMPORT_KEY = Column(String(14), nullable=True) + DEVELOPER = Column(Integer, nullable=True) + TIPO = Column(String(255), nullable=True) + TIPO_COMERCIAL = Column(String(255), nullable=True) + FK_EMPLAZAMIENTO = Column(Integer, nullable=True) + LAST_CONTACT = Column(Date, nullable=True) + EX_MONTH = Column(Integer, nullable=True) + EX_MONTH2 = Column(String(50), nullable=True) + ESTADO = Column(String(150), nullable=True) + ESTADO_COMERCIAL = Column(String(150), nullable=True) + AGENCIA = Column(String(150), nullable=True) + ANUNCIANTE = Column(String(150), nullable=True) \ No newline at end of file diff --git a/Back_comercial_iko/models/Projet_model.py b/Back_comercial_iko/models/Projet_model.py new file mode 100644 index 0000000..ac37627 --- /dev/null +++ b/Back_comercial_iko/models/Projet_model.py @@ -0,0 +1,52 @@ +from sqlalchemy import Column, Integer, String, DateTime, Text, Float, Date, TIMESTAMP +from sqlalchemy.ext.declarative import declarative_base +from datetime import datetime + +Base = declarative_base() + +class ProjetModel(Base): + __tablename__ = "llx_projet" + + ROWID = Column(Integer, primary_key=True, autoincrement=True, nullable=False) + FK_SOC = Column(Integer, nullable=True) + DATEC = Column(DateTime, nullable=True) + TMS = Column(TIMESTAMP, nullable=True) + DATEO = Column(Date, nullable=True) + DATEE = Column(Date, nullable=True) + REF = Column(String(50), nullable=True) + ENTITY = Column(Integer, nullable=False, default=1) + TITLE = Column(String(255), nullable=False) + DESCRIPTION = Column(Text, nullable=True) + FK_USER_CREAT = Column(Integer, nullable=False) + FK_USER_MODIF = Column(Integer, nullable=True) + PUBLIC = Column(Integer, nullable=True) + FK_STATUT = Column(Integer, nullable=False, default=0) + FK_OPP_STATUS = Column(Integer, nullable=True) + OPP_PERCENT = Column(Float, nullable=True) + FK_OPP_STATUS_END = Column(Integer, nullable=True) + DATE_CLOSE = Column(DateTime, nullable=True) + FK_USER_CLOSE = Column(Integer, nullable=True) + NOTE_PRIVATE = Column(Text, nullable=True) + NOTE_PUBLIC = Column(Text, nullable=True) + EMAIL_MSGID = Column(String(175), nullable=True) + OPP_AMOUNT = Column(Float, nullable=True) + BUDGET_AMOUNT = Column(Float, nullable=True) + USAGE_OPPORTUNITY = Column(Integer, nullable=True, default=0) + USAGE_TASK = Column(Integer, nullable=True, default=1) + USAGE_BILL_TIME = Column(Integer, nullable=True, default=0) + USAGE_ORGANIZE_EVENT = Column(Integer, nullable=True, default=0) + DATE_START_EVENT = Column(DateTime, nullable=True) + DATE_END_EVENT = Column(DateTime, nullable=True) + LOCATION = Column(String(255), nullable=True) + ACCEPT_CONFERENCE_SUGGESTIONS = Column(Integer, nullable=True, default=0) + ACCEPT_BOOTH_SUGGESTIONS = Column(Integer, nullable=True, default=0) + MAX_ATTENDEES = Column(Integer, nullable=True, default=0) + PRICE_REGISTRATION = Column(Float, nullable=True) + PRICE_BOOTH = Column(Float, nullable=True) + MODEL_PDF = Column(String(255), nullable=True) + IP = Column(String(250), nullable=True) + LAST_MAIN_DOC = Column(String(255), nullable=True) + IMPORT_KEY = Column(String(14), nullable=True) + EXTRAPARAMS = Column(String(255), nullable=True) + CREATED_AT = Column(DateTime, default=datetime.utcnow) + UPDATED_AT = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) \ No newline at end of file diff --git a/Back_comercial_iko/models/Societe_model.py b/Back_comercial_iko/models/Societe_model.py new file mode 100644 index 0000000..d7d2624 --- /dev/null +++ b/Back_comercial_iko/models/Societe_model.py @@ -0,0 +1,99 @@ +from sqlalchemy import Column, Integer, String, DateTime, Text, Float, TIMESTAMP +from sqlalchemy.ext.declarative import declarative_base +from datetime import datetime + +Base = declarative_base() + + +class SocieteModel(Base): + __tablename__ = "llx_societe" + + ROWID = Column(Integer, primary_key=True, autoincrement=True, nullable=False) + NOM = Column(String(128), nullable=True) + NAME_ALIAS = Column(String(128), nullable=True) + ENTITY = Column(Integer, nullable=False, default=1) + REF_EXT = Column(String(255), nullable=True) + STATUT = Column(Integer, nullable=True, default=0) + PARENT = Column(Integer, nullable=True) + STATUS = Column(Integer, nullable=True, default=1) + CODE_CLIENT = Column(String(24), nullable=True) + CODE_FOURNISSEUR = Column(String(24), nullable=True) + CODE_COMPTA = Column(String(24), nullable=True) + CODE_COMPTA_FOURNISSEUR = Column(String(24), nullable=True) + ADDRESS = Column(String(255), nullable=True) + ZIP = Column(String(25), nullable=True) + TOWN = Column(String(50), nullable=True) + FK_DEPARTEMENT = Column(Integer, nullable=True, default=0) + FK_PAYS = Column(Integer, nullable=True, default=0) + FK_ACCOUNT = Column(Integer, nullable=True, default=0) + PHONE = Column(String(20), nullable=True) + FAX = Column(String(20), nullable=True) + URL = Column(String(255), nullable=True) + EMAIL = Column(String(128), nullable=True) + SOCIALNETWORKS = Column(Text, nullable=True) + FK_EFFECTIF = Column(Integer, nullable=True, default=0) + FK_TYPENT = Column(Integer, nullable=True) + FK_FORME_JURIDIQUE = Column(Integer, nullable=True, default=0) + FK_CURRENCY = Column(String(3), nullable=True) + SIREN = Column(String(128), nullable=True) + SIRET = Column(String(128), nullable=True) + APE = Column(String(128), nullable=True) + IDPROF4 = Column(String(128), nullable=True) + IDPROF5 = Column(String(128), nullable=True) + IDPROF6 = Column(String(128), nullable=True) + TVA_INTRA = Column(String(20), nullable=True) + CAPITAL = Column(Float, nullable=True) + FK_STCOMM = Column(Integer, nullable=False, default=0) + NOTE_PRIVATE = Column(Text, nullable=True) + NOTE_PUBLIC = Column(Text, nullable=True) + MODEL_PDF = Column(String(255), nullable=True) + LAST_MAIN_DOC = Column(String(255), nullable=True) + PREFIX_COMM = Column(String(5), nullable=True) + CLIENT = Column(Integer, nullable=True, default=0) + FOURNISSEUR = Column(Integer, nullable=True, default=0) + SUPPLIER_ACCOUNT = Column(String(32), nullable=True) + FK_PROSPECTLEVEL = Column(String(12), nullable=True) + FK_INCOTERMS = Column(Integer, nullable=True) + LOCATION_INCOTERMS = Column(String(255), nullable=True) + CUSTOMER_BAD = Column(Integer, nullable=True, default=0) + CUSTOMER_RATE = Column(Float, nullable=True, default=0) + SUPPLIER_RATE = Column(Float, nullable=True, default=0) + REMISE_CLIENT = Column(Float, nullable=True, default=0) + REMISE_SUPPLIER = Column(Float, nullable=True, default=0) + MODE_REGLEMENT = Column(Integer, nullable=True) + COND_REGLEMENT = Column(Integer, nullable=True) + DEPOSIT_PERCENT = Column(String(63), nullable=True) + TRANSPORT_MODE = Column(Integer, nullable=True) + MODE_REGLEMENT_SUPPLIER = Column(Integer, nullable=True) + COND_REGLEMENT_SUPPLIER = Column(Integer, nullable=True) + TRANSPORT_MODE_SUPPLIER = Column(Integer, nullable=True) + FK_SHIPPING_METHOD = Column(Integer, nullable=True) + TVA_ASSUJ = Column(Integer, nullable=True, default=1) + LOCALTAX1_ASSUJ = Column(Integer, nullable=True, default=0) + LOCALTAX1_VALUE = Column(Float, nullable=True) + LOCALTAX2_ASSUJ = Column(Integer, nullable=True, default=0) + LOCALTAX2_VALUE = Column(Float, nullable=True) + BARCODE = Column(String(180), nullable=True) + FK_BARCODE_TYPE = Column(Integer, nullable=True, default=0) + PRICE_LEVEL = Column(Integer, nullable=True) + OUTSTANDING_LIMIT = Column(Float, nullable=True) + ORDER_MIN_AMOUNT = Column(Float, nullable=True) + SUPPLIER_ORDER_MIN_AMOUNT = Column(Float, nullable=True) + DEFAULT_LANG = Column(String(6), nullable=True) + LOGO = Column(String(255), nullable=True) + LOGO_SQUARRED = Column(String(255), nullable=True) + CANVAS = Column(String(32), nullable=True) + FK_WAREHOUSE = Column(Integer, nullable=True) + WEBSERVICES_URL = Column(String(255), nullable=True) + WEBSERVICES_KEY = Column(String(128), nullable=True) + ACCOUNTANCY_CODE_SELL = Column(String(32), nullable=True) + ACCOUNTANCY_CODE_BUY = Column(String(32), nullable=True) + TMS = Column(TIMESTAMP, nullable=True) + DATEC = Column(DateTime, nullable=True) + FK_USER_CREAT = Column(Integer, nullable=True) + FK_USER_MODIF = Column(Integer, nullable=True) + FK_MULTICURRENCY = Column(Integer, nullable=True) + MULTICURRENCY_CODE = Column(String(3), nullable=True) + IMPORT_KEY = Column(String(14), nullable=True) + CREATED_AT = Column(DateTime, default=datetime.utcnow) + UPDATED_AT = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) \ No newline at end of file diff --git a/Back_comercial_iko/models/User_model.py b/Back_comercial_iko/models/User_model.py new file mode 100644 index 0000000..ce2c11d --- /dev/null +++ b/Back_comercial_iko/models/User_model.py @@ -0,0 +1,88 @@ +from sqlalchemy import Column, Integer, String, DateTime, Text, Float, Date, TIMESTAMP +from sqlalchemy.ext.declarative import declarative_base +from datetime import datetime + +Base = declarative_base() + + +class UserModel(Base): + __tablename__ = "llx_user" + + ROWID = Column(Integer, primary_key=True, autoincrement=True, nullable=False) + ENTITY = Column(Integer, nullable=False, default=1) + REF_EMPLOYEE = Column(String(50), nullable=True) + REF_EXT = Column(String(50), nullable=True) + ADMIN = Column(Integer, nullable=True, default=0) + EMPLOYEE = Column(Integer, nullable=True, default=1) + FK_ESTABLISHMENT = Column(Integer, nullable=True, default=0) + DATEC = Column(DateTime, nullable=True) + TMS = Column(TIMESTAMP, nullable=True) + FK_USER_CREAT = Column(Integer, nullable=True) + FK_USER_MODIF = Column(Integer, nullable=True) + LOGIN = Column(String(50), nullable=False) + PASS_ENCODING = Column(String(24), nullable=True) + PASS = Column(String(128), nullable=True) + PASS_CRYPTED = Column(String(128), nullable=True) + PASS_TEMP = Column(String(128), nullable=True) + API_KEY = Column(String(128), nullable=True) + GENDER = Column(String(10), nullable=True) + CIVILITY = Column(String(6), nullable=True) + LASTNAME = Column(String(50), nullable=True) + FIRSTNAME = Column(String(50), nullable=True) + ADDRESS = Column(String(255), nullable=True) + ZIP = Column(String(25), nullable=True) + TOWN = Column(String(50), nullable=True) + FK_STATE = Column(Integer, nullable=True, default=0) + FK_COUNTRY = Column(Integer, nullable=True, default=0) + BIRTH = Column(Date, nullable=True) + BIRTH_PLACE = Column(String(64), nullable=True) + JOB = Column(String(128), nullable=True) + OFFICE_PHONE = Column(String(20), nullable=True) + OFFICE_FAX = Column(String(20), nullable=True) + USER_MOBILE = Column(String(20), nullable=True) + PERSONAL_MOBILE = Column(String(20), nullable=True) + EMAIL = Column(String(255), nullable=True) + PERSONAL_EMAIL = Column(String(255), nullable=True) + SIGNATURE = Column(Text, nullable=True) + SOCIALNETWORKS = Column(Text, nullable=True) + FK_SOC = Column(Integer, nullable=True) + FK_SOCPEOPLE = Column(Integer, nullable=True) + FK_MEMBER = Column(Integer, nullable=True) + FK_USER = Column(Integer, nullable=True) + FK_USER_EXPENSE_VALIDATOR = Column(Integer, nullable=True) + FK_USER_HOLIDAY_VALIDATOR = Column(Integer, nullable=True) + NOTE_PUBLIC = Column(Text, nullable=True) + NOTE_PRIVATE = Column(Text, nullable=True) + MODEL_PDF = Column(String(255), nullable=True) + DATELASTLOGIN = Column(DateTime, nullable=True) + DATEPREVIOUSLOGIN = Column(DateTime, nullable=True) + DATELASTPASSVALIDATION = Column(DateTime, nullable=True) + DATESTARTVALIDITY = Column(DateTime, nullable=True) + DATEENDVALIDITY = Column(DateTime, nullable=True) + IPLASTLOGIN = Column(String(250), nullable=True) + IPPREVIOUSLOGIN = Column(String(250), nullable=True) + EGROUPWARE_ID = Column(Integer, nullable=True) + LDAP_SID = Column(String(255), nullable=True) + OPENID = Column(String(255), nullable=True) + STATUT = Column(Integer, nullable=True, default=1) + PHOTO = Column(String(255), nullable=True) + LANG = Column(String(6), nullable=True) + COLOR = Column(String(6), nullable=True) + BARCODE = Column(String(255), nullable=True) + FK_BARCODE_TYPE = Column(Integer, nullable=True, default=0) + ACCOUNTANCY_CODE = Column(String(32), nullable=True) + NB_HOLIDAY = Column(Integer, nullable=True, default=0) + THM = Column(Float, nullable=True) + TJM = Column(Float, nullable=True) + SALARY = Column(Float, nullable=True) + SALARYEXTRA = Column(Float, nullable=True) + DATEEMPLOYMENT = Column(Date, nullable=True) + DATEEMPLOYMENTEND = Column(Date, nullable=True) + WEEKLYHOURS = Column(Float, nullable=True) + IMPORT_KEY = Column(String(14), nullable=True) + DEFAULT_RANGE = Column(Integer, nullable=True) + DEFAULT_C_EXP_TAX_CAT = Column(Integer, nullable=True) + NATIONAL_REGISTRATION_NUMBER = Column(String(50), nullable=True) + FK_WAREHOUSE = Column(Integer, nullable=True) + CREATED_AT = Column(DateTime, default=datetime.utcnow) + UPDATED_AT = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) \ No newline at end of file diff --git a/Back_comercial_iko/requirements.txt b/Back_comercial_iko/requirements.txt new file mode 100644 index 0000000..fa71c06 --- /dev/null +++ b/Back_comercial_iko/requirements.txt @@ -0,0 +1,20 @@ +annotated-doc==0.0.4 +annotated-types==0.7.0 +anyio==4.12.1 +click==8.3.1 +colorama==0.4.6 +fastapi==0.135.1 +greenlet==3.3.2 +h11==0.16.0 +idna==3.11 +pydantic==2.12.5 +pydantic-settings==2.13.1 +pydantic_core==2.41.5 +PyJWT==2.12.1 +PyMySQL==1.1.2 +python-dotenv==1.2.2 +SQLAlchemy==2.0.48 +starlette==0.52.1 +typing-inspection==0.4.2 +typing_extensions==4.15.0 +uvicorn==0.42.0 diff --git a/Back_comercial_iko/services/Comercial_service.py b/Back_comercial_iko/services/Comercial_service.py new file mode 100644 index 0000000..3f72745 --- /dev/null +++ b/Back_comercial_iko/services/Comercial_service.py @@ -0,0 +1,24 @@ +from Back_comercial_iko.database.Database import Database +from Back_comercial_iko.models.Societe_model import SocieteModel +from Back_comercial_iko.core.validators.Field_validator import FieldValidator +from Back_comercial_iko.core.SocieteNotFoundException import SocieteNotFoundException + +class ComercialService: + + def __init__(self): + self.conn = Database() + self.db = self.conn.setConnection() + + def create_project_commercial(self, data: dict): + + FieldValidator.required(data.get("ex_societe"), "ex_societe") + FieldValidator.required(data.get("nomUser"), "nomUser") + nombre_soc = data.get("ex_societe") + result_soc = (self.db.query(SocieteModel.ROWID, SocieteModel.NOM).filter(SocieteModel.NOM == nombre_soc).first()) + if not result_soc: + raise SocieteNotFoundException() + + return { + "fk_soc": result_soc.ROWID, + "nombre_soc": nombre_soc + } \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py new file mode 100644 index 0000000..a7f3a02 --- /dev/null +++ b/main.py @@ -0,0 +1,10 @@ +from fastapi import FastAPI +from Back_comercial_iko.main import app as backComercial + +app = FastAPI() +app.mount("/Back_comercial_iko", backComercial) + + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8000)