<commit_before>#
# Copyright (c) 2004 Specifix, Inc.
# All rights reserved
#

"""
Contains the doCook() function which builds a recipe and commits the
resulting packages to the repository.
"""

import buildpackage
import changeset
import files
import log
import lookaside
import os
import package
import recipe
import repository
import sha1helper
import signal
import sys
import time
import types
import util
import tempfile

# -------------------- private below this line -------------------------

# type could be "src"
#
# returns a (pkg, fileMap) tuple
def _createPackage(repos, branch, bldPkg, ident):
    fileMap = {}
    p = package.Package(bldPkg.getName(), bldPkg.getVersion())

    for (path, buildFile) in bldPkg.items():
        realPath = buildFile.getRealPath()
        if isinstance(buildFile, buildpackage.BuildDeviceFile):
            f = files.FileFromInfoLine(buildFile.infoLine(), ident(path))
        elif realPath:
            f = files.FileFromFilesystem(realPath, ident(path),
                                         type = buildFile.getType(),
                                         requireSymbolicOwnership=True)
	    # setuid or setgid must be set explicitly in buildFile
	    f.thePerms &= 01777
        else:
            raise CookError("unable to create file object for package")

        # set ownership, flags, etc
        f.merge(buildFile)

	duplicateVersion = checkBranchForDuplicate(repos, branch, f)
        if not duplicateVersion:
	    p.addFile(f.id(), path, bldPkg.getVersion())
	else:
	    p.addFile(f.id(), path, duplicateVersion)

        fileMap[f.id()] = (f, realPath, path)

    return (p, fileMap)

class _IdGen:
    def __call__(self, path):
	if self.map.has_key(path):
	    return self.map[path]

	hash = sha1helper.hashString("%s %f %s" % (path, time.time(),
							self.noise))
	self.map[path] = hash
	return hash

    def __init__(self, map=None):
	# file ids need to be unique. we include the time and path when
	# we generate them; any data put here is also used
	uname = os.uname()
	self.noise = "%s %s" % (uname[1], uname[2])
        if map is None:
            self.map = {}
        else:
            self.map = map

    def populate(self, repos, lcache, pkg):
	# Find the files and ids which were owned by the last version of
	# this package on the branch. We also construct an object which
	# lets us look for source files this build needs inside of the
	# repository
	for (fileId, path, version) in pkg.fileList():
	    self.map[path] = fileId
	    if path[0] != "/":
		# we might need to retrieve this source file
		# to enable a build, so we need to find the
		# sha1 hash of it since that's how it's indexed
		# in the file store
		f = repos.getFileVersion(fileId, version)
		lcache.addFileHash(path, f.sha1())

def _cook(repos, cfg, recipeFile, prep=0, macros=()):
    repos.open("r")

    buildBranch = cfg.defaultbranch

    if type(recipeFile) is types.ClassType:
        classList = {recipeFile.__name__: recipeFile}
    else:
        try:
            classList = recipe.RecipeLoader(recipeFile)
        except recipe.RecipeFileError, msg:
            raise CookError(str(msg))
    built = []

    for (className, recipeClass) in classList.items():
	log.info("Building %s", className)
	fullName = cfg.packagenamespace + ":" + recipeClass.name
	srcName = fullName + ":sources"

	lcache = lookaside.RepositoryCache(repos)

        srcdirs = [ os.path.dirname(recipeClass.filename),
                    cfg.sourcepath % {'pkgname': recipeClass.name} ]
	recipeObj = recipeClass(cfg, lcache, srcdirs, macros)

	newVersion = None
	if repos.hasPackage(fullName):
	    # if this package/version exists already, increment the
	    # existing revision
	    newVersion = repos.pkgLatestVersion(fullName, buildBranch)
	    if newVersion and (
	      recipeObj.version == newVersion.trailingVersion().getVersion()):
		newVersion = newVersion.copy()
		newVersion.incrementVersionRelease()
	    else:
		newVersion = None

	# this package/version doesn't exist yet
	if not newVersion:
	    newVersion = buildBranch.copy()
	    newVersion.appendVersionRelease(recipeObj.version, 1)

	builddir = cfg.buildpath + "/" + recipeObj.name

	recipeObj.setup()
	recipeObj.unpackSources(builddir)

        # if we're only extracting, continue to the next recipe class.
        if prep:
            continue

        cwd = os.getcwd()
        util.mkdirChain(builddir + '/' + recipeObj.mainDir())
        os.chdir(builddir + '/' + recipeObj.mainDir())
	repos.close()

        util.mkdirChain(cfg.tmpdir)
	destdir = tempfile.mkdtemp("", "srs-%s-" % recipeObj.name, cfg.tmpdir)
	recipeObj.doBuild(builddir, destdir)
	log.info('Processing %s', className)
        recipeObj.doDestdirProcess() # includes policy

	repos.open("w")

        os.chdir(cwd)

	packageList = []

	# build up the name->fileid mapping so we reuse fileids wherever
	# possible; we do this by looking in the database for a pacakge
	# with the same name as the recipe and recursing through it's
	# subpackages; this mechanism continues to work as subpackages
	# come and go

	ident = _IdGen()
	if repos.hasPackage(fullName):
	    pkgList = [ (fullName,
			[repos.pkgLatestVersion(fullName, buildBranch)]) ]
	    while pkgList:
		(name, versionList) = pkgList[0]
		del pkgList[0]
		for version in versionList:
		    pkg = repos.getPackageVersion(name, version)
		    pkgList += pkg.getPackageList()
		    ident.populate(repos, lcache, pkg)

	for buildPkg in recipeObj.getPackages(cfg.packagenamespace, newVersion):
	    (p, fileMap) = _createPackage(repos, buildBranch, buildPkg, ident)
            built.append((p.getName(), p.getVersion().asString()))
	    packageList.append((p, fileMap))

        recipes = [ recipeClass.filename ]
        # add any recipe that this recipeClass decends from to the sources
        baseRecipeClasses = list(recipeClass.__bases__)
        while baseRecipeClasses:
            parent = baseRecipeClasses.pop()
            baseRecipeClasses.extend(list(parent.__bases__))
            if not parent.__dict__.has_key('filename'):
                continue
            if not parent.filename in recipes:
                recipes.append(parent.filename)

	srcBldPkg = buildpackage.BuildPackage(srcName, newVersion)
	for file in recipeObj.allSources() + recipes:
            src = lookaside.findAll(cfg, lcache, file, recipeObj.name, srcdirs)
	    srcBldPkg.addFile(os.path.basename(src), src, type="src")

        for recipeFile in recipes:
            srcBldPkg[os.path.basename(recipeFile)].isConfig(True)

	# build the group before the source package is added to the
	# packageList; the package's group doesn't include sources
	grpName = cfg.packagenamespace + ":" + recipeClass.name
	grp = package.Package(grpName, newVersion)
	for (pkg, map) in packageList:
	    grp.addPackage(pkg.getName(), [ pkg.getVersion() ])

	(p, fileMap) = _createPackage(repos, buildBranch, srcBldPkg, ident)
	packageList.append((p, fileMap))

	changeSet = changeset.CreateFromFilesystem(packageList)
	grpDiff = grp.diff(None, abstract = 1)[0]

	changeSet.newPackage(grpDiff)

	repos.commitChangeSet(changeSet)

	repos.open("r")

	recipeObj.cleanup(builddir, destdir)

    return built

# -------------------- public below this line -------------------------

def doCook(repos, cfg, recipeFile, prep=0, macros=()):
    try:
	return _cook(repos, cfg, recipeFile, prep = prep, macros = macros)
    except repository.RepositoryError, e:
	raise CookError(str(e))

class CookError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __repr__(self):
	return self.msg

    def __str__(self):
	return repr(self)

def cookCommand(cfg, args, prep, macros):
    # this ensures the repository exists
    repos = repository.LocalRepository(cfg.reppath, "c")
    repos.close()

    for file in args:
        if file[0] != '/':
            file = "%s/%s" % (os.getcwd(), file)
        # we want to fork here to isolate changes the recipe might make
        # in the environment (such as environment variables)
        signal.signal(signal.SIGTTOU, signal.SIG_IGN)
        pid = os.fork()
        if not pid:
            # child, set ourself to be the foreground process
            os.setpgrp()
            os.tcsetpgrp(0, os.getpgrp())
	    repos = repository.LocalRepository(cfg.reppath, "r")
            try:
                built = doCook(repos, cfg, file, prep=prep, macros=macros)
            except CookError, msg:
		log.error(str(msg))
                sys.exit(1)
            for (pkg, version) in built:
                print "Committed", pkg, version, "to the repository"
            sys.exit(0)
        else:
            while 1:
                try:
                    # XXX replace 2 with os.WUNTRACED in python 2.3
                    (id, status) = os.waitpid(pid, 2)
                    if os.WIFSTOPPED(status):
                        # if our child has been stopped (Ctrl+Z or similar)
                        # stop ourself
                        os.kill(os.getpid(), os.WSTOPSIG(status))
                        # when we continue, place our child back
                        # in the foreground process group
                        os.tcsetpgrp(0, pid)
                        # tell the child to continue
                        os.kill(-pid, signal.SIGCONT)
                    else:
                        # if our child exited with a non-0 status, exit
                        # with that status
                        if os.WEXITSTATUS(status):
                            sys.exit(os.WEXITSTATUS(status))
                        break
                except KeyboardInterrupt:
                    os.kill(-pid, signal.SIGINT)
        # make sure that we are the foreground process again
        os.tcsetpgrp(0, os.getpgrp())

#
# see if the head of the specified branch is a duplicate
# of the file object passed; it so return the version object
# for that duplicate
def checkBranchForDuplicate(repos, branch, file):
    version = repos.fileLatestVersion(file.id(), branch)
    if not version:
	return None

    lastFile = repos.getFileVersion(file.id(), version)

    if file.same(lastFile):
	return version

    return None

def makeFileId(*args):
    assert(args)
    str = "".join(args)
    return _IdGen()(str)
<commit_msg>1) renamed doCook() cookFile() 2) renamed _cook cookObject()<commit_after>#
# Copyright (c) 2004 Specifix, Inc.
# All rights reserved
#

"""
Contains the functions which builds a recipe and commits the
resulting packages to the repository.
"""

import buildpackage
import changeset
import files
import log
import lookaside
import os
import package
import recipe
import repository
import sha1helper
import signal
import sys
import time
import types
import util
import tempfile

# -------------------- private below this line -------------------------

# type could be "src"
#
# returns a (pkg, fileMap) tuple
def _createPackage(repos, branch, bldPkg, ident):
    fileMap = {}
    p = package.Package(bldPkg.getName(), bldPkg.getVersion())

    for (path, buildFile) in bldPkg.items():
        realPath = buildFile.getRealPath()
        if isinstance(buildFile, buildpackage.BuildDeviceFile):
            f = files.FileFromInfoLine(buildFile.infoLine(), ident(path))
        elif realPath:
            f = files.FileFromFilesystem(realPath, ident(path),
                                         type = buildFile.getType(),
                                         requireSymbolicOwnership=True)
	    # setuid or setgid must be set explicitly in buildFile
	    f.thePerms &= 01777
        else:
            raise CookError("unable to create file object for package")

        # set ownership, flags, etc
        f.merge(buildFile)

	duplicateVersion = checkBranchForDuplicate(repos, branch, f)
        if not duplicateVersion:
	    p.addFile(f.id(), path, bldPkg.getVersion())
	else:
	    p.addFile(f.id(), path, duplicateVersion)

        fileMap[f.id()] = (f, realPath, path)

    return (p, fileMap)

class _IdGen:
    def __call__(self, path):
	if self.map.has_key(path):
	    return self.map[path]

	hash = sha1helper.hashString("%s %f %s" % (path, time.time(),
							self.noise))
	self.map[path] = hash
	return hash

    def __init__(self, map=None):
	# file ids need to be unique. we include the time and path when
	# we generate them; any data put here is also used
	uname = os.uname()
	self.noise = "%s %s" % (uname[1], uname[2])
        if map is None:
            self.map = {}
        else:
            self.map = map

    def populate(self, repos, lcache, pkg):
	# Find the files and ids which were owned by the last version of
	# this package on the branch. We also construct an object which
	# lets us look for source files this build needs inside of the
	# repository
	for (fileId, path, version) in pkg.fileList():
	    self.map[path] = fileId
	    if path[0] != "/":
		# we might need to retrieve this source file
		# to enable a build, so we need to find the
		# sha1 hash of it since that's how it's indexed
		# in the file store
		f = repos.getFileVersion(fileId, version)
		lcache.addFileHash(path, f.sha1())

def cookObject(repos, cfg, className, recipeClass, prep=0, macros=()):
    repos.open("r")

    buildBranch = cfg.defaultbranch
    built = []

    log.info("Building %s", className)
    fullName = cfg.packagenamespace + ":" + recipeClass.name
    srcName = fullName + ":sources"

    lcache = lookaside.RepositoryCache(repos)

    srcdirs = [ os.path.dirname(recipeClass.filename),
		cfg.sourcepath % {'pkgname': recipeClass.name} ]
    recipeObj = recipeClass(cfg, lcache, srcdirs, macros)

    newVersion = None
    if repos.hasPackage(fullName):
	# if this package/version exists already, increment the
	# existing revision
	newVersion = repos.pkgLatestVersion(fullName, buildBranch)
	if newVersion and (
	  recipeObj.version == newVersion.trailingVersion().getVersion()):
	    newVersion = newVersion.copy()
	    newVersion.incrementVersionRelease()
	else:
	    newVersion = None

    # this package/version doesn't exist yet
    if not newVersion:
	newVersion = buildBranch.copy()
	newVersion.appendVersionRelease(recipeObj.version, 1)

    # build up the name->fileid mapping so we reuse fileids wherever
    # possible; we do this by looking in the database for a pacakge
    # with the same name as the recipe and recursing through it's
    # subpackages; this mechanism continues to work as subpackages
    # come and go. this has to happen early as we build up the entries
    # for the source lookaside cache simultaneously

    ident = _IdGen()
    if repos.hasPackage(fullName):
	pkgList = [ (fullName,
		    [repos.pkgLatestVersion(fullName, buildBranch)]) ]
	while pkgList:
	    (name, versionList) = pkgList[0]
	    del pkgList[0]
	    for version in versionList:
		pkg = repos.getPackageVersion(name, version)
		pkgList += pkg.getPackageList()

    srcName = fullName + ":sources"
    if repos.hasPackage(srcName):
	print "HERE"
	pkg = repos.getLatestPackage(srcName, buildBranch)
	ident.populate(repos, lcache, pkg)

    builddir = cfg.buildpath + "/" + recipeObj.name

    recipeObj.setup()
    recipeObj.unpackSources(builddir)

    # if we're only extracting, continue to the next recipe class.
    if prep:
	return

    cwd = os.getcwd()
    util.mkdirChain(builddir + '/' + recipeObj.mainDir())
    os.chdir(builddir + '/' + recipeObj.mainDir())
    repos.close()

    util.mkdirChain(cfg.tmpdir)
    destdir = tempfile.mkdtemp("", "srs-%s-" % recipeObj.name, cfg.tmpdir)
    recipeObj.doBuild(builddir, destdir)
    log.info('Processing %s', className)
    recipeObj.doDestdirProcess() # includes policy

    repos.open("w")

    os.chdir(cwd)

    # build up the name->fileid mapping so we reuse fileids wherever
    # build up the name->fileid mapping so we reuse fileids wherever
    # possible; we do this by looking in the database for a pacakge
    # with the same name as the recipe and recursing through it's
    # subpackages; this mechanism continues to work as subpackages
    # come and go

    ident = _IdGen()
    if repos.hasPackage(fullName):
	pkgList = [ (fullName,
		    [repos.pkgLatestVersion(fullName, buildBranch)]) ]
	while pkgList:
	    (name, versionList) = pkgList[0]
	    del pkgList[0]
	    for version in versionList:
		pkg = repos.getPackageVersion(name, version)
		pkgList += pkg.getPackageList()

    srcName = fullName + ":sources"
    if repos.hasPackage(srcName):
	print "HERE"
	pkg = repos.getLatestPackage(srcName, buildBranch)
	ident.populate(repos, lcache, pkg)

    # possible; we do this by looking in the database for a pacakge
    # with the same name as the recipe and recursing through it's
    # subpackages; this mechanism continues to work as subpackages
    # come and go

    ident = _IdGen()
    if repos.hasPackage(fullName):
	pkgList = [ (fullName,
		    [repos.pkgLatestVersion(fullName, buildBranch)]) ]
	while pkgList:
	    (name, versionList) = pkgList[0]
	    del pkgList[0]
	    for version in versionList:
		pkg = repos.getPackageVersion(name, version)
		pkgList += pkg.getPackageList()

    srcName = fullName + ":sources"
    if repos.hasPackage(srcName):
	pkg = repos.getLatestPackage(srcName, buildBranch)
	ident.populate(repos, lcache, pkg)

    packageList = []

    for buildPkg in recipeObj.getPackages(cfg.packagenamespace, newVersion):
	(p, fileMap) = _createPackage(repos, buildBranch, buildPkg, ident)
	built.append((p.getName(), p.getVersion().asString()))
	packageList.append((p, fileMap))

    recipes = [ recipeClass.filename ]
    # add any recipe that this recipeClass decends from to the sources
    baseRecipeClasses = list(recipeClass.__bases__)
    while baseRecipeClasses:
	parent = baseRecipeClasses.pop()
	baseRecipeClasses.extend(list(parent.__bases__))
	if not parent.__dict__.has_key('filename'):
	    continue
	if not parent.filename in recipes:
	    recipes.append(parent.filename)

    srcBldPkg = buildpackage.BuildPackage(srcName, newVersion)
    for file in recipeObj.allSources() + recipes:
	src = lookaside.findAll(cfg, lcache, file, recipeObj.name, srcdirs)
	srcBldPkg.addFile(os.path.basename(src), src, type="src")

    for recipeFile in recipes:
	srcBldPkg[os.path.basename(recipeFile)].isConfig(True)

    # build the group before the source package is added to the
    # packageList; the package's group doesn't include sources
    grpName = cfg.packagenamespace + ":" + recipeClass.name
    grp = package.Package(grpName, newVersion)
    for (pkg, map) in packageList:
	grp.addPackage(pkg.getName(), [ pkg.getVersion() ])

    (p, fileMap) = _createPackage(repos, buildBranch, srcBldPkg, ident)
    packageList.append((p, fileMap))

    changeSet = changeset.CreateFromFilesystem(packageList)
    grpDiff = grp.diff(None, abstract = 1)[0]

    changeSet.newPackage(grpDiff)

    repos.commitChangeSet(changeSet)

    repos.open("r")

    recipeObj.cleanup(builddir, destdir)

    return built

# -------------------- public below this line -------------------------

def cookFile(repos, cfg, recipeFile, prep=0, macros=()):
    try:
	classList = recipe.RecipeLoader(recipeFile)
    except recipe.RecipeFileError, msg:
	raise CookError(str(msg))

    built = []
    for (className, classObject) in classList.iteritems():
	try:
	    built += cookObject(repos, cfg, className, classObject,
				prep = prep, macros = macros)
	except repository.RepositoryError, e:
	    raise CookError(str(e))

    return built

class CookError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __repr__(self):
	return self.msg

    def __str__(self):
	return repr(self)

def cookCommand(cfg, args, prep, macros):
    # this ensures the repository exists
    repos = repository.LocalRepository(cfg.reppath, "c")
    repos.close()

    for file in args:
        if file[0] != '/':
            file = "%s/%s" % (os.getcwd(), file)
        # we want to fork here to isolate changes the recipe might make
        # in the environment (such as environment variables)
        signal.signal(signal.SIGTTOU, signal.SIG_IGN)
        pid = os.fork()
        if not pid:
            # child, set ourself to be the foreground process
            os.setpgrp()
            os.tcsetpgrp(0, os.getpgrp())
	    repos = repository.LocalRepository(cfg.reppath, "r")
            try:
                built = cookFile(repos, cfg, file, prep=prep, macros=macros)
            except CookError, msg:
		log.error(str(msg))
                sys.exit(1)
            for (pkg, version) in built:
                print "Committed", pkg, version, "to the repository"
            sys.exit(0)
        else:
            while 1:
                try:
                    # XXX replace 2 with os.WUNTRACED in python 2.3
                    (id, status) = os.waitpid(pid, 2)
                    if os.WIFSTOPPED(status):
                        # if our child has been stopped (Ctrl+Z or similar)
                        # stop ourself
                        os.kill(os.getpid(), os.WSTOPSIG(status))
                        # when we continue, place our child back
                        # in the foreground process group
                        os.tcsetpgrp(0, pid)
                        # tell the child to continue
                        os.kill(-pid, signal.SIGCONT)
                    else:
                        # if our child exited with a non-0 status, exit
                        # with that status
                        if os.WEXITSTATUS(status):
                            sys.exit(os.WEXITSTATUS(status))
                        break
                except KeyboardInterrupt:
                    os.kill(-pid, signal.SIGINT)
        # make sure that we are the foreground process again
        os.tcsetpgrp(0, os.getpgrp())

#
# see if the head of the specified branch is a duplicate
# of the file object passed; it so return the version object
# for that duplicate
def checkBranchForDuplicate(repos, branch, file):
    version = repos.fileLatestVersion(file.id(), branch)
    if not version:
	return None

    lastFile = repos.getFileVersion(file.id(), version)

    if file.same(lastFile):
	return version

    return None

def makeFileId(*args):
    assert(args)
    str = "".join(args)
    return _IdGen()(str)
<|endoftext|>


<commit_before>from data_importers.management.commands import BaseXpressDemocracyClubCsvImporter

class Command(BaseXpressDemocracyClubCsvImporter):
    council_id = "MIK"
    addresses_name = "2021-04-12T09:06:38.958847/Democracy_Club__06May2021.tsv"
    stations_name = "2021-04-12T09:06:38.958847/Democracy_Club__06May2021.tsv"
    elections = ["2021-05-06"]
    csv_delimiter = "\t"

    def station_record_to_dict(self, record):

        if record.polling_place_id in [
            "8851",  # Stony Stratford Library 5-7 Church Street Stony Stratford Milton Keynes MK11 1BD
            "8915",  # Moorlands Family Centre Dodkin Beanhill MK6 4LP
            "8628",  # St Mary`s Church Newport Road Woughton on the Green Milton Keynes MK6 3BE
        ]:
            record = record._replace(polling_place_easting="")
            record = record._replace(polling_place_northing="")

        return super().station_record_to_dict(record)

    def address_record_to_dict(self, record):
        uprn = record.property_urn.strip().lstrip("0")

        if uprn in [
            "25098995",  # BUNGALOW WOBURN GOLF AND COUNTRY CLUB BOW BRICKHILL TO LITTLE BRICKHILL ROAD, LITTLE BRICKHILL
            "25074114",  # DROPSHORT FARM, WATLING STREET, LITTLE BRICKHILL, MILTON KEYNES
            "25063716",  # SKEW BRIDGE COTTAGE, DRAYTON ROAD, BLETCHLEY, MILTON KEYNES
            "25003647",  # SHENLEY GROUNDS FARM WHADDON ROAD, CALVERTON
            "25107493",  # MAYA LOFT AYLESBURY STREET, WOLVERTON
            "25107492",  # FLAT 1, INCA HOUSE, AYLESBURY STREET, WOLVERTON, MILTON KEYNES
            "25093780",  # NEW FARM HOUSE, PINDON END, HANSLOPE, MILTON KEYNES
            "25093789",  # CARAVAN 2 BLACK HORSE LODGE WOLVERTON ROAD, GREAT LINFORD, MILTON KEYNES
            "25093788",  # CARAVAN 1 BLACK HORSE LODGE WOLVERTON ROAD, GREAT LINFORD, MILTON KEYNES
            "10094484063",  # THE BUNGALOW WOODLEYS FARM BOW BRICKHILL ROAD, WOBURN SANDS
            "10094484064",  # THE COTTAGE WOODLEYS FARM BOW BRICKHILL ROAD, WOBURN SANDS
            "10094480672",  # 5 IVY CLOSE, NEWPORT PAGNELL
        ]:
            return None

        if record.addressline6 in [
            "MK2 2NY",
            "MK13 9DZ",
            "MK13 7NH",
            "MK17 9NH",
            "MK4 4EL",
            "MK4 4AG",
            "MK4 4AU",
            "MK46 5AF",
            "MK46 4JS",
            "MK16 0HW",
            "MK14 6DL",
            "MK12 5LS",
            "MK9 2HS",
            "MK46 5LN",
        ]:
            return None

        return super().address_record_to_dict(record)
<commit_msg>Import script for Milton Keynes (2022-05-05) (closes #4528)<commit_after>from data_importers.management.commands import BaseXpressDemocracyClubCsvImporter

class Command(BaseXpressDemocracyClubCsvImporter):
    council_id = "MIK"
    addresses_name = (
        "2022-05-05/2022-03-31T17:15:28.543864/Democracy_Club__05May2022.tsv"
    )
    stations_name = (
        "2022-05-05/2022-03-31T17:15:28.543864/Democracy_Club__05May2022.tsv"
    )
    elections = ["2022-05-05"]
    csv_delimiter = "\t"

    def station_record_to_dict(self, record):
        # Stony Stratford Library 5-7 Church Street Stony Stratford Milton Keynes MK11 1BD
        if record.polling_place_id == "9878":
            # not actually in the sea
            record = record._replace(
                polling_place_easting="",
                polling_place_northing="",
                polling_place_uprn="25001127",
            )

        # Moorlands Family Centre Dodkin Beanhill MK6 4LP
        if record.polling_place_id == "9938":
            # also not in the sea
            record = record._replace(
                polling_place_easting="",
                polling_place_northing="",
                polling_place_uprn="10090355529",
            )

        return super().station_record_to_dict(record)

    def address_record_to_dict(self, record):
        uprn = record.property_urn.strip().lstrip("0")

        if uprn in [
            "25063716",  # SKEW BRIDGE COTTAGE, DRAYTON ROAD, BLETCHLEY, MILTON KEYNES
            "25107493",  # MAYA LOFT AYLESBURY STREET, WOLVERTON
            "25091328",  # BROUGHTON MANOR, BROUGHTON, MILTON KEYNES
        ]:
            return None

        if record.addressline6 in [
            "MK4 4EL",
            "MK17 8XS",
            "MK13 9DZ",
            "MK4 4AU",
            "MK46 4JS",
            "MK14 6DL",
            "MK4 4AG",
            "MK46 5AF",
            "MK13 7NH",
            "MK7 7FP",
        ]:
            return None

        return super().address_record_to_dict(record)
<|endoftext|>


<commit_before>from warnings import warn
from tables.tableextension import *

_warnmsg = ("tableExtension is pending deprecation, import tableextension instead. "
            "You may use the pt2to3 tool to update your source code.")
warn(_warnmsg, DeprecationWarning, stacklevel=2)
<commit_msg>Delete tableExtension.py<commit_after><|endoftext|>


<commit_before>#
# Copyright (c) 2004 Specifix, Inc.
# All rights reserved
#
import changeset
import commit
import copy
import files
import lookaside
import os
import package
import recipe
import sha1helper
import shutil
import tempfile
import time
import types
import util

# type could be "src"
def createPackage(repos, cfg, destdir, fileList, name, version, ident,
		  pkgtype = "auto"):
    fileMap = {}
    p = package.Package(name)

    for filePath in fileList:
	if pkgtype == "auto":
	    realPath = destdir + filePath
	    targetPath = filePath
	else:
	    realPath = filePath
	    targetPath = os.path.basename(filePath)

	file = files.FileFromFilesystem(realPath, ident(targetPath),
					type = pkgtype)

	infoFile = repos.getFileDB(file.id())

	duplicateVersion = \
	    infoFile.checkBranchForDuplicate(cfg.defaultbranch, file)
	if not duplicateVersion:
	    p.addFile(file.id(), targetPath, version)
	else:
	    p.addFile(file.id(), targetPath, duplicateVersion)

	if (pkgtype == "src"):
	    fileMap[file.id()] = (file, realPath, targetPath)
	else:
	    fileMap[file.id()] = (file, realPath, targetPath)

    return (p, fileMap)

def cook(repos, cfg, recipeFile, prep=0, macros=()):
    repos.open("r")

    if type(recipeFile) is types.ClassType:
        classList = {recipeFile.__name__: recipeFile}
    else:
        classList = recipe.RecipeLoader(recipeFile)
    built = []

    for (className, recipeClass) in classList.items():
	print "Building", className

	# Find the files and ids which were owned by the last version of
	# this package on the branch. We also construct an object which
	# lets us look for source files this build needs inside of the
	# repository
	fileIdMap = {}
	fullName = cfg.packagenamespace + "/" + recipeClass.name
	lcache = lookaside.RepositoryCache(repos)
	pkg = None
	for pkgName in repos.getPackageList(fullName):
	    pkgSet = repos.getPackageSet(pkgName)
	    pkg = pkgSet.getLatestPackage(cfg.defaultbranch)
	    for (fileId, path, version) in pkg.fileList():
		fileIdMap[path] = fileId
		if path[0] != "/":
		    # we might need to retrieve this source file
		    # to enable a build, so we need to find the
		    # sha1 hash of it since that's how it's indexed
		    # in the file store
		    filedb = repos.getFileDB(fileId)
		    file = filedb.getVersion(version)
		    lcache.addFileHash(path, file.sha1())

	ident = IdGen(fileIdMap)

        srcdirs = [ os.path.dirname(recipeClass.filename), cfg.sourcepath % {'pkgname': recipeClass.name} ]
	recipeObj = recipeClass(cfg, lcache, srcdirs, macros)

	nameList = repos.getPackageList(fullName)
	version = None
	if nameList:
	    # if this package/version exists already, increment the
	    # existing revision
	    pkgSet = repos.getPackageSet(nameList[0])
	    version = pkgSet.getLatestVersion(cfg.defaultbranch)
	    if version and recipeObj.version == version.trailingVersion():
		version = copy.deepcopy(version)
		version.incrementVersionRelease()
	    else:
		version = None

	# this package/version doesn't exist yet
	if not version:
	    version = copy.deepcopy(cfg.defaultbranch)
	    version.appendVersionRelease(recipeObj.version, 1)

	builddir = cfg.buildpath + "/" + recipeObj.name

	recipeObj.setup()
	recipeObj.unpackSources(builddir)

        # if we're only extracting, continue to the next recipe class.
        if prep:
            continue

        cwd = os.getcwd()
        os.chdir(builddir + '/' + recipeObj.mainDir())

	repos.close()
	recipeObj.doBuild(builddir)
	repos.open("w")

	destdir = "/var/tmp/srs/%s-%d" % (recipeObj.name, int(time.time()))
        if os.path.exists(destdir):
            shutil.rmtree(destdir)
        util.mkdirChain(destdir)
	recipeObj.doInstall(builddir, destdir)

        os.chdir(cwd)

        pkgname = cfg.packagenamespace + "/" + recipeObj.name

	packageList = []
        recipeObj.packages(destdir)

	for (name, buildPkg) in recipeObj.getPackageSet().packageSet():
	    fullName = pkgname + "/" + name
	    (p, fileMap) = createPackage(repos, cfg, destdir, buildPkg.keys(),
				         fullName, version, ident, "auto")

            built.append(fullName)
	    packageList.append((fullName, p, fileMap))

        recipes = [ recipeClass.filename ]
        # add any recipe that this recipeClass decends from to the sources
        baseRecipeClasses = list(recipeClass.__bases__)
        while baseRecipeClasses:
            parent = baseRecipeClasses.pop()
            baseRecipeClasses.extend(list(parent.__bases__))
            if not parent.__dict__.has_key('filename'):
                continue
            if not parent.filename in recipes:
                recipes.append(parent.filename)

	srcList = []
	for file in recipeObj.allSources() + recipes:
            src = lookaside.findAll(cfg, lcache, file, recipeObj.name, srcdirs)
	    srcList.append(src)

	(p, fileMap) = createPackage(repos, cfg, destdir, srcList,
				     pkgname + "/sources", version, ident,
				     "src")
	packageList.append((pkgname + "/sources", p, fileMap))

	changeSet = changeset.CreateFromFilesystem(packageList, version)
	commit.commitChangeSet(repos, cfg, changeSet)

	repos.open("r")

	recipeObj.cleanup(builddir, destdir)

    return built

class IdGen:

    def __call__(self, path):
	if self.map.has_key(path):
	    return self.map[path]

	hash = sha1helper.hashString("%s %f %s" % (path, time.time(),
							self.noise))
	self.map[path] = hash
	return hash

    def __init__(self, map):
	# file ids need to be unique. we include the time and path when
	# we generate them; any data put here is also used
	uname = os.uname()
	self.noise = "%s %s" % (uname[1], uname[2])
	self.map = map
<commit_msg>we don't need to reopen the repository until after doInstall()<commit_after>#
# Copyright (c) 2004 Specifix, Inc.
# All rights reserved
#
import changeset
import commit
import copy
import files
import lookaside
import os
import package
import recipe
import sha1helper
import shutil
import tempfile
import time
import types
import util

# type could be "src"
def createPackage(repos, cfg, destdir, fileList, name, version, ident,
		  pkgtype = "auto"):
    fileMap = {}
    p = package.Package(name)

    for filePath in fileList:
	if pkgtype == "auto":
	    realPath = destdir + filePath
	    targetPath = filePath
	else:
	    realPath = filePath
	    targetPath = os.path.basename(filePath)

	file = files.FileFromFilesystem(realPath, ident(targetPath),
					type = pkgtype)

	infoFile = repos.getFileDB(file.id())

	duplicateVersion = \
	    infoFile.checkBranchForDuplicate(cfg.defaultbranch, file)
	if not duplicateVersion:
	    p.addFile(file.id(), targetPath, version)
	else:
	    p.addFile(file.id(), targetPath, duplicateVersion)

	if (pkgtype == "src"):
	    fileMap[file.id()] = (file, realPath, targetPath)
	else:
	    fileMap[file.id()] = (file, realPath, targetPath)

    return (p, fileMap)

def cook(repos, cfg, recipeFile, prep=0, macros=()):
    repos.open("r")

    if type(recipeFile) is types.ClassType:
        classList = {recipeFile.__name__: recipeFile}
    else:
        classList = recipe.RecipeLoader(recipeFile)
    built = []

    for (className, recipeClass) in classList.items():
	print "Building", className

	# Find the files and ids which were owned by the last version of
	# this package on the branch. We also construct an object which
	# lets us look for source files this build needs inside of the
	# repository
	fileIdMap = {}
	fullName = cfg.packagenamespace + "/" + recipeClass.name
	lcache = lookaside.RepositoryCache(repos)
	pkg = None
	for pkgName in repos.getPackageList(fullName):
	    pkgSet = repos.getPackageSet(pkgName)
	    pkg = pkgSet.getLatestPackage(cfg.defaultbranch)
	    for (fileId, path, version) in pkg.fileList():
		fileIdMap[path] = fileId
		if path[0] != "/":
		    # we might need to retrieve this source file
		    # to enable a build, so we need to find the
		    # sha1 hash of it since that's how it's indexed
		    # in the file store
		    filedb = repos.getFileDB(fileId)
		    file = filedb.getVersion(version)
		    lcache.addFileHash(path, file.sha1())

	ident = IdGen(fileIdMap)

        srcdirs = [ os.path.dirname(recipeClass.filename), cfg.sourcepath % {'pkgname': recipeClass.name} ]
	recipeObj = recipeClass(cfg, lcache, srcdirs, macros)

	nameList = repos.getPackageList(fullName)
	version = None
	if nameList:
	    # if this package/version exists already, increment the
	    # existing revision
	    pkgSet = repos.getPackageSet(nameList[0])
	    version = pkgSet.getLatestVersion(cfg.defaultbranch)
	    if version and recipeObj.version == version.trailingVersion():
		version = copy.deepcopy(version)
		version.incrementVersionRelease()
	    else:
		version = None

	# this package/version doesn't exist yet
	if not version:
	    version = copy.deepcopy(cfg.defaultbranch)
	    version.appendVersionRelease(recipeObj.version, 1)

	builddir = cfg.buildpath + "/" + recipeObj.name

	recipeObj.setup()
	recipeObj.unpackSources(builddir)

        # if we're only extracting, continue to the next recipe class.
        if prep:
            continue

        cwd = os.getcwd()
        os.chdir(builddir + '/' + recipeObj.mainDir())

	repos.close()
	recipeObj.doBuild(builddir)

	destdir = "/var/tmp/srs/%s-%d" % (recipeObj.name, int(time.time()))
        if os.path.exists(destdir):
            shutil.rmtree(destdir)
        util.mkdirChain(destdir)
	recipeObj.doInstall(builddir, destdir)

	repos.open("w")

        os.chdir(cwd)

        pkgname = cfg.packagenamespace + "/" + recipeObj.name

	packageList = []
        recipeObj.packages(destdir)

	for (name, buildPkg) in recipeObj.getPackageSet().packageSet():
	    fullName = pkgname + "/" + name
	    (p, fileMap) = createPackage(repos, cfg, destdir, buildPkg.keys(),
				         fullName, version, ident, "auto")

            built.append(fullName)
	    packageList.append((fullName, p, fileMap))

        recipes = [ recipeClass.filename ]
        # add any recipe that this recipeClass decends from to the sources
        baseRecipeClasses = list(recipeClass.__bases__)
        while baseRecipeClasses:
            parent = baseRecipeClasses.pop()
            baseRecipeClasses.extend(list(parent.__bases__))
            if not parent.__dict__.has_key('filename'):
                continue
            if not parent.filename in recipes:
                recipes.append(parent.filename)

	srcList = []
	for file in recipeObj.allSources() + recipes:
            src = lookaside.findAll(cfg, lcache, file, recipeObj.name, srcdirs)
	    srcList.append(src)

	(p, fileMap) = createPackage(repos, cfg, destdir, srcList,
				     pkgname + "/sources", version, ident,
				     "src")
	packageList.append((pkgname + "/sources", p, fileMap))

	changeSet = changeset.CreateFromFilesystem(packageList, version)
	commit.commitChangeSet(repos, cfg, changeSet)

	repos.open("r")

	recipeObj.cleanup(builddir, destdir)

    return built

class IdGen:

    def __call__(self, path):
	if self.map.has_key(path):
	    return self.map[path]

	hash = sha1helper.hashString("%s %f %s" % (path, time.time(),
							self.noise))
	self.map[path] = hash
	return hash

    def __init__(self, map):
	# file ids need to be unique. we include the time and path when
	# we generate them; any data put here is also used
	uname = os.uname()
	self.noise = "%s %s" % (uname[1], uname[2])
	self.map = map
<|endoftext|>


<commit_before>from django.forms import ModelForm
from django import forms
from models import Expense, ExpenseCategory

class CategoryCreationForm(ModelForm):

    class Meta:
        model = ExpenseCategory

class ExpenseCreationForm(ModelForm):

    class Meta:
        model = Expense
        exclude = ('usr', 'status')

    def save(self, request, commit=True):
        model = super(ExpenseCreationForm, self).save(commit=False)

        model.usr = request.user

        model.save()

        return model

    def clean_amount(self):
        amount = self.cleaned_data['amount']
        max_limit = self.cleaned_data['category'].max_limit
        if amount > max_limit:
            raise forms.ValidationError("Max limit for this category is %s" % (max_limit))
        elif amount <= 0:
            raise forms.ValidationError("Amount should be greater than 0.")
        else:
            return amount

<commit_msg>check if key 'category' exists before using it.<commit_after>from django.forms import ModelForm
from django import forms
from models import Expense, ExpenseCategory

class CategoryCreationForm(ModelForm):

    class Meta:
        model = ExpenseCategory

class ExpenseCreationForm(ModelForm):

    class Meta:
        model = Expense
        exclude = ('usr', 'status')

    def save(self, request, commit=True):
        model = super(ExpenseCreationForm, self).save(commit=False)

        model.usr = request.user

        model.save()

        return model

    def clean_amount(self):
        try:
            self.cleaned_data['category']
        except KeyError:
            raise forms.ValidationError("Select Category")
        amount = self.cleaned_data['amount']
        max_limit = self.cleaned_data['category'].max_limit
        if amount > max_limit:
            raise forms.ValidationError("Max limit for this category is %s" % (max_limit))
        elif amount <= 0:
            raise forms.ValidationError("Amount should be greater than 0.")
        else:
            return amount

<|endoftext|>


<commit_before>#-*- coding:utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    d$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from datetime import datetime
from openerp.osv import osv, fields
from openerp.tools.translate import _

class ResPartner(osv.Model):

    _inherit = "res.partner"

    def credit_available_order(self, cr, uid, id, payment_term_id, value, date=False,  context=None):
        if not date:
            date = datetime.strftime(datetime.now(), '%Y-%m-%d')

        payment_term_obj = self.pool.get('account.payment.term')
        result =  payment_term_obj.compute(cr, uid, payment_term_id, value, date_ref=date, context=context)
        sum = 0.0
        for elem in result:
            if elem[0] != date:
                sum += elem[1]

        if sum == 0.0:
            return True
        else:
            partner = self.browse(cr, uid, id[0], context=context)
            print partner.credit, sum, partner.credit_limit
            if partner.credit + sum <= partner.credit_limit:
                return True
            else:
                return False

    def credit_available_invoice(self, cr, uid, id, payment_term_id, value, date=False,  context=None):
        if not date:
            date = datetime.strftime(datetime.now(), '%Y-%m-%d')

        payment_term_obj = self.pool.get('account.payment.term')
        result =  payment_term_obj.compute(cr, uid, payment_term_id, value, date_ref=date, context=context)
        sum = 0.0
        for elem in result:
            if elem[0] != date:
                sum += elem[1]

        if sum == 0.0:
            return True
        else:
            partner = self.browse(cr, uid, id[0], context=context)
            if partner.credit - sum <= partner.credit_limit:
                return True
            else:
                return False

class SaleOrder(osv.Model):

    _inherit = 'sale.order'

    def action_button_confirm(self, cr, uid, ids, context=None):
        sale_order = self.browse(cr, uid, ids[0], context=context)

        if sale_order.payment_term:
            if self.pool.get('res.users').has_group(cr, uid,
            'account_invoice_payment_term.group_account_payment_term_unlimited'):
                return super(SaleOrder,self).action_button_confirm(cr, uid, ids, context=context)

            if not sale_order.partner_id.credit_available_order(sale_order.payment_term.id,
            sale_order.amount_total, date=sale_order.date_order, context=context):
                raise osv.except_osv(_('Error'),_('Not enough credit is available to confirm the order.'))

        return super(SaleOrder,self).action_button_confirm(cr, uid, ids, context=context)

class AccountInvoice(osv.Model):

    _inherit = 'account.invoice'

    def invoice_validate(self, cr, uid, ids, context=None):
        invoice = self.browse(cr, uid, ids[0], context=context)
        if invoice.type == 'out_invoice':
            if self.pool.get('res.users').has_group(cr, uid,
            'account_invoice_payment_term.group_account_payment_term_unlimited'):
                return super(AccountInvoice,self).invoice_validate(cr, uid, ids, context=context)

            if invoice.payment_term:
                date = invoice.date_invoice or False

                if not invoice.partner_id.credit_available_invoice(invoice.payment_term.id,
                invoice.amount_total, date=date, context=context):
                    raise osv.except_osv(_('Error'),_('Not enough credit is available to confirm the invoice.'))

        return super(AccountInvoice,self).invoice_validate(cr, uid, ids, context=context)
    <commit_msg>[IMP] - Added comment to undocumented method to improve reading<commit_after>#-*- coding:utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
#    d$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from datetime import datetime
from openerp.osv import osv, fields
from openerp.tools.translate import _

class ResPartner(osv.Model):

    _inherit = "res.partner"

    def credit_available_order(self, cr, uid, id, payment_term_id, value, date=False,  context=None):
        if not date:
            date = datetime.strftime(datetime.now(), '%Y-%m-%d')

        payment_term_obj = self.pool.get('account.payment.term')
        result =  payment_term_obj.compute(cr, uid, payment_term_id, value, date_ref=date, context=context)
        sum = 0.0
        # elem is a tuple of date, value
        # example ('2014-03-27', 200.65)
        for elem in result:
            if elem[0] != date:
                sum += elem[1]

        if sum == 0.0:
            return True
        else:
            partner = self.browse(cr, uid, id[0], context=context)
            print partner.credit, sum, partner.credit_limit
            if partner.credit + sum <= partner.credit_limit:
                return True
            else:
                return False

    def credit_available_invoice(self, cr, uid, id, payment_term_id, value, date=False,  context=None):
        if not date:
            date = datetime.strftime(datetime.now(), '%Y-%m-%d')

        payment_term_obj = self.pool.get('account.payment.term')
        result =  payment_term_obj.compute(cr, uid, payment_term_id, value, date_ref=date, context=context)
        sum = 0.0
        # elem is a tuple of date, value
        # example ('2014-03-27', 200.65)
        for elem in result:
            if elem[0] != date:
                sum += elem[1]

        if sum == 0.0:
            return True
        else:
            partner = self.browse(cr, uid, id[0], context=context)
            if partner.credit - sum <= partner.credit_limit:
                return True
            else:
                return False

class SaleOrder(osv.Model):

    _inherit = 'sale.order'

    def action_button_confirm(self, cr, uid, ids, context=None):
        sale_order = self.browse(cr, uid, ids[0], context=context)

        if sale_order.payment_term:
            if self.pool.get('res.users').has_group(cr, uid,
            'account_invoice_payment_term.group_account_payment_term_unlimited'):
                return super(SaleOrder,self).action_button_confirm(cr, uid, ids, context=context)

            if not sale_order.partner_id.credit_available_order(sale_order.payment_term.id,
            sale_order.amount_total, date=sale_order.date_order, context=context):
                raise osv.except_osv(_('Error'),_('Not enough credit is available to confirm the order.'))

        return super(SaleOrder,self).action_button_confirm(cr, uid, ids, context=context)

class AccountInvoice(osv.Model):

    _inherit = 'account.invoice'

    def invoice_validate(self, cr, uid, ids, context=None):
        invoice = self.browse(cr, uid, ids[0], context=context)
        if invoice.type == 'out_invoice':
            if self.pool.get('res.users').has_group(cr, uid,
            'account_invoice_payment_term.group_account_payment_term_unlimited'):
                return super(AccountInvoice,self).invoice_validate(cr, uid, ids, context=context)

            if invoice.payment_term:
                date = invoice.date_invoice or False

                if not invoice.partner_id.credit_available_invoice(invoice.payment_term.id,
                invoice.amount_total, date=date, context=context):
                    raise osv.except_osv(_('Error'),_('Not enough credit is available to confirm the invoice.'))

        return super(AccountInvoice,self).invoice_validate(cr, uid, ids, context=context)
    <|endoftext|>


<commit_before>#  Copyright 2015 Agile Business Group <http://www.agilebg.com>
#  License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from datetime import date, datetime

from dateutil.rrule import MONTHLY

from odoo.addons.account.tests.common import AccountTestInvoicingCommon

class TestTax(AccountTestInvoicingCommon):
    @classmethod
    def setUpClass(cls, chart_template_ref=None):
        super().setUpClass(chart_template_ref=chart_template_ref)

        cls.range_type = cls.env["date.range.type"].create(
            {"name": "Fiscal year", "company_id": False, "allow_overlap": False}
        )
        generator = cls.env["date.range.generator"]
        generator = generator.create(
            {
                "date_start": "%s-01-01" % datetime.now().year,
                "name_prefix": "%s-" % datetime.now().year,
                "type_id": cls.range_type.id,
                "duration_count": 1,
                "unit_of_time": str(MONTHLY),
                "count": 12,
            }
        )
        generator.action_apply()
        prev_year_generator = generator.create(
            {
                "date_start": "%s-01-01" % (datetime.now().year - 1),
                "name_prefix": "%s-" % (datetime.now().year - 1),
                "type_id": cls.range_type.id,
                "duration_count": 1,
                "unit_of_time": str(MONTHLY),
                "count": 12,
            }
        )
        prev_year_generator.action_apply()
        cls.tax_model = cls.env["account.tax"]
        cls.account_model = cls.env["account.account"]
        cls.term_model = cls.env["account.payment.term"]
        cls.term_line_model = cls.env["account.payment.term.line"]
        cls.invoice_model = cls.env["account.move"]
        cls.invoice_line_model = cls.env["account.move.line"]
        today = datetime.now().date()
        cls.current_period = cls.env["date.range"].search(
            [("date_start", "<=", today), ("date_end", ">=", today)]
        )
        cls.last_year_date = date(today.year - 1, today.month, today.day)
        cls.last_year_period = cls.env["date.range"].search(
            [
                ("date_start", "<=", cls.last_year_date),
                ("date_end", ">=", cls.last_year_date),
            ]
        )
        cls.vat_statement_model = cls.env["account.vat.period.end.statement"]
        cls.paid_vat_account = (
            cls.env["account.account"]
            .search(
                [
                    (
                        "user_type_id",
                        "=",
                        cls.env.ref("account.data_account_type_current_assets").id,
                    )
                ],
                limit=1,
            )
            .id
        )
        cls.received_vat_account = (
            cls.env["account.account"]
            .search(
                [
                    (
                        "user_type_id",
                        "=",
                        cls.env.ref("account.data_account_type_current_liabilities").id,
                    )
                ],
                limit=1,
            )
            .id
        )

        # ----- Set invoice date to recent date in the system
        # ----- This solves problems with account_invoice_sequential_dates
        cls.recent_date = (
            cls.invoice_model.search(
                [("invoice_date", "!=", False)], order="invoice_date desc", limit=1
            ).invoice_date
            or today
        )
        cls.last_year_recent_date = date(
            cls.recent_date.year - 1, cls.recent_date.month, cls.recent_date.day
        )
        cls.account_tax_22 = cls.company_data["default_tax_sale"].copy(
            {
                "name": "22%",
                "amount": 22,
                "amount_type": "percent",
                "vat_statement_account_id": cls.received_vat_account,
                "type_tax_use": "sale",
            }
        )
        cls.account_tax_22_credit = cls.company_data["default_tax_purchase"].copy(
            {
                "name": "22% credit",
                "amount": 22,
                "amount_type": "percent",
                "vat_statement_account_id": cls.paid_vat_account,
                "type_tax_use": "purchase",
            }
        )

        cls.vat_authority = cls.account_model.create(
            {
                "code": "VAT AUTH",
                "name": "VAT Authority",
                "reconcile": True,
                "user_type_id": cls.env.ref("account.data_account_type_payable").id,
            }
        )

        cls.account_payment_term = cls.term_model.create(
            {
                "name": "16 Days End of Month",
                "note": "16 Days End of Month",
            }
        )
        cls.term_line_model.create(
            {
                "value": "balance",
                "days": 16,
                "option": "after_invoice_month",
                "payment_id": cls.account_payment_term.id,
            }
        )
        cls.sale_journal = cls.company_data["default_journal_sale"]
        cls.purchase_journal = cls.company_data["default_journal_purchase"]
        cls.general_journal = cls.company_data["default_journal_misc"]

    def test_vat_statement(self):
        in_invoice_line_account = (
            self.env["account.account"]
            .search(
                [
                    (
                        "user_type_id",
                        "=",
                        self.env.ref("account.data_account_type_revenue").id,
                    )
                ],
                limit=1,
            )
            .id
        )

        out_invoice = self.invoice_model.create(
            {
                "invoice_date": self.recent_date,
                "journal_id": self.sale_journal.id,
                "partner_id": self.env.ref("base.res_partner_3").id,
                "move_type": "out_invoice",
                "invoice_line_ids": [
                    (
                        0,
                        0,
                        {
                            "name": "service",
                            "price_unit": 100,
                            "quantity": 1,
                            "tax_ids": [(6, 0, [self.account_tax_22.id])],
                        },
                    )
                ],
            }
        )
        out_invoice._recompute_tax_lines()
        out_invoice.action_post()

        in_invoice = self.invoice_model.create(
            {
                "invoice_date": self.recent_date,
                "journal_id": self.purchase_journal.id,
                "partner_id": self.env.ref("base.res_partner_4").id,
                "move_type": "in_invoice",
                "invoice_line_ids": [
                    (
                        0,
                        0,
                        {
                            "name": "service",
                            "account_id": in_invoice_line_account,
                            "price_unit": 50,
                            "quantity": 1,
                            "tax_ids": [(6, 0, [self.account_tax_22_credit.id])],
                        },
                    )
                ],
            }
        )
        in_invoice._recompute_tax_lines()
        in_invoice.action_post()

        last_year_in_invoice = self.invoice_model.create(
            {
                "invoice_date": self.last_year_recent_date,
                "journal_id": self.purchase_journal.id,
                "partner_id": self.env.ref("base.res_partner_4").id,
                "move_type": "in_invoice",
                "invoice_line_ids": [
                    (
                        0,
                        0,
                        {
                            "name": "service",
                            "price_unit": 50,
                            "quantity": 1,
                            "tax_ids": [(6, 0, [self.account_tax_22_credit.id])],
                        },
                    )
                ],
            }
        )
        last_year_in_invoice._recompute_tax_lines()
        last_year_in_invoice.action_post()

        self.last_year_vat_statement = self.vat_statement_model.create(
            {
                "journal_id": self.general_journal.id,
                "authority_vat_account_id": self.vat_authority.id,
                "payment_term_id": self.account_payment_term.id,
                "date": self.last_year_date,
            }
        )
        self.last_year_period.vat_statement_id = self.last_year_vat_statement
        self.last_year_vat_statement.compute_amounts()

        self.vat_statement = self.vat_statement_model.create(
            {
                "journal_id": self.general_journal.id,
                "authority_vat_account_id": self.vat_authority.id,
                "payment_term_id": self.account_payment_term.id,
            }
        )
        self.current_period.vat_statement_id = self.vat_statement
        self.account_tax_22.refresh()
        self.vat_statement.compute_amounts()
        self.vat_statement._compute_authority_vat_amount()
        self.vat_statement.previous_credit_vat_account_id = self.received_vat_account

        self.assertEqual(self.vat_statement.previous_credit_vat_amount, 11)
        self.assertTrue(self.vat_statement.previous_year_credit)
        self.assertEqual(self.vat_statement.authority_vat_amount, 0)
        self.assertEqual(self.vat_statement.deductible_vat_amount, 11)
        self.assertEqual(self.vat_statement.residual, 0)
        self.assertEqual(len(self.vat_statement.debit_vat_account_line_ids), 1)
        self.assertEqual(len(self.vat_statement.credit_vat_account_line_ids), 1)
        self.vat_statement.advance_account_id = self.paid_vat_account
        self.vat_statement.advance_amount = 100
        self.vat_statement._compute_authority_vat_amount()
        self.assertEqual(self.vat_statement.authority_vat_amount, -100)
        self.vat_statement.create_move()
        self.assertEqual(self.vat_statement.state, "confirmed")
        self.assertTrue(self.vat_statement.move_id)
        vat_auth_found = False
        for line in self.vat_statement.move_id.line_ids:
            if line.account_id.id == self.vat_statement.authority_vat_account_id.id:
                vat_auth_found = True
                self.assertEqual(line.debit, 100)
        self.assertTrue(vat_auth_found)
        # TODO payment
<commit_msg>[FIX] account_vat_period_end_statement: fix test tags<commit_after>#  Copyright 2015 Agile Business Group <http://www.agilebg.com>
#  License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from datetime import date, datetime

from dateutil.rrule import MONTHLY

from odoo.tests import tagged

from odoo.addons.account.tests.common import AccountTestInvoicingCommon

@tagged("post_install", "-at_install")
class TestTax(AccountTestInvoicingCommon):
    @classmethod
    def setUpClass(cls, chart_template_ref=None):
        super().setUpClass(chart_template_ref=chart_template_ref)

        cls.range_type = cls.env["date.range.type"].create(
            {"name": "Fiscal year", "company_id": False, "allow_overlap": False}
        )
        generator = cls.env["date.range.generator"]
        generator = generator.create(
            {
                "date_start": "%s-01-01" % datetime.now().year,
                "name_prefix": "%s-" % datetime.now().year,
                "type_id": cls.range_type.id,
                "duration_count": 1,
                "unit_of_time": str(MONTHLY),
                "count": 12,
            }
        )
        generator.action_apply()
        prev_year_generator = generator.create(
            {
                "date_start": "%s-01-01" % (datetime.now().year - 1),
                "name_prefix": "%s-" % (datetime.now().year - 1),
                "type_id": cls.range_type.id,
                "duration_count": 1,
                "unit_of_time": str(MONTHLY),
                "count": 12,
            }
        )
        prev_year_generator.action_apply()
        cls.tax_model = cls.env["account.tax"]
        cls.account_model = cls.env["account.account"]
        cls.term_model = cls.env["account.payment.term"]
        cls.term_line_model = cls.env["account.payment.term.line"]
        cls.invoice_model = cls.env["account.move"]
        cls.invoice_line_model = cls.env["account.move.line"]
        today = datetime.now().date()
        cls.current_period = cls.env["date.range"].search(
            [("date_start", "<=", today), ("date_end", ">=", today)]
        )
        cls.last_year_date = date(today.year - 1, today.month, today.day)
        cls.last_year_period = cls.env["date.range"].search(
            [
                ("date_start", "<=", cls.last_year_date),
                ("date_end", ">=", cls.last_year_date),
            ]
        )
        cls.vat_statement_model = cls.env["account.vat.period.end.statement"]
        cls.paid_vat_account = (
            cls.env["account.account"]
            .search(
                [
                    (
                        "user_type_id",
                        "=",
                        cls.env.ref("account.data_account_type_current_assets").id,
                    )
                ],
                limit=1,
            )
            .id
        )
        cls.received_vat_account = (
            cls.env["account.account"]
            .search(
                [
                    (
                        "user_type_id",
                        "=",
                        cls.env.ref("account.data_account_type_current_liabilities").id,
                    )
                ],
                limit=1,
            )
            .id
        )

        # ----- Set invoice date to recent date in the system
        # ----- This solves problems with account_invoice_sequential_dates
        cls.recent_date = (
            cls.invoice_model.search(
                [("invoice_date", "!=", False)], order="invoice_date desc", limit=1
            ).invoice_date
            or today
        )
        cls.last_year_recent_date = date(
            cls.recent_date.year - 1, cls.recent_date.month, cls.recent_date.day
        )
        cls.account_tax_22 = cls.company_data["default_tax_sale"].copy(
            {
                "name": "22%",
                "amount": 22,
                "amount_type": "percent",
                "vat_statement_account_id": cls.received_vat_account,
                "type_tax_use": "sale",
            }
        )
        cls.account_tax_22_credit = cls.company_data["default_tax_purchase"].copy(
            {
                "name": "22% credit",
                "amount": 22,
                "amount_type": "percent",
                "vat_statement_account_id": cls.paid_vat_account,
                "type_tax_use": "purchase",
            }
        )

        cls.vat_authority = cls.account_model.create(
            {
                "code": "VAT AUTH",
                "name": "VAT Authority",
                "reconcile": True,
                "user_type_id": cls.env.ref("account.data_account_type_payable").id,
            }
        )

        cls.account_payment_term = cls.term_model.create(
            {
                "name": "16 Days End of Month",
                "note": "16 Days End of Month",
            }
        )
        cls.term_line_model.create(
            {
                "value": "balance",
                "days": 16,
                "option": "after_invoice_month",
                "payment_id": cls.account_payment_term.id,
            }
        )
        cls.sale_journal = cls.company_data["default_journal_sale"]
        cls.purchase_journal = cls.company_data["default_journal_purchase"]
        cls.general_journal = cls.company_data["default_journal_misc"]

    def test_vat_statement(self):
        in_invoice_line_account = (
            self.env["account.account"]
            .search(
                [
                    (
                        "user_type_id",
                        "=",
                        self.env.ref("account.data_account_type_revenue").id,
                    )
                ],
                limit=1,
            )
            .id
        )

        out_invoice = self.invoice_model.create(
            {
                "invoice_date": self.recent_date,
                "journal_id": self.sale_journal.id,
                "partner_id": self.env.ref("base.res_partner_3").id,
                "move_type": "out_invoice",
                "invoice_line_ids": [
                    (
                        0,
                        0,
                        {
                            "name": "service",
                            "price_unit": 100,
                            "quantity": 1,
                            "tax_ids": [(6, 0, [self.account_tax_22.id])],
                        },
                    )
                ],
            }
        )
        out_invoice._recompute_tax_lines()
        out_invoice.action_post()

        in_invoice = self.invoice_model.create(
            {
                "invoice_date": self.recent_date,
                "journal_id": self.purchase_journal.id,
                "partner_id": self.env.ref("base.res_partner_4").id,
                "move_type": "in_invoice",
                "invoice_line_ids": [
                    (
                        0,
                        0,
                        {
                            "name": "service",
                            "account_id": in_invoice_line_account,
                            "price_unit": 50,
                            "quantity": 1,
                            "tax_ids": [(6, 0, [self.account_tax_22_credit.id])],
                        },
                    )
                ],
            }
        )
        in_invoice._recompute_tax_lines()
        in_invoice.action_post()

        last_year_in_invoice = self.invoice_model.create(
            {
                "invoice_date": self.last_year_recent_date,
                "journal_id": self.purchase_journal.id,
                "partner_id": self.env.ref("base.res_partner_4").id,
                "move_type": "in_invoice",
                "invoice_line_ids": [
                    (
                        0,
                        0,
                        {
                            "name": "service",
                            "price_unit": 50,
                            "quantity": 1,
                            "tax_ids": [(6, 0, [self.account_tax_22_credit.id])],
                        },
                    )
                ],
            }
        )
        last_year_in_invoice._recompute_tax_lines()
        last_year_in_invoice.action_post()

        self.last_year_vat_statement = self.vat_statement_model.create(
            {
                "journal_id": self.general_journal.id,
                "authority_vat_account_id": self.vat_authority.id,
                "payment_term_id": self.account_payment_term.id,
                "date": self.last_year_date,
            }
        )
        self.last_year_period.vat_statement_id = self.last_year_vat_statement
        self.last_year_vat_statement.compute_amounts()

        self.vat_statement = self.vat_statement_model.create(
            {
                "journal_id": self.general_journal.id,
                "authority_vat_account_id": self.vat_authority.id,
                "payment_term_id": self.account_payment_term.id,
            }
        )
        self.current_period.vat_statement_id = self.vat_statement
        self.account_tax_22.refresh()
        self.vat_statement.compute_amounts()
        self.vat_statement._compute_authority_vat_amount()
        self.vat_statement.previous_credit_vat_account_id = self.received_vat_account

        self.assertEqual(self.vat_statement.previous_credit_vat_amount, 11)
        self.assertTrue(self.vat_statement.previous_year_credit)
        self.assertEqual(self.vat_statement.authority_vat_amount, 0)
        self.assertEqual(self.vat_statement.deductible_vat_amount, 11)
        self.assertEqual(self.vat_statement.residual, 0)
        self.assertEqual(len(self.vat_statement.debit_vat_account_line_ids), 1)
        self.assertEqual(len(self.vat_statement.credit_vat_account_line_ids), 1)
        self.vat_statement.advance_account_id = self.paid_vat_account
        self.vat_statement.advance_amount = 100
        self.vat_statement._compute_authority_vat_amount()
        self.assertEqual(self.vat_statement.authority_vat_amount, -100)
        self.vat_statement.create_move()
        self.assertEqual(self.vat_statement.state, "confirmed")
        self.assertTrue(self.vat_statement.move_id)
        vat_auth_found = False
        for line in self.vat_statement.move_id.line_ids:
            if line.account_id.id == self.vat_statement.authority_vat_account_id.id:
                vat_auth_found = True
                self.assertEqual(line.debit, 100)
        self.assertTrue(vat_auth_found)
        # TODO payment
<|endoftext|>


<commit_before># coding=utf-8
from django.db import models

# Create your models here.

class Event(models.Model):
    class Meta:
        verbose_name = u'展会'
        verbose_name_plural = u'展会'

    name = models.CharField(max_length=64, unique=True, verbose_name=u'名字')
    abbr = models.CharField(max_length=64, blank=True, default='', verbose_name=u'简写')

    def __unicode__(self):
        if self.abbr:
            return u'%s(%s)' % (self.name, self.abbr)
        else:
            return self.name

class Tag(models.Model):

    name = models.CharField(max_length=255, blank=False, null=False, unique=True, verbose_name=u'tag名称')

    def __unicode__(self):
        return self.name

class Booth(models.Model):
    class Meta:
        verbose_name = u'摊位'
        verbose_name_plural = u'摊位'

    event = models.ForeignKey(Event, verbose_name=u'展会')
    circle = models.CharField(max_length=64, verbose_name=u'社团名/企业名')
    logo = models.ImageField(upload_to='booth-logo', blank=True, max_length=255, verbose_name=u'LOGO')
    location = models.CharField(max_length=64, blank=True, verbose_name=u'摊位号')
    page = models.URLField(max_length=255, blank=True, verbose_name=u'专门页面')
    tags = models.TextField(blank=True, verbose_name=u'标签（用英文逗号,分隔）')
    comment = models.TextField(blank=True, verbose_name=u'备注')
    tag_set = models.ManyToManyField(Tag, through='BoothTag', through_fields=('booth','tag'), related_name='booth_set')

    def __unicode__(self):
        return u'%s - %s' % (self.circle, self.location)

    def save(self, *args, **kwargs):
        def parse_tags(tag_str):
            sp = ','
            tags = [t.strip() for t in tag_str.strip().split(sp)]
            tags = [t for t in tags if t]
            return tags

        tags = parse_tags(self.tags)
        for t in tags:
            try:
                tag = Tag.objects.get(name__exact=t)
                try:
                    self.tag_set.add(tag)
                except:
                    pass
            except Tag.DoesNotExist:
                self.tag_set.create(name=t)

        super(Booth, self).save(*args, **kwargs)

class BoothTag(models.Model):
    class Meta:
        db_table = 'expo_booth_tag_set'

    booth = models.ForeignKey(Booth)
    tag = models.ForeignKey(Tag)
<commit_msg>modified<commit_after># coding=utf-8
from django.db import models

# Create your models here.

class Event(models.Model):
    class Meta:
        verbose_name = u'展会'
        verbose_name_plural = u'展会'

    name = models.CharField(max_length=64, unique=True, verbose_name=u'名字')
    abbr = models.CharField(max_length=64, blank=True, default='', verbose_name=u'简写')

    def __unicode__(self):
        if self.abbr:
            return u'%s(%s)' % (self.name, self.abbr)
        else:
            return self.name

class Tag(models.Model):

    name = models.CharField(max_length=255, blank=False, null=False, unique=True, verbose_name=u'tag名称')

    def __unicode__(self):
        return self.name

class Booth(models.Model):
    class Meta:
        verbose_name = u'摊位'
        verbose_name_plural = u'摊位'

    event = models.ForeignKey(Event, verbose_name=u'展会')
    circle = models.CharField(max_length=64, verbose_name=u'社团名/企业名')
    logo = models.ImageField(upload_to='booth-logo', blank=True, max_length=255, verbose_name=u'LOGO')
    location = models.CharField(max_length=64, blank=True, verbose_name=u'摊位号')
    page = models.URLField(max_length=255, blank=True, verbose_name=u'专门页面')
    tags = models.TextField(blank=True, verbose_name=u'标签（用英文逗号,分隔）')
    comment = models.TextField(blank=True, verbose_name=u'备注')
    tag_set = models.ManyToManyField(Tag, through='BoothTag', through_fields=('booth','tag'), related_name='booth_set')

    def __unicode__(self):
        return u'%s - %s' % (self.circle, self.location)

    def save(self, *args, **kwargs):
        def parse_tags(tag_str):
            sp = ','
            tags = [t.strip() for t in tag_str.strip().split(sp)]
            tags = [t for t in tags if t]
            return tags

        super(Booth, self).save(*args, **kwargs)

        tags = parse_tags(self.tags)
        for t in tags:
            tag, created = Tag.objects.get_or_create(name=t)
            try:
                BoothTag.objects.create(booth=self, tag=tag)
            except:
                pass

class BoothTag(models.Model):
    class Meta:
        db_table = 'expo_booth_tag_set'

    booth = models.ForeignKey(Booth)
    tag = models.ForeignKey(Tag)
<|endoftext|>


<commit_before>import codecs
import logging
import sys

try:
    import requests_cache
    requests_cache.install_cache('fr_cache')
except ImportError:
    # If the cache library isn't present, do nothing -- we'll just make full
    # HTTP requests rather than looking it up from the cache
    pass

from regparser.builder import Builder, LayerCacheAggregator
from regparser.diff.tree import changes_between
from regparser.tree.struct import FrozenNode

logger = logging.getLogger('build_from')
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())

if __name__ == "__main__":
    if len(sys.argv) < 5:
        print("Usage: python build_from.py regulation.xml title "
              + "notice_doc_# act_title act_section (Generate diffs? "
              + "True/False)")
        print("  e.g. python build_from.py rege.txt 12 15 1693 "
              + "False")
        exit()

    with codecs.open(sys.argv[1], 'r', 'utf-8') as f:
        reg = f.read()

    #   First, the regulation tree
    reg_tree = Builder.reg_tree(reg)

    title = int(sys.argv[2])
    title_part = reg_tree.label_id()

    doc_number = Builder.determine_doc_number(reg, title, title_part)
    if not doc_number:
        raise ValueError("Could not determine document number")

    #   Run Builder
    builder = Builder(cfr_title=title,
                      cfr_part=title_part,
                      doc_number=doc_number)

    #  Didn't include the provided version
    if not any(n['document_number'] == doc_number for n in builder.notices):
        print("Could not find notice_doc_#, %s" % doc_number)
        exit()

    builder.write_notices()

    #   Always do at least the first reg
    logger.info("Version %s", doc_number)
    builder.write_regulation(reg_tree)
    layer_cache = LayerCacheAggregator()
    builder.gen_and_write_layers(reg_tree, sys.argv[3:5], layer_cache)
    layer_cache.replace_using(reg_tree)
    if len(sys.argv) < 6 or sys.argv[5].lower() == 'true':
        all_versions = {doc_number: reg_tree}
        for last_notice, old, new_tree, notices in builder.revision_generator(
                reg_tree):
            version = last_notice['document_number']
            logger.info("Version %s", version)
            all_versions[version] = new_tree
            builder.doc_number = version
            builder.write_regulation(new_tree)
            layer_cache.invalidate_by_notice(last_notice)
            builder.gen_and_write_layers(new_tree, sys.argv[3:5],
                                         layer_cache, notices)
            layer_cache.replace_using(new_tree)

        from time import time
        start_time = time()
        # convert to frozen trees
        for doc in all_versions:
            all_versions[doc] = FrozenNode.from_node(all_versions[doc])

        # now build diffs - include "empty" diffs comparing a version to itself
        for lhs_version, lhs_tree in all_versions.iteritems():
            for rhs_version, rhs_tree in all_versions.iteritems():
                changes = changes_between(lhs_tree, rhs_tree)
                builder.writer.diff(
                    reg_tree.label_id(), lhs_version, rhs_version
                ).write(dict(changes))
        print(time() - start_time)
<commit_msg>Remove timing code<commit_after>import codecs
import logging
import sys

try:
    import requests_cache
    requests_cache.install_cache('fr_cache')
except ImportError:
    # If the cache library isn't present, do nothing -- we'll just make full
    # HTTP requests rather than looking it up from the cache
    pass

from regparser.builder import Builder, LayerCacheAggregator
from regparser.diff.tree import changes_between
from regparser.tree.struct import FrozenNode

logger = logging.getLogger('build_from')
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())

if __name__ == "__main__":
    if len(sys.argv) < 5:
        print("Usage: python build_from.py regulation.xml title "
              + "notice_doc_# act_title act_section (Generate diffs? "
              + "True/False)")
        print("  e.g. python build_from.py rege.txt 12 15 1693 "
              + "False")
        exit()

    with codecs.open(sys.argv[1], 'r', 'utf-8') as f:
        reg = f.read()

    #   First, the regulation tree
    reg_tree = Builder.reg_tree(reg)

    title = int(sys.argv[2])
    title_part = reg_tree.label_id()

    doc_number = Builder.determine_doc_number(reg, title, title_part)
    if not doc_number:
        raise ValueError("Could not determine document number")

    #   Run Builder
    builder = Builder(cfr_title=title,
                      cfr_part=title_part,
                      doc_number=doc_number)

    #  Didn't include the provided version
    if not any(n['document_number'] == doc_number for n in builder.notices):
        print("Could not find notice_doc_#, %s" % doc_number)
        exit()

    builder.write_notices()

    #   Always do at least the first reg
    logger.info("Version %s", doc_number)
    builder.write_regulation(reg_tree)
    layer_cache = LayerCacheAggregator()
    builder.gen_and_write_layers(reg_tree, sys.argv[3:5], layer_cache)
    layer_cache.replace_using(reg_tree)
    if len(sys.argv) < 6 or sys.argv[5].lower() == 'true':
        all_versions = {doc_number: reg_tree}
        for last_notice, old, new_tree, notices in builder.revision_generator(
                reg_tree):
            version = last_notice['document_number']
            logger.info("Version %s", version)
            all_versions[version] = new_tree
            builder.doc_number = version
            builder.write_regulation(new_tree)
            layer_cache.invalidate_by_notice(last_notice)
            builder.gen_and_write_layers(new_tree, sys.argv[3:5],
                                         layer_cache, notices)
            layer_cache.replace_using(new_tree)

        # convert to frozen trees
        for doc in all_versions:
            all_versions[doc] = FrozenNode.from_node(all_versions[doc])

        # now build diffs - include "empty" diffs comparing a version to itself
        for lhs_version, lhs_tree in all_versions.iteritems():
            for rhs_version, rhs_tree in all_versions.iteritems():
                changes = changes_between(lhs_tree, rhs_tree)
                builder.writer.diff(
                    reg_tree.label_id(), lhs_version, rhs_version
                ).write(dict(changes))
<|endoftext|>