def test_revise_one_parent_post_unselected(self): """ Tests a post request to revise a part which has one parent. This parent is not selected, and so its bom should not change. """ parent = PartController.create("RefParent", "Part", "a", self.user, self.DATA) parent.add_child(self.controller, 10, 25, "-") link = parent.get_children(1)[0].link data = { "revision": "b", "parents-TOTAL_FORMS": "1", "parents-INITIAL_FORMS": "1", "parents-0-selected": "", "parents-0-link": link.id, "parents-0-new_parent": parent.id, "children-TOTAL_FORMS": "0", "children-INITIAL_FORMS": "0", "documents-TOTAL_FORMS": "0", "documents-INITIAL_FORMS": "0", } response = self.post(self.base_url + "revisions/", data) revisions = self.controller.get_next_revisions() self.assertEqual(1, len(revisions)) rev = revisions[0].part self.assertEqual("b", rev.revision) # ensure the old revision is still a child of the parent children = parent.get_children(1) self.assertEqual([(1, link)], children) self.assertFalse(PartController(rev, self.user).get_parents())
def get_all_geometry_files(self, doc_file): if self.PartDecompose is not None: pctrl = PartController(self.PartDecompose, self._user) if self._stps is None: children_ids = [ c.link.child_id for c in pctrl.get_children(-1, related=("child__id"), only=( "child__id", "parent__id", )) ] if children_ids: docs = pmodels.DocumentPartLink.objects.now().filter( document__type="Document3D", part__in=children_ids).values_list("document", flat=True) dfs = pmodels.DocumentFile.objects.filter(document__in=docs, deprecated=False)\ .filter(is_stp).values_list("id", flat=True) self._stps = dfs else: self._stps = pmodels.DocumentFile.objects.none( ).values_list("id", flat=True) q = Q(stp=doc_file) stps = list(self._stps) if stps: q |= Q(stp__in=stps) gfs = GeometryFile.objects.filter(q) else: gfs = GeometryFile.objects.filter(stp=doc_file) return gfs.values_list("file", flat=True)
def test_revise_one_child_post_unselected(self): """ Tests a post request to revise a part with child which is not selected. """ child = PartController.create("RefChild", "Part", "a", self.user, self.DATA) self.controller.add_child(child, 10, 25, "-") link = self.controller.get_children(1)[0].link data = { "revision": "b", "parents-TOTAL_FORMS": "0", "parents-INITIAL_FORMS": "0", "children-TOTAL_FORMS": "1", "children-INITIAL_FORMS": "1", "children-0-selected": "", "children-0-link": link.id, "documents-TOTAL_FORMS": "0", "documents-INITIAL_FORMS": "0", } response = self.post(self.base_url + "revisions/", data) revisions = self.controller.get_next_revisions() self.assertEqual(1, len(revisions)) rev = revisions[0].part self.assertEqual("b", rev.revision) # ensure the part is still a child of the old revision children = self.controller.get_children(1) self.assertEqual([(1, link)], children) # ensure the part is not a child of the new revision children = PartController(rev, self.user).get_children(1) self.assertEqual(0, len(children))
def test_update_no_checkin(self): ctrl = self.create("d1", "Document3D") natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.build_assembly(_ASSEMBLY1, natives, steps, False) tree = copy.deepcopy(_UPDATED_ASSEMBLY1) tree["children"][0]["document"]["checkin"] = False natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native") steps = get_steps("bolt.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.update_assembly(tree, natives, steps) self.assertEqual(5, models.Part.objects.all().count()) self.assertEqual(5, models.Document.objects.all().count()) # root root = PartController(ctrl.PartDecompose, self.user) self.assertDoc(root.object, "test.step", "test.native_asm") self.assertEqual("test", root.name) children = root.get_children(-1) self.assertEqual(4, len(children)) # l-bracket pcl = children[0].link child = pcl.child self.assertLink(pcl, "L-BRACKET", root.object, 1, 1) self.assertDoc(child, u"l-bracket.step", u"L-BRACKET.native") # nba_asm pcl = children[1].link child = nba_asm = pcl.child self.assertLink(pcl, "NBA_ASM", root.object, 2, 3) self.assertDoc(child, u"NBA_ASM.step", u"NBA_ASM.native_asm") # bolt pcl = children[2].link child = pcl.child self.assertLink(pcl, "BOLT", nba_asm, 1, 2) self.assertDoc(child, u"bolt.step", u"BOLT.native") # nut pcl = children[3].link child = pcl.child self.assertLink(pcl, "NUT", nba_asm, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # minor revisions of document files for doc in models.Document.objects.all(): for f in doc.files: if doc.name == "L-BRACKET": self.assertEqual(1, f.revision) else: self.assertEqual(2, f.revision) # check product is valid self.assertProduct(ctrl)
def _add_children(self, component, root): pctrl = PartController(root, self.user) pctrl.check_readable() children = pctrl.get_children(-1) if not children: return components = { root.id: component, } links = [c.link for c in children] locations = defaultdict(list) # pcl -> locations for loc in Location_link.objects.filter(link__in=links): locations[loc.link_id].append(loc) parts = [l.child_id for l in links] part2doc = {} for doc in Document3D.objects.filter(PartDecompose__in=parts): key = doc.PartDecompose_id # if two revisions are present, takes the newest one otherdoc = part2doc.get(key) if otherdoc is None or otherdoc.ctime < doc.ctime: part2doc[key] = doc visited_links = set() mtime = root.ctime for link in links: if link.id in visited_links: pass try: comp = components[link.parent_id] part = link.child doc = part2doc[part.id] locs = locations[link.id] except KeyError: # it is not an interessing link pass else: mtime = max(mtime, link.ctime) child_comp = self._get_component(doc, part) locs = [{"local_name": l.name, "local_matrix": l.to_array()} for l in locs] comp["children"].append({ "component": child_comp, "locations": locs, }) components[part.id] = child_comp visited_links.add(link.id) self._allowed_checkout = self._get_checkout(mtime)
def test_update_assembly_locations(self): ctrl = self.create("d1", "Document3D") natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.build_assembly(_ASSEMBLY1, natives, steps, False) tree = copy.deepcopy(_UPDATED_ASSEMBLY1) m1 = [1, 7, 5, 9, 5, 4, 3, 2, 2, 0, 5, 1] tree["children"][0]["local_matrix"] = m1 steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.update_assembly(tree, natives, steps) self.assertEqual(5, models.Document.objects.all().count()) self.assertEqual(5, models.Part.objects.all().count()) # root root = PartController(ctrl.PartDecompose, self.user) self.assertDoc(root.object, "test.step", "test.native_asm") self.assertEqual("test", root.name) children = root.get_children(-1) self.assertEqual(4, len(children)) # l-bracket pcl = children[0].link child = pcl.child self.assertLink(pcl, "L-BRACKET", root.object, 1, 1) self.assertEqual(m1, pcl.extensions[0].to_array()) self.assertDoc(child, u"l-bracket.step", u"L-BRACKET.native") # nba_asm pcl = children[1].link child = nba_asm = pcl.child self.assertLink(pcl, "NBA_ASM", root.object, 2, 3) self.assertDoc(child, u"NBA_ASM.step", u"NBA_ASM.native_asm") # bolt pcl = children[2].link child = pcl.child self.assertLink(pcl, "BOLT", nba_asm, 1, 2) self.assertDoc(child, u"bolt.step", u"BOLT.native") # nut pcl = children[3].link child = pcl.child self.assertLink(pcl, "NUT", nba_asm, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # check product is valid self.assertProduct(ctrl)
def test_build_assembly(self): self.assertEqual(0, models.PLMObject.objects.all().count()) ctrl = self.create("d1", "Document3D") natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) df = builder.build_assembly(_ASSEMBLY1, natives, steps, False) self.assertEqual(5, models.Document.objects.all().count()) self.assertEqual(5, models.Part.objects.all().count()) # root self.assertEqual("test.native_asm", df.filename) root = PartController(ctrl.PartDecompose, self.user) self.assertDoc(root.object, "test.step", "test.native_asm") self.assertEqual("test", root.name) children = root.get_children(-1) self.assertEqual(4, len(children)) # l-bracket pcl = children[0].link child = pcl.child self.assertLink(pcl, "L-BRACKET", root.object, 1, 1) self.assertEqual( [4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], pcl.extensions[0].to_array()) self.assertDoc(child, u"l-bracket.step", u"L-BRACKET.native") # nba_asm pcl = children[1].link child = nba_asm = pcl.child self.assertLink(pcl, "NBA_ASM", root.object, 2, 3) self.assertDoc(child, u"NBA_ASM.step", u"NBA_ASM.native_asm") # bolt pcl = children[2].link child = pcl.child self.assertLink(pcl, "BOLT", nba_asm, 1, 1) self.assertDoc(child, u"bolt.step", u"BOLT.native") # nut pcl = children[3].link child = pcl.child self.assertLink(pcl, "NUT", nba_asm, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # check product is valid self.assertProduct(ctrl)
def test_revise_two_childrens_post(self): """ Tests a post request to revise a part with two children. Only one child is selected. """ child1 = PartController.create("RefChild1", "Part", "a", self.user, self.DATA) self.controller.add_child(child1, 10, 25, "-") child2 = PartController.create("RefChild2", "Part", "a", self.user, self.DATA) self.controller.add_child(child2, 10, 55, "-") link1, link2 = [c.link for c in self.controller.get_children(1)] data = { "revision": "b", "parents-TOTAL_FORMS": "0", "parents-INITIAL_FORMS": "0", "children-TOTAL_FORMS": "1", "children-INITIAL_FORMS": "1", "children-0-selected": "on", "children-0-link": link1.id, "children-1-selected": "", "children-1-link": link2.id, "documents-TOTAL_FORMS": "0", "documents-INITIAL_FORMS": "0", } response = self.post(self.base_url + "revisions/", data) revisions = self.controller.get_next_revisions() self.assertEqual(1, len(revisions)) rev = revisions[0].part self.assertEqual("b", rev.revision) # ensure the part is still a child of the old revision children = self.controller.get_children(1) self.assertEqual(set(((1, link1), (1, link2))), set(children)) children = PartController(rev, self.user).get_children(1) self.assertEqual(1, len(children)) link = children[0].link self.assertEqual(link1.child, link.child) self.assertEqual(link1.order, link.order) self.assertEqual(link1.quantity, link.quantity) self.assertEqual(link1.unit, link.unit)
def test_attach(self): expected = [] result_part = [] result_doc = [] for pstate, dstate, powner, downer, can_attach in self.MATRICE: self.part.object.state = self.states[pstate] self.part.object.lifecycle = self.lifecycles[pstate] self.doc.object.state = self.states[dstate] self.doc.object.lifecycle = self.lifecycles[dstate] self.part.set_owner(self.user if powner else self.other_owner, True) self.doc.set_owner(self.user if downer else self.other_owner, True) expected.append(can_attach) pctrl = PartController(self.part.object, self.user) result_part.append(pctrl.can_attach_document(self.doc.object)) dctrl = DocumentController(self.doc.object, self.user) result_doc.append(dctrl.can_attach_part(self.part.object)) self.assertEqual(expected, result_part) self.assertEqual(expected, result_doc)
def get_product(self, doc_file, recursive=False): """ Returns the :class:`.Product` associated to *doc_file*. If *recursive* is True, it returns a complet product, built by browsing the BOM of the attached part, if it has been decomposed. """ try: af = ArbreFile.objects.get(stp=doc_file) except: return None product = classes.Product.from_list(json.loads(af.file.read())) if recursive and product: if self.PartDecompose is not None: # Here be dragons # this code try to reduce the number of database queries: # h queries (h: height of the BOM) to get children # + 1 query to doc-part links # + 1 query to get STP files # + 1 query to get location links # + 1 query to get ArbreFile pctrl = PartController(self.PartDecompose, self._user) children = pctrl.get_children(-1, related=("child__id"), only=( "child__id", "parent__id", )) if not children: return product links, children_ids = zip(*[(c.link.id, c.link.child_id) for c in children]) docs = [] part_to_docs = defaultdict(list) for doc, part in pmodels.DocumentPartLink.current_objects.filter( document__type="Document3D", part__in=children_ids).values_list( "document", "part").order_by("-ctime"): # order by -ctime to test the most recently attached document first part_to_docs[part].append(doc) docs.append(doc) if not docs: return product dfs = dict(pmodels.DocumentFile.objects.filter(document__in=docs, deprecated=False)\ .filter(is_stp).values_list("document", "id")) # cache this values as it may be useful for get_all_geometry_files self._stps = dfs.values() locs = defaultdict(list) for l in Location_link.objects.filter(link__in=links): locs[l.link_id].append(l) # read all jsons files jsons = {} for af in ArbreFile.objects.filter(stp__in=dfs.values()): jsons[af.stp_id] = json.loads(af.file.read()) # browse the BOM and build product previous_level = 0 products = [product] for level, link in children: if level <= previous_level: del products[level:] stp = None for doc in part_to_docs[link.child_id]: if doc in dfs: stp = dfs[doc] break if stp is not None and stp in jsons: pr = products[-1] prod = classes.Product.from_list( jsons[stp], product=False, product_root=product, deep=level, to_update_product_root=pr) for location in locs[link.id]: pr.links[-1].add_occurrence( location.name, location) products.append(prod) previous_level = level return product
def test_update_add_existing_rod(self): rod = self.create("rod", "Document3D") rod.name = "ROD" rod.save() rod_step = rod.add_file(get_steps("rod.step")[0]) rod_native = rod.add_file(get_natives("ROD.native")[0]) rod_part = PartController.create("rod", "Part", "a", self.user, { "group": self.group, "lifecycle": rod.lifecycle, "name": rod.name }) rod.attach_to_part(rod_part) rod.PartDecompose = rod_part.object rod.save() ctrl = self.create("d1", "Document3D") natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native", "ROD.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step", "rod.step") builder = AssemblyBuilder(ctrl) builder.build_assembly(_ASSEMBLY1, natives, steps, False) tree = copy.deepcopy(_UPDATED_ASSEMBLY1) tree["children"].append({ u'children': [], u'local_matrix': [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], u'local_name': u'ROD', u'native': { "id": rod_native.id }, u'part': { "id": rod_part.id }, u'document': { "id": rod.id, "checkin": True }, u'step': { "id": rod_step.id }, }) natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native", "ROD.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step", "rod.step") builder = AssemblyBuilder(ctrl) builder.update_assembly(tree, natives, steps) self.assertEqual(6, models.Part.objects.all().count()) self.assertEqual(6, models.Document.objects.all().count()) # root root = PartController(ctrl.PartDecompose, self.user) self.assertDoc(root.object, "test.step", "test.native_asm") self.assertEqual("test", root.name) children = root.get_children(-1) self.assertEqual(5, len(children)) # l-bracket pcl = children[0].link child = pcl.child self.assertLink(pcl, "L-BRACKET", root.object, 1, 1) self.assertDoc(child, u"l-bracket.step", u"L-BRACKET.native") # nba_asm pcl = children[1].link child = nba_asm = pcl.child self.assertLink(pcl, "NBA_ASM", root.object, 2, 3) self.assertDoc(child, u"NBA_ASM.step", u"NBA_ASM.native_asm") # bolt pcl = children[2].link child = pcl.child self.assertLink(pcl, "BOLT", nba_asm, 1, 2) self.assertDoc(child, u"bolt.step", u"BOLT.native") # nut pcl = children[3].link child = pcl.child self.assertLink(pcl, "NUT", nba_asm, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # rod pcl = children[4].link child = pcl.child self.assertEqual(child.id, rod_part.id) self.assertLink(pcl, "ROD", root.object, 3, 1) self.assertDoc(child, u"rod.step", u"ROD.native") # minor revisions of document files for doc in models.Document.objects.all(): for f in doc.files: self.assertEqual(2, f.revision) # check product is valid self.assertProduct(ctrl)
def test_update_new_assembly(self): ctrl = self.create("d1", "Document3D") natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.build_assembly(_ASSEMBLY1, natives, steps, False) tree = copy.deepcopy(_UPDATED_ASSEMBLY1) tree["children"].append({ u'children': [ { u'children': [], u'local_matrix': [ 1.5, 5.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ], u'local_name': u'BOLT', u'native': deferred_file('BOLT.native'), u'part': deferred_part('BOLT'), u'document': deferred_doc('BOLT'), u'step': deferred_file(u'bolt.step'), }, { u'children': [], u'local_matrix': [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 838.2, 0.0, 0.0, 1.0, 0.0 ], u'local_name': u'NUT', u'native': deferred_file('NUT.native'), u'part': deferred_part('NUT'), u'document': deferred_doc('NUT'), u'step': deferred_file(u'nut.step'), }, ], u'local_matrix': [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], u'local_name': u'ROD', u'native': u'ROD.native_asm', u'part_name': u'ROD', }) natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native", "ROD.native_asm") steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.update_assembly(tree, natives, steps) self.assertEqual(6, models.Part.objects.all().count()) self.assertEqual(6, models.Document.objects.all().count()) # root root = PartController(ctrl.PartDecompose, self.user) self.assertDoc(root.object, "test.step", "test.native_asm") self.assertEqual("test", root.name) children = root.get_children(-1) self.assertEqual(7, len(children)) # l-bracket pcl = children[0].link child = pcl.child self.assertLink(pcl, "L-BRACKET", root.object, 1, 1) self.assertDoc(child, u"l-bracket.step", u"L-BRACKET.native") # nba_asm pcl = children[1].link child = nba_asm = pcl.child self.assertLink(pcl, "NBA_ASM", root.object, 2, 3) self.assertDoc(child, u"NBA_ASM.step", u"NBA_ASM.native_asm") # bolt pcl = children[2].link child = pcl.child self.assertLink(pcl, "BOLT", nba_asm, 1, 2) self.assertDoc(child, u"bolt.step", u"BOLT.native") # nut pcl = children[3].link child = pcl.child self.assertLink(pcl, "NUT", nba_asm, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # rod pcl = children[4].link rod = child = pcl.child self.assertLink(pcl, "ROD", root.object, 3, 1) self.assertDoc(child, u"ROD.step", u"ROD.native_asm") # rod -> bolt pcl = children[5].link child = pcl.child self.assertLink(pcl, "BOLT", rod, 1, 1) self.assertDoc(child, u"bolt.step", u"BOLT.native") # rod -> nut pcl = children[6].link child = pcl.child self.assertLink(pcl, "NUT", rod, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # minor revisions of document files for doc in models.Document.objects.all(): for f in doc.files: if doc.name == "ROD": self.assertEqual(1, f.revision) else: self.assertEqual(2, f.revision) # check product is valid self.assertProduct(ctrl)
def test_update_assembly_more_bolts(self): ctrl = self.create("d1", "Document3D") natives = get_natives("test.native_asm", "NBA_ASM.native_asm", "NUT.native", "BOLT.native", "L-BRACKET.native") steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.build_assembly(_ASSEMBLY1, natives, steps, False) tree = copy.deepcopy(_UPDATED_ASSEMBLY1) m1 = [1, 7, 5, 9, 5, 4, 3, 2, 2, 0, 5, 1] tree["children"].append({ u'children': [], u'local_matrix': m1, u'local_name': u'BOLT', u'native': deferred_file('BOLT.native'), u'part': deferred_part('BOLT'), u'document': deferred_doc('BOLT'), u'step': deferred_file(u'bolt.step'), }) steps = get_steps("bolt.step", "l-bracket.step", "nut.step") builder = AssemblyBuilder(ctrl) builder.update_assembly(tree, natives, steps) self.assertEqual(5, models.Part.objects.all().count()) self.assertEqual(5, models.Document.objects.all().count()) # root root = PartController(ctrl.PartDecompose, self.user) self.assertDoc(root.object, "test.step", "test.native_asm") self.assertEqual("test", root.name) children = root.get_children(-1) self.assertEqual(5, len(children)) # l-bracket pcl = children[0].link child = pcl.child self.assertLink(pcl, "L-BRACKET", root.object, 1, 1) self.assertDoc(child, u"l-bracket.step", u"L-BRACKET.native") # nba_asm pcl = children[1].link child = nba_asm = pcl.child self.assertLink(pcl, "NBA_ASM", root.object, 2, 3) self.assertDoc(child, u"NBA_ASM.step", u"NBA_ASM.native_asm") # bolt pcl = children[2].link child = pcl.child first_bolt = child.id self.assertLink(pcl, "BOLT", nba_asm, 1, 2) self.assertDoc(child, u"bolt.step", u"BOLT.native") # nut pcl = children[3].link child = pcl.child self.assertLink(pcl, "NUT", nba_asm, 2, 1) self.assertDoc(child, u"nut.step", u"NUT.native") # new bolt pcl = children[4].link child = pcl.child self.assertLink(pcl, "BOLT", root.object, 3, 1) self.assertDoc(child, u"bolt.step", u"BOLT.native") self.assertEqual(first_bolt, child.id) # minor revisions of document files for doc in models.Document.objects.all(): for f in doc.files: self.assertEqual(2, f.revision) # check product is valid self.assertProduct(ctrl)