'''
from openerp.osv import osv, fields
+from datetime import date, timedelta, datetime
class Mesurable(osv.Model):
_name = "cmmi.axes.mesurable"
+ _description = "Table de reference des mesusrables."
+
_statuts = [("cree", "Crée"), ("encours", "En cours"),
("termine", "Terminé"), ("abandonne", "Abandonné"),
("suspendu", "Suspendu"), ("generique", "Générique")]
+ def _nb_jours_init(self, cr, uid, ids, field, arg, context=None):
+ result = {}
+ for m in self.browse(cr, uid, ids, context=context):
+ result[m.id] = Mesurable._nb_jours_ouvre_entre_2_dates(
+ datetime.strptime(m.date_init_deb, "%Y-%m-%d").date(),
+ datetime.strptime(m.date_init_fin, "%Y-%m-%d").date())
+ return result
+
_columns = {
"name": fields.char(string="Title", size=64, required=True),
"description": fields.text(string="Description"),
"date_plan_fin": fields.date(string="Date plannifiée de fin"),
"date_reel_deb": fields.date(string="Data réelle début"),
"date_reel_fin": fields.date(string="Data réelle fin"),
+ "nb_jours_projets": fields.function(_nb_jours_init,
+ type="integer",
+ string="Nombre de jour"),
}
_sql_constraints = [
]
-class Chantier(osv.Model):
- _name = "cmmi.axes.chantier"
+#==================== TRAVAIL CALCUL JOURS OUVRES =============================
- _inherit = "projet.axes.mesurable"
+ @staticmethod
+ def _get_date_paques(annee):
+ """
+ Retourne la date du dimanque de pâques pour une année donnée
+ sous la forme d'un objet date.
+ """
+ a = annee % 19
+ b = annee // 100
+ c = annee % 100
+ d = (19 * a + b - b // 4 - ((b - (b + 8) // 25 + 1) // 3) + 15) % 30
+ e = (32 + 2 * (b % 4) + 2 * (c // 4) - d - (c % 4)) % 7
+ f = d + e - 7 * ((a + 11 * d + 22 * e) // 451) + 114
+ mois = f // 31
+ jours = f % 31 + 1
+ return date(annee, mois, jours)
- _columns = {
- "projet_id": fields.many2one("projet.projet",
- string="Projet",
- required=True),
- "evolutions": fields.one2many("projet.evolution",
- "chantier_id",
- string="Evolutions"),
- }
+
+ @staticmethod
+ def _get_jours_feries(annee):
+ """
+ Retourne une liste contenant les jours fériés d'une année donnée.
+ """
+ date_paques = Mesurable._get_date_paques(annee)
+ return [
+ date_paques+timedelta(days=1), # Lundi de Pâques
+ date_paques+timedelta(days=39), # Jeudi de l'Ascension
+ date_paques+timedelta(days=50), # Lundi de Pentecôte
+ date(annee, 1, 1), # Jour de l'An
+ date(annee, 5, 1), # Fête du travail
+ date(annee, 5, 8), # Armistice 1945
+ date(annee, 7, 14), # Fête Nationale
+ date(annee, 8, 15), # Assomption
+ date(annee, 11, 1), # Toussaint
+ date(annee, 11, 11), # Armistice 1918
+ date(annee, 12, 25), # Noël
+ ]
+
+
+ @staticmethod
+ def _jour_ouvre(d):
+ """ Retourne vrai si la date est un jour ouvre, faux sinon."""
+ if (5,6).__contains__(d.weekday()) or Mesurable._get_jours_feries(d.year).__contains__(d):
+ return False
+ else:
+ return True
+
+
+ @staticmethod
+ def _nb_jours_ouvre_entre_2_dates(d1, d2):
+ """
+ Retourne le nombre de jours ouvres entre deux dates données.
+
+ >>> nb_jours_ouvre_entre_2_dates(date(2013, 5, 1), date(2013, 7, 31))
+ 62
+ >>> nb_jours_ouvre_entre_2_dates(date(2013, 7, 31), date(2013, 5, 1))
+ 62
+ """
+ if d1>d2:
+ d1, d2 = d2, d1 #Switch les 2 dates pour que d1 soit la plus petite
+ tmp = d1
+ jour_ouvres = 0
+ while tmp <= d2:
+ if Mesurable._jour_ouvre(tmp): # Si tmp est un jour ouvre
+ jour_ouvres += 1
+ tmp += timedelta(days=1)
+ return jour_ouvres
+
+#==============================================================================
class Palier(osv.Model):
_name = "cmmi.axes.palier"
- _inherit = "projet.axes.mesurable"
+ _description = "Palier d'un projet."
+
+ _inherit = "cmmi.axes.mesurable"
_types_palier = [("normal", "Normal"), ("exceptionnel", "Exceptionnel"),
("correctif", "Correctif"), ("autre", "Autre")]
_columns = {
"type_palier": fields.selection(_types_palier, string="Type"),
- "projet_id": fields.many2one("projet.projet",
+ "projet_id": fields.many2one("cmmi.projet",
string="Projet",
required=True),
- "evolutions": fields.one2many("projet.evolution",
+ "evolutions": fields.one2many("cmmi.evolution",
"palier_id",
string="Evolutions"),
- "phases": fields.one2many("projet.phase",
+ "phases": fields.one2many("cmmi.axes.palier.phase",
"palier_id",
string="Phases"),
}
+
+
+class PalierPhase(osv.Model):
+ _name = "cmmi.axes.palier.phase"
+
+ _description = "Phase d'un palier"
+
+ _inherit = "cmmi.axes.mesurable"
+
+ def _get_name(self, cr, uid, ids, field_name=None, arg=None, context=None):
+ if isinstance(ids, (int, long)):
+ ids = [ids]
+ return dict([(i, r.phase_id.name) for i, r in
+ zip(ids, self.browse(cr, uid, ids, context=context))])
+
+
+ _columns = {
+ "name": fields.function(_get_name,
+ type='char',
+ store=True,
+ string="Nom de la phase"),
+ "phase_id": fields.many2one("cmmi.projet.phase",
+ string="Phase du projet"),
+ "palier_id": fields.many2one("cmmi.axes.palier",
+ string="Palier"),
+ # backrefs
+ "charges": fields.one2many("cmmi.evolution.charge",
+ "phase_id",
+ string="Charges"),
+# "evolutions": fields.one2many("cmmi.evolution", #Supprimé !
+# "phase_id",
+# string="Evolutions"),
+ }
+
+ def create(self, cr, uid, vals, context=None):
+ # TODO: gérer la création d'une phase de palier.
+ # Vérifier les valeurs contenues dans vals et les modifier / rajouter si nécessaire selon les cas suivants
+
+ # Si description est vide, alors par défaut, recopie de la description du palier et de la phase (concaténés avec un retour à la ligne entre les deux).
+ # Si commentaire est vide, alors par défaut, recopie du commentaire du palier.
+ # Si version est vide, alors par dégaut, recopie de la version du palier.
+
+ return osv.Model.create(self, cr, uid, vals, context=context)
+
+
+class Chantier(osv.Model):
+ _name = "cmmi.axes.chantier"
+
+ _description = "Chantiers d'un projet."
+
+ _inherit = "cmmi.axes.mesurable"
+
+ _columns = {
+ "projet_id": fields.many2one("cmmi.projet",
+ string="Projet",
+ required=True),
+ "module_ids": fields.many2many("cmmi.description.module",
+ "cmmi_module_chantier_rel",
+ "chantier_id",
+ "module_id",
+ "Modules"),
+ "evolutions": fields.one2many("cmmi.evolution",
+ "chantier_id",
+ string="Evolutions"),
+ }