def upgrade(): disable_listeners() op.add_column('task', sa.Column('date', sa.Date())) from autonomie.models.task import Task from autonomie_base.models.base import DBSESSION session = DBSESSION() for task in Task.query().filter(Task.type_!='manualinvoice'): task.date = task.taskDate session.merge(task) session.flush() op.execute("alter table groups modify label VARCHAR(255);") op.execute("alter table payment modify remittance_amount VARCHAR(255);") from autonomie.models.user import User, Group for group_id, group_name, group_label in GROUPS: group = session.query(Group).filter(Group.name==group_name).first() if group is None: group = Group(name=group_name, label=group_label) session.add(group) session.flush() users = session.query(User).filter(User.primary_group==group_id) for user in users: user._groups.append(group) session.merge(user) label = u"Peut saisir/modifier/supprimer les paiements de ses factures" group_name = "payment_admin" group = Group.query().filter(Group.name==group_name).first() if group is not None: group.label = label session.merge(group)
def migrate_datas(): logger = logging.getLogger("alembic.autonomie") from autonomie_base.models.base import DBSESSION session = DBSESSION() from autonomie.models.config import Config import json from autonomie.models.files import ( File, FileType, ) json_str = Config.get_value("attached_filetypes", "[]") try: configured_filetypes = json.loads(json_str) except: logger.exception(u"Error in json str : %s" % json_str) configured_filetypes = [] if configured_filetypes: result = [] for filetype_label in configured_filetypes: if filetype_label: filetype = FileType(label=filetype_label) session.add(filetype) session.flush() result.append(filetype) for typ_ in result: query = File.query().filter_by(label=typ_.label) for file_ in query: file_.file_type_id = typ_.id session.merge(file_) session.flush()
def assign_number(cls, invoice, template): """ This function should be run within an SQL transaction to enforce sequence index unicity. """ if invoice.official_number: raise ValueError('This invoice already have an official number') cls.validate_template(template) db = DBSESSION() formatter = InvoiceNumberFormatter(invoice, cls.SEQUENCES_MAP) invoice_number = formatter.format(template) involved_sequences = cls.get_involved_sequences(invoice, template) # Create SequenceNumber objects (the index useages have not been # booked until now). for sequence, next_index in involved_sequences: sn = SequenceNumber( sequence=sequence.db_key, index=next_index, task_id=invoice.id, ) db.add(sn) db.flush() invoice.official_number = invoice_number db.merge(invoice) return invoice_number
def migrate_datas(): from autonomie_base.models.base import DBSESSION from alembic.context import get_bind from autonomie.models.user.userdatas import SocialStatusDatas session = DBSESSION() connection = get_bind() userdatas_helper = sa.Table( 'user_datas', sa.MetaData(), sa.Column('id', sa.Integer, primary_key=True), sa.Column('statut_social_status_id', sa.Integer()), sa.Column('statut_social_status_today_id', sa.Integer()), ) for userdata in connection.execute(userdatas_helper.select()): if userdata.statut_social_status_id: social_status_entry = SocialStatusDatas( step='entry', userdatas_id=userdata.id, social_status_id=userdata.statut_social_status_id ) session.add(social_status_entry) if userdata.statut_social_status_today_id: social_status_today = SocialStatusDatas( step='today', userdatas_id=userdata.id, social_status_id=userdata.statut_social_status_today_id ) session.add(social_status_today) session.flush()
def upgrade(): from autonomie.models import user from autonomie_base.models.base import DBSESSION db = DBSESSION() for u in db.query(user.User)\ .filter(user.User.userdatas==None)\ .filter(user.User.primary_group==3): situation = "sortie" if u.email: userdata = user.UserDatas( situation_situation=situation, coordonnees_firstname=u.firstname, coordonnees_lastname=u.lastname, coordonnees_email1=u.email, coordonnees_civilite=u'?', ) userdata.user_id = u.id for company in u.companies: companydata = user.CompanyDatas( title=company.goal, name=company.name, ) userdata.activity_companydatas.append(companydata) db.add(userdata) db.flush()
def migrate_datas(): logger = logging.getLogger("alembic.autonomie") from autonomie_base.models.base import DBSESSION session = DBSESSION() from autonomie.models.config import Config import json from autonomie.models.files import ( File, FileType, ) json_str = Config.get_value("attached_filetypes", "[]") try: configured_filetypes = json.loads(json_str) except: logger.exception(u"Error in json str : %s" % json_str) configured_filetypes = [] if configured_filetypes: result = [] for filetype_label in configured_filetypes: if filetype_label: filetype = FileType(label=filetype_label) session.add(filetype) session.flush() result.append(filetype) for typ_ in result: query = File.query().filter_by(label=typ_.label) for file_ in query: file_.file_type_id = typ_.id session.merge(file_) session.flush()
def upgrade(): disable_listeners() op.add_column('task', sa.Column('date', sa.Date())) from autonomie.models.task import Task from autonomie_base.models.base import DBSESSION session = DBSESSION() for task in Task.query().filter(Task.type_ != 'manualinvoice'): task.date = task.taskDate session.merge(task) session.flush() op.execute("alter table groups modify label VARCHAR(255);") op.execute("alter table payment modify remittance_amount VARCHAR(255);") from autonomie.models.user import User, Group for group_id, group_name, group_label in GROUPS: group = session.query(Group).filter(Group.name == group_name).first() if group is None: group = Group(name=group_name, label=group_label) session.add(group) session.flush() users = session.query(User).filter(User.primary_group == group_id) for user in users: user._groups.append(group) session.merge(user) label = u"Peut saisir/modifier/supprimer les paiements de ses factures" group_name = "payment_admin" group = Group.query().filter(Group.name == group_name).first() if group is not None: group.label = label session.merge(group)
def upgrade(): from autonomie_base.models.base import DBSESSION session = DBSESSION() from alembic.context import get_bind request = "select id, type_, name, creationDate, updateDate from task" conn = get_bind() result = conn.execute(request) index = 0 max_id = -1 for id_, type_, name, creationDate, updateDate in result: creationDate = format_date(creationDate) updateDate = format_date(updateDate) index += 1 node = Node( id=id_, created_at=creationDate, updated_at=updateDate, name=name, type_=type_ ) session.add(node) if index % 50 == 0: session.flush() if id_ > max_id: max_id = id_ request = "select id, name, creationDate, updateDate from project ORDER BY id DESC" result = conn.execute(request).fetchall() # We disable foreign key constraints check op.execute("SET FOREIGN_KEY_CHECKS=0;") index = 0 for id_, name, creationDate, updateDate in result: new_id = id_ + max_id creationDate = format_date(creationDate) updateDate = format_date(updateDate) index += 1 node = Node( id=new_id, created_at=creationDate, updated_at=updateDate, name=name, type_='project' ) session.add(node) # We update the foreignkeys for table in ('estimation', 'invoice', 'cancelinvoice', 'phase', 'project_customer'): op.execute("update {0} set project_id={1} where project_id={2}".format(table, new_id, id_)) # We update the project id op.execute("update project set id={0} where id={1};".format(new_id, id_)) if index % 50 == 0: session.flush() op.execute("SET FOREIGN_KEY_CHECKS=1;")
def upgrade(): from autonomie_base.models.base import DBSESSION session = DBSESSION() from alembic.context import get_bind request = "select id, type_, name, creationDate, updateDate from task" conn = get_bind() result = conn.execute(request) index = 0 max_id = -1 for id_, type_, name, creationDate, updateDate in result: creationDate = format_date(creationDate) updateDate = format_date(updateDate) index += 1 node = Node(id=id_, created_at=creationDate, updated_at=updateDate, name=name, type_=type_) session.add(node) if index % 50 == 0: session.flush() if id_ > max_id: max_id = id_ request = "select id, name, creationDate, updateDate from project ORDER BY id DESC" result = conn.execute(request).fetchall() # We disable foreign key constraints check op.execute("SET FOREIGN_KEY_CHECKS=0;") index = 0 for id_, name, creationDate, updateDate in result: new_id = id_ + max_id creationDate = format_date(creationDate) updateDate = format_date(updateDate) index += 1 node = Node(id=new_id, created_at=creationDate, updated_at=updateDate, name=name, type_='project') session.add(node) # We update the foreignkeys for table in ('estimation', 'invoice', 'cancelinvoice', 'phase', 'project_customer'): op.execute( "update {0} set project_id={1} where project_id={2}".format( table, new_id, id_)) # We update the project id op.execute("update project set id={0} where id={1};".format( new_id, id_)) if index % 50 == 0: session.flush() op.execute("SET FOREIGN_KEY_CHECKS=1;")
def user_add_command(arguments, env): """ Add a user in the database """ logger = logging.getLogger(__name__) login = get_value(arguments, 'user', 'admin.majerti') login = login.decode('utf-8') logger.debug(u"Adding a user {0}".format(login)) password = get_value(arguments, 'pwd', get_pwd()) password = password.decode('utf-8') login = Login(login=login) login.set_password(password) group = get_value(arguments, 'group', None) if group: try: login.groups.append(group) except NoResultFound: print(u""" ERROR : group %s doesn't exist, did you launched the syncdb command : autonomie-admin <fichier.ini> syncdb """ % (group, )) return db = DBSESSION() db.add(login) db.flush() firstname = get_value(arguments, 'firstname', 'Admin') lastname = get_value(arguments, 'lastname', 'Majerti') email = get_value(arguments, 'email', '*****@*****.**') user = User(login=login, firstname=firstname, lastname=lastname, email=email) db.add(user) db.flush() print(u""" User Account created : ID : {0.id} Login : {0.login.login} Firstname : {0.firstname} Lastname : {0.lastname} Email : {0.email} Groups : {0.login.groups} """.format(user)) if 'pwd' not in arguments: print(u""" Password : {0}""".format(password)) logger.debug(u"-> Done") return user
def upgrade(): from autonomie.models.company import Company from autonomie.models.files import File from autonomie_base.models.base import DBSESSION from alembic.context import get_bind from autonomie.models.config import ConfigFiles for i in ('header_id', 'logo_id',): col = sa.Column(i, sa.Integer, sa.ForeignKey('file.id')) op.add_column('company', col) query = "select id, header, logo from company;" conn = get_bind() result = conn.execute(query) session = DBSESSION() for id_, header, logo in result: company = Company.get(id_) basepath = u"%scompany/%s" % (BASEFILEPATH, id_,) if header: header_path = u"%s/header/%s" % (basepath, header) try: file_datas = load_file_struct(header_path, header) except: print("Error while loading a header") print(id_) file_datas = None if file_datas: company.header = file_datas session.add(company.header_file) session.flush() if logo: logo_path = u"%s/logo/%s" % (basepath, logo) try: file_datas = load_file_struct(logo_path, logo) except: print("Error while loading a logo") print(id_) file_datas = None if file_datas: company.logo = file_datas company = session.merge(company) session.flush() filepath = u"%s/main/logo.png" % BASEFILEPATH if os.path.isfile(filepath): ConfigFiles.set('logo.png', load_file_struct(filepath, 'logo.png')) filepath = u"%s/main/accompagnement_header.png" % BASEFILEPATH if os.path.isfile(filepath): ConfigFiles.set( 'accompagnement_header.png', load_file_struct(filepath, 'accompagnement_header.png') )
def migrate_datas(): from autonomie_base.models.base import DBSESSION session = DBSESSION() from alembic.context import get_bind connection = get_bind() from autonomie.models.user.login import Login op.execute("update groups set editable=0;") op.execute("update groups set `primary`=0;") op.execute( "update groups set `primary`=1 where name IN ('admin', 'contractor', 'manager')" ) op.execute('update accounts set civilite="Monsieur"') for user in connection.execute(user_helper.select()): login = Login( user_id=user.id, login=user.login, ) login.pwd_hash = user.password, login.active = user.active == 'Y' session.add(login) session.flush() op.execute( 'UPDATE user_groups set login_id="%s" where user_id=%s' % ( login.id, user.id ) ) op.drop_column("accounts", "login") op.drop_column("accounts", "password") op.drop_column("accounts", "active") from autonomie.models.user.user import User for userdatas in connection.execute(userdatas_helper.select()): if userdatas.user_id is None: user = User( lastname=userdatas.coordonnees_lastname, firstname=userdatas.coordonnees_firstname, email=userdatas.coordonnees_email1, civilite=userdatas.coordonnees_civilite or 'Monsieur', ) session.add(user) session.flush() connection.execute( userdatas_helper.update().where( userdatas_helper.c.id == userdatas.id ).values(user_id=user.id) ) else: user = User.get(userdatas.user_id) user.civilite = userdatas.coordonnees_civilite or 'Monsieur' session.merge(user) session.flush() op.execute('update accounts set civilite="Monsieur" where civilite is NULL')
def add_customer( **kw): #company, customer_name, customer_code, customer_lastname): customer = Customer(**kw) session = DBSESSION() session.add(customer) session.flush() print u"Added customer to %s: %s" % (customer.company.name, customer.name) return customer
def add_expense_type(type_, **kwargs): if type_ == 'km': e = ExpenseKmType(**kwargs) elif type_ == 'tel': e = ExpenseTelType(**kwargs) else: e = ExpenseType(**kwargs) session = DBSESSION() session.add(e) session.flush()
def migrate_datas(): from autonomie.models.project.types import BusinessType from autonomie.models.config import Config from autonomie.models.task.mentions import TaskMention from autonomie.models.project.mentions import BusinessTypeTaskMention from autonomie_base.models.base import DBSESSION from alembic.context import get_bind session = DBSESSION() conn = get_bind() # Collect business type ids business_type_ids = [b[0] for b in session.query(BusinessType.id)] # for each fixed config key we now use mentions for index, (doctype, key, label, title) in enumerate((( 'estimation', 'coop_estimationfooter', u"Informations sur l'acceptation des devis", u"Acceptation du devis", ), ( "invoice", "coop_invoicepayment", u"Informations de paiement pour les factures", u"Mode de paiement", ), ( "invoice", "coop_invoicelate", u"Informations sur les retards de paiement", u"Retard de paiement", ))): # We retrieve the configurated value value = Config.get_value(key, "") mention = TaskMention( order=index, label=label, title=title, full_text=value.replace('%IBAN%', "{IBAN}").replace( '%RIB%', "{RIB}").replace('%ENTREPRENEUR%', '{name}')) session.add(mention) session.flush() for btype_id in business_type_ids: rel = BusinessTypeTaskMention( task_mention_id=mention.id, business_type_id=btype_id, doctype=doctype, mandatory=True, ) session.add(rel) session.flush() op.execute( u"INSERT INTO mandatory_task_mention_rel (task_id, mention_id) \ SELECT task.id, {mention_id} from task join node on task.id=node.id where \ node.type_='{type_}'".format(mention_id=mention.id, type_=doctype))
def add_phase(project, phase_name): phase = Phase(name=phase_name) phase.project = project session = DBSESSION() session.add(phase) session.flush() print u"Added phase to %s: %s" % (project.name, phase_name) return phase
def add_customer(**kw): #company, customer_name, customer_code, customer_lastname): customer = Customer(**kw) session = DBSESSION() session.add(customer) session.flush() print u"Added customer to %s: %s" % ( customer.company.name, customer.name) return customer
def add_project(customer, company, project_name, project_code): project = Project(name=project_name, code=project_code) project.customers.append(customer) project.company = company session = DBSESSION() session.add(project) session.flush() print u"Added project to %s for %s: %s" % (company.name, customer.name, project_name) return project
def add_company(user, company_name, goal=""): company = Company() company.name = company_name company.goal = goal or u"Entreprise de %s" % user.login user.companies.append(company) session = DBSESSION() session.add(company) session.flush() print "Added company for %s: %s" % (user.login, company_name) return company
def upgrade(): from autonomie.models.task import ( TaskLine, TaskLineGroup, Task, Estimation, CancelInvoice, Invoice, ) from autonomie_base.models.base import ( DBSESSION, ) session = DBSESSION() index = 0 query = Task.query() query = query.with_polymorphic([Invoice, CancelInvoice, Estimation]) query = query.filter( Task.type_.in_(['invoice', 'estimation', 'cancelinvoice']) ) for task in query: group = TaskLineGroup(task_id=task.id, order=0) for line in task.lines: tline = TaskLine( group=group, order=line.rowIndex, description=line.description, cost=line.cost, tva=line.tva, quantity=line.quantity, ) if hasattr(line, 'product_id'): tline.product_id = line.product_id session.add(tline) if index % 100 == 0: session.flush() op.alter_column( table_name='estimation_payment', column_name='rowIndex', new_column_name='order', type_=sa.Integer, )
def assign_number(cls, invoice, template): """ This function should be run within an SQL transaction to enforce sequence index unicity. """ if invoice.official_number: raise ValueError('This invoice already have an official number') db = DBSESSION() formatter = InvoiceNumberFormatter(invoice, cls.SEQUENCES_MAP) invoice_number = formatter.format(template) involved_sequences = cls.get_involved_sequences(invoice, template) with db.begin_nested(): # Create SequenceNumber objects (the index useages have not been # booked until now). for sequence, next_index in involved_sequences: sn = SequenceNumber( sequence=sequence.db_key, index=next_index, task_id=invoice.id, ) db.add(sn) invoice.official_number = invoice_number db.merge(invoice) # Imported here to avoid circular dependencies from autonomie.models.task import Task, Invoice, CancelInvoice query = Task.query().with_polymorphic([Invoice, CancelInvoice]) query = query.filter( Task.official_number == invoice_number, Task.id != invoice.id, Task.legacy_number == False, ).scalar() if query is not None: # This case is exceptionnal, we can afford a crash here # Context manager will take care of rolling back # subtransaction. raise ValueError( 'Invoice number collision, rolling back to avoid it' ) return invoice_number
def upgrade(): from autonomie.models.task import ( TaskLine, TaskLineGroup, Task, Estimation, CancelInvoice, Invoice, ) from autonomie_base.models.base import ( DBSESSION, ) session = DBSESSION() index = 0 query = Task.query() query = query.with_polymorphic([Invoice, CancelInvoice, Estimation]) query = query.filter( Task.type_.in_(['invoice', 'estimation', 'cancelinvoice'])) for task in query: group = TaskLineGroup(task_id=task.id, order=0) for line in task.lines: tline = TaskLine( group=group, order=line.rowIndex, description=line.description, cost=line.cost, tva=line.tva, quantity=line.quantity, ) if hasattr(line, 'product_id'): tline.product_id = line.product_id session.add(tline) if index % 100 == 0: session.flush() op.alter_column( table_name='estimation_payment', column_name='rowIndex', new_column_name='order', type_=sa.Integer, )
def add_user(login, password, group, firstname="", lastname="", email=""): user = User(login=login, firstname=firstname, lastname=lastname, email=email) user.set_password(password) user.groups.append(group) session = DBSESSION() session.add(user) session.flush() print "Added %s: %s/%s" % (group, login, password) return user
def user_add(arguments, env): """ Add a user in the database """ logger = logging.getLogger(__name__) login = get_value(arguments, 'user', 'admin.majerti') login = login.decode('utf-8') logger.debug(u"Adding a user {0}".format(login)) password = get_value(arguments, 'pwd', get_pwd()) password = password.decode('utf-8') firstname = get_value(arguments, 'firstname', 'Admin') lastname = get_value(arguments, 'lastname', 'Majerti') email = get_value(arguments, 'email', '*****@*****.**') group = get_value(arguments, 'group', None) user = User(login=login, firstname=firstname, lastname=lastname, email=email) if group: user.groups.append(group) user.set_password(password) db = DBSESSION() db.add(user) db.flush() print(u""" Account created : ID : {0.id} Login : {0.login} Firstname : {0.firstname} Lastname : {0.lastname} Email : {0.email} Groups : {0.groups} """.format(user)) if 'pwd' not in arguments: print(u""" Password : {0}""".format(password)) logger.debug(u"-> Done") return user
def migrate_datas(): from autonomie_base.models.base import DBSESSION from autonomie.models.config import Config session = DBSESSION() Config.query().filter_by(app='autonomie', name='invoice_number_template').delete() prefix = session.query(Config.value).filter_by( app='autonomie', name='invoiceprefix', ).scalar() or '' default_format = Config(app='autonomie', name='invoice_number_template', value=prefix + '{SEQYEAR}') session.add(default_format) session.flush()
def upgrade(): op.add_column('node', sa.Column('_acl', sa.Text())) from autonomie_base.models.base import DBSESSION from autonomie.models.node import Node session = DBSESSION() from alembic.context import get_bind conn = get_bind() req = "select max(id) from node" result = conn.execute(req).fetchall() max_id = result[0][0] print("The new max_id is : %s" % max_id) request = "select id, coordonnees_lastname from user_datas" result = conn.execute(request) op.execute("SET FOREIGN_KEY_CHECKS=0;") for index, (id, lastname) in enumerate(result): max_id += 1 new_id = max_id node = Node( id=new_id, name=lastname, type_='userdata', ) session.add(node) # Update des relations for table in "userdatas_socialdocs", "external_activity_datas", \ "company_datas", "date_diagnostic_datas", \ "date_convention_cape_datas", "date_dpae_datas": op.execute( "update {0} set userdatas_id={1} where userdatas_id={2}". format(table, new_id, id)) # Update de la table node op.execute("update user_datas set id={0} where id={1};".format( new_id, id)) if index % 50 == 0: session.flush() op.execute("SET FOREIGN_KEY_CHECKS=1;")
def upgrade(): from autonomie_base.models.base import DBSESSION session = DBSESSION() from autonomie.models.activity import ActivityAction from alembic.context import get_bind for name in "subaction_id", "action_id": col = sa.Column(name, sa.Integer, sa.ForeignKey("activity_action.id")) op.add_column("activity", col) label_request = "select id, action_label, subaction_label from activity" conn = get_bind() result = conn.execute(label_request) already_added = {} for id, action_label, subaction_label in result: if (action_label, subaction_label) not in already_added.keys(): found = False for key, value in already_added.items(): if action_label == key[0]: action_id = value[0] found = True if not found: action = ActivityAction(label=action_label) session.add(action) session.flush() action_id = action.id subaction = ActivityAction(label=subaction_label, parent_id=action_id) session.add(subaction) session.flush() subaction_id = subaction.id already_added[(action_label, subaction_label)] = (action_id, subaction_id) else: action_id, subaction_id = already_added[(action_label, subaction_label)] op.execute("update activity set action_id={0}, subaction_id={1} \ where id={2}".format(action_id, subaction_id, id))
def upgrade(): from autonomie_base.models.base import DBSESSION session = DBSESSION() from autonomie.models.activity import ActivityAction from alembic.context import get_bind for name in "subaction_id", "action_id": col = sa.Column(name, sa.Integer, sa.ForeignKey("activity_action.id")) op.add_column("activity", col) label_request = "select id, action_label, subaction_label from activity" conn = get_bind() result = conn.execute(label_request) already_added = {} for id, action_label, subaction_label in result: if (action_label, subaction_label) not in already_added.keys(): found = False for key, value in already_added.items(): if action_label == key[0]: action_id = value[0] found = True if not found: action = ActivityAction(label=action_label) session.add(action) session.flush() action_id = action.id subaction = ActivityAction(label=subaction_label, parent_id=action_id) session.add(subaction) session.flush() subaction_id = subaction.id already_added[(action_label, subaction_label)] = (action_id, subaction_id) else: action_id, subaction_id = already_added[(action_label, subaction_label)] op.execute("update activity set action_id={0}, subaction_id={1} \ where id={2}".format(action_id, subaction_id, id))
def migrate_datas(): from autonomie_base.models.base import DBSESSION from autonomie.models.config import Config session = DBSESSION() Config.query().filter_by( app='autonomie', name='invoice_number_template' ).delete() prefix = session.query(Config.value).filter_by( app='autonomie', name='invoiceprefix', ).scalar() or '' default_format = Config( app='autonomie', name='invoice_number_template', value=prefix + '{SEQYEAR}' ) session.add(default_format) session.flush()
def add_activity_mode(label): session = DBSESSION() session.add(ActivityMode(label=label)) session.flush()
def upgrade(): from autonomie.models.task.invoice import ManualInvoice # Fix an error in table names for some installations class OldManualInvoice(DBBASE): """ Modèle pour les factures manuelles (ancienne version) """ __tablename__ = 'manualinvoice' id = Column('id', BigInteger, primary_key=True) officialNumber = Column('sequence_id', BigInteger) description = Column('libelle', String(255)) montant_ht = Column("montant_ht", Integer) tva = Column("tva", Integer) payment_ok = Column("paiement_ok", Integer) statusDate = Column("paiement_date", Date()) paymentMode = Column("paiement_comment", String(255)) taskDate = Column("date_emission", Date(), default=datetime.datetime.now) created_at = Column("created_at", DateTime, default=datetime.datetime.now) updated_at = Column("updated_at", DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now) client_id = Column('client_id', Integer, ForeignKey('customer.code')) company_id = Column('compagnie_id', Integer, ForeignKey('company.id')) if not table_exists("manualinvoice"): force_rename_table('manual_invoice', 'manualinvoice') from autonomie_base.models.base import DBSESSION for manualinv in OldManualInvoice.query().all(): m = ManualInvoice() m.montant_ht = manualinv.montant_ht m.tva = manualinv.tva m.client_id = manualinv.client_id m.company_id = manualinv.company_id m.description = manualinv.description m.CAEStatus = 'valid' if manualinv.payment_ok == '1' or manualinv.montant_ht < 0: m.CAEStatus = "resulted" if manualinv.montant_ht < 0: if manualinv.paymentMode == u"chèque": payment_mode = "CHEQUE" elif manualinv.paymentMode == u"virement": payment_mode = "VIREMENT" else: payment_mode = None if payment_mode: # We don't care about amounts since there is only one payment payment = Payment(mode=payment_mode, date=manualinv.statusDate, amount=0) m.payments.append(payment) m.statusDate = manualinv.statusDate m.taskDate = manualinv.taskDate m.creationDate = manualinv.created_at m.updateDate = manualinv.updated_at m.phase_id = 0 m.name = u"Facture manuelle %s" % manualinv.officialNumber m.officialNumber = manualinv.officialNumber m.owner_id = 0 DBSESSION.add(m)
def upgrade(): import logging logger = logging.getLogger('alembic.here') op.add_column( "user_datas", sa.Column( 'statut_social_status_today_id', sa.Integer, sa.ForeignKey('social_status_option.id'), ) ) op.add_column( "user_datas", sa.Column( "parcours_employee_quality_id", sa.Integer, sa.ForeignKey('employee_quality_option.id'), ) ) op.add_column( "user_datas", sa.Column( "situation_antenne_id", sa.Integer, sa.ForeignKey('antenne_option.id') ) ) op.add_column( "task", sa.Column( "internal_number", sa.String(40), ) ) op.add_column( "task", sa.Column("company_index", sa.Integer) ) op.execute("alter table task CHANGE sequence_number project_index int(11)") op.add_column( "task", sa.Column( "company_id", sa.Integer, sa.ForeignKey('company.id'), ) ) from autonomie_base.models.base import ( DBSESSION, ) session = DBSESSION() add_company_id(session, logger) add_company_index(session, logger) add_internal_number(session, logger) logger.warn("Adding Contract Histories") from autonomie.models.user import UserDatas, ContractHistory for id_, last_avenant in UserDatas.query('id', 'parcours_last_avenant'): if last_avenant: session.add( ContractHistory( userdatas_id=id_, date=last_avenant, number=-1 ) ) op.add_column( "date_convention_cape_datas", sa.Column('end_date', sa.Date(), nullable=True) ) op.execute("alter table customer MODIFY code VARCHAR(4);") op.execute("alter table project MODIFY code VARCHAR(4);") create_custom_treasury_modules(session, logger) from zope.sqlalchemy import mark_changed mark_changed(session)
def migrate_datas(): from autonomie.models.project.types import BusinessType from autonomie.models.config import Config from autonomie.models.task.mentions import TaskMention from autonomie.models.project.mentions import BusinessTypeTaskMention from autonomie_base.models.base import DBSESSION from alembic.context import get_bind session = DBSESSION() conn = get_bind() # Collect business type ids business_type_ids = [b[0] for b in session.query(BusinessType.id)] # for each fixed config key we now use mentions for index, (doctype, key, label, title) in enumerate(( ( 'estimation', 'coop_estimationfooter', u"Informations sur l'acceptation des devis", u"Acceptation du devis", ), ( "invoice", "coop_invoicepayment", u"Informations de paiement pour les factures", u"Mode de paiement", ), ( "invoice", "coop_invoicelate", u"Informations sur les retards de paiement", u"Retard de paiement", ) )): # We retrieve the configurated value value = Config.get_value(key, "") mention = TaskMention( order=index, label=label, title=title, full_text=value.replace( '%IBAN%', "{IBAN}").replace( '%RIB%', "{RIB}").replace( '%ENTREPRENEUR%', '{name}') ) session.add(mention) session.flush() for btype_id in business_type_ids: rel = BusinessTypeTaskMention( task_mention_id=mention.id, business_type_id=btype_id, doctype=doctype, mandatory=True, ) session.add(rel) session.flush() op.execute( u"INSERT INTO mandatory_task_mention_rel (task_id, mention_id) \ SELECT task.id, {mention_id} from task join node on task.id=node.id where \ node.type_='{type_}'".format(mention_id=mention.id, type_=doctype) )
def populate_default_datas(): """ Populate the database with missing default entries if needed """ from autonomie.models.user.userdatas import CaeSituationOption from autonomie.models.career_stage import CareerStage from autonomie.models.career_path import TypeContratOption session = DBSESSION() # Populate contract types if session.query(TypeContratOption).filter(TypeContratOption.label=="CDD").count() == 0: session.add(TypeContratOption(label=u"CDD", order=0)) if session.query(TypeContratOption).filter(TypeContratOption.label=="CDI").count() == 0: session.add(TypeContratOption(label=u"CDI", order=0)) if session.query(TypeContratOption).filter(TypeContratOption.label=="CESA").count() == 0: session.add(TypeContratOption(label=u"CESA", order=0)) session.flush() # Populate CAE situations situation_cand = session.query(CaeSituationOption).filter(CaeSituationOption.label=="Candidat").first() if situation_cand is None: situation_cand = CaeSituationOption(label=u"Candidat", order=0) session.add(situation_cand) situation_conv = session.query(CaeSituationOption).filter(CaeSituationOption.label=="En convention").first() if situation_conv is None: situation_conv = CaeSituationOption(label=u"En convention", is_integration=True) session.add(situation_conv) situation_es = session.query(CaeSituationOption).filter(CaeSituationOption.label=="Entrepreneur salarié").first() if situation_es is None: situation_es = CaeSituationOption(label=u"Entrepreneur salarié", is_integration=True) session.add(situation_es) situation_out = session.query(CaeSituationOption).filter(CaeSituationOption.label=="Sortie").first() if situation_out is None: situation_out = CaeSituationOption(label=u"Sortie") session.add(situation_out) session.flush() # Populate Career Stages if CareerStage.query().count() == 0: stage_diag = CareerStage(active=True, name="Diagnostic", cae_situation_id=None, stage_type=None, ) stage_cape = CareerStage(active=True, name="Contrat CAPE", cae_situation_id=situation_conv.id, stage_type="entry", ) stage_dpae = CareerStage(active=True, name="Contrat DPAE", cae_situation_id=None, stage_type=None, ) stage_cesa = CareerStage(active=True, name="Contrat CESA", cae_situation_id=situation_es.id, stage_type="contract", ) stage_avct = CareerStage(active=True, name="Avenant contrat", cae_situation_id=None, stage_type="amendment", ) stage_out = CareerStage(active=True, name="Sortie", cae_situation_id=situation_out.id, stage_type="exit", ) session.add(stage_diag) session.add(stage_cape) session.add(stage_dpae) session.add(stage_cesa) session.add(stage_avct) session.add(stage_out) session.flush() return ( situation_conv.id, situation_es.id, situation_out.id ), ( stage_diag.id, stage_cape.id, stage_dpae.id, stage_cesa.id, stage_avct.id, stage_out.id, )
def migrate_datas(situations_ids, stages_ids): """ Migrate parcours's data from user_datas and related tables to career_path """ from autonomie.models.career_path import CareerPath session = DBSESSION() cnx = op.get_bind() userdatas = cnx.execute("SELECT \ id,\ parcours_contract_type,\ parcours_start_date,\ parcours_end_date,\ parcours_last_avenant,\ parcours_taux_horaire,\ parcours_taux_horaire_letters,\ parcours_num_hours,\ parcours_salary,\ parcours_salary_letters,\ parcours_employee_quality_id,\ sortie_date,\ sortie_motif_id,\ sortie_type_id \ FROM user_datas") for u in userdatas: # Diagnotic diagnotics = cnx.execute("SELECT date FROM date_diagnostic_datas WHERE date>'2000-01-01' AND userdatas_id=%s" % u.id) for diagnotic in diagnotics: session.add(CareerPath(userdatas_id=u.id, career_stage_id=stages_ids[0], start_date=diagnotic.date)) # CAPE capes = cnx.execute("SELECT date, end_date FROM date_convention_cape_datas WHERE date>'2000-01-01' AND userdatas_id=%s" % u.id) for cape in capes: session.add(CareerPath( userdatas_id=u.id, career_stage_id=stages_ids[1], start_date=cape.date, end_date=cape.end_date, cae_situation_id=situations_ids[0], stage_type="entry" )) # DPAE dpaes = cnx.execute("SELECT date FROM date_dpae_datas WHERE date>'2000-01-01' AND userdatas_id=%s" % u.id) for dpae in dpaes: session.add(CareerPath(userdatas_id=u.id, career_stage_id=stages_ids[2], start_date=dpae.date)) # Contrat if u.parcours_start_date and u.parcours_contract_type is not None: from autonomie.models.career_path import TypeContratOption cdi_type = session.query(TypeContratOption).filter( TypeContratOption.label==u.parcours_contract_type.upper() ).first() if cdi_type: cdi_type_id = cdi_type.id else: cdi_type_id = None session.add(CareerPath( userdatas_id=u.id, career_stage_id=stages_ids[3], start_date=u.parcours_start_date, end_date=u.parcours_end_date, cae_situation_id=situations_ids[1], stage_type="contrat", type_contrat_id=cdi_type_id, employee_quality_id=u.parcours_employee_quality_id, taux_horaire=u.parcours_taux_horaire, num_hours=u.parcours_num_hours )) # Avenant contrat if u.parcours_last_avenant: avenants = cnx.execute("SELECT date, number FROM contract_history WHERE date>'2000-01-01' AND userdatas_id=%s" % u.id) for avenant in avenants: model_avenant = CareerPath( userdatas_id=u.id, career_stage_id=stages_ids[4], start_date=avenant.date, stage_type="amendment", amendment_number=avenant.number ) if u.parcours_last_avenant==avenant.date: model_avenant.taux_horaire=u.parcours_taux_horaire model_avenant.num_hours=u.parcours_num_hours session.add(model_avenant) # Sortie if u.sortie_date: session.add(CareerPath( userdatas_id=u.id, career_stage_id=stages_ids[5], start_date=u.sortie_date, cae_situation_id=situations_ids[2], stage_type="exit", type_sortie_id=u.sortie_type_id, motif_sortie_id=u.sortie_motif_id )) # Historique des situations changes = cnx.execute("SELECT date, situation_id FROM cae_situation_change WHERE date>'2000-01-01' AND userdatas_id=%s" % u.id) for change in changes: session.add(CareerPath(userdatas_id=u.id, start_date=change.date, cae_situation_id=change.situation_id)) # Sauvegarde du parcours de l'utilisateur session.flush()
class Anonymizer(object): def __init__(self, logger): self.us_faker = Faker() self.faker = Faker('fr_FR') self.logger = logger self.session = DBSESSION() def _zipcode(self): if hasattr(self.faker, 'zipcode'): return self.faker.zipcode() else: return self.faker.postcode() def _an_activity(self): from autonomie.models.activity import Activity, ActivityType from autonomie.models.workshop import Workshop for activity in self.session.query(Activity): for fieldname in ( 'point', 'objectifs', 'action', 'documents', 'notes' ): setattr(activity, fieldname, self.faker.text()) for workshop in self.session.query(Workshop).options(load_only('id')): workshop.description = self.faker.text() self.session.merge(workshop) type_labels = ( u"RV conseil", u"RV suivi", u"RV Gestion", u"RV Admin", u"RV RH", u"RV Compta", u"RV hebdo", u"RV Mensuel", ) for index, typ in enumerate(self.session.query(ActivityType).all()): typ.label = type_labels[index % 7] def _an_commercial(self): from autonomie.models.commercial import TurnoverProjection for t in self.session.query(TurnoverProjection): t.comment = self.faker.text() def _an_company(self): from autonomie.models.company import Company for comp in self.session.query(Company): comp.name = self.faker.company() comp.goal = self.faker.bs() comp.comments = self.faker.catch_phrase() comp.phone = self.faker.phone_number() comp.mobile = self.faker.phone_number() comp.email = self.faker.ascii_safe_email() header = build_header( u"{0}\n {1} - {2}".format(comp.name, comp.phone, comp.email) ) comp.header = {'name': 'header.png', 'data': header} self.session.execute(u"update company set cgv=''") def _an_competence(self): from autonomie.models.competence import ( CompetenceGridItem, CompetenceGridSubItem, ) for item in self.session.query(CompetenceGridItem): item.progress = self.faker.text() for item in self.session.query(CompetenceGridSubItem): item.comments = self.faker.text() def _an_config(self): from autonomie.models.config import Config, ConfigFiles Config.set('cae_admin_mail', self.faker.ascii_safe_email()) Config.set('welcome', self.faker.sentence(nb_words=15)) ConfigFiles.set( 'logo.png', { 'data': pkg_resources.resource_stream( 'autonomie', 'static/img/autonomie.jpg' ), 'filename': 'logo.jpg', } ) Config.set('coop_cgv', self.faker.paragraph(nb_sentences=40)) Config.set('coop_pdffootertitle', u"""Une activité de ma CAE SARL SCOP à \ capital variable""") Config.set('coop_pdffootercourse', u"""Organisme de formation N° de déclaration \ d'activité au titre de la FPC : xx xx xxxxx. MA CAE est exonérée de TVA pour \ les activités s'inscrivant dans le cadre de la formation professionnelle \ conformément à l'art. L920-4 du Code du travail et de l'art. 202 C de \ l'annexe II du code général des impôts""") footer = u"""RCS XXXX 000 000 000 00000 - SIRET 000 \ 000 000 000 00 - Code naf 0000Z TVA INTRACOM : FR0000000. Siège social : 10 \ rue vieille 23200 Aubusson""" Config.set('coop_pdffootercontent', footer) Config.set('coop_pdffootertext', footer) Config.set('coop_invoicepayment', u"""Par chèque libellé à l'ordre de : \ MA CAE/ %ENTREPRENEUR% à envoyer à l'adresse suivante : MA CAE/ %ENTREPRENEUR% 10 rue Vieille 23200 Aubusson Ou par virement sur le compte de MA CAE/ %ENTREPRENEUR% MA BANQUE RIB : xxxxx xxxx xxxxxxxxxxxxx IBAN : xxxx xxxx xxxx xxxx xxxx xxxx xxx BIC : MABAFRMACAXX Merci d'indiquer le numéro de facture sur le libellé de votre virement ou \ dos de votre chèque. """) Config.set("coop_invoicelate", u"""Tout retard de paiement entraînera à titre de \ clause pénale, conformément à la loi 92.1442 du 31 décembre 1992, une \ pénalité égale à un taux d'intérêt équivalent à une fois et demi le taux \ d'intérêt légal en vigueur à cette échéance. Une indemnité de 40 euros forfaitaire sera demandée en sus pour chaque \ facture payée après l’échéance fixée. Celle-ci n’est pas soumise à TVA.""") Config.set("activity_footer", footer) Config.set('workshop_footer', footer) def _an_customer(self): from autonomie.models.customer import Customer for cust in self.session.query(Customer): cust.name = self.faker.company() cust.address = self.faker.street_address() cust.zipcode = self._zipcode() cust.city = self.faker.city() cust.lastname = self.faker.last_name() cust.firstname = self.faker.first_name() cust.email = self.faker.ascii_safe_email() cust.phone = self.faker.phone_number() cust.fax = self.faker.phone_number() cust.tva_intracomm = "" cust.comments = self.faker.bs() def _an_expense(self): from autonomie.models.expense.sheet import ( BaseExpenseLine, ExpenseKmLine, Communication, ) for line in self.session.query(BaseExpenseLine): line.description = self.faker.text() for line in self.session.query(ExpenseKmLine): line.start = self.faker.city() line.end = self.faker.city() for com in self.session.query(Communication): com.content = self.faker.text() def _an_node(self): from autonomie.models.node import Node for node in self.session.query(Node): node.name = self.faker.sentence(nb_words=4, variable_nb_words=True) def _an_payment(self): from autonomie.models.payments import BankAccount for b in self.session.query(BankAccount): b.label = u"Banque : {0}".format(self.faker.company()) def _an_project(self): from autonomie.models.project import Project, Phase for p in self.session.query(Project): p.name = self.faker.sentence(nb_words=5) p.definition = self.faker.text() for p in self.session.query(Phase): if not p.name.is_default(): p.name = self.faker.sentence(nb_words=3) def _an_sale_product(self): from autonomie.models.sale_product import ( SaleProductCategory, SaleProduct, SaleProductGroup, ) for cat in self.session.query(SaleProductCategory): cat.title = self.faker.sentence(nb_words=3) cat.description = self.faker.text() for prod in self.session.query(SaleProduct): prod.label = self.faker.sentence(nb_words=2) prod.description = self.faker.text() for group in self.session.query(SaleProductGroup): group.title = self.faker.sentence(nb_words=2) group.description = self.faker.text() def _an_statistic(self): from autonomie.models.statistics import ( StatisticSheet ) for s in self.session.query(StatisticSheet): s.title = self.faker.sentence(nb_words=4) def _an_task(self): from autonomie.models.task import ( Task, DiscountLine, TaskLine, TaskLineGroup, Estimation, TaskStatus, ) for task in self.session.query(Task): if task.status_comment: task.status_comment = self.faker.text() task.description = self.faker.text() task.address = task.customer.full_address task.workplace = self.faker.address() task.payment_conditions = u"Par chèque ou virement à réception de " u"facture" if task.notes: task.notes = self.faker.text() for line in self.session.query(DiscountLine): line.description = self.faker.text() for line in self.session.query(TaskLine): line.description = self.faker.text() for group in self.session.query(TaskLineGroup): if group.title: group.title = self.faker.sentence(nb_words=4) if group.description: group.description = self.faker.text() for status in self.session.query(TaskStatus): status.status_comment = self.faker.sentence(nb_words=6) def _an_task_config(self): from autonomie.models.task import ( PaymentConditions, ) for i in self.session.query(PaymentConditions): self.session.delete(i) for index, label in enumerate( [u"30 jours fin de mois", u"À réception de facture"] ): condition = PaymentConditions(label=label) if index == 0: condition.default = True self.session.add(condition) def _an_user(self): from autonomie.models.user.login import ( Login, ) from autonomie.models.user.user import ( User, ) self.session.execute("Update accounts set session_datas='{}'") counter = itertools.count() found_contractor = False for u in self.session.query(Login).join(User).filter(Login.active==True): index = counter.next() if index == 1: u.login = u"admin1" u.groups = ['admin'] elif index == 2: u.login = u"manager1" u.groups = ["manager"] elif not found_contractor and "contractor" in u.groups: u.login = u"entrepreneur1" found_contractor = True else: u.login = u"user_{0}".format(index) u.user.lastname = self.faker.last_name() u.user.firstname = self.faker.first_name() u.user.email = self.faker.ascii_safe_email() u.set_password(u.login) if u.user.has_userdatas(): u.user.userdatas.coordonnees_lastname = u.user.lastname u.user.userdatas.coordonnees_firstname = u.user.firstname u.user.userdatas.coordonnees_email1 = u.user.email for u in self.session.query(Login).join(User).filter(Login.active==False ): index = counter.next() u.login = u"user_{0}".format(index) u.user.lastname = self.faker.last_name() u.user.firstname = self.faker.first_name() u.user.email = self.faker.ascii_safe_email() u.set_password(u.login) if u.user.has_userdatas(): u.user.userdatas.coordonnees_lastname = u.user.lastname u.user.userdatas.coordonnees_firstname = u.user.firstname u.user.userdatas.coordonnees_email1 = u.user.email def _an_userdatas(self): from autonomie.models.user.userdatas import ( UserDatas, CompanyDatas, AntenneOption, ) for u in self.session.query(UserDatas): if u.user_id is None: u.coordonnees_lastname = self.faker.last_name() u.coordonnees_firstname = self.faker.first_name() u.coordonnees_email1 = self.faker.ascii_safe_email() u.coordonnees_ladies_lastname = self.faker.last_name_female() u.coordonnees_email2 = self.faker.ascii_safe_email() u.coordonnees_tel = self.faker.phone_number()[:14] u.coordonnees_mobile = self.faker.phone_number()[:14] u.coordonnees_address = self.faker.street_address() u.coordonnees_zipcode = self._zipcode() u.coordonnees_city = self.faker.city() u.coordonnees_birthplace = self.faker.city() u.coordonnees_birthplace_zipcode = self._zipcode() u.coordonnees_secu = u"0 00 00 000 000 00" u.coordonnees_emergency_name = self.faker.name() u.coordonnees_emergency_phone = self.faker.phone_number()[:14] u.parcours_goals = self.faker.text() for datas in self.session.query(CompanyDatas): datas.title = self.faker.company() datas.name = self.faker.company() datas.website = self.faker.url() for a in AntenneOption.query(): a.label = u"Antenne : {0}".format(self.faker.city()) def _an_files(self): from autonomie.models.files import File for file_ in self.session.query(File): self.session.delete(file_) from autonomie.models.files import Template sample_tmpl_path = os.path.abspath( pkg_resources.resource_filename('autonomie', 'sample_templates') ) for filename in os.listdir(sample_tmpl_path): filepath = os.path.join(sample_tmpl_path, filename) with open(filepath, 'r') as fbuf: tmpl = Template(name=filename, description=filename) tmpl.data = fbuf.read() self.session.add(tmpl) def _an_celery_jobs(self): self.session.execute("delete from mailing_job") self.session.execute("delete from file_generation_job") self.session.execute("delete from csv_import_job") self.session.execute("delete from job") def _an_task_mentions(self): from autonomie.models.task.mentions import TaskMention for mention in TaskMention.query(): mention.full_text = self.faker.paragraph(nb_sentences=3) self.session.merge(mention) def run(self, module_key=None): if module_key is not None: if not module_key.startswith('_an_'): module_key = u"_an_%s" % module_key keys = [module_key] methods = {module_key: getattr(self, module_key)} else: methods = {} for method_name, method in inspect.getmembers( self, inspect.ismethod ): if method_name.startswith('_an_'): methods[method_name] = method keys = methods.keys() keys.sort() for key in keys: self.logger.debug(u"Step : {0}".format(key)) methods[key]() transaction.commit() transaction.begin()
def add_activity_action(label, **kw): session = DBSESSION() a = ActivityAction(label=label, **kw) session.add(a) session.flush() return a
def add_activity_type(label): session = DBSESSION() session.add(ActivityType(label=label)) session.flush()
def upgrade(): from autonomie_base.models.base import DBSESSION from autonomie.models.workshop import WorkshopAction from alembic.context import get_bind session = DBSESSION() conn = get_bind() col = sa.Column('activity_id', sa.Integer(), sa.ForeignKey('company_activity.id')) op.add_column('company_datas', col) col = sa.Column('archived', sa.Boolean(), default=False, server_default="0") op.add_column('customer', col) # Migration de accompagnement_header.png en activity_header.png op.execute('update config_files set config_files.key="activity_header_img.png" where \ config_files.key="accompagnement_header.png";') # Le bas de page des pdfs est celui par defaut pour les ateliers et rdv from autonomie.models.config import Config val = Config.get('coop_pdffootertext').value if val: for key in ('activity', 'workshop'): config_key = '%s_footer' % key config = Config.set(config_key, val) # Migration de la taille des libelles pour les actions des rendez-vous op.execute("alter table activity_action modify label VARCHAR(255)") # Migration des intitules des ateliers # 1- Ajout des nouvelles foreignkey for name in 'info1_id', 'info2_id', 'info3_id': col = sa.Column(name, sa.Integer, sa.ForeignKey("workshop_action.id")) op.add_column("workshop", col) # 2- création des options en fonction des valeurs en durs request = "select id, info1, info2, info3 from workshop" result = conn.execute(request) already_added = {} for id, info1, info2, info3 in result: info1 = info1.lower() info2 = info2.lower() info3 = info3.lower() info1_id = info2_id = info3_id = None if (info1, info2, info3) not in already_added.keys(): for key, value in already_added.items(): if key[0] == info1 and info1: info1_id = value[0] if key[1] == info2 and info2: info2_id = value[1] if info1_id is None and info1: w = WorkshopAction(label=info1) session.add(w) session.flush() info1_id = w.id if info2_id is None and info2: w = WorkshopAction(label=info2, parent_id=info1_id) session.add(w) session.flush() info2_id = w.id if info3: w = WorkshopAction(label=info3, parent_id=info2_id) session.add(w) session.flush() info3_id = w.id already_added[(info1, info2, info3)] = (info1_id, info2_id, info3_id,) else: info1_id, info2_id, info3_id = already_added[(info1, info2, info3)] request = "update workshop " if info1_id: request += "set info1_id={0}".format(info1_id) if info2_id: request += ", info2_id={0}".format(info2_id) if info3_id: request += ", info3_id={0}".format(info3_id) request += " where id={0}".format(id) op.execute(request)
def add_unity(label): t = WorkUnit(label=label) session = DBSESSION() session.add(t) session.flush()
def add_tva(value, default=False): t = Tva(name="%s %%" % (value/100.0), value=value, default=default) session = DBSESSION() session.add(t) session.flush()
def add_payment_mode(label): p = PaymentMode(label=label) session = DBSESSION() session.add(p) session.flush()