def gen_invoices(cls, business, user, payment_deadlines=None): """ Generate the invoices associated to the given payment deadlines :param obj business: The Business in which we work :param obj user: The current connected user :param list payment_deadlines: Optionnal the deadlines for which we generate invoices else all deadlines :returns: A list of invoices """ if not payment_deadlines: payment_deadlines = business.payment_deadlines elif not hasattr(payment_deadlines, '__iter__'): payment_deadlines = [payment_deadlines] invoices = [] for deadline in payment_deadlines: estimation = deadline.estimation if deadline.deposit: invoice = estimation.gen_deposit_invoice( user, ) else: invoice = estimation.gen_invoice( deadline.payment_line, user, ) invoice.initialize_business_datas(business) DBSESSION().add(invoice) DBSESSION().flush() deadline.invoice_id = invoice.id DBSESSION().merge(deadline) invoices.append(invoice) return invoices
def upgrade(): logger = logging.getLogger("alembic.add_compte_cg") op.add_column("tva", sa.Column("compte_cg", sa.String(125), default="")) op.add_column("tva", sa.Column("code", sa.String(125), default="")) op.add_column("company", sa.Column("contribution", sa.Integer)) op.add_column("customer", sa.Column("compte_cg", sa.String(125), default="")) op.add_column("customer", sa.Column("compte_tiers", sa.String(125), default="")) # Ajout du code produit au ligne des factures et avoirs for table in ("invoice_line", "cancelinvoice_line"): op.add_column(table, sa.Column("product_id", sa.Integer, default="")) # Ajout d'un tag "exporte" aux factures et avoirs for table in ("invoice", "cancelinvoice"): op.add_column(table, sa.Column("exported", sa.Boolean())) # Les factures et avoirs deja validees sont considerees comme exportees logger.warn(u"On tag des factures comme exportees") for invoice in Invoice.query(): if invoice.CAEStatus in Invoice.valid_states: invoice.exported = True DBSESSION().merge(invoice) logger.warn(u"officialNumber : {0.officialNumber} \ {0.financial_year}".format(invoice)) for cinv in CancelInvoice.query(): if cinv.CAEStatus in CancelInvoice.valid_states: cinv.exported = True DBSESSION().merge(cinv) logger.warn(u"officialNumber : {0.officialNumber} \ {0.financial_year}".format(cinv))
def query_existing_project_indicators(cls, project_id, file_type_id, task_id=None, business_id=None): """ Build a query for indicators related to a given project Excludes indicators related to task_id :param int project_id: The Project id :param int file_type_id: The type of file the indicators are related to :param int task_id: The id of the task to exclude from the query :param int business_id: The id of the business to exclude from the query """ from autonomie.models.task import Task from autonomie.models.project.business import Business tasks_id_query = DBSESSION().query( Task.id).filter_by(project_id=project_id) if task_id: tasks_id_query = tasks_id_query.filter(Task.id != task_id) businesses_id_query = DBSESSION().query( Business.id).filter_by(project_id=project_id) if business_id: businesses_id_query = businesses_id_query.filter( Business.id != business_id) query = SaleFileRequirement.query().filter_by( file_type_id=file_type_id) return query.filter( or_( SaleFileRequirement.node_id.in_(businesses_id_query), SaleFileRequirement.node_id.in_(tasks_id_query), ))
def deferred_customer_widget(node, kw): if default_option: values = [default_option] else: values = [] if is_admin: query = Customer.query().join(Customer.company) query = query.options( contains_eager(Customer.company).load_only('name') ) query = query.options(load_only('id', 'label')) if with_invoice: query = query.filter( Customer.id.in_( DBSESSION().query(distinct(Task.customer_id)).filter( Task.type_.in_(['invoice', 'cancelinvoice']) ) ) ) elif with_estimation: query = query.filter( Customer.id.in_( DBSESSION().query(distinct(Task.customer_id)).filter( Task.type_ == 'estimation' ) ) ) datas = OrderedDict() for item in query: datas.setdefault(item.company.name, []).append( (item.id, item.label) ) # All customers, grouped by Company for company_name, customers in datas.items(): values.append( deform.widget.OptGroup( company_name, *customers ) ) else: # Company customers only company = kw['request'].context for cust in company.customers: values.append( (cust.id, u"%s (%s)" % (cust.name, cust.code)) ) return deform.widget.Select2Widget( values=values, **(widget_options or {}) )
def is_used(self): query = DBSESSION().query(File).filter_by(file_type_id=self.id) file_exists = DBSESSION().query(query.exists()).scalar() from autonomie.models.indicators import SaleFileRequirement indicator_query = DBSESSION().query(SaleFileRequirement).filter_by( file_type_id=self.id) indicator_exists = DBSESSION().query(indicator_query.exists()).scalar() return file_exists or indicator_exists
def deferred_company_id_widget(node, kw): """ Defer the company id selection widget """ datas = DBSESSION().query(distinct(AccountingOperation.company_id)).all() datas = zip(*datas)[0] values = DBSESSION().query(Company.id, Company.name).all() values.insert(0, ('', u"Toutes les entreprises")) return deform.widget.Select2Widget(values=values)
def get_recording_job(self): """ Initialize a job for importation recording """ # We initialize a job record in the database job = CsvImportJob() job.set_owner(self.request.user.login.login) DBSESSION().add(job) DBSESSION().flush() return job
def downgrade(): from autonomie.models.task import WorkUnit from autonomie.models.task.estimation import EstimationLine from autonomie.models.task.invoice import InvoiceLine from autonomie.models.task.invoice import CancelInvoiceLine from autonomie_base.models.base import DBSESSION for factory in (EstimationLine, InvoiceLine, CancelInvoiceLine): for line in factory.query(): line.unity = translate_inverse(line.unity) DBSESSION().merge(line) for value in WorkUnit.query(): DBSESSION().delete(value)
def reorder(cls, category_id): """ Regenerate order attributes :param int category_id: The category to manage """ items = DBSESSION().query(cls).filter_by( category_id=category_id).filter_by(active=True).order_by( cls.order).all() for index, item in enumerate(items): item.order = index DBSESSION().merge(item)
def downgrade(): for p in PaymentMode.query(): DBSESSION().delete(p) for p in Payment.query(): if p.mode == u"par chèque": p.mode = u"cheque" elif p.mode == u"par virement": p.mode = u"virement" elif p.mode == u"en liquide": p.mode = u"liquide" else: p.mode = "inconnu" DBSESSION().merge(p)
def is_used(self): task_query = DBSESSION().query(TASK_MENTION.c.task_id).filter( TASK_MENTION.c.mention_id == self.id ) mandatory_query = DBSESSION().query( MANDATORY_TASK_MENTION.c.task_id ).filter( MANDATORY_TASK_MENTION.c.mention_id == self.id ) return DBSESSION().query(task_query.exists()).scalar() or \ DBSESSION().query(mandatory_query.exists()).scalar()
def downgrade(): from autonomie.models.task.invoice import PaymentMode, Payment for p in PaymentMode.query(): DBSESSION().delete(p) for p in Payment.query(): if p.mode == u"par chèque": p.mode = u"cheque" elif p.mode == u"par virement": p.mode = u"virement" elif p.mode == u"en liquide": p.mode = u"liquide" else: p.mode = "inconnu" DBSESSION().merge(p)
def set(cls, key, appstruct): """ Set a file for the given key, if the key isn't field yet, add a new instance """ instance = cls.get(key) if instance is None: instance = cls(key=key) for attr_name, attr_value in appstruct.items(): setattr(instance, attr_name, attr_value) if instance.id is not None: DBSESSION().merge(instance) else: DBSESSION().add(instance)
def query(self): """ Return the main query used to find objects e.g: query = DBSESSION().query(distinct(UserDatas.id), UserDatas) query = query.filter(UserDatas.name.startswith('test')) query = query.outerjoin(UserDatas.conseiller) query = query.filter(User.lastname=='A manager') query = query.filter( UserDatas.id.in_( [list of ids retrieved from independant queries] ) ) """ self.already_joined = [] if self.root: main_query = DBSESSION().query(distinct(self.model.id), self.model) else: main_query = DBSESSION().query(distinct(self.model.id)) # Pour chaque critère sur lesquels on va ajouter des filtres, on a # besoin d'être sûr que la classe concernée est bien requêtée, il faut # donc ajouter des outerjoins pour chaque classe liée. # NOTE: on ne gère pas les alias (les joins sur deux tables identiques # pour deux relations différentes) for criterion in self.query_helpers: # On génère le filtre filter_ = criterion.gen_filter() having = criterion.gen_having_clause() # si il y a un filtre ... if filter_ is not None: main_query = self.join(main_query, criterion) main_query = main_query.filter(filter_) elif having is not None: main_query = self.join(main_query, criterion) main_query = main_query.group_by(self.model.id) main_query = main_query.having(having) if self.query_factories: ids = list(self._get_ids_from_factories()) main_query = main_query.filter(self.model.id.in_(ids)) return main_query
def get_or_create_invoice_indicator(cls, business): from autonomie.models.indicators import CustomBusinessIndicator indicator = CustomBusinessIndicator.query().filter_by( business_id=business.id).filter_by(name="invoiced").first() if indicator is None: indicator = CustomBusinessIndicator( name="invoiced", label=u"Facturation", ) DBSESSION().add(indicator) DBSESSION().flush() business.indicators.append(indicator) DBSESSION().merge(business) return indicator
def upgrade(): for payment in Payment.query(): if payment.mode in (u"cheque", u"CHEQUE"): payment.mode = u"par chèque" elif payment.mode in (u"virement", u"VIREMENT"): payment.mode = u"par virement" elif payment.mode in (u"liquide", u"LIQUIDE"): payment.mode = u"en liquide" else: payment.mode = "mode de paiement inconnu" DBSESSION().merge(payment) for mode in (u"par chèque", u"par virement", u"en liquide"): pmode = PaymentMode(label=mode) DBSESSION().add(pmode)
def migrate_projects_to_multiple_clients(): """ move project's client to the manytomany relationship """ from autonomie_base.models.base import DBSESSION from autonomie.models.project import Project from autonomie.models.client import Client for proj in DBSESSION().query(Project): try: client = Client.get(proj.client_id) if client is not None: proj.clients.append(client) DBSESSION().merge(proj) except: continue
def insert(cls, item, new_order): """ Place the item at the given index :param obj item: The item to move :param int new_order: The new index of the item """ items = DBSESSION().query(cls).filter_by(active=True).filter( cls.id != item.id).order_by(cls.order).all() items.insert(new_order, item) for index, item in enumerate(items): item.order = index DBSESSION().merge(item)
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 get_types(cls, active=True, keys=()): query = DBSESSION().query(cls) if keys: query = query.options(load_only(*keys)) if active: query = query.filter_by(active=True) return query
def is_used(self): """ Check if there is a project using this specific type """ from autonomie.models.project.project import Project query = Project.query().filter_by(project_type_id=self.id) return DBSESSION().query(query.exists()).scalar()
def migrate_datas(): from autonomie_base.models.base import DBSESSION session = DBSESSION() from alembic.context import get_bind conn = get_bind() for row in list(conn.execute('SELECT id, leaders FROM workshop')): if not row.leaders: continue try: leaders_list = json.loads(row.leaders) except ValueError: # This should not happen, but some dumps we use have a bare string # in leaders field. leaders_list = [row.leaders] req = sa.text(""" UPDATE workshop SET description=CONCAT( 'Formateurs: ', IFNULL(:leaders, ''), ' ', IFNULL(description, '') ) WHERE id=:id_ """) conn.execute( req, leaders=', '.join(leaders_list), id_=row.id, ) mark_changed(session) session.flush()
def find_by_login(cls, login, active=True): query = DBSESSION().query(cls) query = query.options(load_only('pwd_hash')) query = query.filter_by(login=login) if active: query = query.filter_by(active=True) return query.first()
def check_phase_id(cls, project_id, phase_id): """ Check phase_id is attached to project_id """ from autonomie.models.project import Phase return DBSESSION().query(Phase.id).filter_by(id=phase_id).filter_by( project_id=project_id).count() > 0
def _query(cls, invoice): from autonomie.models.task import Task q = DBSESSION().query(func.Max(SequenceNumber.index)) q = q.filter(Task.type_.in_(('invoice', 'cancelinvoice'))) q = q.filter_by(sequence=cls.db_key) return q
def query(self): """ Return the main query for our list view """ logger.debug("Queryiing") query = DBSESSION().query(distinct(User.id), User) return query.outerjoin(User.companies)
def set(cls, key, value): instance = cls.get(key) if instance is None: instance = cls(name=key) instance.value = value DBSESSION().merge(instance)
def deferred_categories_widget(node, kw): query = DBSESSION().query( IncomeStatementMeasureTypeCategory.label, IncomeStatementMeasureTypeCategory.label, ) choices = query.filter_by(active=True).all() return deform.widget.CheckboxChoiceWidget(values=choices)
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 is_default_project_type(cls, business): """ Check if the parent's project type is of type default :param obj business: The current business instance this service is attached to :rtype: bool """ from autonomie.models.project.project import Project from autonomie.models.project.types import ProjectType project_type_id = DBSESSION().query(Project.project_type_id).filter_by( id=business.project_id).scalar() ptype_name = DBSESSION().query( ProjectType.name).filter_by(id=project_type_id).scalar() return ptype_name == u"default"